use crate::doc_parts::*;
use crate::parse::event_buffer::*;
use crate::util::md_tools::md_parse::*;
use crate::util::md_tools::*;
use std::collections::HashSet;
pub(crate) struct ParseManager<'a> {
item: Option<&'a syn::Item>,
}
impl<'a> ParseManager<'a> {
pub fn new() -> Self {
Self { item: None }
}
pub fn with_item(self, item: &'a syn::Item) -> Self {
let item = Some(item);
Self { item }
}
pub fn parse(&self, md: &'a str) -> DocChunk<'a> {
let parser = MdParser::parse(md);
let mut ret = Self::build_doc_tree(self.item, parser);
Self::assign_chunk_ids(&mut ret);
ret
}
fn build_doc_tree(item: Option<&'a syn::Item>, parser: MdParser<'a>) -> DocChunk<'a> {
let ret = DocChunk::new_empty_root(DocMeta::new(item, parser.defs));
let buf = &mut EventBuffer::new();
let mut curr = ret.clone();
for event in parser.events {
if let MdOutline::Heading(lv) = MdOutline::get(&event) {
let child = DocChunk::new_empty_chunk(lv);
let parent = &mut Self::find_parent(&curr, &child);
curr = parent.append_chunk(child);
}
if let Some(block) = buf.input(event) {
curr.append_block(block);
}
}
ret
}
fn find_parent(start: &DocChunk<'a>, target: &DocChunk<'a>) -> DocChunk<'a> {
let mut curr = start.clone();
while curr.borrow().level() >= target.borrow().level() {
curr = match curr.parent() {
None => break,
Some(x) => x,
};
}
curr
}
fn assign_chunk_ids(root: &mut DocChunk) {
let md_ids = &mut HashSet::new();
let rs_ids = &mut HashSet::new();
traverse(root.clone(), md_ids, rs_ids);
fn traverse(chunk: DocChunk, md_ids: &mut HashSet<String>, rs_ids: &mut HashSet<String>) {
let this = &mut chunk.borrow_mut();
if !this.title().is_empty() {
let md_id = chunk_id::md_id(&this.title(), md_ids);
let rs_id = chunk_id::rs_id(&this.title(), rs_ids);
this.set_md_id(md_id.clone());
this.set_rs_id(rs_id.clone());
md_ids.insert(md_id);
rs_ids.insert(rs_id);
}
let rs_ids = &mut HashSet::new();
for chunk in this.chunks() {
traverse(chunk, md_ids, rs_ids);
}
}
}
}