pdg
A declarative document in; a paginated PDF out.
A layout engine that turns a small declarative XML document into a print-ready PDF. You describe what is on the page — headings, tables, columns, rules — and pdg decides where it goes: wrapping text, nesting containers, and paginating whatever overflows.
The whole engine rests on one question. Every element is asked given this much space, how much of you fits? and answers one of three ways: it fits, it partially fits — handing back the remainder to continue on a fresh page — or it does not fit at all. Applied recursively, that single protocol is what produces text wrapping, nested layout and multi-page flow, none of them a special case. A table’s header repeats on every page and an over-tall row splits across the break because of it, not because tables were taught about pages. Parse, layout, paginate and render are separate stages, with PDF behind a feature flag on the far side of a positioned-primitive IR: layout has never heard of PDF.
The vocabulary stays small: text with inline markup, vertical / horizontal
as one flex-like engine, box, table, list, stack, and style:
attributes carrying the box model on any element at all. A <layout> block is a
page template repeated on every physical page, including the ones pagination
creates; <defaults> sets per-tag defaults that scope positionally, to the
siblings after them; <pdf> merges pages out of an external file.
Two things make it liveable. debug="true" on any element is a layout inspector
in the spirit of browser devtools — boxes, gaps, padding and margin drawn on top
without disturbing the layout it measures. And the engine never aborts: an
unknown tag is skipped, a malformed length defaults, and every one of those
silent recoveries is reported as a diagnostic carrying a line:col and the
enclosing-tag trace, a stack trace into your document; strict mode makes errors
block output instead.
Fonts are embedded and subset to the glyphs used, so Cyrillic renders and files
stay small, and the 14 standard PDF faces are referenced at zero bytes. And
since a document is only markup, damask is what writes
it: a component renders pdg’s XML at compile time, so a PDF comes out of the
same typed, compiler-checked templates a web page does — a struct in, a PDF out,
one cargo build. Rust; the playground is that engine compiled to WebAssembly,
so the browser previews exactly the PDF the CLI writes.