markdown_stream/lib.rs
1//! `markdown-stream` — an incremental, streaming CommonMark/GFM parser.
2//!
3//! Pure `std`, no runtime dependencies. Feed bytes to a [`StreamParser`] with [`Parser::write`] and
4//! consume the flat [`Event`] stream it emits; call [`Parser::flush`] at end of input. The event
5//! stream is **independent of how the input is chunked** (split-equivalence) — this is what makes
6//! the parser usable on a live token stream from an LLM.
7//!
8//! The parser is *append-only and chunk-safe*; renderers (`markdown-html`, `markdown-terminal`)
9//! consume the events and never re-parse Markdown.
10
11#![forbid(unsafe_code)]
12
13mod block;
14mod entity;
15mod event;
16mod inline;
17mod linkref;
18mod parser;
19
20pub use block::StreamParser;
21pub use event::{
22 Alignment, BlockData, BlockKind, Event, Inline, InlineStyle, Link, ListData, Span,
23};
24pub use parser::Parser;
25
26/// Parse a complete document to a `Vec<Event>` (convenience over the streaming API).
27pub fn parse(input: &str) -> Vec<Event> {
28 let mut p = StreamParser::new();
29 let mut events = p.write(input.as_bytes());
30 events.extend(p.flush());
31 events
32}
33
34/// Parse a complete document with GFM-only extensions enabled (extended autolinks, task-list items),
35/// in addition to the always-on strikethrough and tables.
36pub fn parse_gfm(input: &str) -> Vec<Event> {
37 let mut p = StreamParser::new_gfm();
38 let mut events = p.write(input.as_bytes());
39 events.extend(p.flush());
40 events
41}