报告开头改成重点摘要卡

新报告用围栏画出大运和事业、财富、婚恋,标题下写名字与日期。旧报告不变。

自测:pytest test_report_full_data_fix.py 10 通过;相关四份报告测试退出码 0;前端相关测试 147 通过、0 失败、0 取消;tsc 退出码 0;lint 0 error。

Co-Authored-By: Grok (agent loop)
This commit is contained in:
jesse-ux
2026-10-13 21:45:43 +08:00
co-authored by Grok (agent loop)
parent 963276ca2f
commit 8883f8475f
20 changed files with 856 additions and 82 deletions
+48 -12
View File
@@ -91,7 +91,12 @@ def _load_bhava_rows():
return bhava_house_rows
def _sanitize_pl9_ai_density_markdown(markdown: str, title: str = "印度占星星盘报告") -> str:
def _sanitize_pl9_ai_density_markdown(
markdown: str,
title: str = "印度占星星盘报告",
*,
opening_summary: bool = True,
) -> str:
"""Keep the parity volume's facts while removing internal-only labels."""
try:
@@ -111,6 +116,8 @@ def _sanitize_pl9_ai_density_markdown(markdown: str, title: str = "印度占星
from pl9_language_terms import translate_zh_glued_phrases
except ModuleNotFoundError: # pragma: no cover - package import compatibility
from scripts.pl9_language_terms import translate_zh_glued_phrases
hold_focus_fences, restore_focus_fences = _focus_fence_tools()
markdown, focus_slots = hold_focus_fences(markdown)
# Whole phrases and glued planet+dignity tokens before shorter word swaps.
# Chapters appended after the parity strip still pass through here.
text = translate_zh_glued_phrases(_sanitize_pl9_public_markdown(markdown))
@@ -515,10 +522,12 @@ def _sanitize_pl9_ai_density_markdown(markdown: str, title: str = "印度占星
continue
first_body_line = line
break
has_opening_summary = bool(first_body_line) and any(
marker in first_body_line for marker in ("摘要:", "结论:", "重点:")
has_opening_summary = _opening_focus_authored(text) or (
bool(first_body_line) and any(
marker in first_body_line for marker in ("摘要:", "结论:", "重点:")
)
)
if text.startswith(f"# {title}") and not has_opening_summary:
if opening_summary and text.startswith(f"# {title}") and not has_opening_summary:
summary = "\n".join(
[
f"# {title}",
@@ -532,7 +541,7 @@ def _sanitize_pl9_ai_density_markdown(markdown: str, title: str = "印度占星
]
)
text = re.sub(r"^#\s+.*$", summary, text, count=1, flags=re.MULTILINE)
return strip_han_plural_s(text) + "\n"
return restore_focus_fences(strip_han_plural_s(text) + "\n", focus_slots)
@@ -887,7 +896,8 @@ def _sanitize_pl9_ai_density_markdown_en(markdown: str, title: str = "Vedic Astr
except ModuleNotFoundError: # pragma: no cover - package import compatibility
from scripts.pl9_language_terms import normalize_en_markdown_terms
text = markdown
hold_focus_fences, restore_focus_fences = _focus_fence_tools()
text, focus_slots = hold_focus_fences(markdown)
replacements = {
"# PL9 对标主册": f"# {title}",
"PL9 对标主册": title,
@@ -1266,7 +1276,7 @@ def _sanitize_pl9_ai_density_markdown_en(markdown: str, title: str = "Vedic Astr
# 防御性幂等:折叠残留的 "condition condition"(确保 sanitize 可安全重复执行)。
text = re.sub(r"\b(condition)(?:\s+condition)+\b", r"\1", text, flags=re.IGNORECASE)
text = re.sub(r"\n{3,}", "\n\n", text).strip() + "\n"
return text
return restore_focus_fences(text, focus_slots)
@@ -1279,7 +1289,10 @@ _ZH_FUNCTION_WORD_RE = re.compile(
r"(?<![A-Za-z])(?:of|in|the|and|by|from|with|listed|background|native|condition|met|satisfied|occupied)(?![A-Za-z])",
re.IGNORECASE,
)
_ZH_CHART_FENCE_RE = re.compile(r"```jyotish-chart\n.*?\n```", re.DOTALL)
_ZH_CHART_FENCE_RE = re.compile(
r"```(?:jyotish-chart|jyotish-focus)\n.*?\n```",
re.DOTALL,
)
def _zh_body_residue(markdown: str) -> dict[str, int]:
@@ -2230,14 +2243,36 @@ def _append_native_rashi_dashas(markdown: str, packet: dict) -> str:
return markdown.rstrip() + "\n\n" + chapter
def _focus_fence_tools():
try:
from report_focus_block import hold_focus_fences, restore_focus_fences
except ModuleNotFoundError: # pragma: no cover - package import compatibility
from scripts.report_focus_block import hold_focus_fences, restore_focus_fences
return hold_focus_fences, restore_focus_fences
def _opening_focus_authored(text: str) -> bool:
"""True when the title is already followed by the focus heading or fence.
The fixed checklist must not come back just because the old one-line
「重点:」 summary was removed.
"""
head = "\n".join((text or "").splitlines()[:16])
if re.search(r"(?m)^## (?:重点|Focus)\s*$", head):
return True
return "```jyotish-focus" in head or "JYOTISHFOCUSHOLD" in head
def _insert_opening_focus(markdown: str, focus: str) -> str:
"""Put the current-period focus directly under the title."""
first = next((line.strip() for line in focus.splitlines() if line.strip()), "")
if not first or first in markdown:
if "```jyotish-focus" not in (focus or ""):
return markdown
match = re.search(r"^#\s+.+$", markdown, flags=re.MULTILINE)
if "```jyotish-focus" in (markdown or ""):
return markdown
match = re.search(r"^#\s+.+$", markdown or "", flags=re.MULTILINE)
if not match:
return focus.rstrip() + "\n\n" + markdown
return focus.rstrip() + "\n\n" + (markdown or "")
return markdown[: match.end()] + "\n\n" + focus.rstrip() + "\n" + markdown[match.end() :]
@@ -2286,6 +2321,7 @@ def render_full_data_markdown(packet: dict) -> str:
zh_structured_markdown = _sanitize_pl9_ai_density_markdown(
_render_pl9_ai_density_raw_data_markdown_en(packet),
_pl9_public_report_title(packet),
opening_summary=False,
)
zh_structured_appendix = re.sub(
r"^#\s+.*?(?:\n{2,}|\n)",