rushdown 0.18.0

A 100% CommonMark-compatible GitHub Flavored Markdown parser and renderer
Documentation
use crate::{
    ast::{Arena, Emphasis, NodeRef, Strong},
    parser::{parse_delimiter, Context, Delimiter, DelimiterProcessor, InlineParser},
    text::{self},
};

/// [`InlineParser`] for emphasis.
#[derive(Debug)]
pub struct EmphasisParser {
    processor: DelimiterProcessor,
}

fn is_delimiter(c: u8) -> bool {
    c == b'*' || c == b'_'
}

fn can_open_closer(opener: &Delimiter, closer: &Delimiter) -> bool {
    opener.char() == closer.char()
}

fn on_match(arena: &mut Arena, consumes: usize) -> NodeRef {
    if consumes == 2 {
        return arena.new_node(Strong::new());
    }
    arena.new_node(Emphasis::new())
}

impl EmphasisParser {
    /// Returns a new [`EmphasisParser`].
    pub fn new() -> Self {
        Self::default()
    }
}

impl Default for EmphasisParser {
    fn default() -> Self {
        let processor = DelimiterProcessor::new(is_delimiter, can_open_closer, on_match);
        Self { processor }
    }
}

impl InlineParser for EmphasisParser {
    fn trigger(&self) -> &[u8] {
        b"*_"
    }

    fn parse(
        &self,
        arena: &mut Arena,
        parent_ref: NodeRef,
        reader: &mut text::BlockReader,
        ctx: &mut Context,
    ) -> Option<NodeRef> {
        parse_delimiter(arena, parent_ref, reader, 1, &self.processor, ctx)
    }
}