Skip to content

Replace electron-pdf + markdown-styles with WeasyPrint + markdown-it#18

Open
svc-finitelabs[bot] wants to merge 2 commits into
mainfrom
agent/replace-electron-pdf-weasyprint
Open

Replace electron-pdf + markdown-styles with WeasyPrint + markdown-it#18
svc-finitelabs[bot] wants to merge 2 commits into
mainfrom
agent/replace-electron-pdf-weasyprint

Conversation

@svc-finitelabs

Copy link
Copy Markdown
Contributor

Summary

Replaces the docs pipeline's two unmaintained npm packages — electron-pdf (HTML→PDF) and markdown-styles (MD→HTML) — which pin ancient transitive deps (marked ^0.3.5, uuid ^2.0.1, @sentry/electron 1.5.2, highlight.js ^9, cookie <0.7.0, form-data 2.5.1, plus Electron itself) that keep tripping GitHub's security scanner with no auto-fix path. Root cause of DRV-45 through DRV-51.

New pipeline (template-managed files):

  • MD → HTML: tools/render-md.mjs — markdown-it + markdown-it highlight + github-markdown-css + highlight.js github theme. npm audit = 0 vulnerabilities.
  • HTML → PDF: tools/render-pdf.py — WeasyPrint, a CSS Paged Media engine (no browser/Chromium). Installed into the project .venv, so the same make init provisions it locally and in CI.
  • Pagination: automatic and content-aware (headings kept with content, tables/code never split, orphan/widow control) via CSS Paged Media rules — replaces hand-placed <div page-break> markers that landed at odd spots.

Why not puppeteer

Evaluated first; its post-install Chromium fetch corrupts on macOS (dlopen framework errors) and drags a ~300MB browser download — worse dev/CI ergonomics.

CI (build.yml.jinja)

Removes the entire Electron/Chromium shared-lib stack (libnss3, libatk*, libcups2, libgbm1, libasound2, …), xvfb, xvfb-run, and ELECTRON_DISABLE_SANDBOX. Adds WeasyPrint's lighter deps (libpangocairo, libgdk-pixbuf, libffi). Net fewer system packages.

Local

WeasyPrint needs the Pango stack (brew install pango, one time on macOS). The Makefile auto-sets DYLD_FALLBACK_LIBRARY_PATH on Darwin so make docs-pdf just works.

Validation

Proved out end-to-end on control4-tplink (finitelabs/control4-tplink#9) before porting here:

  • CI green on a clean Ubuntu runner (58s)
  • npm audit: 0 vulnerabilities
  • PDFs verified (margins, automatic pagination, tables, code spans, logo)

Template render validated with copier copy using tplink's answers — all docs files resolve correctly.

Rollout after merge

  1. Tag a new template version
  2. copier update in each consuming repo: control4-esphome, control4-mqtt, control4-hatch, control4-home-connect, control4-influxdb, control4-finite-labs-essentials, control4-tplink, control4-zigbee3
  3. Close DRV-45 … DRV-51

Closes

DRV-45, DRV-46, DRV-47, DRV-48, DRV-49, DRV-50, DRV-51 (on full rollout)

OpenClaw added 2 commits July 18, 2026 16:47
electron-pdf and markdown-styles are stale and pin ancient transitive deps
(marked ^0.3.5, uuid ^2.0.1, @sentry/electron 1.5.2, highlight.js ^9,
cookie <0.7.0, form-data 2.5.1, plus Electron itself) that keep tripping
GitHub's security scanner with no auto-fix path. See DRV-45 through DRV-51.

Puppeteer was evaluated first but its post-install Chromium fetch corrupts
on macOS (dlopen framework errors) and drags a ~300MB browser download.

New docs pipeline:
- MD -> HTML: tools/render-md.mjs (markdown-it + markdown-it highlight +
  github-markdown-css + highlight.js github theme). npm audit: 0 vulns.
- HTML -> PDF: tools/render-pdf.py (WeasyPrint, a CSS Paged Media engine,
  no browser). Installed into the project venv so `make init` provisions it
  locally and in CI. @page sets Letter + 0.4in margins; pagination is
  automatic and content-aware (headings kept with content, tables/code not
  split, orphan/widow control) instead of hand-placed page-break markers.

Makefile.jinja: WeasyPrint links Pango/Cairo/GObject at runtime; on macOS
those Homebrew libs are outside the default dyld path, so docs-pdf sets
DYLD_FALLBACK_LIBRARY_PATH on Darwin only.

build.yml.jinja: drop the Electron/Chromium shared-lib stack + xvfb +
ELECTRON_DISABLE_SANDBOX; add WeasyPrint's lighter deps (libpangocairo,
libgdk-pixbuf, libffi). Net fewer system packages.

Validated on control4-tplink (CI green, 0 vulns, PDFs verified) before
porting here. Consuming repos pick this up via copier update.
WeasyPrint pins the PDF step to Python, so consolidate the whole docs render
there rather than straddling Node + Python.

- tools/render-docs.py: single MD -> HTML -> PDF pipeline (markdown-it-py +
  Pygments + vendored github-markdown.css + WeasyPrint), two subcommands
  wired to docs-html/docs-pdf.
- Remove tools/render-md.mjs and tools/render-pdf.py; vendor
  tools/github-markdown.css.
- package.json.jinja: drop markdown-it, github-markdown-css, highlight.js.
  Node/npm now only provides stylua + prettier (formatting), no docs deps.
- Makefile.jinja: venv installs the Python doc stack.

Validated on control4-tplink (CI green, 0 npm vulns, PDFs unchanged).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants