#!/usr/bin/env python3 """Project ledger.yaml into notes/sections/symbols.tex and optional claims.md.""" from __future__ import annotations import argparse import sys from pathlib import Path import yaml def tex_escape(text: str) -> str: return ( text.replace("\\", "\\textbackslash{}") .replace("&", "\\&") .replace("%", "\\%") .replace("#", "\\#") .replace("_", "\\_") ) def render(work: Path) -> None: ledger = yaml.safe_load((work / "ledger.yaml").read_text(encoding="utf-8")) symbols = ledger.get("symbols") or [] claims = ledger.get("claims") or [] sec = work / "notes" / "sections" sec.mkdir(parents=True, exist_ok=True) lines = [ "% generated by render_ledger.py — do not edit", "\\begin{itemize}", ] if not symbols: lines.append("\\item (无符号)") for sym in symbols: name = tex_escape(str(sym.get("name", ""))) meaning = tex_escape(str(sym.get("meaning", ""))) kind = tex_escape(str(sym.get("kind", ""))) latex = sym.get("latex") or name lines.append(f"\\item ${latex}$ — {meaning} ({kind};{name})") lines.append("\\end{itemize}") (sec / "symbols.tex").write_text("\n".join(lines) + "\n", encoding="utf-8") md = ["# Claims", ""] for c in claims: md.append(f"- `{c.get('id')}` ({c.get('status')}): {c.get('text')}") (work / "claims.md").write_text("\n".join(md) + "\n", encoding="utf-8") def main() -> int: parser = argparse.ArgumentParser() parser.add_argument("--work", required=False) parser.add_argument("--out", dest="work") args = parser.parse_args() if not args.work: print("usage: render_ledger.py --work