zcbot/rendering/render.py

64 lines
3.0 KiB
Python

"""平台渲染统一入口。各 skill 出 docx/pdf 都调这一个,不再自带 render 脚本。
用法(沙盒内 / host 同):
python /sandbox/rendering/render.py --profile brief --format docx <sections> -o out.docx
python /sandbox/rendering/render.py --profile brief --format pdf <sections> -o out.pdf
python /sandbox/rendering/render.py --profile paper --format docx <sections> --lang zh -o out.docx
python /sandbox/rendering/render.py --profile proposal --format docx <sections> --fund-type key_rd -o out.docx
--no-color 出黑白(brief docx / 任意 pdf 生效)。<sections> 可为目录(拼接其 *.md)或单个 .md。
"""
from __future__ import annotations
import argparse
import os
import sys
from pathlib import Path
# bootstrap:让 `import rendering.*` 在 `python /sandbox/rendering/render.py` 直接调时也能解析。
# render.py 恒在 <root>/rendering/render.py,故 dirname(dirname(__file__)) 恒为含 rendering/ 的根
# (沙盒=/sandbox,host=repo 根),与挂载点 / 深度无关。
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from rendering import docx_brief, docx_manuscript, pdf # noqa: E402
def main(argv: list[str] | None = None) -> int:
ap = argparse.ArgumentParser(description="md(sections 目录或单 .md)→ docx / pdf")
ap.add_argument("src", type=Path, help="sections 目录(拼接其 *.md)或单个 .md")
ap.add_argument("--profile", required=True, choices=["brief", "paper", "proposal"])
ap.add_argument("--format", default="docx", choices=["docx", "pdf"])
ap.add_argument("-o", "--output", type=Path, required=True, help="输出路径")
ap.add_argument("--no-color", dest="color", action="store_false",
help="关配色出黑白(brief docx / pdf 生效)")
ap.add_argument("--lang", choices=["zh", "en"], default="en",
help="paper 图题前缀 图/Fig.;默认 en")
ap.add_argument("--toc", action="store_true", help="paper 生成目录页(proposal 始终带)")
ap.add_argument("--fund-type", default="key_rd",
help="proposal 基金类型(仅打印标注)")
args = ap.parse_args(argv)
if not args.src.exists():
print(f"[render] 输入不存在:{args.src}", file=sys.stderr)
return 1
if args.format == "pdf":
out = pdf.md_to_pdf(args.src, args.output, color=args.color, profile=args.profile)
print(f"[render] OK pdf -> {out} ({out.stat().st_size} bytes)")
return 0
# docx
if args.profile == "brief":
docx_brief.render_sections(args.src, args.output, args.color)
elif args.profile == "paper":
docx_manuscript.render_sections("paper", args.src, args.output,
lang=args.lang, toc=args.toc)
else: # proposal
docx_manuscript.render_sections("proposal", args.src, args.output,
fund_type=args.fund_type)
return 0
if __name__ == "__main__":
sys.exit(main())