Showing
4 changed files
with
16 additions
and
16 deletions
| @@ -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,包括响应式与打印样式""" |
-
Please register or login to post a comment