1use crate::{MarkdownExt, Share};
2use equt_md as markdown;
3use equt_md_error::Result;
4use equt_md_frontmatter::FrontMatter;
5use serde_yaml;
6use std::iter::Peekable;
7use std::rc::Rc;
8use std::cell::RefCell;
9
10#[must_use = "iterators are lazy and do nothing unless consumed"]
14pub struct Parser<'e> {
15 parser: Peekable<markdown::Parser<'e>>,
16 frontmatter: Share<RefCell<Option<FrontMatter>>>,
17}
18
19impl<'e> Parser<'e> {
20 pub fn new(text: &'e str) -> Result<Parser<'e>> {
22 let mut parser = markdown::Parser::new_ext(text, markdown::Options::all()).peekable();
23 return if let Some(markdown::Event::Frontmatter(s)) = parser.peek() {
24 let fm: FrontMatter = serde_yaml::from_str(s)?;
25 parser.next();
26 Ok(Parser {
27 parser,
28 frontmatter: Rc::new(RefCell::new(Some(fm))).into(),
29 })
30 } else {
31 Ok(Parser {
32 parser,
33 frontmatter: Rc::new(RefCell::new(None)).into(),
34 })
35 };
36 }
37}
38
39impl<'e> Iterator for Parser<'e> {
40 type Item = markdown::Event<'e>;
41
42 fn next(&mut self) -> Option<Self::Item> {
43 self.parser.next()
44 }
45}
46
47impl<'e> MarkdownExt<markdown::Event<'e>> for Parser<'e> {
48 fn frontmatter(&mut self) -> &mut Share<RefCell<Option<FrontMatter>>> {
49 &mut self.frontmatter
50 }
51}