Files
Christian Nennemann 56f2ce669c feat: unified drafts/ structure with PDF outputs for ACT and ECT
Both drafts now live in workspace/drafts/ as siblings:
  drafts/
  ├── act/                       (ACT -01, native to parent repo)
  │   ├── draft-nennemann-act-01.md     kramdown-rfc source
  │   ├── draft-nennemann-act-01.{xml,txt,html,pdf}
  │   ├── .refcache/             bibxml cache
  │   └── build.sh
  ├── ietf-wimse-ect/            (ECT -02, submodule, PDF added)
  │   └── ...
  └── README-pdf.md              PDF toolchain docs

ACT kramdown-rfc conversion:
- full YAML frontmatter (title, author, refs)
- section structure matches kramdown-rfc conventions
- {{REF}} citation syntax, auto-numbered sections
- references auto-built from normative/informative blocks
- removed manual TOC (kramdown-rfc generates)
- builds cleanly: 133K XML, 89K TXT, 208K HTML, 167K PDF

PDF toolchain:
- xml2rfc --pdf via weasyprint<60 + pydyf<0.10 injected into xml2rfc pipx venv
- both build.sh scripts now produce PDF as Step 4
- README-pdf.md documents the setup for new machines

Submodule: bump ietf-wimse-ect pointer for build.sh PDF step
2026-04-12 14:01:57 +02:00

2.3 KiB

PDF Generation for IETF Drafts

Status

xml2rfc --pdf is wired up on this machine. PDFs are generated automatically as part of build.sh in each draft directory.

How it works

xml2rfc is installed via pipx in its own venv (/home/c/.local/share/pipx/venvs/xml2rfc/). The --pdf switch requires several extra dependencies that had to be injected into that venv:

pipx inject xml2rfc "weasyprint<60" pycairo pangocffi
/home/c/.local/share/pipx/venvs/xml2rfc/bin/python -m pip install "pydyf<0.10"

Version pins matter:

  • weasyprint 59.x — xml2rfc's --pdf code path calls weasyprint's write_pdf(target, stylesheets=[...], presentational_hints=True). Newer weasyprint (60+) changes the signature.
  • pydyf <0.10 — weasyprint 59 calls pydyf.PDF(version, identifier) with two positional args. pydyf 0.10+ removed those.

System libs used via ctypes: pango, pangocairo, cairo, harfbuzz (all already present via Fedora packages).

Fonts: xml2rfc uses Noto + Roboto Mono embedded in the weasyprint output. Not installed system-wide but weasyprint fonttools handles them.

Build step (pattern for build.sh)

After the HTML step, add:

# Step 4: XML -> PDF
echo "Generating PDF output..."
if "$XML2RFC" "$DIR/$DRAFT.xml" --pdf --quiet 2>/dev/null; then
  PDF_OK=1
else
  echo "  xml2rfc --pdf failed; falling back to weasyprint on HTML"
  if command -v weasyprint >/dev/null 2>&1; then
    weasyprint "$DIR/$DRAFT.html" "$DIR/$DRAFT.pdf" >/dev/null 2>&1 \
      && PDF_OK=1 || PDF_OK=0
  else
    PDF_OK=0
  fi
fi

Verification

ietf-wimse-ect/draft-nennemann-wimse-ect-02.pdf — 178 KB, generated via xml2rfc --pdf (IETF-idiomatic layout with Noto fonts, title page, bookmarks, and proper TOC). The fallback weasyprint html->pdf produces a 172 KB PDF that works but renders the html2rfc template instead of the official IETF print layout; use it only if xml2rfc --pdf is unavailable.

Reinstallation checklist (on a new machine)

  1. pipx install xml2rfc
  2. pipx inject xml2rfc "weasyprint<60" pycairo pangocffi
  3. /home/c/.local/share/pipx/venvs/xml2rfc/bin/python -m pip install "pydyf<0.10"
  4. Install system libs: dnf install pango cairo harfbuzz (Fedora) or apt install libpango-1.0-0 libpangoft2-1.0-0 libharfbuzz0b (Debian)
  5. Test: xml2rfc some-draft.xml --pdf