markdown_that/parser/inline/builtin/
inline_parser.rs

1use crate::parser::block::builtin::BlockParserRule;
2use crate::parser::core::{CoreRule, Root};
3use crate::parser::extset::{InlineRootExtSet, RootExtSet};
4use crate::{MarkdownThat, Node, NodeValue};
5
6#[derive(Debug)]
7/// Temporary node which gets replaced with inline nodes when
8/// [InlineParser](crate::parser::inline::InlineParser) is called.
9pub struct InlineRoot {
10    pub content: String,
11    pub mapping: Vec<(usize, usize)>,
12    pub ext: InlineRootExtSet,
13}
14
15impl InlineRoot {
16    pub fn new(content: String, mapping: Vec<(usize, usize)>) -> Self {
17        Self {
18            content,
19            mapping,
20            ext: InlineRootExtSet::new(),
21        }
22    }
23}
24
25// this token is supposed to be replaced by one or many actual tokens by inline rule
26impl NodeValue for InlineRoot {}
27
28pub fn add(md: &mut MarkdownThat) {
29    md.add_rule::<InlineParserRule>()
30        .after::<BlockParserRule>()
31        .before_all();
32}
33
34pub struct InlineParserRule;
35impl CoreRule for InlineParserRule {
36    fn run(root: &mut Node, md: &MarkdownThat) {
37        fn walk_recursive(node: &mut Node, md: &MarkdownThat, root_ext: &mut RootExtSet) {
38            let mut idx = 0;
39            while idx < node.children.len() {
40                let child = &mut node.children[idx];
41                if let Some(data) = child.cast_mut::<InlineRoot>() {
42                    let content = std::mem::take(&mut data.content);
43                    let mapping = std::mem::take(&mut data.mapping);
44                    let mut inline_ext = std::mem::take(&mut data.ext);
45
46                    let mut root = std::mem::take(child);
47                    root.ext = std::mem::take(&mut node.ext);
48                    root.children = Vec::new();
49                    root = md
50                        .inline
51                        .parse(content, mapping, root, md, root_ext, &mut inline_ext);
52
53                    let len = root.children.len();
54                    node.children
55                        .splice(idx..=idx, std::mem::take(&mut root.children));
56                    node.ext = std::mem::take(&mut root.ext);
57                    idx += len;
58                } else {
59                    stacker::maybe_grow(64 * 1024, 1024 * 1024, || {
60                        walk_recursive(child, md, root_ext);
61                    });
62                    idx += 1;
63                }
64            }
65        }
66
67        let data = root.cast_mut::<Root>().unwrap();
68        let mut root_ext = std::mem::take(&mut data.ext);
69
70        // this is invalid if input only contains reference;
71        // so if user disables block parser, he must insert smth like this instead
72        /*if root.children.is_empty() {
73            // block parser disabled, parse as if input was one big inline block
74            let data = root.cast_mut::<Root>().unwrap();
75            let node = Node::new(InlineRoot {
76                content: data.content.clone(),
77                mapping: vec![(0, 0)],
78            });
79            root.children.push(node);
80        }*/
81
82        walk_recursive(root, md, &mut root_ext);
83
84        let data = root.cast_mut::<Root>().unwrap();
85        data.ext = root_ext;
86    }
87}