Add the ledger schema, class router, lint codes, ingest/build pipeline, and three work-tree examples: align derivation, superfig delegation, and supertensor delegation.
68 lines
2.0 KiB
Python
Executable File
68 lines
2.0 KiB
Python
Executable File
#!/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 <dir>", file=sys.stderr)
|
||
return 2
|
||
work = Path(args.work).resolve()
|
||
if not (work / "ledger.yaml").is_file():
|
||
print(f"no ledger at {work / 'ledger.yaml'}", file=sys.stderr)
|
||
return 2
|
||
render(work)
|
||
return 0
|
||
|
||
|
||
if __name__ == "__main__":
|
||
sys.exit(main())
|