Something went wrong. Try again.
Markdown parser fork with extended syntax for personal use.
Something went wrong. Try again.
4.5 kB · 153 lines
Rust
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154//! Space or tab occurs in tons of places.//!//! ## Grammar//!//! Space or tab forms with the following BNF//! (<small>see [construct][crate::construct] for character groups</small>)://!//! ```bnf//! space_or_tab ::= 1*('\t' | ' ')//! ```//!//! ## References//!//! * [`micromark-factory-space/index.js` in `micromark`](https://github.com/micromark/micromark/blob/main/packages/micromark-factory-space/dev/index.js)
use crate::event::{Content, Link, Name};use crate::state::{Name as StateName, State};use crate::subtokenize::link;use crate::tokenizer::Tokenizer;
/// Configuration.#[derive(Debug)]pub struct Options { /// Minimum allowed bytes (inclusive). pub min: usize, /// Maximum allowed bytes (inclusive). pub max: usize, /// Name to use for events. pub kind: Name, /// Connect this event to the previous. pub connect: bool, /// Embedded content type to use. pub content: Option<Content>,}
/// One or more `space_or_tab`.////// ```bnf/// space_or_tab ::= 1*( ' ' '\t' )/// ```pub fn space_or_tab(tokenizer: &mut Tokenizer) -> StateName { space_or_tab_min_max(tokenizer, 1, usize::MAX)}
/// Between `x` and `y` `space_or_tab`.////// ```bnf/// space_or_tab_min_max ::= x*y( ' ' '\t' )/// ```pub fn space_or_tab_min_max(tokenizer: &mut Tokenizer, min: usize, max: usize) -> StateName { space_or_tab_with_options( tokenizer, Options { kind: Name::SpaceOrTab, min, max, content: None, connect: false, }, )}
/// `space_or_tab`, with the given options.pub fn space_or_tab_with_options(tokenizer: &mut Tokenizer, options: Options) -> StateName { tokenizer.tokenize_state.space_or_tab_connect = options.connect; tokenizer.tokenize_state.space_or_tab_content = options.content; tokenizer.tokenize_state.space_or_tab_min = options.min; tokenizer.tokenize_state.space_or_tab_max = options.max; tokenizer.tokenize_state.space_or_tab_token = options.kind; StateName::SpaceOrTabStart}
/// Start of `space_or_tab`.////// ```markdown/// > | a␠␠b/// ^/// ```pub fn start(tokenizer: &mut Tokenizer) -> State { if tokenizer.tokenize_state.space_or_tab_max > 0 && matches!(tokenizer.current, Some(b'\t' | b' ')) { if let Some(ref content) = tokenizer.tokenize_state.space_or_tab_content { tokenizer.enter_link( tokenizer.tokenize_state.space_or_tab_token.clone(), Link { previous: None, next: None, content: content.clone(), }, ); } else { tokenizer.enter(tokenizer.tokenize_state.space_or_tab_token.clone()); }
if tokenizer.tokenize_state.space_or_tab_connect { let index = tokenizer.events.len() - 1; link(&mut tokenizer.events, index); } else { tokenizer.tokenize_state.space_or_tab_connect = true; }
State::Retry(StateName::SpaceOrTabInside) } else { State::Retry(StateName::SpaceOrTabAfter) }}
/// In `space_or_tab`.////// ```markdown/// > | a␠␠b/// ^/// ```pub fn inside(tokenizer: &mut Tokenizer) -> State { match tokenizer.current { Some(b'\t' | b' ') if tokenizer.tokenize_state.space_or_tab_size < tokenizer.tokenize_state.space_or_tab_max => { tokenizer.consume(); tokenizer.tokenize_state.space_or_tab_size += 1; State::Next(StateName::SpaceOrTabInside) } _ => { tokenizer.exit(tokenizer.tokenize_state.space_or_tab_token.clone()); State::Retry(StateName::SpaceOrTabAfter) } }}
/// After `space_or_tab`.////// ```markdown/// > | a␠␠b/// ^/// ```pub fn after(tokenizer: &mut Tokenizer) -> State { let state = if tokenizer.tokenize_state.space_or_tab_size >= tokenizer.tokenize_state.space_or_tab_min { State::Ok } else { State::Nok }; tokenizer.tokenize_state.space_or_tab_connect = false; tokenizer.tokenize_state.space_or_tab_content = None; tokenizer.tokenize_state.space_or_tab_size = 0; tokenizer.tokenize_state.space_or_tab_max = 0; tokenizer.tokenize_state.space_or_tab_min = 0; tokenizer.tokenize_state.space_or_tab_token = Name::SpaceOrTab; state}