Something went wrong. Try again.
Markdown parser fork with extended syntax for personal use.
Something went wrong. Try again.
4.0 kB · 135 lines
Rust
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136//! Block quotes occur in the [document][] content type.//!//! ## Grammar//!//! Block quotes form with the following BNF//! (<small>see [construct][crate::construct] for character groups</small>)://!//! ```bnf//! block_quote_start ::= '>' [ space_or_tab ]//! block_quote_cont ::= '>' [ space_or_tab ]//! ```//!//! Further lines that are not prefixed with `block_quote_cont` cause the block//! quote to be exited, except when those lines are lazy continuation.//! Like so many things in markdown, block quotes too are complex.//! See [*§ Phase 1: block structure* in `CommonMark`][commonmark-block] for//! more on parsing details.//!//! As block quote is a container, it takes several bytes from the start of the//! line, while the rest of the line includes more containers or flow.//!//! ## HTML//!//! Block quote relates to the `<blockquote>` element in HTML.//! See [*§ 4.4.4 The `blockquote` element*][html-blockquote] in the HTML spec//! for more info.//!//! ## Recommendation//!//! Always use a single space after a block quote marker (`>`).//! Never use lazy continuation.//!//! ## Tokens//!//! * [`BlockQuote`][Name::BlockQuote]//! * [`BlockQuoteMarker`][Name::BlockQuoteMarker]//! * [`BlockQuotePrefix`][Name::BlockQuotePrefix]//! * [`SpaceOrTab`][Name::SpaceOrTab]//!//! ## References//!//! * [`block-quote.js` in `micromark`](https://github.com/micromark/micromark/blob/main/packages/micromark-core-commonmark/dev/lib/block-quote.js)//! * [*§ 5.1 Block quotes* in `CommonMark`](https://spec.commonmark.org/0.31/#block-quotes)//!//! [document]: crate::construct::document//! [html-blockquote]: https://html.spec.whatwg.org/multipage/grouping-content.html#the-blockquote-element//! [commonmark-block]: https://spec.commonmark.org/0.31/#phase-1-block-structure
use crate::construct::partial_space_or_tab::space_or_tab_min_max;use crate::event::Name;use crate::state::{Name as StateName, State};use crate::tokenizer::Tokenizer;use crate::util::constant::TAB_SIZE;
/// Start of block quote.////// ```markdown/// > | > a/// ^/// ```pub fn start(tokenizer: &mut Tokenizer) -> State { if tokenizer.parse_state.options.constructs.block_quote { tokenizer.enter(Name::BlockQuote); State::Retry(StateName::BlockQuoteContStart) } else { State::Nok }}
/// Start of block quote continuation.////// Also used to parse the first block quote opening.////// ```markdown/// | > a/// > | > b/// ^/// ```pub fn cont_start(tokenizer: &mut Tokenizer) -> State { if matches!(tokenizer.current, Some(b'\t' | b' ')) { tokenizer.attempt(State::Next(StateName::BlockQuoteContBefore), State::Nok); State::Retry(space_or_tab_min_max( tokenizer, 1, if tokenizer.parse_state.options.constructs.code_indented { TAB_SIZE - 1 } else { usize::MAX }, )) } else { State::Retry(StateName::BlockQuoteContBefore) }}
/// At `>`, after optional whitespace.////// Also used to parse the first block quote opening.////// ```markdown/// | > a/// > | > b/// ^/// ```pub fn cont_before(tokenizer: &mut Tokenizer) -> State { match tokenizer.current { Some(b'>') => { tokenizer.enter(Name::BlockQuotePrefix); tokenizer.enter(Name::BlockQuoteMarker); tokenizer.consume(); tokenizer.exit(Name::BlockQuoteMarker); State::Next(StateName::BlockQuoteContAfter) } _ => State::Nok, }}
/// After `>`, before optional whitespace.////// ```markdown/// > | > a/// ^/// > | >b/// ^/// ```pub fn cont_after(tokenizer: &mut Tokenizer) -> State { if let Some(b'\t' | b' ') = tokenizer.current { tokenizer.enter(Name::SpaceOrTab); tokenizer.consume(); tokenizer.exit(Name::SpaceOrTab); }
tokenizer.exit(Name::BlockQuotePrefix); State::Ok}