Skip to main content

Crate quillmark_content

Crate quillmark_content 

Source
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 — the Content type, 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.
  • islandKnownIslandType, 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, CodeMirror ChangeSet semantics) 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 — see delta.
  • 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 Delta of 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 Content content model — one text sequence per field carrying line attributes, anchored marks, and embedded islands, over a single coordinate space of Unicode scalar values (Rust char).
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 via quillmark_core::error::MAX_NESTING_DEPTH), so a document that imports also renders.