SRD tools

Python tooling that turns the SRD 2.0 PDF (DH_SRD_2_2026_08_25.pdf, repo root, not committed) into content/**/*.md and checks the result. Module docstrings are the reference; this is the outline.

Setup: pip install -r tools/requirements.txt (pypdf; pdfplumber is listed but not installed on Pragma and not needed by the main pipeline). Run from daggerheart-web/.

Pipeline

  1. Extract — srd_extract.py [--force] decodes positioned PDF text (two-column order, tabular-number glyphs, gear-table joins, bold/italic spans) into tools/_cache/srd-<sha12>.json. Everything else reads this cache.
  2. Records — srd_catalog.py / srd_records.py slice the corpus into typed records (abilities, classes, subclasses, heritages, gear, adversaries, environments, frames). Wording comes only from the PDF. srd_records.py --entities --folder X token-diffs records against the site.
  3. Generate — srd_generate.py --kind <kind> [--include-existing] [--write]. Dry run by default; refuses pages whose emitted tokens differ from the record. Kinds: abilities, domains, classes, subclasses, ancestries, communities, transformations, weapons, armor, items, consumables, adversaries, environments, tables, frames, all. Paragraph breaks come from vertical gaps (line spacing + 2.5 pt).
  4. Overrides — srd_overrides.py: explicit (old, new) fixes per page for PDF typos and house style; fails loudly if an old string disappears.
  5. Emphasis — srd_emph.py, applied during generate: re-wraps PDF bold/italic in body text only (**, *; never _, index cards read *). Never changes the underlying text.
  6. Verify — verify_srd.py [--section NAME] [--skip-tables]: dice/stat checks (errors) and prose drift (warnings) → tools/_cache/verify-report.json.

Tests: npm run test:srd-extract (golden fixtures, test_srd_extract.py), npm run test:tools (+ share links). Review any --write with git diff before committing.

House rules: SRD 2.0 wording wins over older text; attack modifiers +0 and − (U+2212); Title Case titles; renamed pages need a 301 in netlify.toml.

Known gaps