ipsae-core 0.1.0

markdown parser for DIY lover
Documentation
use regex::Regex;

use crate::{Markdown, MarkdownType};
use crate::parser::markdown::{MarkdownVisitable, Visitable};
use crate::parser::visitor::{Visitor, VisitorBase};

#[derive(Debug)]
pub struct MarkdownIterator<V: Visitor + Clone, A: Visitable<V>> {
    visitor: V,
    visitable_block_list: Vec<A>,
    visitable_inline_list: Vec<A>,
}

impl<V: Visitor + Clone, A: Visitable<V>> MarkdownIterator<V, A> {
    pub fn create(visitor: V, visitable_block_list: Vec<A>, visitable_inline_list: Vec<A>) -> Self {
        Self { visitor, visitable_block_list, visitable_inline_list }
    }

    pub fn parse_markdown(&self, input: String) -> Vec<Markdown> {
        let mut result: Vec<Markdown> = vec![];
        let input_vec: Vec<&str> = input
            .split('\n')
            .into_iter()
            .collect();

        for input in input_vec {
            for visitable in self.visitable_block_list.iter() {
                match visitable.accept(self.visitor.clone(), input) {
                    Some(markdown) => result.push(markdown),
                    None => continue,
                }
            }
        }

        result
            .into_iter()
            .map(|mut markdown_item| {
                if markdown_item.style == MarkdownType::P {
                    for visitable in self.visitable_inline_list.iter() {
                        match visitable.accept(self.visitor.clone(), markdown_item.content.clone().as_str()) {
                            Some(markdown_child) => {
                                markdown_item.children.push(markdown_child);
                                break;
                            },
                            None => continue,
                        }
                    }
                }
                return markdown_item;
            })
            .collect()
    }
}

pub fn get_markdown_iterator(visitor: VisitorBase) -> MarkdownIterator<VisitorBase, MarkdownVisitable> {
    let markdown_h1 = MarkdownVisitable {
        style: MarkdownType::H1,
        regex: Regex::new(r"^#\s").unwrap(),
        is_block: true,
    };

    let markdown_h2 = MarkdownVisitable {
        style: MarkdownType::H2,
        regex: Regex::new(r"^#{2}\s").unwrap(),
        is_block: true,
    };

    let markdown_h3 = MarkdownVisitable {
        style: MarkdownType::H3,
        regex: Regex::new(r"^#{3}\s").unwrap(),
        is_block: true,
    };

    let markdown_p = MarkdownVisitable {
        style: MarkdownType::P,
        regex: Regex::new(r"^[^#\-]+$").unwrap(),
        is_block: true,
    };

    let markdown_strong = MarkdownVisitable {
        style: MarkdownType::Strong,
        regex: Regex::new(r"((\*){2})([^*].+)((\*){2})").unwrap(),
        is_block: false,
    };

    let markdown_italic = MarkdownVisitable {
        style: MarkdownType::Italic,
        regex: Regex::new(r"((\*){1})([^*].+)((\*){1})").unwrap(),
        is_block: false,
    };

    MarkdownIterator::create(visitor,
                             vec![markdown_h1, markdown_h2, markdown_h3, markdown_p],
                             vec![markdown_strong, markdown_italic])
}