Skip to content

0.17.0 — Paged media page selection, CSS Grid in HTML, page-number font fix

Choose a tag to compare

@danmolitor danmolitor released this 03 Sep 04:28
· 122 commits to main since this release

One shared version line: forme-pdf (crates.io), every @formepdf/* npm package, formepdf (PyPI), forme-go (tag), and the VS Code extension all ship as 0.17.0.

CSS Paged Media page selection (HTML path + engine)

  • @page :left / :right — per-parity margins and margin boxes. Mirrored margins (equal left+right sum) apply as an exact translation — never a re-layout, so no output drift and no perf cost. Page 1 is a :right page (LTR page progression per spec); dir="rtl" warns rather than silently assuming.
  • Named pages@page <name> + the page: <name> property. A named run starts at a forced break, so real vertical margins work (the classic zero-margin cover). Named margin boxes override or suppress the base running headers per name. Composes with :first/:left/:right (@page cover:first); precedence follows spec specificity.
  • Out-of-subset Paged Media features warn by name: :blank, :nth() page groups, string-set/content: string(), position: running(), footnotes.

CSS Grid through the HTML path

display: grid now maps in @formepdf/html — the documented subset: template columns/rows (px/pt/em/fr/auto/minmax()/integer repeat()), gaps, auto tracks, and explicit placement. Everything outside warns by name.

Fixed

  • Page-number placeholders no longer switch fonts. {{pageNumber}}/{{totalPages}} (and HTML counter(page)) in a custom/provided font used to render the digits in non-embedded base-14 Helvetica — splitting one footer line across two typefaces and hard-failing PDF/A. The digits now stay in the surrounding font, are properly subset, and keep their ToUnicode mappings. Default-font documents are byte-identical. (Thanks for the excellent report.)

Performance

  • ~2× fewer allocations in large-document layout (shared glyph font families, elided dead table-cell rollback checkpoints); the sentinel re-layout pass is skipped when no page-number placeholder exists.
  • A fixed, deterministic benchmark corpus now feeds the measured numbers on parity.formepdf.com.

Housekeeping

  • npm audit: 18 → 0 across the monorepo (all dev/build-side; test toolchain moved to vitest 4 + current workers pool).

Full per-package detail: engine/CHANGELOG.md, packages/html/CHANGELOG.md, packages/core/CHANGELOG.md.

🤖 Generated with Claude Code