fix(report): project annual sections and thicken dasha reading
完整数据版第二轮。年运章写出资料包里已有的节,没有数据的不新算。大运解释补回可能段落。瑜伽作用不再断言寿命。术语替换不进标识符。罗睺和计都不写守护第未列出宫。未合入 staging。
This commit is contained in:
+334
-112
@@ -226,7 +226,7 @@ def _strip_pl9_user_engineering_markers(markdown: str) -> str:
|
||||
"neecha_bhanga": "落陷取消",
|
||||
"dhana": "财富",
|
||||
"putra": "子女/创造",
|
||||
"ayur": "寿命/健康",
|
||||
"ayur": "体质参考",
|
||||
"auspicious": "吉性",
|
||||
"nabhasa": "天象格局",
|
||||
"surya": "太阳类",
|
||||
@@ -258,8 +258,12 @@ def _strip_pl9_user_engineering_markers(markdown: str) -> str:
|
||||
"Aquarius": "水瓶座",
|
||||
"Pisces": "双鱼座",
|
||||
}
|
||||
try:
|
||||
from pl9_language_terms import replace_natural_language_term as _replace_term
|
||||
except ModuleNotFoundError: # pragma: no cover
|
||||
from scripts.pl9_language_terms import replace_natural_language_term as _replace_term
|
||||
for raw, public in sorted(glossary_terms.items(), key=lambda item: len(item[0]), reverse=True):
|
||||
text = re.sub(rf"(?<![A-Za-z]){re.escape(raw)}(?![A-Za-z])", public, text)
|
||||
text = _replace_term(text, raw, public)
|
||||
text = re.sub(r"\b[a-zA-Z_]+_profile\b", "计算口径", text)
|
||||
text = re.sub(r"\b[a-zA-Z_]+_status\b", "状态", text)
|
||||
text = re.sub(r"\b[a-zA-Z_]+_producer\b", "计算项", text)
|
||||
@@ -306,7 +310,6 @@ def _strip_pl9_user_engineering_markers(markdown: str) -> str:
|
||||
"太阳 and 水星": "太阳与水星",
|
||||
"金星 and 水星": "金星与水星",
|
||||
"Lagna": "上升",
|
||||
"Kendra": "角宫",
|
||||
"Trikona": "三方宫",
|
||||
"Trine": "三方宫",
|
||||
"Navamsa": "九分盘",
|
||||
@@ -331,6 +334,7 @@ def _strip_pl9_user_engineering_markers(markdown: str) -> str:
|
||||
}
|
||||
for raw, public in natural_replacements.items():
|
||||
text = text.replace(raw, public)
|
||||
text = _replace_term(text, "Kendra", "角宫")
|
||||
cleanups = {
|
||||
"Special 上升s and Points": "特殊上升与派生点",
|
||||
"Special 上升s": "特殊上升",
|
||||
@@ -353,7 +357,11 @@ def _strip_pl9_user_engineering_markers(markdown: str) -> str:
|
||||
text = re.sub(r"(?<=[\u4e00-\u9fff])\s+大运", "大运", text)
|
||||
text = re.sub(r"大运\s+(?=[\u4e00-\u9fff])", "大运", text)
|
||||
text = re.sub(r"(太阳|月亮|火星|水星|木星|金星|土星|北交点/罗睺|南交点/计都)\1", r"\1", text)
|
||||
return text
|
||||
try:
|
||||
from pl9_language_terms import strip_han_plural_s
|
||||
except ModuleNotFoundError: # pragma: no cover
|
||||
from scripts.pl9_language_terms import strip_han_plural_s
|
||||
return strip_han_plural_s(text)
|
||||
|
||||
|
||||
def _sanitize_pl9_public_markdown(markdown: str) -> str:
|
||||
@@ -410,9 +418,6 @@ def _render_pl9_user_markdown(packet: dict) -> str:
|
||||
"{planets}": "相关行星",
|
||||
"natural_benefic": "自然吉星",
|
||||
"natural_malefic": "自然凶星",
|
||||
"functional_benefic": "功能吉星",
|
||||
"functional_malefic": "功能凶星",
|
||||
"functional_neutral": "功能中性",
|
||||
"functional_role_not_returned": "功能属性未单独返回",
|
||||
"absolute Virupas; precise Sthana/Dig/Kala/Drik; bounded BPHS Chesta": "以 Virupa 为单位,综合 Sthana、Dig、Kala、Drik 与 BPHS Chesta",
|
||||
"Chesta remains cross-engine method-conflicted; totals inherit that boundary.": "Chesta Bala 的算法口径会影响总分,阅读时以同一口径内比较为主。",
|
||||
@@ -428,6 +433,16 @@ def _render_pl9_user_markdown(packet: dict) -> str:
|
||||
}
|
||||
for raw, public in replacements.items():
|
||||
text = text.replace(raw, public)
|
||||
try:
|
||||
from pl9_language_terms import replace_natural_language_term
|
||||
except ModuleNotFoundError: # pragma: no cover
|
||||
from scripts.pl9_language_terms import replace_natural_language_term
|
||||
for raw, public in (
|
||||
("functional_benefic", "功能吉星"),
|
||||
("functional_malefic", "功能凶星"),
|
||||
("functional_neutral", "功能中性"),
|
||||
):
|
||||
text = replace_natural_language_term(text, raw, public)
|
||||
text = re.sub(r"^#\s+.*$", f"# {title}", text, count=1, flags=re.MULTILINE)
|
||||
drop_fragments = (
|
||||
"本册只编排原版",
|
||||
@@ -559,15 +574,25 @@ def render_pl9_parity_markdown(packet: dict) -> str:
|
||||
if field.get('status') in {'blocked', 'not_applicable'}:
|
||||
return '-'
|
||||
if field.get('status') == 'conflict':
|
||||
labels = {'solar_return': '太阳返照', 'tajika': 'Tajika'}
|
||||
labels = (
|
||||
{'solar_return': 'solar return', 'tajika': 'Tajika'}
|
||||
if _lang == 'en'
|
||||
else {'solar_return': '太阳返照', 'tajika': 'Tajika'}
|
||||
)
|
||||
other = 'another method' if _lang == 'en' else '另一口径'
|
||||
values = []
|
||||
for item in _list(field.get('values')):
|
||||
item = _dict(item)
|
||||
data = _dict(item.get('value'))
|
||||
value = next((data.get(key) for key in keys if data.get(key)), None)
|
||||
if value is not None:
|
||||
values.append(f"{labels.get(item.get('producer'), '另一口径')}:{_token(value)}")
|
||||
return ';'.join(values) + '(两者不同)' if values else '-'
|
||||
sep = ': ' if _lang == 'en' else ':'
|
||||
values.append(f"{labels.get(item.get('producer'), other)}{sep}{_token(value)}")
|
||||
if not values:
|
||||
return '-'
|
||||
if _lang == 'en':
|
||||
return '; '.join(values) + ' (the two differ)'
|
||||
return ';'.join(values) + '(两者不同)'
|
||||
data = _dict(field.get('data') or field)
|
||||
return _token(next((data.get(key) for key in keys if data.get(key)), None))
|
||||
|
||||
@@ -575,13 +600,20 @@ def render_pl9_parity_markdown(packet: dict) -> str:
|
||||
year_lord = _dict(year_lord)
|
||||
blocked_detail = _dict(year_lord.get('blocked_detail'))
|
||||
if year_lord.get('status') == 'blocked' and blocked_detail.get('selection_basis_text'):
|
||||
# BUG-1223: no stand-in year lord; 「年主暂无法确定(原因)」.
|
||||
# BUG-1223: no stand-in year lord. Chinese keeps 「年主暂无法确定(原因)」.
|
||||
# English uses the twin sentence and does not keep the Chinese source line.
|
||||
if _lang == 'en' and blocked_detail.get('selection_basis_text_en'):
|
||||
return _cell(blocked_detail['selection_basis_text_en'])
|
||||
return _cell(blocked_detail['selection_basis_text'])
|
||||
if year_lord.get('status') == 'conflict':
|
||||
if _lang == 'en':
|
||||
return 'The two calculations name different year lords, so they are not merged'
|
||||
return '两种计算口径给出的年主不同,暂不合并'
|
||||
data = _dict(year_lord.get('data') or year_lord)
|
||||
# BUG-1214: the producer's one-sentence Panchadhikari basis (replaces
|
||||
# the BUG-1212 "Muntha lord for now" stand-in).
|
||||
if _lang == 'en' and data.get('selection_basis_text_en'):
|
||||
return _cell(data['selection_basis_text_en'])
|
||||
if data.get('selection_basis_text'):
|
||||
return _cell(data['selection_basis_text'])
|
||||
if data.get('selection_basis'):
|
||||
@@ -666,18 +698,31 @@ def render_pl9_parity_markdown(packet: dict) -> str:
|
||||
|
||||
def _public_report_text(value) -> str:
|
||||
text = str(value or '').strip()
|
||||
replacements = {
|
||||
'parameter_sensitive': '参考',
|
||||
'blocked': '未列',
|
||||
'observed_relationships': '已形成',
|
||||
'observed_empty': '未形成',
|
||||
'external_replay_pending': '待补充',
|
||||
'Evidence label': '证据口径',
|
||||
'证据标签': '证据口径',
|
||||
}
|
||||
text = text.replace('blocked_external_callable', '外部回放待校对')
|
||||
text = text.replace('pyjhora_behavior_only / not_multiengine_parity', '外部行为参考')
|
||||
text = text.replace('pyjhora_behavior_only', '外部行为参考')
|
||||
if _lang == 'en':
|
||||
replacements = {
|
||||
'blocked_external_callable': 'external replay still to review',
|
||||
'pyjhora_behavior_only / not_multiengine_parity': 'external behavior note',
|
||||
'pyjhora_behavior_only': 'external behavior note',
|
||||
'parameter_sensitive': 'reference',
|
||||
'blocked': 'not supplied',
|
||||
'observed_relationships': 'formed',
|
||||
'observed_empty': 'not formed',
|
||||
'external_replay_pending': 'to be supplied',
|
||||
'Evidence label': 'note',
|
||||
}
|
||||
else:
|
||||
replacements = {
|
||||
'blocked_external_callable': '外部回放待校对',
|
||||
'pyjhora_behavior_only / not_multiengine_parity': '外部行为参考',
|
||||
'pyjhora_behavior_only': '外部行为参考',
|
||||
'parameter_sensitive': '参考',
|
||||
'blocked': '未列',
|
||||
'observed_relationships': '已形成',
|
||||
'observed_empty': '未形成',
|
||||
'external_replay_pending': '待补充',
|
||||
'Evidence label': '证据口径',
|
||||
'证据标签': '证据口径',
|
||||
}
|
||||
for raw, public in replacements.items():
|
||||
text = text.replace(raw, public)
|
||||
return text
|
||||
@@ -2047,12 +2092,20 @@ def render_pl9_parity_markdown(packet: dict) -> str:
|
||||
current_year = _dict(annual.get('pl9_current_year_results'))
|
||||
current_sections = _list(current_year.get('sections'))
|
||||
if current_sections:
|
||||
lines.extend([
|
||||
'### p139-p141 Varshaphala 年度结果解释',
|
||||
'',
|
||||
'| 项目 | 锚点 | 年度主题 |',
|
||||
'|------|------|----------|',
|
||||
])
|
||||
if _lang == 'en':
|
||||
lines.extend([
|
||||
'### Varshaphala annual result notes',
|
||||
'',
|
||||
'| Item | Anchor | Annual theme |',
|
||||
'|------|--------|---------------|',
|
||||
])
|
||||
else:
|
||||
lines.extend([
|
||||
'### p139-p141 Varshaphala 年度结果解释',
|
||||
'',
|
||||
'| 项目 | 锚点 | 年度主题 |',
|
||||
'|------|------|----------|',
|
||||
])
|
||||
for section in current_sections:
|
||||
if not isinstance(section, dict):
|
||||
continue
|
||||
@@ -2070,12 +2123,20 @@ def render_pl9_parity_markdown(packet: dict) -> str:
|
||||
annual_dasha = _dict(annual.get('pl9_annual_dasha_results'))
|
||||
dasha_rows = _list(annual_dasha.get('rows'))
|
||||
if dasha_rows:
|
||||
lines.extend([
|
||||
'### p144-p145 Annual Dasha 结果解释',
|
||||
'',
|
||||
'| 阶段 | 主星 | 年盘宫位 | 日期边界 | 主题 |',
|
||||
'|------|------|----------|----------|------|',
|
||||
])
|
||||
if _lang == 'en':
|
||||
lines.extend([
|
||||
'### Annual Dasha result notes',
|
||||
'',
|
||||
'| Stage | Lord | Annual house | Date boundary | Theme |',
|
||||
'|-------|------|---------------|---------------|-------|',
|
||||
])
|
||||
else:
|
||||
lines.extend([
|
||||
'### p144-p145 Annual Dasha 结果解释',
|
||||
'',
|
||||
'| 阶段 | 主星 | 年盘宫位 | 日期边界 | 主题 |',
|
||||
'|------|------|----------|----------|------|',
|
||||
])
|
||||
for row in dasha_rows:
|
||||
if not isinstance(row, dict):
|
||||
continue
|
||||
@@ -2102,6 +2163,20 @@ def render_pl9_parity_markdown(packet: dict) -> str:
|
||||
f"{_cell(row.get('start'))} | {_cell(row.get('end'))} | {_public_status_note(row.get('boundary_status'))} |"
|
||||
)
|
||||
lines.append('')
|
||||
readings = [str(row.get('reading')).strip() for row in mudda_rows if isinstance(row, dict) and str(row.get('reading') or '').strip()]
|
||||
if readings:
|
||||
lines.extend([
|
||||
'#### Mudda period notes' if _lang == 'en' else '#### Mudda 阶段可能主题',
|
||||
'',
|
||||
])
|
||||
for reading in readings:
|
||||
lines.append(f"- {_public_report_text(reading)}")
|
||||
lines.append('')
|
||||
if _lang == 'en':
|
||||
lines.append('Day-level rows and a second balance profile are not in this table.')
|
||||
else:
|
||||
lines.append('这张表没有日级行,也没有第二套余额口径。')
|
||||
lines.append('')
|
||||
patyayini_rows = _list(normalized.get('patyayini_rows'))
|
||||
if patyayini_rows:
|
||||
lines.extend([
|
||||
@@ -2151,9 +2226,15 @@ def render_pl9_parity_markdown(packet: dict) -> str:
|
||||
if not isinstance(row, dict):
|
||||
continue
|
||||
forming = row.get('forming_planets') or row.get('planets') or row.get('raw_relationships')
|
||||
motion_key = str(row.get('motion') or row.get('aspect_motion') or '-')
|
||||
motion_labels = (
|
||||
{'applying': 'applying', 'separating': 'separating'}
|
||||
if _lang == 'en'
|
||||
else {'applying': '入相', 'separating': '分离'}
|
||||
)
|
||||
lines.append(
|
||||
f"| {_cell(row.get('yoga') or row.get('name'))} | {_cell(_public_report_text(row.get('observation_status') or row.get('condition_status') or row.get('present')))} | "
|
||||
f"{_cell(forming)} | {_cell({'applying': '入相', 'separating': '分离'}.get(str(row.get('motion') or row.get('aspect_motion') or '-'), row.get('motion') or row.get('aspect_motion') or '-'))} |"
|
||||
f"{_cell(forming)} | {_cell(motion_labels.get(motion_key, motion_key))} |"
|
||||
)
|
||||
lines.append('')
|
||||
saham_rows = _list(normalized.get('saham_rows'))
|
||||
@@ -2175,26 +2256,40 @@ def render_pl9_parity_markdown(packet: dict) -> str:
|
||||
public_replay = _dict(annual.get('public_panchavargiya_replay'))
|
||||
replay_coverage = _dict(public_replay.get('coverage'))
|
||||
if public_replay:
|
||||
lines.extend([
|
||||
'### 公开 Panchavargiya 数值复核边界',
|
||||
'',
|
||||
'| 项目 | 结果 |',
|
||||
'|------|------|',
|
||||
f"| 公开复核状态 | {_cell(public_replay.get('status'))} |",
|
||||
f"| 覆盖行星 | {_cell(replay_coverage.get('planet_count'))} |",
|
||||
f"| 已匹配分量 | {_cell(replay_coverage.get('exact_component_match_count'))} / {_cell(replay_coverage.get('component_count'))} |",
|
||||
f"| 已匹配总分 | {_cell(replay_coverage.get('exact_total_match_count'))} / {_cell(replay_coverage.get('planet_count'))} |",
|
||||
f"| 可直接用于公式升级 | {_cell(public_replay.get('promotion_allowed'))} |",
|
||||
'',
|
||||
])
|
||||
if _lang == 'en':
|
||||
lines.extend([
|
||||
'### Public Panchavargiya value check',
|
||||
'',
|
||||
'| Item | Result |',
|
||||
'|------|--------|',
|
||||
f"| Public check status | {_cell(public_replay.get('status'))} |",
|
||||
f"| Planets covered | {_cell(replay_coverage.get('planet_count'))} |",
|
||||
f"| Components matched | {_cell(replay_coverage.get('exact_component_match_count'))} / {_cell(replay_coverage.get('component_count'))} |",
|
||||
f"| Totals matched | {_cell(replay_coverage.get('exact_total_match_count'))} / {_cell(replay_coverage.get('planet_count'))} |",
|
||||
f"| Usable for a formula upgrade | {_cell(public_replay.get('promotion_allowed'))} |",
|
||||
'',
|
||||
])
|
||||
else:
|
||||
lines.extend([
|
||||
'### 公开 Panchavargiya 数值复核边界',
|
||||
'',
|
||||
'| 项目 | 结果 |',
|
||||
'|------|------|',
|
||||
f"| 公开复核状态 | {_cell(public_replay.get('status'))} |",
|
||||
f"| 覆盖行星 | {_cell(replay_coverage.get('planet_count'))} |",
|
||||
f"| 已匹配分量 | {_cell(replay_coverage.get('exact_component_match_count'))} / {_cell(replay_coverage.get('component_count'))} |",
|
||||
f"| 已匹配总分 | {_cell(replay_coverage.get('exact_total_match_count'))} / {_cell(replay_coverage.get('planet_count'))} |",
|
||||
f"| 可直接用于公式升级 | {_cell(public_replay.get('promotion_allowed'))} |",
|
||||
'',
|
||||
])
|
||||
annual_extra_specs = (
|
||||
('annual_anchor_rows', 'p126 年度锚点', ('name', 'label', 'value', 'sign', 'degree', 'house')),
|
||||
('annual_planet_rows', 'p127 年度行星资料', ('planet', 'sign', 'degree', 'longitude', 'nakshatra', 'pada')),
|
||||
('annual_anchor_rows', 'Annual anchors' if _lang == 'en' else 'p126 年度锚点', ('name', 'label', 'value', 'sign', 'degree', 'house')),
|
||||
('annual_planet_rows', 'Annual planet data' if _lang == 'en' else 'p127 年度行星资料', ('planet', 'sign', 'degree', 'longitude', 'nakshatra', 'pada')),
|
||||
('true_solar_return_rows', 'True Solar Return', ('field', 'value', 'date', 'time', 'dt_local')),
|
||||
('panchadhikari_rows', 'Panchadhikari', ('planet', 'role', 'value', 'sign', 'house')),
|
||||
('tripataki_placement_rows', 'Tripataki Placement', ('planet', 'sign', 'house', 'degree', 'placement')),
|
||||
('tripataki_vedha_rows', 'Tripataki Vedha', ('planet', 'target', 'sign', 'house', 'result')),
|
||||
('current_year_result_rows', 'p139-p141 年度结果', ('title', 'value', 'theme', 'summary', 'anchor')),
|
||||
('current_year_result_rows', 'Annual result notes' if _lang == 'en' else 'p139-p141 年度结果', ('title', 'value', 'theme', 'summary', 'anchor')),
|
||||
('tajika_presence_rows', 'Tajika Presence', ('yoga', 'name', 'present', 'forming_planets')),
|
||||
('tajika_condition_status_rows', 'Tajika Condition', ('yoga', 'name', 'condition', 'present')),
|
||||
('tajika_forming_pair_rows', 'Tajika Forming Pair', ('yoga', 'name', 'planet_a', 'planet_b', 'forming_planets')),
|
||||
@@ -2282,12 +2377,20 @@ def render_pl9_parity_markdown(packet: dict) -> str:
|
||||
monthly_pack = _dict(annual.get('monthly_chart_pack'))
|
||||
monthly_rows = _list(monthly_pack.get('rows'))
|
||||
if monthly_rows:
|
||||
lines.extend([
|
||||
'### 年度月返照图盘数据',
|
||||
'',
|
||||
'| 月份 | 本地时刻 | 年盘上升 | 上升度数 | 行星黄经(度) |',
|
||||
'|------|----------|----------|----------|-----------------|',
|
||||
])
|
||||
if _lang == 'en':
|
||||
lines.extend([
|
||||
'### Monthly returns within the year',
|
||||
'',
|
||||
'| Month | Local time | Annual ascendant | Ascendant degree | Planet longitudes (deg) |',
|
||||
'|-------|------------|------------------|------------------|--------------------------|',
|
||||
])
|
||||
else:
|
||||
lines.extend([
|
||||
'### 年度月返照图盘数据',
|
||||
'',
|
||||
'| 月份 | 本地时刻 | 年盘上升 | 上升度数 | 行星黄经(度) |',
|
||||
'|------|----------|----------|----------|-----------------|',
|
||||
])
|
||||
for row in monthly_rows:
|
||||
if not isinstance(row, dict):
|
||||
continue
|
||||
@@ -2311,12 +2414,20 @@ def render_pl9_parity_markdown(packet: dict) -> str:
|
||||
for row in _list(page.get('rows')) if isinstance(row, dict)
|
||||
]
|
||||
if lifetime_rows:
|
||||
lines.extend([
|
||||
'### 生命周期年度返照图盘数据',
|
||||
'',
|
||||
'| 年龄 | 年份 | 年返时刻 | 上升 | 上升度数 | 行星黄经(度) |',
|
||||
'|------|------|----------|------|----------|-----------------|',
|
||||
])
|
||||
if _lang == 'en':
|
||||
lines.extend([
|
||||
'### Lifetime annual return charts',
|
||||
'',
|
||||
'| Age | Year | Return time | Ascendant | Ascendant degree | Planet longitudes (deg) |',
|
||||
'|-----|------|-------------|-----------|------------------|--------------------------|',
|
||||
])
|
||||
else:
|
||||
lines.extend([
|
||||
'### 生命周期年度返照图盘数据',
|
||||
'',
|
||||
'| 年龄 | 年份 | 年返时刻 | 上升 | 上升度数 | 行星黄经(度) |',
|
||||
'|------|------|----------|------|----------|-----------------|',
|
||||
])
|
||||
for row in lifetime_rows:
|
||||
asc = _dict(row.get('ascendant'))
|
||||
longitudes = _dict(row.get('planet_longitudes'))
|
||||
@@ -2332,20 +2443,36 @@ def render_pl9_parity_markdown(packet: dict) -> str:
|
||||
)
|
||||
lines.append('')
|
||||
annual_series = _dict(annual.get('annual_chart_series_pack'))
|
||||
for series_key, title in (
|
||||
('birth_place_eight_year_overview', '出生地八年年度总览'),
|
||||
('local_eight_year_overview', '现居地八年年度总览'),
|
||||
):
|
||||
eight_year_titles = (
|
||||
(
|
||||
('birth_place_eight_year_overview', 'Eight-year overview at the birthplace'),
|
||||
('local_eight_year_overview', 'Eight-year overview at the current residence'),
|
||||
)
|
||||
if _lang == 'en'
|
||||
else (
|
||||
('birth_place_eight_year_overview', '出生地八年年度总览'),
|
||||
('local_eight_year_overview', '现居地八年年度总览'),
|
||||
)
|
||||
)
|
||||
for series_key, title in eight_year_titles:
|
||||
series = _dict(annual_series.get(series_key))
|
||||
series_rows = _list(series.get('rows'))
|
||||
if not series_rows:
|
||||
continue
|
||||
lines.extend([
|
||||
f'### {title}',
|
||||
'',
|
||||
'| 年份 | 年龄 | 年返时刻 | 年盘上升 |',
|
||||
'|------|------|----------|----------|',
|
||||
])
|
||||
if _lang == 'en':
|
||||
lines.extend([
|
||||
f'### {title}',
|
||||
'',
|
||||
'| Year | Age | Return time | Annual ascendant |',
|
||||
'|------|-----|-------------|-------------------|',
|
||||
])
|
||||
else:
|
||||
lines.extend([
|
||||
f'### {title}',
|
||||
'',
|
||||
'| 年份 | 年龄 | 年返时刻 | 年盘上升 |',
|
||||
'|------|------|----------|----------|',
|
||||
])
|
||||
for row in series_rows:
|
||||
if not isinstance(row, dict):
|
||||
continue
|
||||
@@ -2358,7 +2485,41 @@ def render_pl9_parity_markdown(packet: dict) -> str:
|
||||
annual_visual = annual.get('pl9_annual_visual_panels') if isinstance(annual.get('pl9_annual_visual_panels'), dict) else {}
|
||||
panels = annual_visual.get('panels') if isinstance(annual_visual.get('panels'), list) else []
|
||||
if panels:
|
||||
lines.extend(['### p139-p155 年度北印度图盘', ''])
|
||||
lines.extend([
|
||||
'### Annual north-Indian chart' if _lang == 'en' else '### p139-p155 年度北印度图盘',
|
||||
'',
|
||||
])
|
||||
else:
|
||||
occupancy_longitudes = _dict(_dict(annual_chart.get('data')).get('planet_longitudes'))
|
||||
if occupancy_longitudes:
|
||||
signs = list(globals().get('SIGNS') or [])
|
||||
asc_idx = _dict(annual_chart.get('data')).get('asc_sign_idx')
|
||||
asc_name = _dict(annual_chart.get('data')).get('asc_sign')
|
||||
if not isinstance(asc_idx, int) and signs and asc_name in signs:
|
||||
asc_idx = signs.index(asc_name)
|
||||
lines.extend([
|
||||
'### Annual north-Indian chart' if _lang == 'en' else '### p139-p155 年度北印度图盘',
|
||||
'',
|
||||
(
|
||||
'Sign occupancy from the annual longitudes already calculated. This is a text table, not a drawn chart.'
|
||||
if _lang == 'en'
|
||||
else '下面按已算出的年度黄经,把行星放进年返上升起的整宫。这是文字表,不是另画的图。'
|
||||
),
|
||||
'',
|
||||
'| Planet | Sign | House from annual Lagna |' if _lang == 'en' else '| 行星 | 星座 | 自年返上升的宫 |',
|
||||
'|--------|------|--------------------------|' if _lang == 'en' else '|------|------|----------------|',
|
||||
])
|
||||
if isinstance(asc_idx, int) and signs:
|
||||
lines.append(f"| Lagna | {_cell(_token(signs[asc_idx % 12]))} | 1 |")
|
||||
for planet in ('Sun', 'Moon', 'Mars', 'Mercury', 'Jupiter', 'Venus', 'Saturn', 'Rahu', 'Ketu'):
|
||||
longitude = occupancy_longitudes.get(planet)
|
||||
if not isinstance(longitude, (int, float)) or isinstance(longitude, bool):
|
||||
continue
|
||||
sign_idx = int(float(longitude) // 30) % 12
|
||||
sign = signs[sign_idx] if signs else '-'
|
||||
house = ((sign_idx - asc_idx) % 12) + 1 if isinstance(asc_idx, int) else '-'
|
||||
lines.append(f"| {_cell(_token(planet))} | {_cell(_token(sign))} | {_cell(house)} |")
|
||||
lines.append('')
|
||||
for panel in panels:
|
||||
if not isinstance(panel, dict):
|
||||
continue
|
||||
@@ -2378,13 +2539,25 @@ def render_pl9_parity_markdown(packet: dict) -> str:
|
||||
annual_chart_data = _dict(annual_chart.get('data'))
|
||||
solar_return = _dict(annual_pack.get('solar_return'))
|
||||
solar_return_data = _dict(solar_return.get('data') or solar_return)
|
||||
lines.extend([f'### {year} 年度 Varshaphala / Tajika 细项', ''])
|
||||
if _lang == 'en':
|
||||
lines.extend([f'### {year} annual Varshaphala / Tajika detail', ''])
|
||||
else:
|
||||
lines.extend([f'### {year} 年度 Varshaphala / Tajika 细项', ''])
|
||||
if solar_return_data or annual_chart_data:
|
||||
asc_label = 'Annual ascendant' if _lang == 'en' else '年返上升'
|
||||
if _lang == 'en':
|
||||
lines.extend([
|
||||
'| Item | Value |',
|
||||
'|------|-------|',
|
||||
])
|
||||
else:
|
||||
lines.extend([
|
||||
'| 项目 | 数值 |',
|
||||
'|------|------|',
|
||||
])
|
||||
lines.extend([
|
||||
'| 项目 | 数值 |',
|
||||
'|------|------|',
|
||||
f"| Varshapravesha | {_cell(solar_return_data.get('dt_local') or solar_return_data.get('local_time') or solar_return_data.get('date') or '-')} |",
|
||||
f"| 年返上升 | {_cell(_token(annual_chart_data.get('asc_sign')))} |",
|
||||
f"| {asc_label} | {_cell(_token(annual_chart_data.get('asc_sign')))} |",
|
||||
])
|
||||
year_lord = _dict(annual_pack.get('year_lord'))
|
||||
year_lord_data = _dict(year_lord.get('data') or year_lord)
|
||||
@@ -2398,12 +2571,20 @@ def render_pl9_parity_markdown(packet: dict) -> str:
|
||||
planet_longitudes = _dict(annual_chart_data.get('planet_longitudes'))
|
||||
if planet_longitudes:
|
||||
signs = globals().get('SIGNS', [])
|
||||
lines.extend([
|
||||
'#### 年度行星资料',
|
||||
'',
|
||||
'| 行星 | 星座 | 落座度数 | 黄经 |',
|
||||
'|------|------|----------|------|',
|
||||
])
|
||||
if _lang == 'en':
|
||||
lines.extend([
|
||||
'#### Annual planet data',
|
||||
'',
|
||||
'| Planet | Sign | Degree in sign | Longitude |',
|
||||
'|--------|------|----------------|-----------|',
|
||||
])
|
||||
else:
|
||||
lines.extend([
|
||||
'#### 年度行星资料',
|
||||
'',
|
||||
'| 行星 | 星座 | 落座度数 | 黄经 |',
|
||||
'|------|------|----------|------|',
|
||||
])
|
||||
if annual_chart_data.get('asc_sign') is not None:
|
||||
lines.append(f"| Lagna | {_cell(_token(annual_chart_data.get('asc_sign')))} | - | - |")
|
||||
for planet in ('Sun', 'Moon', 'Mars', 'Mercury', 'Jupiter', 'Venus', 'Saturn', 'Rahu', 'Ketu'):
|
||||
@@ -2419,12 +2600,20 @@ def render_pl9_parity_markdown(packet: dict) -> str:
|
||||
annual_dasha = _dict(annual_pack.get('pl9_annual_dasha_results'))
|
||||
dasha_rows = _list(annual_dasha.get('rows'))
|
||||
if dasha_rows:
|
||||
lines.extend([
|
||||
'#### Annual Dasha 阶段表',
|
||||
'',
|
||||
'| 阶段 | 主星 | 年盘宫位 | 日期边界 | 主题 |',
|
||||
'|------|------|----------|----------|------|',
|
||||
])
|
||||
if _lang == 'en':
|
||||
lines.extend([
|
||||
'#### Annual Dasha periods',
|
||||
'',
|
||||
'| Stage | Lord | Annual house | Date boundary | Theme |',
|
||||
'|-------|------|---------------|---------------|-------|',
|
||||
])
|
||||
else:
|
||||
lines.extend([
|
||||
'#### Annual Dasha 阶段表',
|
||||
'',
|
||||
'| 阶段 | 主星 | 年盘宫位 | 日期边界 | 主题 |',
|
||||
'|------|------|----------|----------|------|',
|
||||
])
|
||||
for row in dasha_rows:
|
||||
if not isinstance(row, dict):
|
||||
continue
|
||||
@@ -2435,15 +2624,26 @@ def render_pl9_parity_markdown(packet: dict) -> str:
|
||||
)
|
||||
lines.append('')
|
||||
normalized = _dict(annual_pack.get('normalized_tables'))
|
||||
future_specs = (
|
||||
('mudda_rows', 'Mudda / Patyayini 年度 Dasha 表', ('balance_profile', 'lord', 'start', 'end', 'boundary_status')),
|
||||
('patyayini_rows', 'Patyayini / Patyamsha ending-date 表', ('main', 'sub', 'boundary', 'boundary_status')),
|
||||
('saham_rows', 'Sahams 点位表', ('name', 'saham', 'sign', 'degree_in_sign')),
|
||||
('tajika_yoga_rows', 'Tajika Yoga Presence 表', ('yoga', 'name', 'present', 'forming_planets')),
|
||||
('pyjhora_tajika_yoga_rows', 'Tajika Yoga Presence 表', ('yoga', 'name', 'present', 'forming_planets')),
|
||||
('annual_planet_rows', '年度行星扩展字段', ('planet', 'sign', 'degree', 'longitude', 'nakshatra', 'pada')),
|
||||
('annual_anchor_rows', '年度锚点', ('name', 'label', 'value', 'sign', 'degree', 'house')),
|
||||
)
|
||||
if _lang == 'en':
|
||||
future_specs = (
|
||||
('mudda_rows', 'Mudda dasha table', ('balance_profile', 'lord', 'start', 'end', 'boundary_status')),
|
||||
('patyayini_rows', 'Patyayini ending dates', ('main', 'sub', 'boundary', 'boundary_status')),
|
||||
('saham_rows', 'Saham positions', ('name', 'saham', 'sign', 'degree_in_sign')),
|
||||
('tajika_yoga_rows', 'Tajika yoga presence', ('yoga', 'name', 'present', 'forming_planets')),
|
||||
('pyjhora_tajika_yoga_rows', 'Tajika yoga presence', ('yoga', 'name', 'present', 'forming_planets')),
|
||||
('annual_planet_rows', 'Annual planet extras', ('planet', 'sign', 'degree', 'longitude', 'nakshatra', 'pada')),
|
||||
('annual_anchor_rows', 'Annual anchors', ('name', 'label', 'value', 'sign', 'degree', 'house')),
|
||||
)
|
||||
else:
|
||||
future_specs = (
|
||||
('mudda_rows', 'Mudda / Patyayini 年度 Dasha 表', ('balance_profile', 'lord', 'start', 'end', 'boundary_status')),
|
||||
('patyayini_rows', 'Patyayini / Patyamsha ending-date 表', ('main', 'sub', 'boundary', 'boundary_status')),
|
||||
('saham_rows', 'Sahams 点位表', ('name', 'saham', 'sign', 'degree_in_sign')),
|
||||
('tajika_yoga_rows', 'Tajika Yoga Presence 表', ('yoga', 'name', 'present', 'forming_planets')),
|
||||
('pyjhora_tajika_yoga_rows', 'Tajika Yoga Presence 表', ('yoga', 'name', 'present', 'forming_planets')),
|
||||
('annual_planet_rows', '年度行星扩展字段', ('planet', 'sign', 'degree', 'longitude', 'nakshatra', 'pada')),
|
||||
('annual_anchor_rows', '年度锚点', ('name', 'label', 'value', 'sign', 'degree', 'house')),
|
||||
)
|
||||
rendered_titles = set()
|
||||
for table_key, title, preferred_keys in future_specs:
|
||||
rows = [row for row in _list(normalized.get(table_key)) if isinstance(row, dict)]
|
||||
@@ -2473,12 +2673,20 @@ def render_pl9_parity_markdown(packet: dict) -> str:
|
||||
special = _dict(annual_pack.get('annual_special_points'))
|
||||
special_data = _dict(special.get('data'))
|
||||
if special_data:
|
||||
lines.extend([
|
||||
'#### 年度特殊点',
|
||||
'',
|
||||
'| 点位 | 星座 | 落座度数 | 黄经 | 守护星 |',
|
||||
'|------|------|----------|------|--------|',
|
||||
])
|
||||
if _lang == 'en':
|
||||
lines.extend([
|
||||
'#### Annual special points',
|
||||
'',
|
||||
'| Point | Sign | Degree in sign | Longitude | Ruler |',
|
||||
'|-------|------|----------------|-----------|-------|',
|
||||
])
|
||||
else:
|
||||
lines.extend([
|
||||
'#### 年度特殊点',
|
||||
'',
|
||||
'| 点位 | 星座 | 落座度数 | 黄经 | 守护星 |',
|
||||
'|------|------|----------|------|--------|',
|
||||
])
|
||||
for name, row in special_data.items():
|
||||
if not isinstance(row, dict):
|
||||
continue
|
||||
@@ -2491,12 +2699,20 @@ def render_pl9_parity_markdown(packet: dict) -> str:
|
||||
monthly_pack = _dict(annual_pack.get('monthly_chart_pack'))
|
||||
monthly_rows = _list(monthly_pack.get('rows'))
|
||||
if monthly_rows:
|
||||
lines.extend([
|
||||
'#### 年度月返照图盘数据',
|
||||
'',
|
||||
'| 月份 | 本地时刻 | 年盘上升 | 上升度数 |',
|
||||
'|------|----------|----------|----------|',
|
||||
])
|
||||
if _lang == 'en':
|
||||
lines.extend([
|
||||
'#### Monthly returns within the year',
|
||||
'',
|
||||
'| Month | Local time | Annual ascendant | Ascendant degree |',
|
||||
'|-------|------------|------------------|-------------------|',
|
||||
])
|
||||
else:
|
||||
lines.extend([
|
||||
'#### 年度月返照图盘数据',
|
||||
'',
|
||||
'| 月份 | 本地时刻 | 年盘上升 | 上升度数 |',
|
||||
'|------|----------|----------|----------|',
|
||||
])
|
||||
for row in monthly_rows:
|
||||
if not isinstance(row, dict):
|
||||
continue
|
||||
@@ -2677,10 +2893,16 @@ def render_pl9_parity_markdown(packet: dict) -> str:
|
||||
effects = row.get('effects') if isinstance(row.get('effects'), list) else []
|
||||
yoga_name = row.get('name_cn') or row.get('name') or row.get('type')
|
||||
combination = row.get('combination') or row.get('source_reference') or row.get('reason')
|
||||
effect_text = _public_report_text(_brief(effects, 3) or row.get('interpretation') or row.get('summary'))
|
||||
try:
|
||||
from pl9_language_terms import soften_lifespan_wording
|
||||
except ModuleNotFoundError: # pragma: no cover
|
||||
from scripts.pl9_language_terms import soften_lifespan_wording
|
||||
effect_text = soften_lifespan_wording(str(effect_text or ''), _lang)
|
||||
lines.append(
|
||||
f"| {_cell(yoga_name)} | {_cell(row.get('category') or row.get('subtype'))} | "
|
||||
f"{_cell(row.get('strength'))} | {_cell(combination)} | "
|
||||
f"{_cell(_public_report_text(_brief(effects, 3) or row.get('interpretation') or row.get('summary')))} |"
|
||||
f"{_cell(effect_text)} |"
|
||||
)
|
||||
lines.append('')
|
||||
if yoga_pages:
|
||||
|
||||
Reference in New Issue
Block a user