rushdown/parser/
strikethrough.rs1extern crate alloc;
2
3use crate::{
4 as_kind_data,
5 ast::{Arena, NodeRef, Strikethrough},
6 parser::{self, parse_delimiter, Delimiter, DelimiterProcessor, InlineParser},
7 text::{self, Reader},
8};
9
10#[derive(Debug)]
12pub struct StrikethroughParser {
13 processor: DelimiterProcessor,
14}
15
16fn is_delimiter(c: u8) -> bool {
17 c == b'~'
18}
19
20fn can_open_closer(opener: &Delimiter, closer: &Delimiter) -> bool {
21 opener.char() == closer.char()
22}
23
24fn on_match(arena: &mut Arena, _consumes: usize) -> NodeRef {
25 arena.new_node(Strikethrough::new())
26}
27
28impl Default for StrikethroughParser {
29 fn default() -> Self {
30 let processor = DelimiterProcessor::new(is_delimiter, can_open_closer, on_match);
31 Self { processor }
32 }
33}
34
35impl StrikethroughParser {
36 pub fn new() -> Self {
38 Self::default()
39 }
40}
41
42impl InlineParser for StrikethroughParser {
43 fn trigger(&self) -> &[u8] {
44 b"~"
45 }
46
47 fn parse(
48 &self,
49 arena: &mut Arena,
50 parent_ref: NodeRef,
51 reader: &mut text::BlockReader,
52 ctx: &mut parser::Context,
53 ) -> Option<NodeRef> {
54 let precending = reader.precending_charater();
55 let text = parse_delimiter(arena, parent_ref, reader, 1, &self.processor, ctx)?;
56 let index = as_kind_data!(arena, text, Text).index()?;
57 if index.len() > 2 || precending == '~' {
58 return None;
59 }
60 Some(text)
61 }
62}