Harden Jyotish runtime evidence gates

This commit is contained in:
732642856
2026-07-05 18:27:33 +08:00
parent 8520921f40
commit 4764482c73
76 changed files with 5628 additions and 253 deletions
+251
View File
@@ -0,0 +1,251 @@
#!/usr/bin/env python3
"""Export the chart research book root to a simple readable PDF."""
from __future__ import annotations
import argparse
import re
from pathlib import Path
from reportlab.lib.colors import HexColor
from reportlab.lib.enums import TA_CENTER
from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import ParagraphStyle, getSampleStyleSheet
from reportlab.lib.units import mm
from reportlab.pdfbase.pdfmetrics import registerFont
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.platypus import PageBreak, Paragraph, Preformatted, SimpleDocTemplate, Spacer
FONT_CANDIDATES = [
("/System/Library/Fonts/Supplemental/Songti.ttc", 0),
("/System/Library/Fonts/Supplemental/Arial Unicode.ttf", 0),
("/Library/Fonts/Arial Unicode.ttf", 0),
]
def _parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(description="Export chart research book root to PDF")
parser.add_argument(
"--report-root",
default="docs/reports/chart_research_REDACTED_DATE_REDACTED_TIME",
help="Path to the chart research report root",
)
parser.add_argument(
"--output",
default=None,
help="Output PDF path; defaults to <report-root>/exports/chart_research_REDACTED_DATE_REDACTED_TIME.pdf",
)
return parser.parse_args()
def _load_order(book_path: Path) -> list[Path]:
text = book_path.read_text(encoding="utf-8")
links = re.findall(r"\]\(\./([^)]+\.md)\)", text)
return [book_path.parent / link for link in links]
def _clean_inline(text: str) -> str:
text = re.sub(r"\[([^\]]+)\]\([^)]+\)", r"\1", text)
text = text.replace("`", "")
text = text.replace("**", "")
text = text.replace("*", "")
return text.strip()
def _register_book_font() -> str:
font_name = "ChartResearchBookFont"
for font_path, subfont_index in FONT_CANDIDATES:
path = Path(font_path)
if not path.exists():
continue
registerFont(TTFont(font_name, str(path), subfontIndex=subfont_index))
return font_name
raise RuntimeError(
"No renderable CJK font found for PDF export. Tried: "
+ ", ".join(path for path, _ in FONT_CANDIDATES)
)
def _styles():
font_name = _register_book_font()
base = getSampleStyleSheet()
title = ParagraphStyle(
"BookTitle",
parent=base["Title"],
fontName=font_name,
fontSize=22,
leading=28,
alignment=TA_CENTER,
textColor=HexColor("#2c241c"),
spaceAfter=18,
)
h1 = ParagraphStyle(
"H1",
parent=base["Heading1"],
fontName=font_name,
fontSize=18,
leading=24,
textColor=HexColor("#2f2a24"),
spaceBefore=10,
spaceAfter=8,
)
h2 = ParagraphStyle(
"H2",
parent=base["Heading2"],
fontName=font_name,
fontSize=14,
leading=20,
textColor=HexColor("#3d352c"),
spaceBefore=8,
spaceAfter=6,
)
h3 = ParagraphStyle(
"H3",
parent=base["Heading3"],
fontName=font_name,
fontSize=12,
leading=17,
textColor=HexColor("#4a4036"),
spaceBefore=6,
spaceAfter=4,
)
body = ParagraphStyle(
"Body",
parent=base["BodyText"],
fontName=font_name,
fontSize=10.5,
leading=16,
textColor=HexColor("#332b24"),
spaceAfter=4,
)
bullet = ParagraphStyle(
"Bullet",
parent=body,
leftIndent=10,
firstLineIndent=0,
)
mono = ParagraphStyle(
"Mono",
parent=body,
fontName=font_name,
fontSize=8.8,
leading=12,
)
return {"title": title, "h1": h1, "h2": h2, "h3": h3, "body": body, "bullet": bullet, "mono": mono}
def _render_markdown(md_path: Path, styles: dict[str, ParagraphStyle]) -> list:
text = md_path.read_text(encoding="utf-8")
lines = text.splitlines()
flow = []
i = 0
while i < len(lines):
line = lines[i].rstrip()
stripped = line.strip()
if not stripped:
flow.append(Spacer(1, 4))
i += 1
continue
if stripped.startswith("|"):
block = []
while i < len(lines) and lines[i].strip().startswith("|"):
block.append(lines[i].rstrip())
i += 1
flow.append(Preformatted("\n".join(block), styles["mono"]))
flow.append(Spacer(1, 5))
continue
if stripped.startswith("# "):
flow.append(Paragraph(_clean_inline(stripped[2:]), styles["h1"]))
i += 1
continue
if stripped.startswith("## "):
flow.append(Paragraph(_clean_inline(stripped[3:]), styles["h2"]))
i += 1
continue
if stripped.startswith("### "):
flow.append(Paragraph(_clean_inline(stripped[4:]), styles["h3"]))
i += 1
continue
if stripped.startswith("> "):
flow.append(Paragraph(_clean_inline(stripped[2:]), styles["body"]))
i += 1
continue
if stripped.startswith("- "):
flow.append(Paragraph("" + _clean_inline(stripped[2:]), styles["bullet"]))
i += 1
continue
if re.match(r"^\d+\.\s", stripped):
flow.append(Paragraph(_clean_inline(stripped), styles["bullet"]))
i += 1
continue
para = [stripped]
i += 1
while i < len(lines):
nxt = lines[i].strip()
if not nxt or nxt.startswith(("#", "|", "-", ">")) or re.match(r"^\d+\.\s", nxt):
break
para.append(nxt)
i += 1
flow.append(Paragraph(_clean_inline(" ".join(para)), styles["body"]))
return flow
def build_pdf(report_root: Path, output_pdf: Path) -> Path:
styles = _styles()
md_files = _load_order(report_root / "book.md")
story = [
Spacer(1, 25 * mm),
Paragraph("B.V. Raman / Parashara / Jaimini Comprehensive Chart Research", styles["title"]),
Paragraph("REDACTED_DATE REDACTED_TIME UTC+8 | REDACTED_PLACE Fengfeng, Hebei | Raman ayanamsa | Mean Node", styles["body"]),
Spacer(1, 12 * mm),
Paragraph("Markdown-first export generated from the report book root.", styles["body"]),
PageBreak(),
]
for idx, md_path in enumerate(md_files):
if idx > 0:
story.append(PageBreak())
story.extend(_render_markdown(md_path, styles))
output_pdf.parent.mkdir(parents=True, exist_ok=True)
doc = SimpleDocTemplate(
str(output_pdf),
pagesize=A4,
leftMargin=18 * mm,
rightMargin=18 * mm,
topMargin=18 * mm,
bottomMargin=18 * mm,
title="B.V. Raman / Parashara / Jaimini Comprehensive Chart Research",
author="Codex + repo runtime outputs",
)
doc.build(story)
return output_pdf
def main() -> int:
args = _parse_args()
report_root = Path(args.report_root).resolve()
output_pdf = (
Path(args.output).resolve()
if args.output
else report_root / "exports" / "chart_research_REDACTED_DATE_REDACTED_TIME.pdf"
)
build_pdf(report_root, output_pdf)
print(output_pdf)
return 0
if __name__ == "__main__":
raise SystemExit(main())