Expand description
Content — the canonical content model for Quillmark (issue #831).
One Content per content field: a single text sequence carrying line
attributes, anchored marks, and embedded islands, over one coordinate space
of Unicode scalar values. Markdown is demoted to a projection — import
(import::from_markdown) and export (export::to_markdown) codecs — so
every edit is a splice and all structure moves with it.
core, quillmark, and both backends (typst, pdfform) consume this
crate: the seam carries content JSON, storage embeds it structurally (see
prose/canon/DOCUMENT_STORAGE.md), and the content edit surface
(delta, ops) drives per-field splices.
§Layout
model— theContenttype, the mark set, normalization (the three Spike-A rules), and invariants. The freeze.serial— canonical, byte-deterministic JSON. One encoding for the seam and for storage.island—KnownIslandType, the closed dispatch authority for island types; adding a type is one variant and the compiler enforces every arm.import— markdown → content (normalize → pulldown → content).export— content → markdown, per island loss class.delta— the per-field edit surface: a text-splice change set (retain/insert/delete, CodeMirrorChangeSetsemantics) plus the cold-parse + content-diff stale-text writer with a block-move detector. The text-splice channel is the positional core; mark and line-attribute edits are separate op channels, not op attributes — seedelta.ops— mark and line op channels:Content::apply_text_delta,apply_mark_ops,apply_line_ops.normalize— the markdown-string input primitive (line endings, bidi strip, HTML-comment fence repair), applied at the import boundary.usv— USV → UTF-8 byte-offset conversion for slicing the content.
Re-exports§
pub use delta::diff_import;pub use delta::Assoc;pub use delta::Delta;pub use delta::Op;pub use export::to_markdown;pub use export::to_plaintext;pub use import::from_markdown;pub use import::from_plaintext;pub use island::KnownIslandType;pub use model::Container;pub use model::Invariant;pub use model::Island;pub use model::Line;pub use model::LineKind;pub use model::Loss;pub use model::Mark;pub use model::MarkKind;pub use model::Content;pub use model::Usv;pub use normalize::normalize_markdown;pub use ops::change_bundle_from_value;pub use ops::line_op_from_value;pub use ops::line_op_to_value;pub use ops::mark_op_from_value;pub use ops::mark_op_to_value;pub use ops::ApplyError;pub use ops::LineOp;pub use ops::MarkOp;pub use serial::ParseError;
Modules§
- delta
- The per-field edit surface: a
Deltaof text splices over the USV content, plus the stale-text writer path — cold-parse a full new markdown document, char-diff it against the base, and rebase the base’s identity marks (anchors/comments) through the diff so annotations survive an LLM full-document rewrite with no preservation contract on the LLM. - export
- Markdown export: content → markdown, per island loss class.
- import
- Markdown import (cold):
normalize → pulldown → content. - island
- Island types — the closed dispatch authority.
- model
- The
Contentcontent model — one text sequence per field carrying line attributes, anchored marks, and embedded islands, over a single coordinate space of Unicode scalar values (Rustchar). - normalize
- Markdown-string input normalization — the boundary preprocessing content
import runs before parsing. Converts line endings to
\n, strips invisible Unicode bidi controls (which sit adjacent to**/_and defeat delimiter recognition), and repairs<!-- ... -->HTML-comment fences that would otherwise swallow trailing text. - ops
- Mark and line op channels — structural edits separate from text splices.
- serial
- Canonical JSON serialization — the freeze.
- usv
- USV → UTF-8 byte conversion, the one coordinate crossing storage needs.
Constants§
- MAX_
NESTING_ DEPTH - Maximum container nesting depth the markdown codecs accept before erroring.
The import guard (
import::from_markdown) and the typst backend’s markup converter share this one limit (the backend re-exports it viaquillmark_core::error::MAX_NESTING_DEPTH), so a document that imports also renders.