Skip to main content

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}