from dataclasses import dataclass, field from pathlib import Path from typing import Optional import tomllib @dataclass class ThesisConfig: """论文配置数据(学生信息、元数据等,不包含正文内容)。""" student_name: str = "" student_id: str = "" college: str = "" major: str = "" class_: str = "" advisor: str = "" advisor_title: str = "" title: str = "" title_from_md: bool = True body_start_keywords: list[str] = field(default_factory=lambda: ["绪论", "引言"]) body_end_keywords: list[str] = field( default_factory=lambda: ["致谢", "参考文献", "附录"] ) 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, } def load_config(path: str | Path) -> ThesisConfig: """从 TOML 文件加载论文配置。""" path = Path(path) with open(path, "rb") as f: raw = tomllib.load(f) meta = raw.get("metadata", {}) 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", ""), title_from_md=opts.get("title_from_md", True), body_start_keywords=opts.get("body_start_keywords", ["绪论", "引言"]), body_end_keywords=opts.get( "body_end_keywords", ["致谢", "参考文献", "附录"] ), )