diff --git a/.gitignore b/.gitignore index ccd5df9..5e2299a 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,7 @@ wheels/ *.docx *.doc *.txt + +.vscode/ +.tmp/ +*.toml diff --git a/transit/config.py b/transit/config.py index a25209e..7a7e940 100644 --- a/transit/config.py +++ b/transit/config.py @@ -6,17 +6,15 @@ import tomllib @dataclass class ThesisConfig: - """论文配置数据(学生信息、元数据等,不包含正文内容)。""" + """论文配置数据。 - student_name: str = "" - student_id: str = "" - college: str = "" - major: str = "" - class_: str = "" - advisor: str = "" - advisor_title: str = "" - title: str = "" + ``metadata`` 直接透传 TOML 的 ``[metadata]`` 节,不再为每个变量声明字段。 + 新增模板变量只需改 TOML,无需修改 Python。 + """ + metadata: dict = field(default_factory=dict) + + # 以下字段仍有业务逻辑,保留为显式属性 title_from_md: bool = True body_start_keywords: list[str] = field(default_factory=lambda: ["绪论", "引言"]) body_end_keywords: list[str] = field( @@ -27,17 +25,8 @@ class ThesisConfig: reference_style: str = "列出段落1" def to_dict(self) -> dict: - """转成模板渲染用的扁平字典,排除 options 命名空间。""" - return { - "student_name": self.student_name, - "student_id": self.student_id, - "college": self.college, - "major": self.major, - "class": self.class_, - "advisor": self.advisor, - "advisor_title": self.advisor_title, - "title": self.title, - } + """透传 metadata(模板变量来源)。""" + return self.metadata def load_config(path: str | Path) -> ThesisConfig: @@ -50,14 +39,7 @@ def load_config(path: str | Path) -> ThesisConfig: opts = raw.get("options", {}) return ThesisConfig( - student_name=meta.get("student_name", ""), - student_id=meta.get("student_id", ""), - college=meta.get("college", ""), - major=meta.get("major", ""), - class_=meta.get("class", ""), - advisor=meta.get("advisor", ""), - advisor_title=meta.get("advisor_title", ""), - title=meta.get("title", ""), + metadata=meta, title_from_md=opts.get("title_from_md", True), body_start_keywords=opts.get("body_start_keywords", ["绪论", "引言"]), body_end_keywords=opts.get( diff --git a/transit/renderer.py b/transit/renderer.py index f54700e..e7fdf73 100644 --- a/transit/renderer.py +++ b/transit/renderer.py @@ -15,7 +15,8 @@ from .body import body_to_paragraphs, replace_placeholder from .references import references_to_paragraphs -_TEXT_FIELDS = [ +# 解析器可能产生的字段(用于填充报告) +_PARSER_FIELDS = [ "title", "abstact_cn_context", "abstract_cn_keywords", @@ -24,13 +25,7 @@ _TEXT_FIELDS = [ "acknowledgement", "reference", "appendix", - "student_name", - "student_id", - "college", - "major", - "class", - "advisor", - "advisor_title", + "body_md", ] @@ -81,12 +76,11 @@ def generate_thesis( body_end_kw=config.body_end_keywords, ) - # 3. 合并配置 → 上下文(配置优先) + # 3. 合并配置 → 上下文(配置填充解析器未产生的空白) for k, v in config.to_dict().items(): if k == "title" and config.title_from_md and context.get("title"): continue # 以 markdown 标题为准 - if v != "": - context[k] = v + context.setdefault(k, v) # 4. 用 defaultdict 兜底缺失键 ctx = defaultdict(lambda: "", context) @@ -129,17 +123,18 @@ def generate_thesis( print(f"[完成] 论文生成完成: {output_path}") - # 10. 字段填充报告 + # 10. 字段填充报告(动态收集所有模板与解析字段) + report_fields = list(dict.fromkeys([*config.metadata.keys(), *_PARSER_FIELDS])) print("\n--- 字段填充情况 ---") - for key in _TEXT_FIELDS: - val = ctx[key] + for key in report_fields: + val = ctx.get(key, "") if val == "": print(f" [缺失] {key}") else: preview = str(val)[:60].replace("\n", " ") print(f" [OK] {key}: {preview}...") - missing = [k for k in _TEXT_FIELDS if ctx[k] == ""] + missing = [k for k in report_fields if ctx.get(k, "") == ""] if missing: print("\n[警告] 以下字段缺失,已填充 '':") for f in missing: