- Sync references/mahadasha_editorial_bilingual.json (9 lords x 3 paragraphs, zh + en, per-paragraph source locators) and mahadasha_editorial_policy.md, plus the one-line pointers in SKILL.md and vimshottari_dasha_guide.md. - New chapter after 大运解释 in both editions: the three paragraphs side by side (general / traditionally supportive / traditionally strained), never picked by lord or chart, Mahadasha layer only; source labelled as secondary study notes with the original edition pending verification; English only in the English edition. - Coverage contract: the topic moves from NOT_CARRIED to the checked list. No change to the frozen exporter, dates or any scoring. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DbBXoyeZrYn6ryNcSe5Y2Y
95 lines
4.5 KiB
Python
95 lines
4.5 KiB
Python
"""「大运传统参考」: nine Mahadasha lords, three paragraphs each, both editions.
|
||
|
||
Text: `references/mahadasha_editorial_bilingual.json`, synced from the
|
||
astrologer's skill repository (yinduzhanxing 058c4f5f, 2026-11-06). Rules:
|
||
`references/mahadasha_editorial_policy.md`.
|
||
|
||
- A general reference, the three paragraphs side by side. Nothing here picks
|
||
「有利」 or 「压力」 for this chart, and nothing says the reader is afflicted.
|
||
- Mahadasha lord layer only; no Mahadasha/Antardasha combinations.
|
||
- The source is secondary study notes; the page markers are not BPHS edition
|
||
pages, and the report says so. The English edition shows English only.
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
import json
|
||
import re
|
||
from functools import lru_cache
|
||
from pathlib import Path
|
||
|
||
_PATH = Path(__file__).resolve().parents[2] / "references" / "mahadasha_editorial_bilingual.json"
|
||
_KINDS = (
|
||
("general", "一般背景", "General background"),
|
||
("supportive_conditions", "传统有利条件下", "Under traditionally supportive conditions"),
|
||
("strained_conditions", "传统压力条件下", "Under traditionally strained conditions"),
|
||
)
|
||
_HAN = re.compile(r"[一-鿿]")
|
||
|
||
|
||
@lru_cache(maxsize=1)
|
||
def load_reference() -> dict:
|
||
with _PATH.open(encoding="utf-8") as handle:
|
||
return json.load(handle)
|
||
|
||
|
||
def _source_line(pages: list[int], language: str) -> str:
|
||
pages_text = "、".join(str(page) for page in pages) if language == "zh" else ", ".join(str(page) for page in pages)
|
||
if language == "zh":
|
||
return f"来源:《BPHS 读书笔记》第 44 节,PDF 页 {pages_text}(二手资料;原典印刷版待核)。"
|
||
return f"Source: BPHS Study Notes, section 44, PDF page {pages_text} (secondary source; original edition pending verification)."
|
||
|
||
|
||
def render_dasha_reference(language: str) -> str:
|
||
data = load_reference()
|
||
zh = language == "zh"
|
||
lines = [
|
||
"## 大运传统参考(通用)" if zh else "## Traditional Dasha Reference (general)",
|
||
"",
|
||
(
|
||
"下面是九颗大运主星在传统文本里的通用主题,三段并列。哪一段更贴近这张盘,"
|
||
"要看功能吉凶、宫主与落宫、尊贵、力量、燃烧、相照与缓解因素,本章不替这张盘做判断,也不是推算结果。"
|
||
"只写大运主星这一层,不拼接小运。"
|
||
) if zh else (
|
||
"Traditional themes for each of the nine Mahadasha lords, the three paragraphs side by side. "
|
||
"Which one is closer to this chart depends on functional roles, house lordship and placement, dignity, "
|
||
"strength, combustion, aspects and mitigating factors; this chapter does not decide that for the chart "
|
||
"and is not a calculated result. It covers the Mahadasha lord only, not sub-period combinations."
|
||
),
|
||
"",
|
||
]
|
||
for planet in data.get("planets") or []:
|
||
if not isinstance(planet, dict):
|
||
continue
|
||
name = planet.get("name_zh") if zh else planet.get("id")
|
||
paragraphs = {item.get("kind"): item for item in planet.get("paragraphs") or [] if isinstance(item, dict)}
|
||
if not name or not all(kind in paragraphs for kind, _zh, _en in _KINDS):
|
||
continue
|
||
lines.extend([f"### {name}", ""])
|
||
pages: list[int] = []
|
||
for kind, label_zh, label_en in _KINDS:
|
||
item = paragraphs[kind]
|
||
text = str(item.get("zh" if zh else "en") or "").strip()
|
||
if not text or (not zh and _HAN.search(text)):
|
||
continue
|
||
lines.extend([f"**{label_zh if zh else label_en}**:{text}" if zh else f"**{label_en}**: {text}", ""])
|
||
page = item.get("pdf_page")
|
||
if isinstance(page, int) and page not in pages:
|
||
pages.append(page)
|
||
if pages:
|
||
lines.extend([_source_line(pages, language), ""])
|
||
return "\n".join(lines).rstrip() + "\n"
|
||
|
||
|
||
def insert_dasha_reference(markdown: str, language: str) -> str:
|
||
"""Right after the 「大运解释」 / Dasha Interpretation chapter; unchanged when it is absent."""
|
||
if not markdown:
|
||
return markdown
|
||
heading = r"^## (?:大运解释|Dasha Interpretation)\s*$"
|
||
match = re.search(heading, markdown, flags=re.MULTILINE)
|
||
if not match:
|
||
return markdown
|
||
following = re.search(r"^## ", markdown[match.end():], flags=re.MULTILINE)
|
||
cut = match.end() + following.start() if following else len(markdown)
|
||
return markdown[:cut].rstrip() + "\n\n" + render_dasha_reference(language).rstrip() + "\n\n" + markdown[cut:].lstrip()
|