#!/usr/bin/env python3 r"""Ratchet checks for the re-typeset project. Exit 1 on any hard failure. - every manifest row marked done points at an existing page file (or is dropped/colophon) - every src/pages file is a manifest row marked done - page file carries \origpage{P}/\plateop{P} with P == manifest.printed - a head macro (\chaphead/\chapstart/\chapnum/\partstart/\sectionstart) precedes \origpage - printed page numbers increase in PDF order; note numbers \fn{n} run 1,2,3… per chapter - lists \unsure{} readings so they can be mirrored in QUESTIONS.md - every \erratum{corrected}{as printed} has a matching \erratumline in src/errata.tex """ import csv, re, glob, os, sys fail=[]; warn=[] rows=list(csv.DictReader(open("manifest.tsv"),delimiter="\t")) files=set(glob.glob("src/pages/p*.tex")) seen=set(); last_printed=0; fn_expect=1; unsure=[]; errata_used=[] for r in sorted(rows,key=lambda r:int(r["pdf_page"])): p=int(r["pdf_page"]); st=r["status"]; kind=r["kind"]; f=r["src_file"] if st!="done": continue if kind in ("dropped","colophon"): continue if not f or not os.path.exists(f): fail.append(f"PDF {p}: done but src_file missing ({f!r})"); continue seen.add(f); s=open(f).read() m=re.search(r"\\(?:origpage|plateop)\{(\d+)\}",s) if not m: fail.append(f"{f}: no \\origpage/\\plateop") else: pr=int(m.group(1)) if r["printed"] and pr!=int(r["printed"]): fail.append(f"{f}: \\origpage{{{pr}}} but manifest printed={r['printed']}") if pr<=last_printed: fail.append(f"{f}: printed {pr} not after previous {last_printed}") last_printed=pr heads = ("\\chaphead", "\\chapstart", "\\partstart", "\\sectionstart", "\\chapnum") if any(h in s for h in heads): if s.find("\\origpage")!=-1 and s.find("\\origpage")