Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/edda

crates/nornir-docbook/src/lib.rs

//! nornir-docbook — the pure, warehouse-free documentation **render engine**.
//!
//! Markdown (already assembled) → pulldown-cmark events → typst markup →
//! `typst-as-lib` engine (embedded template + fonts) → PDF / HTML / per-page
//! SVG bytes. No shellout, no JavaScript, 100% Rust, deterministic. The default
//! template (`assets/typst/report.typ`) is embedded at compile time via
//! `rust-embed`.
//!
//! This is the render *primitive* lifted verbatim out of nornir's `docs`
//! subsystem. nornir keeps a byte-stable `docs::export` re-export shim, so its
//! own bins and the doc-book xtasks (dwarves / korp / korp-rustfs-s3) — which
//! import exactly [`export::export_svg_pages`],
//! [`export::export_svg_pages_per_chapter`], [`export::ChapterInput`] and
//! [`export::ExportMeta`] — resolve unchanged.
//!
//! Rendered pages are stored as **`.svgz`** — gzip-compressed SVG, the standard
//! compressed-SVG container. See [`svgz`]: a typst page is `<use>`-into-`<symbol>`
//! glyph reuse, indented, with `f64` print noise on every coordinate, and korp's
//! real 84-page book measures 35.21 MB as typst emits it, 24.17 MB after the
//! lossless text pass and **4.49 MB** gzipped. Both steps live in this crate rather
//! than in each repo's book xtask, so every book inherits the same bytes from the
//! same writer. [`export_svgz_pages_per_chapter`] is the compressed twin of
//! [`export::export_svg_pages_per_chapter`]; the uncompressed function is unchanged,
//! so an existing consumer keeps working untouched.
//!
//! A page a *browser* gets is [`export_svg_column`] instead — one tall column
//! rather than a stack of sheets — and since 0.1.2 it carries a
//! [`TextLayer`]: an invisible `<text>` element over each shaped run, so the
//! typeset page is selectable, copyable, findable and readable aloud, the way a
//! PDF viewer's text layer has always worked. Since 0.1.3 the page's links are
//! lifted above that layer, so they take a click again. Since 0.1.4
//! [`export_pdf`] takes the same [`ImageSet`], so the PDF a browser-facing
//! caller typesets carries the pictures its SVG column already did. `TextLayer::Off` is the
//! 0.1.1 picture, byte for byte, for a caller that rasterizes or diffs the page.
//!
//! [`SvgzBook`] is the ONE door between a render and the bytes a repo commits:
//! `write` produces the page set (compressed, deterministic, stale files swept) and
//! `check` answers — rendering and writing nothing — whether what is on disk is
//! exactly what `write` would produce. `check` is the gate a repo's docs verb runs;
//! it is only possible because [`to_svgz`] pins the gzip header, so an unchanged
//! doc re-renders to a byte-identical file. Ordinary builds run neither: they embed
//! the committed bytes and never see typst.
//!
//! Since 0.1.5 none of that is paid for twice. A render of a big document used
//! to hold the laid-out `PagedDocument` while it built the page, then a second
//! copy of the page to optimize it, then a third to put the text layer on —
//! MEASURED at 3195 MB of peak RSS for 3 MB of markdown. The document is now
//! dropped the moment the page is serialised, [`optimize_svg_owned`] rewrites
//! the page in its own buffer, and the dressing is done in place: **2685 MB,
//! -16%, and the SVG identical to the byte**. What is left is typst's own
//! layout — 93.8% of the peak growth, and out of this crate's reach without a
//! fork. `examples/mem.rs` is the instrument and `examples/bench.rs` the table.
//!
//! The *assembly* half (section markers, bench/coverage tables) and the
//! *history* half (the Iceberg `doc_exports` table, the release book, the docs
//! search index) stay in nornir: they read the warehouse and are genuinely
//! Mímir.

pub mod export;
pub mod svgz;

pub use export::{
    export as export_bytes, export_html, export_pdf, export_repo, export_svg_column,
    export_svg_column_in, export_svg_column_on,
    export_svg_pages, export_svg_pages_per_chapter, export_svgz_pages_per_chapter, ChapterInput,
    DocFormat, ExportMeta, ImageSet, TextLayer,
};
pub use svgz::{
    from_svgz, optimize_svg, optimize_svg_owned, to_svgz, SvgzBook, SvgzMismatch, SvgzStats,
    SVGZ_EXTENSION,
};