use crate::panhelper; use pandoc_ast::{Block, Inline, MutVisitor}; // A structure element in the document: a heading or a scenario snippet. #[derive(Debug)] pub enum Element { // Headings consist of the text and the level of the heading. Heading(String, i64), // Scenario snippets consist just of the unparsed text. Snippet(String), } impl Element { pub fn heading(text: &str, level: i64) -> Element { Element::Heading(text.to_string(), level) } pub fn snippet(text: &str) -> Element { Element::Snippet(text.to_string()) } } // A MutVisitor for extracting document structure. pub struct StructureVisitor { pub elements: Vec, } impl StructureVisitor { pub fn new() -> Self { Self { elements: vec![] } } } impl MutVisitor for StructureVisitor { fn visit_vec_block(&mut self, vec_block: &mut Vec) { use panhelper::is_class; for block in vec_block { match block { Block::Header(level, _attr, inlines) => { let text = join(inlines); let heading = Element::heading(&text, *level); self.elements.push(heading); } Block::CodeBlock(attr, s) => { if is_class(attr, "scenario") { let snippet = Element::snippet(s); self.elements.push(snippet); } } _ => { self.visit_block(block); } } } } } fn join(vec: &[Inline]) -> String { let mut buf = String::new(); join_into_buffer(vec, &mut buf); buf } fn join_into_buffer(vec: &[Inline], buf: &mut String) { for item in vec { match item { Inline::Str(s) => buf.push_str(s), Inline::Emph(v) => join_into_buffer(v, buf), Inline::Strong(v) => join_into_buffer(v, buf), Inline::Strikeout(v) => join_into_buffer(v, buf), Inline::Superscript(v) => join_into_buffer(v, buf), Inline::Subscript(v) => join_into_buffer(v, buf), Inline::SmallCaps(v) => join_into_buffer(v, buf), Inline::Quoted(qt, v) => { let q = match qt { pandoc_ast::QuoteType::SingleQuote => "'", pandoc_ast::QuoteType::DoubleQuote => "\"", }; buf.push_str(q); join_into_buffer(v, buf); buf.push_str(q); } Inline::Cite(_, v) => join_into_buffer(v, buf), Inline::Code(_attr, s) => buf.push_str(s), Inline::Space => buf.push(' '), Inline::SoftBreak => buf.push(' '), Inline::LineBreak => buf.push(' '), Inline::Math(_, s) => buf.push_str(s), Inline::RawInline(_, s) => buf.push_str(s), Inline::Link(_, v, _) => join_into_buffer(v, buf), Inline::Image(_, v, _) => join_into_buffer(v, buf), Inline::Note(_) => buf.push_str(""), Inline::Span(_attr, v) => join_into_buffer(v, buf), #[cfg(feature = "pandoc_ast_08")] Inline::Underline(v) => join_into_buffer(v, buf), } } }