1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
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<Element>,
}
impl StructureVisitor {
pub fn new() -> Self {
Self { elements: vec![] }
}
}
impl MutVisitor for StructureVisitor {
fn visit_vec_block(&mut self, vec_block: &mut Vec<Block>) {
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),
}
}
}
|