马一丁

Add Comments

@@ -68,7 +68,7 @@ class ChapterStorage: @@ -68,7 +68,7 @@ class ChapterStorage:
68 self.base_dir.mkdir(parents=True, exist_ok=True) 68 self.base_dir.mkdir(parents=True, exist_ok=True)
69 self._manifests: Dict[str, Dict[str, object]] = {} 69 self._manifests: Dict[str, Dict[str, object]] = {}
70 70
71 - # ======== 会话 & manifest ======== 71 + # ======== 会话与清单 ========
72 72
73 def start_session(self, report_id: str, metadata: Dict[str, object]) -> Path: 73 def start_session(self, report_id: str, metadata: Dict[str, object]) -> Path:
74 """ 74 """
@@ -51,19 +51,19 @@ class TemplateSection: @@ -51,19 +51,19 @@ class TemplateSection:
51 } 51 }
52 52
53 53
54 -# The parsing expressions intentionally avoid `.*` to keep matching deterministic and  
55 -# eliminate easy Regular-Expression-DoS gadgets on untrusted template text. 54 +# 解析表达式刻意避免使用 `.*`,以保持匹配的确定性,
  55 +# 并规避不可信模板文本中常见的正则DoS风险。
56 heading_pattern = re.compile( 56 heading_pattern = re.compile(
57 r""" 57 r"""
58 - (?P<marker>\#{1,6}) # Markdown heading markers  
59 - [ \t]+ # required whitespace  
60 - (?P<title>[^\r\n]+) # heading text without newline characters 58 + (?P<marker>\#{1,6}) # Markdown标题标记
  59 + [ \t]+ # 必需的空白字符
  60 + (?P<title>[^\r\n]+) # 不包含换行的标题文本
61 """, 61 """,
62 re.VERBOSE, 62 re.VERBOSE,
63 ) 63 )
64 bullet_pattern = re.compile( 64 bullet_pattern = re.compile(
65 r""" 65 r"""
66 - (?P<marker>[-*+]) # list bullet symbol 66 + (?P<marker>[-*+]) # 列表项目符号
67 [ \t]+ 67 [ \t]+
68 (?P<title>[^\r\n]+) 68 (?P<title>[^\r\n]+)
69 """, 69 """,
@@ -130,7 +130,7 @@ def parse_template_sections(template_md: str) -> List[TemplateSection]: @@ -130,7 +130,7 @@ def parse_template_sections(template_md: str) -> List[TemplateSection]:
130 order += SECTION_ORDER_STEP 130 order += SECTION_ORDER_STEP
131 continue 131 continue
132 132
133 - # outline 133 + # 提纲条目
134 if current: 134 if current:
135 current.outline.append(meta["title"]) 135 current.outline.append(meta["title"])
136 136
@@ -26,7 +26,7 @@ from .base_node import BaseNode @@ -26,7 +26,7 @@ from .base_node import BaseNode
26 26
27 try: 27 try:
28 from json_repair import repair_json as _json_repair_fn 28 from json_repair import repair_json as _json_repair_fn
29 -except ImportError: # pragma: no cover - optional dependency 29 +except ImportError: # pragma: no cover - 可选依赖
30 _json_repair_fn = None 30 _json_repair_fn = None
31 31
32 32
@@ -552,7 +552,7 @@ class ChapterGenerationNode(BaseNode): @@ -552,7 +552,7 @@ class ChapterGenerationNode(BaseNode):
552 return None 552 return None
553 try: 553 try:
554 fixed = _json_repair_fn(text) 554 fixed = _json_repair_fn(text)
555 - except Exception as exc: # pragma: no cover - library failure 555 + except Exception as exc: # pragma: no cover - 库级故障
556 logger.warning(f"json_repair 修复章节JSON失败: {exc}") 556 logger.warning(f"json_repair 修复章节JSON失败: {exc}")
557 return None 557 return None
558 if fixed == text: 558 if fixed == text:
@@ -100,7 +100,7 @@ class HTMLRenderer: @@ -100,7 +100,7 @@ class HTMLRenderer:
100 body = self._render_body() 100 body = self._render_body()
101 return f"<!DOCTYPE html>\n<html lang=\"zh-CN\" class=\"no-js\">\n{head}\n{body}\n</html>" 101 return f"<!DOCTYPE html>\n<html lang=\"zh-CN\" class=\"no-js\">\n{head}\n{body}\n</html>"
102 102
103 - # ====== Head / Body ====== 103 + # ====== 头部 / 正文 ======
104 104
105 def _resolve_color_value(self, value: Any, fallback: str) -> str: 105 def _resolve_color_value(self, value: Any, fallback: str) -> str:
106 """从颜色token中提取字符串值""" 106 """从颜色token中提取字符串值"""
@@ -219,7 +219,7 @@ class HTMLRenderer: @@ -219,7 +219,7 @@ class HTMLRenderer:
219 {hydration} 219 {hydration}
220 </body>""".strip() 220 </body>""".strip()
221 221
222 - # ====== Header / Meta / TOC ====== 222 + # ====== 页眉 / 元信息 / 目录 ======
223 223
224 def _render_header(self) -> str: 224 def _render_header(self) -> str:
225 """ 225 """
@@ -653,7 +653,7 @@ class HTMLRenderer: @@ -653,7 +653,7 @@ class HTMLRenderer:
653 words += numerals[ones] 653 words += numerals[ones]
654 return words 654 return words
655 655
656 - # ====== 章节 & Block 渲染 ====== 656 + # ====== 章节与块级渲染 ======
657 657
658 def _render_chapter(self, chapter: Dict[str, Any]) -> str: 658 def _render_chapter(self, chapter: Dict[str, Any]) -> str:
659 """ 659 """
@@ -1074,7 +1074,7 @@ class HTMLRenderer: @@ -1074,7 +1074,7 @@ class HTMLRenderer:
1074 """ 1074 """
1075 return table_html 1075 return table_html
1076 1076
1077 - # ====== Front-matter guards ====== 1077 + # ====== 前置信息防护 ======
1078 1078
1079 def _kpi_signature_from_items(self, items: Any) -> tuple | None: 1079 def _kpi_signature_from_items(self, items: Any) -> tuple | None:
1080 """将KPI数组转换为可比较的签名""" 1080 """将KPI数组转换为可比较的签名"""
@@ -1124,7 +1124,7 @@ class HTMLRenderer: @@ -1124,7 +1124,7 @@ class HTMLRenderer:
1124 return False 1124 return False
1125 return block_signature == self.hero_kpi_signature 1125 return block_signature == self.hero_kpi_signature
1126 1126
1127 - # ====== Inline 渲染 ====== 1127 + # ====== 行内渲染 ======
1128 1128
1129 def _normalize_inline_payload(self, run: Dict[str, Any]) -> tuple[str, List[Dict[str, Any]]]: 1129 def _normalize_inline_payload(self, run: Dict[str, Any]) -> tuple[str, List[Dict[str, Any]]]:
1130 """将嵌套inline node展平成基础文本与marks""" 1130 """将嵌套inline node展平成基础文本与marks"""
@@ -1326,7 +1326,7 @@ class HTMLRenderer: @@ -1326,7 +1326,7 @@ class HTMLRenderer:
1326 escaped = html.escape(self._safe_text(value), quote=True) 1326 escaped = html.escape(self._safe_text(value), quote=True)
1327 return escaped.replace("\n", " ").replace("\r", " ") 1327 return escaped.replace("\n", " ").replace("\r", " ")
1328 1328
1329 - # ====== CSS / JS ====== 1329 + # ====== CSS / JS(样式与脚本) ======
1330 1330
1331 def _build_css(self, tokens: Dict[str, Any]) -> str: 1331 def _build_css(self, tokens: Dict[str, Any]) -> str:
1332 """根据主题token拼接整页CSS,包括响应式与打印样式""" 1332 """根据主题token拼接整页CSS,包括响应式与打印样式"""