atelier. Not just OCR

Not just OCR · section 7

Annex A

Annex A — Pipeline reference

This annex is the terse version of the pipeline section and the technical half of the architecture section, for anyone building the same way. The living original is WORKFLOW.md in the repository; if the two ever disagree, trust the repository.

Sources

Three library-digitized PDFs at the repo root, git-ignored on purpose (the scans stay private provenance):

File Volume Role
910001066311_…AC.pdf 1 Introduction + chansons (298 pages, v1p000…)
910001066313_…AC.pdf 2 Chansons cont., bibliography, indexes (288 pages, v2p000…)
910001066314_…AC.pdf 3 Annex (manuscript photocopies) — excluded

Stable page id: v{vol}p{idx} by PDF page order, zero-padded (v1p051). Printed page numbers are separate metadata (page_numbers.csv).

Stage 1 — vision

One-time; needs OPENAI_API_KEY in .env and a venv with pymupdf openai pillow python-dotenv.

python transcribe.py                  # all vol1+vol2 pages → per-page Markdown
python ocr_page_numbers.py            # printed numbers → page_numbers.csv (gpt-4o-mini)
python merge_corpus_v2.py             # gpt-4o base + Claude verse overlay → corpus

Ran once, in July 2026; per-page model provenance in corpus-v2-sources.csv (499 pages gpt-4o, 87 Claude). See Annex C for the prompt and parameters.

Stage 2 — normalization

python normalize_typography.py        # rewrites corpus/*.md in place, idempotent

Run after any manual corpus edit. Rules: reflow prose (verse divs and page anchors untouched), collapse multiple spaces, spaced hyphen → spaced em dash (not between capitals), narrow no-break space before ; : ! ? and inside « », stacked + → ⁂.

Stage 3 — derived data

(stdlib-only, deterministic; run in this order)

# Command Reads Writes
1 python build_manifest.py corpus, page_numbers.csv manifest.json
2 python assemble_book.py corpus, manifest book.md (+ hyphen-repair log, footnote issues)
3 python build_bibliography.py corpus, manifest bibliography.json
4 python build_catalogue.py corpus, manifest chansons.json
5 python build_citations.py corpus, manifest, bibliography, sigla-overrides.json citations.json
6 python build_references.py corpus, manifest, citations, bibliography references.json
7 python build_footnote_norm.py book, references, bibliography, citations footnote-normalization.json

Review reports (*-flags.md) are regenerated alongside; they are build outputs, not committed artifacts. Hand-authored and never regenerated: manuscripts.json, sigla-overrides.json, the manuscript photos. Data shapes for all seven JSONs are in Annex B.

Or let the tool compute the order and staleness:

python manage.py            # interactive dashboard
python manage.py stale      # rebuild exactly what an edit made stale
python manage.py publish    # rebuild stale → site build → deploy

Stage 4 — site

Eleventy 3 (ESM, Node ≥ 18) in site/; markdown-it + markdown-it-attrs + markdown-it-bracketed-spans. site/src/_data/edition.js reads book.md + the seven JSONs; site/lib/*.js does the apparatus rendering at build time.

cd site && npm install && npm run build     # → site/_site/
npm run serve                               # local dev server

Stage 5 — deploy

.\deploy.ps1

Builds, packs _site/ into a tarball, ships it over scp, extracts on the server. Tarball because piping raw binaries through the PowerShell pipeline corrupts fonts and images.