Parser Boundary
mdwright-document is the only production crate that invokes pulldown-cmark.
Markdown is semantically total after mdwright canonicalises source bytes, but the parser implementation can still panic on malformed edge cases. The document crate contains that implementation risk:
- source bytes are canonicalised into one parser input;
- parser iteration is collected eagerly inside one private
catch_unwindboundary; - parser panics become
mdwright_document::ParseError; - document facts, signatures, HTML rendering, and block checkpoints are built only after successful collection.
Callers do not catch parser panics. They parse source with:
#![allow(unused)]
fn main() {
let doc = mdwright_document::Document::parse(source)?;
}
Operations over an existing Document stay pure over recognised facts. Formatting a parsed document remains infallible:
#![allow(unused)]
fn main() {
let formatted = mdwright_format::format_document(&doc, &opts);
}
Source-convenience APIs are fallible because they cross the parser boundary:
#![allow(unused)]
fn main() {
let formatted = mdwright_format::format_source(source, &opts)?;
let html = mdwright_document::render_html(source)?;
}
The transactional formatter uses the same policy for verification reparses. If a candidate output cannot be parsed, the
candidate is rejected and the unverified bytes are not committed. CLI and LSP delivery turn ParseError into controlled
file/editor diagnostics; they do not install parser-specific panic handlers.