pub struct IncrementalParser<'a> { /* private fields */ }Expand description
Parse Markdown that arrives in pieces, emitting the events of each document-level block once no later text can change them.
Push text as it arrives; each call returns the events of blocks that have become stable. Call IncrementalParser::finish at the end of the input to receive the remaining events. Events are the document’s body events; the document start and end events are not emitted. Text values refer to byte ranges of the accumulated IncrementalParser::source, exactly as EventParser events refer to its source.
use base_markdown::stream::{EventKind, Tag};
use base_markdown::{IncrementalParser, ParseOptions};
let options = ParseOptions::gfm();
let mut parser = IncrementalParser::new(&options);
// An ATX heading is complete at the end of its line.
let events: Vec<_> = parser.push("# Title\nFirst para").collect();
assert!(matches!(events[0].kind, EventKind::Start(Tag::Heading(1))));
assert_eq!(parser.stable_offset(), 8);
// A paragraph remains open until a blank line or another block follows it.
assert_eq!(parser.push("graph.\n").count(), 0);
let events: Vec<_> = parser.push("\nSecond").collect();
assert!(events.iter().any(|event| matches!(event.kind, EventKind::Start(Tag::Paragraph { .. }))));
assert_eq!(&parser.source()[..parser.stable_offset()], "# Title\nFirst paragraph.\n");
// Finishing emits the rest of the document.
let rest: Vec<_> = parser.finish().collect();
assert!(matches!(rest.last().unwrap().kind, EventKind::End(_)));§Stability
The events emitted across all pushes and the final IncrementalParser::finish are the events that EventParser yields for the accumulated source, without the document start and end events, provided that no link reference or footnote call is resolved by a definition in a later document-level block. Stability is defined by block structure: a block is emitted when it and every block before it are closed and no appended text can reinterpret them. Emitted events are never retracted.
Reference resolution is scoped to make the output independent of how the text is divided. Inline content in a document-level block resolves against the definitions that begin before the end of that block, including definitions inside the block itself. A reference to a definition in a later document-level block remains literal text, whereas EventParser resolves forward references across the whole document.
Container contents are not emitted separately: a list is emitted once it ends, because its tightness depends on every item. Frontmatter holds back all output until its closing fence arrives.
Implementations§
Source§impl<'a> IncrementalParser<'a>
impl<'a> IncrementalParser<'a>
Sourcepub fn new(options: &'a ParseOptions) -> Self
pub fn new(options: &'a ParseOptions) -> Self
Create a parser for an empty document.
Sourcepub fn stable_offset(&self) -> usize
pub fn stable_offset(&self) -> usize
The byte offset where the last emitted block ends. Appended text cannot change the events of the source before this offset.
Sourcepub fn push(&mut self, text: &str) -> impl Iterator<Item = Event<'static>> + '_
pub fn push(&mut self, text: &str) -> impl Iterator<Item = Event<'static>> + '_
Append text and return the events of blocks that have become stable.
The text is parsed before this returns; dropping the iterator discards the events it has not yielded.
Only complete lines are prepared, so text without a line ending costs no parsing. Each preparation restarts from the most recent clean document-level block that has been emitted.
§Panics
Panics if called after IncrementalParser::finish.