ipsae_core/parser/
iterator.rs

1use regex::Regex;
2
3use crate::{Markdown, MarkdownType};
4use crate::parser::markdown::{MarkdownVisitable, Visitable};
5use crate::parser::visitor::{Visitor, VisitorBase};
6
7#[derive(Debug)]
8pub struct MarkdownIterator<V: Visitor + Clone, A: Visitable<V>> {
9    visitor: V,
10    visitable_block_list: Vec<A>,
11    visitable_inline_list: Vec<A>,
12}
13
14impl<V: Visitor + Clone, A: Visitable<V>> MarkdownIterator<V, A> {
15    pub fn create(visitor: V, visitable_block_list: Vec<A>, visitable_inline_list: Vec<A>) -> Self {
16        Self { visitor, visitable_block_list, visitable_inline_list }
17    }
18
19    pub fn parse_markdown(&self, input: String) -> Vec<Markdown> {
20        let mut result: Vec<Markdown> = vec![];
21        let input_vec: Vec<&str> = input
22            .split('\n')
23            .into_iter()
24            .collect();
25
26        for input in input_vec {
27            for visitable in self.visitable_block_list.iter() {
28                match visitable.accept(self.visitor.clone(), input) {
29                    Some(markdown) => result.push(markdown),
30                    None => continue,
31                }
32            }
33        }
34
35        result
36            .into_iter()
37            .map(|mut markdown_item| {
38                if markdown_item.style == MarkdownType::P {
39                    for visitable in self.visitable_inline_list.iter() {
40                        match visitable.accept(self.visitor.clone(), markdown_item.content.clone().as_str()) {
41                            Some(markdown_child) => {
42                                markdown_item.children.push(markdown_child);
43                                break;
44                            },
45                            None => continue,
46                        }
47                    }
48                }
49                return markdown_item;
50            })
51            .collect()
52    }
53}
54
55pub fn get_markdown_iterator(visitor: VisitorBase) -> MarkdownIterator<VisitorBase, MarkdownVisitable> {
56    let markdown_h1 = MarkdownVisitable {
57        style: MarkdownType::H1,
58        regex: Regex::new(r"^#\s").unwrap(),
59        is_block: true,
60    };
61
62    let markdown_h2 = MarkdownVisitable {
63        style: MarkdownType::H2,
64        regex: Regex::new(r"^#{2}\s").unwrap(),
65        is_block: true,
66    };
67
68    let markdown_h3 = MarkdownVisitable {
69        style: MarkdownType::H3,
70        regex: Regex::new(r"^#{3}\s").unwrap(),
71        is_block: true,
72    };
73
74    let markdown_p = MarkdownVisitable {
75        style: MarkdownType::P,
76        regex: Regex::new(r"^[^#\-]+$").unwrap(),
77        is_block: true,
78    };
79
80    let markdown_strong = MarkdownVisitable {
81        style: MarkdownType::Strong,
82        regex: Regex::new(r"((\*){2})([^*].+)((\*){2})").unwrap(),
83        is_block: false,
84    };
85
86    let markdown_italic = MarkdownVisitable {
87        style: MarkdownType::Italic,
88        regex: Regex::new(r"((\*){1})([^*].+)((\*){1})").unwrap(),
89        is_block: false,
90    };
91
92    MarkdownIterator::create(visitor,
93                             vec![markdown_h1, markdown_h2, markdown_h3, markdown_p],
94                             vec![markdown_strong, markdown_italic])
95}