ZLATEX-CORE // LATEX ENGINE

// catcodes · macros · text & math grammars · line breaking · hyphenation · pages · footnotes · floats · references · packages · export

Engineering Report GitHub

zlatex-core is the typesetting engine behind zlatex. A .tex source goes in; laid-out pages come out — as a render tree a WebView paints, or as a multi-page PDF, per-page SVG or PNG. It sets documents: text mode with paragraphs hyphenated and broken by TeX's own algorithms, page breaking, sectioning and counters, lists, tables, floats that move whole to the next page, footnotes set under their rule at the foot of the page their marker landed on, cross-references and a table of contents — plus the math engine, reached for every $…$, \(…\) and display. \input and \include are spliced before parsing, so a book split across chapter files typesets as one book. There is no external TeX distribution, no subprocess and nothing to install, and the math layout parameters are read from the font's own OpenType MATH table rather than hardcoded.

TeX's algorithm

The Chapter 17 conversion with Appendix G placement: the 8×8 atom-class spacing table, the Bin→Ord reclassification, script shift-and-clearance rules, fraction and radical construction, delimiter growth.

Font-sourced parameters

Where TeX reads TFM fontdimens, this reads MathConstants. The engine's measurements and the renderer's painting come from one face, so they cannot drift apart.

Total by design

An unknown control sequence becomes a visible error box plus a diagnostic, never an abort — the editor calls this on every keystroke, and a half-typed formula still previews.

Embeddable

Builds rlib, staticlib and cdylib, with one JSON command bus and a headless CLI, so a GUI host, a C ABI host and a shell pipeline all reach the same surface.

A proved fixed point

Passes run until one reads exactly what it wrote, not a fixed count. Because the iteration is in memory, every intermediate state is kept: typeset.converge reports which entries moved and to what, and when there is no fixed point it names the cycle and its period rather than giving up at a rerun cap.

The page budget

Every page limit is met by guessing: compile, look at the last page, delete a sentence, compile again. The page builder placed a known amount of vertical material into pages of a known height, so typeset.fit subtracts and gets a FLOOR — no pagination into the target exists while it is positive — stated in points, body lines and words, with every construct priced against it and the sufficient ones re-laid-out to prove the page count.

Real TeX Live packages

The engine speaks the TeX Live database format directly — the local texlive.tlpdb joined against the mirror's — installs a package's .tar.xz into its own texmf store, and mines a .sty for the macros it defines. No tlmgr, no perl, no root; what could not be honoured is reported rather than pretended.

The pipeline

.tex ─▶ tokenize ─▶ expand ─▶ textmode ─▶ line-break ─▶ page-break ─▶ RenderDoc
        (catcodes)  (macros)   (blocks)   (Knuth-Plass)  (vertical)      (pages)
                                   │            ▲            │
                                   │            └── re-run ──┘
                                   │        while a pass does not read what it wrote
                                   │             (references, pages, contents)
                                   └─▶ math mode ─▶ mlist_to_hlist
                                       ($…$, displays)   ▲
                                                OpenType MATH constants
                                                  + glyph metrics

Modules

ModuleRole
lexTeX's mouth: category codes, control sequences, comments, \def / \newcommand / \let expansion with a recursion bound
parse · symbols · atomThe math-mode grammar, the control-sequence table, and the math-list model (atoms, fields, fractions, radicals, matrices)
textmode · docThe text-mode grammar and the document model: preamble, paragraphs, sectioning, lists, tables, floats, bibliography
linebreak · hyphen · typesetKnuth–Plass total-fit line breaking, Liang's algorithm over TeX's own pattern file feeding it discretionaries, and the page builder with its floats, footnotes and its iteration to the reference fixed point
convergeWhether the document is finished: the pass-by-pass trace read into a verdict — the fixed point and how many passes it took, or the cycle and its period, with every unstable entry tied to the \ref / \pageref sites that read it
fitThe page budget: the material that must be removed to meet a page limit, proved rather than searched for, with every top-level construct priced from the page builder's own record
include\input / \include splicing: the \includeonly list, a page break around each \include, a nesting limit and a cycle guard
style · fontThe eight math styles and their transitions; glyph boxes, MATH constants, and Unicode math-alphabet mapping
boxes · mlistThe box model (width / height / depth) and the layout itself
render · exportThe render tree the frontend paints, and the outline-based exporters
packages · tlnetThe per-package support tier a \usepackage list is scanned against, .sty macro ingestion, and the TeX Live databases, mirror and installer behind them
library · commands · cliThe equation history store, the JSON command bus, and its argv front end

Use it

zlatex typeset source_file=paper.tex             # a whole document → pages
zlatex typeset source='\frac{1}{2}' size_pt=14   # a formula → one equation box
zlatex export.pdf source_file=paper.tex          # multi-page pdf
zlatex export.svg source='x^2 + y^2 = z^2' font=assets/latinmodern-math.otf
zlatex packages.scan source_file=paper.tex       # what this document needs
zlatex typeset.converge source_file=paper.tex    # finished, or chasing itself?
zlatex typeset.fit source_file=paper.tex target_pages=8   # how much has to go?
zlatex palette

Read on

The engineering report covers the layout rules, the coverage, and the limits. The zlatex app docs cover the desktop editor built on this engine.