A page is a constraint,
not a canvas.
Swiss grid systems compiled into executable rules, so that layouts can be counted, scored, sampled, and re-rolled. Gerstner's programmes and Müller-Brockmann's modular grid, read as a specification.
01 The demonstration
This is not a picture of a book.
The Field is an essay in seven chapters on where the grid came from and what it is for, and the only argument this library can make about itself: nobody laid out a single page of it. Real A4 leaves, composed at print size with a nine point face, scaled down like proofs on a light table. Press new grid, and the book is composed again from nothing. Read it full-screen →
02 The argument
Instead of solutions for problems, programmes for solutions.
That is Gerstner, in 1964, and it is the whole API. You do not author a layout. You author the constraints a layout must satisfy — and the library enumerates the ones that do, scores them by rules taken from the books, and lets a seed choose. The same seed returns the same page, forever.
Every typesetting engine can set a beautiful line. TeX has done it since 1981, and this library borrows its algorithm without apology. What no typesetter does is treat the grid as the primitive.
There is no way to express an off-grid position.
Which sounds like a cage and turns out to be a door. Because the set of legal pages is finite, layout stops being a matter of nudging boxes and becomes a search. The rules decide which pages are permitted. Taste — a small object of named weights — decides which permitted page is good.
Each rule has a page number, and each idea has a demo you can hold.
03 The shape of it
Give it words, pictures, a grid, and a seed.
// A programme: the constraints a page must satisfy.
const pages = composeDocument({
grid: ({ side }) => grid({ page: A4, margins, columns: 4,
line: body.lineHeight, rows: 8, side }),
styles: typeSystem({ module: 24, roles: { display, body, caption } }).roles,
story: paragraphs, // text, headings, dropped initials
figures: plates, // anchored: "(Plate 3)" in the prose
textSpan: 2, // a text column spans 2 grid columns
bodyAlign: 'justify', // grid-aware Knuth–Plass
seed: 'a-seed', // same seed, same book, forever
}).pages;
renderDOM(pages[0], el); // live text on the baseline grid
renderPage(pages[0]); // or SVG, or PDF
npm install geviert