Milestone 2: module/model docs (MD, Sphinx RST, PDF) and work log
74 source modules documented with extracted signatures, JSDoc params, imports, and call graphs. 10 first-class models (PriceRule through StatusResponse) have their own MD/RST/PDF. Sphinx HTML builds from docs/sphinx. Per-module PDFs in docs/modules-pdf and docs/models-pdf. Middleware gates 2–6 and 10 pass on MOCK_VERAE without NATS. Learned: RST includes are relative to the RST file; keep one PDF per module; Add Numbers remains the only push required tomorrow.
This commit is contained in:
parent
b814501441
commit
10c663cc0c
347 changed files with 17200 additions and 14 deletions
112
scripts/gen-module-pdfs.py
Normal file
112
scripts/gen-module-pdfs.py
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Render each docs/modules/*.md file to a PDF via reportlab."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from reportlab.lib.pagesizes import letter
|
||||
from reportlab.lib.styles import ParagraphStyle, getSampleStyleSheet
|
||||
from reportlab.lib.units import inch
|
||||
from reportlab.platypus import PageBreak, Paragraph, Preformatted, SimpleDocTemplate, Spacer
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
MD_ROOT = ROOT / "docs" / "modules"
|
||||
PDF_ROOT = ROOT / "docs" / "modules-pdf"
|
||||
|
||||
|
||||
def md_to_flowables(text: str, styles):
|
||||
story = []
|
||||
in_code = False
|
||||
code_buf = []
|
||||
for raw in text.splitlines():
|
||||
line = raw.rstrip()
|
||||
if line.startswith("```"):
|
||||
if in_code:
|
||||
story.append(Preformatted("\n".join(code_buf) or " ", styles["ModuleCode"]))
|
||||
code_buf = []
|
||||
in_code = False
|
||||
else:
|
||||
in_code = True
|
||||
continue
|
||||
if in_code:
|
||||
code_buf.append(line)
|
||||
continue
|
||||
if line.startswith("# "):
|
||||
story.append(Paragraph(esc(line[2:]), styles["Title"]))
|
||||
elif line.startswith("## "):
|
||||
story.append(Spacer(1, 8))
|
||||
story.append(Paragraph(esc(line[3:]), styles["Heading2"]))
|
||||
elif line.startswith("### "):
|
||||
story.append(Paragraph(esc(line[4:]), styles["Heading3"]))
|
||||
elif line.startswith("|"):
|
||||
story.append(Paragraph(esc(line.replace("|", " · ")), styles["BodyText"]))
|
||||
elif line.startswith("- "):
|
||||
story.append(Paragraph("• " + esc(line[2:]), styles["BodyText"]))
|
||||
elif line.strip() == "":
|
||||
story.append(Spacer(1, 6))
|
||||
else:
|
||||
story.append(Paragraph(esc(line), styles["BodyText"]))
|
||||
return story
|
||||
|
||||
|
||||
def esc(s: str) -> str:
|
||||
return (
|
||||
s.replace("&", "&")
|
||||
.replace("<", "<")
|
||||
.replace(">", ">")
|
||||
.replace("`", "")
|
||||
)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
PDF_ROOT.mkdir(parents=True, exist_ok=True)
|
||||
styles = getSampleStyleSheet()
|
||||
styles.add(
|
||||
ParagraphStyle(
|
||||
name="ModuleCode",
|
||||
fontName="Courier",
|
||||
fontSize=7,
|
||||
leading=9,
|
||||
)
|
||||
)
|
||||
mds = sorted(MD_ROOT.rglob("*.md"))
|
||||
n = 0
|
||||
combined = []
|
||||
for md in mds:
|
||||
rel = md.relative_to(MD_ROOT)
|
||||
pdf_path = PDF_ROOT / rel.with_suffix(".pdf")
|
||||
pdf_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
text = md.read_text(encoding="utf-8", errors="replace")
|
||||
doc = SimpleDocTemplate(
|
||||
str(pdf_path),
|
||||
pagesize=letter,
|
||||
leftMargin=0.7 * inch,
|
||||
rightMargin=0.7 * inch,
|
||||
topMargin=0.7 * inch,
|
||||
bottomMargin=0.7 * inch,
|
||||
)
|
||||
flow = md_to_flowables(text, styles)
|
||||
doc.build(flow)
|
||||
combined.extend(flow)
|
||||
combined.append(PageBreak())
|
||||
n += 1
|
||||
|
||||
try:
|
||||
from pypdf import PdfWriter
|
||||
|
||||
writer = PdfWriter()
|
||||
for md in mds:
|
||||
pdf_path = PDF_ROOT / md.relative_to(MD_ROOT).with_suffix(".pdf")
|
||||
if pdf_path.exists():
|
||||
writer.append(str(pdf_path))
|
||||
book = PDF_ROOT / "ALL-MODULES.pdf"
|
||||
with open(book, "wb") as fh:
|
||||
writer.write(fh)
|
||||
print(f"wrote {n} pdfs + {book.name}")
|
||||
except Exception as exc:
|
||||
print(f"wrote {n} pdfs (combined book skipped: {exc})")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Loading…
Add table
Add a link
Reference in a new issue