fix(report): keep the English edition when one phrase was untranslated

The English personal report was discarded whenever a Chinese fragment survived the trailing glossary. English sections now render the English fields that were already calculated.

Co-Authored-By: Grok (agent loop)
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
jesse-ux
2026-10-22 02:56:00 +08:00
co-authored by Grok (agent loop) Cursor
parent 9812f31737
commit ba1ffeb35f
18 changed files with 815 additions and 53 deletions
+74 -34
View File
@@ -23,9 +23,9 @@ for the public reader rather than exposing empty or machine-key rows.
from __future__ import annotations
try: # scripts/ on sys.path
from narayana_legacy_label import LEGACY_NOTE_ZH
from narayana_legacy_label import LEGACY_NOTE_EN, LEGACY_NOTE_ZH
except ImportError: # pragma: no cover - package import
from scripts.narayana_legacy_label import LEGACY_NOTE_ZH
from scripts.narayana_legacy_label import LEGACY_NOTE_EN, LEGACY_NOTE_ZH
import re
SIGNS: list[str] = []
@@ -974,11 +974,16 @@ def render_pl9_parity_markdown(packet: dict) -> str:
'| Panchanga | Value |',
'|-----------|-------|',
])
for key, label in (
panchanga_rows = (
('overall_quality_en', 'Overall quality'),
('auspicious_count', 'Auspicious elements'),
('total_elements', 'Total elements'),
) if _lang == 'en' else (
('overall_quality', '综合性质'),
('auspicious_count', '吉性要素数量'),
('total_elements', '要素总数'),
):
)
for key, label in panchanga_rows:
value = panchanga.get(key)
if value not in (None, ''):
lines.append(f"| {_cell(label)} | {_cell(value)} |")
@@ -1544,7 +1549,11 @@ def render_pl9_parity_markdown(packet: dict) -> str:
arudha_rows = _dict(arudha_pack.get('padas')) or arudha_pack
jaimini_special = _dict(jaimini.get('special_lagnas'))
if karaka_table or arudha_rows or jaimini_special:
lines.extend(['### Jaimini Karaka、Arudha Pada 与特殊 Lagna', ''])
lines.extend([
'### Jaimini Karaka, Arudha Pada and special Lagnas' if _lang == 'en'
else '### Jaimini Karaka、Arudha Pada 与特殊 Lagna',
'',
])
if karaka_table:
lines.extend([
'| Karaka | Planet | Degree | Ranking degree | Domain |',
@@ -1553,11 +1562,15 @@ def render_pl9_parity_markdown(packet: dict) -> str:
for name, row in karaka_table.items():
if not isinstance(row, dict):
continue
karaka_name = name if _lang == 'en' else (row.get('cn_name') or name)
domain = row.get('domain_en') if _lang == 'en' else row.get('domain')
if _lang == 'en' and domain and re.search(r'[\u4e00-\u9fff]', str(domain)):
domain = ''
lines.append(
f"| {_cell(row.get('cn_name') or name)} | {_cell(_token(row.get('planet')))} | "
f"| {_cell(karaka_name)} | {_cell(_token(row.get('planet')))} | "
f"{_cell(_degree(row.get('degree_in_sign') or row.get('sign_degree')))} | "
f"{_cell(_degree(row.get('effective_degree_in_sign', row.get('degree_in_sign'))))} | "
f"{_cell(row.get('domain'))} |"
f"{_cell(domain)} |"
)
lines.append('')
if arudha_rows or jaimini_special:
@@ -1686,7 +1699,8 @@ def render_pl9_parity_markdown(packet: dict) -> str:
vimsopaka = _dict(strengths.get('vimsopaka'))
if vimsopaka:
lines.extend([
'### p30-p60 Vimsopaka / Pushkara / Vargottama 辅助强度',
'### Vimsopaka / Pushkara / Vargottama supporting strength' if _lang == 'en'
else '### p30-p60 Vimsopaka / Pushkara / Vargottama 辅助强度',
'',
'| Planet | Vimsopaka | Grade | Pushkara Navamsa | Pushkara Bhaga | Vargottama |',
'|--------|-----------|-------|------------------|----------------|------------|',
@@ -1923,7 +1937,10 @@ def render_pl9_parity_markdown(packet: dict) -> str:
lines.extend([f'### p{page} {title_text}', ''])
if 'Narayana' in title_text:
# BUG-1215: the product Narayana is the legacy algorithm.
lines.extend([f'- 算法:{LEGACY_NOTE_ZH}', ''])
if _lang == 'en':
lines.extend([f'- Algorithm: {LEGACY_NOTE_EN}', ''])
else:
lines.extend([f'- 算法:{LEGACY_NOTE_ZH}', ''])
lines.extend([
'| 序号 | 主星/星座 | 起始 | 结束 | 年数 |',
'|------|-----------|------|------|------|',
@@ -1999,24 +2016,25 @@ def render_pl9_parity_markdown(packet: dict) -> str:
# Rath table already printed by the reference renderer. Display only.
narayana_packet = _dict(timing.get('narayana_dasha'))
if narayana_packet:
try:
from narayana_legacy_label import rath_report_lines_zh as _rath_lines
except ImportError:
from scripts.narayana_legacy_label import rath_report_lines_zh as _rath_lines
legacy_line = f'- 算法:{LEGACY_NOTE_ZH}'
if _lang == 'en':
try:
from narayana_legacy_label import rath_report_lines_en as _rath_lines
except ImportError:
from scripts.narayana_legacy_label import rath_report_lines_en as _rath_lines
legacy_line = f'- Algorithm: {LEGACY_NOTE_EN}'
alongside_prefix = '- Alongside:'
else:
try:
from narayana_legacy_label import rath_report_lines_zh as _rath_lines
except ImportError:
from scripts.narayana_legacy_label import rath_report_lines_zh as _rath_lines
legacy_line = f'- 算法:{LEGACY_NOTE_ZH}'
alongside_prefix = '- 并列:'
if legacy_line not in lines:
lines.extend(['### Narayana Dasha', '', legacy_line, ''])
rath_view = narayana_packet.get('rath')
rath_lines = [line for line in _rath_lines(rath_view) if line]
if _lang == 'en' and isinstance(rath_view, dict):
for row in _list(rath_view.get('mahadasha')):
if not isinstance(row, dict):
continue
zh_basis = row.get('dual_lord_basis')
en_basis = row.get('dual_lord_basis_en')
if zh_basis and en_basis:
rath_lines = [line.replace(str(zh_basis), str(en_basis)) for line in rath_lines]
if rath_lines and not any(str(line).startswith('- 并列:') for line in lines):
if rath_lines and not any(str(line).startswith(alongside_prefix) for line in lines):
lines.extend(rath_lines)
lines.append('')
source_dasha_pages = _list(source_visible.get('dasha_pages'))
@@ -2092,13 +2110,20 @@ def render_pl9_parity_markdown(packet: dict) -> str:
# Customer tables retain computed boundaries and reference points;
# print-layout rows deliberately blank repeated values.
kantaka_rows = _list(timeline.get('kantaka_rows')) or _list(display_rows.get('kantaka'))
sade_summary = sade_sati.get('summary_en') if _lang == 'en' else sade_sati.get('summary')
if _lang == 'en' and sade_summary and re.search(r'[\u4e00-\u9fff]', str(sade_summary)):
sade_summary = ''
lines.extend([
'### p121-p122 Sade Sati / Dhayya / Kantaka Saturn',
'',
f"- Moon sign:{_cell(_token(sade_sati.get('moon_sign')))}",
f"- 当前阶段:{_cell(sade_sati.get('phase') or sade_sati.get('status'))}",
f"- 是否 active:{_cell(sade_sati.get('is_active'))}",
f"- 摘要:{_cell(sade_sati.get('summary'))}",
f"- Moon sign: {_cell(_token(sade_sati.get('moon_sign')))}" if _lang == 'en'
else f"- Moon sign:{_cell(_token(sade_sati.get('moon_sign')))}",
f"- Current phase: {_cell(sade_sati.get('phase') or sade_sati.get('status'))}" if _lang == 'en'
else f"- 当前阶段:{_cell(sade_sati.get('phase') or sade_sati.get('status'))}",
f"- Active: {_cell(sade_sati.get('is_active'))}" if _lang == 'en'
else f"- 是否 active:{_cell(sade_sati.get('is_active'))}",
f"- Summary: {_cell(sade_summary)}" if _lang == 'en'
else f"- 摘要:{_cell(sade_sati.get('summary'))}",
'',
'| Phase | Sign |',
'|-------|------|',
@@ -2994,8 +3019,12 @@ def render_pl9_parity_markdown(packet: dict) -> str:
for fact_key in ('mars_house', 'mars_sign', 'sun_house', 'sun_sign', 'rahu_house', 'ketu_house', 'moon_sign', 'severity', 'type'):
if row.get(fact_key) not in (None, ''):
fact_bits.append(f"{fact_key}={_token(row.get(fact_key))}")
summary = row.get('summary_en') if _lang == 'en' else row.get('summary')
if _lang == 'en' and summary and re.search(r'[\u4e00-\u9fff]', str(summary)):
summary = ''
joiner = '; ' if _lang == 'en' else ';'
lines.append(
f"| {_cell(label)} | {_cell(detected)} | {_cell(';'.join(map(str, fact_bits)) or '-')} | {_cell(row.get('summary'))} |"
f"| {_cell(label)} | {_cell(detected)} | {_cell(joiner.join(map(str, fact_bits)) or '-')} | {_cell(summary)} |"
)
lines.append('')
dosha_rows = _list(dosha_pack.get('dosha_rows'))
@@ -3062,6 +3091,12 @@ def render_pl9_parity_markdown(packet: dict) -> str:
for row in detected_yogas:
if isinstance(row, dict):
grouped_yogas[_yoga_group_label(row)].append(row)
strength_en_map = {}
if _lang == 'en':
try:
from yoga_engine import STRENGTH_EN as strength_en_map
except ImportError:
from scripts.yoga_engine import STRENGTH_EN as strength_en_map
for group_title, group_rows in grouped_yogas.items():
if not group_rows:
continue
@@ -3074,15 +3109,20 @@ def render_pl9_parity_markdown(packet: dict) -> str:
for row in group_rows:
if _lang == 'en':
effects = row.get('effects_en') if isinstance(row.get('effects_en'), list) else []
if not effects and isinstance(row.get('effects'), list):
effects = row.get('effects')
yoga_name = row.get('name') or row.get('type') or row.get('name_cn')
combination = row.get('combination_en') or row.get('combination') or row.get('source_reference') or row.get('reason')
effects = [item for item in effects if not re.search(r'[\u4e00-\u9fff]', str(item))]
yoga_name = row.get('name') or row.get('type')
combination = row.get('combination_en')
if not combination or re.search(r'[\u4e00-\u9fff]', str(combination)):
combination = ''
strength = row.get('strength_en') or strength_en_map.get(str(row.get('strength') or ''))
if not strength or re.search(r'[\u4e00-\u9fff]', str(strength)):
strength = ''
else:
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'))
strength = row.get('strength')
effect_text = _public_report_text(_brief(effects, 3) or (None if _lang == 'en' else row.get('interpretation') or row.get('summary')))
try:
from pl9_language_terms import soften_lifespan_wording
except ModuleNotFoundError: # pragma: no cover
@@ -3090,7 +3130,7 @@ def render_pl9_parity_markdown(packet: dict) -> str:
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(strength)} | {_cell(combination)} | "
f"{_cell(effect_text)} |"
)
lines.append('')