markdown_that/parser/
main.rs1use crate::Node;
2use crate::common::TypeKey;
3use crate::common::ruler::Ruler;
4use crate::common::sourcemap::SourcePos;
5use crate::parser::block::{self, BlockParser};
6use crate::parser::core::{Root, *};
7use crate::parser::extset::MarkdownThatExtSet;
8use crate::parser::inline::{self, InlineParser};
9use crate::parser::linkfmt::{LinkFormatter, MDLinkFormatter};
10
11type RuleFn = fn(&mut Node, &MarkdownThat);
12
13#[derive(Debug)]
14pub struct MarkdownThat {
16 pub block: BlockParser,
18
19 pub inline: InlineParser,
21
22 pub link_formatter: Box<dyn LinkFormatter>,
24
25 pub ext: MarkdownThatExtSet,
27
28 #[doc(hidden)]
33 pub max_nesting: u32,
34
35 pub max_indent: i32,
38
39 ruler: Ruler<TypeKey, RuleFn>,
40}
41
42impl MarkdownThat {
43 pub fn new() -> Self {
44 Self::default()
45 }
46
47 pub fn parse(&self, src: &str) -> Node {
48 let mut node = Node::new(Root::new(src.to_owned()));
49 node.srcmap = Some(SourcePos::new(0, src.len()));
50
51 for rule in self.ruler.iter() {
52 rule(&mut node, self);
53 debug_assert!(
54 node.is::<Root>(),
55 "root node of the AST must always be Root"
56 );
57 }
58 node
59 }
60
61 pub fn add_rule<T: CoreRule>(&mut self) -> RuleBuilder<RuleFn> {
62 let item = self.ruler.add(TypeKey::of::<T>(), T::run);
63 RuleBuilder::new(item)
64 }
65
66 pub fn has_rule<T: CoreRule>(&mut self) -> bool {
67 self.ruler.contains(TypeKey::of::<T>())
68 }
69
70 pub fn remove_rule<T: CoreRule>(&mut self) {
71 self.ruler.remove(TypeKey::of::<T>());
72 }
73}
74
75impl Default for MarkdownThat {
76 fn default() -> Self {
77 let mut md = Self {
78 block: BlockParser::new(),
79 inline: InlineParser::new(),
80 link_formatter: Box::new(MDLinkFormatter::new()),
81 ext: MarkdownThatExtSet::new(),
82 max_nesting: 100,
83 ruler: Ruler::new(),
84 max_indent: i32::MAX,
85 };
86
87 block::builtin::add(&mut md);
88 inline::builtin::add(&mut md);
89
90 md
91 }
92}