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
101
102
103
104
105
106
use ast::*;
use std::io;
pub trait Traversion<'a, S: Copy + ?Sized> {
fn path_push(&mut self, &'a Element);
fn path_pop(&mut self) -> Option<&'a Element>;
fn get_path(&self) -> &Vec<&'a Element>;
fn work(&mut self,
_root: &'a Element,
_settings: S,
_out: &mut io::Write) -> io::Result<bool> {
Ok(true)
}
fn work_vec(&mut self,
_root: &'a [Element],
_settings: S,
_out: &mut io::Write) -> io::Result<bool> {
Ok(true)
}
fn run_vec(&mut self,
content: &'a [Element],
settings: S,
out: &mut io::Write) -> io::Result<()> {
if !self.work_vec(content, settings, out)? {
return Ok(());
}
for elem in &content[..] {
self.run(elem, settings, out)?;
}
Ok(())
}
fn run(&mut self,
root: &'a Element,
settings: S,
out: &mut io::Write) -> io::Result<()> {
self.path_push(root);
if !self.work(root, settings, out)? {
return Ok(());
}
match *root {
Element::Document(ref e) => self.run_vec(&e.content, settings, out)?,
Element::Formatted(ref e) => self.run_vec(&e.content, settings, out)?,
Element::Paragraph(ref e) => self.run_vec(&e.content, settings, out)?,
Element::ListItem(ref e) => self.run_vec(&e.content, settings, out)?,
Element::List(ref e) => self.run_vec(&e.content, settings, out)?,
Element::TableCell(ref e) => self.run_vec(&e.content, settings, out)?,
Element::HtmlTag(ref e) => self.run_vec(&e.content, settings, out)?,
Element::Gallery(ref e) => self.run_vec(&e.content, settings, out)?,
Element::Heading(ref e) => {
self.run_vec(&e.caption, settings, out)?;
self.run_vec(&e.content, settings, out)?;
},
Element::Template(ref e) => {
self.run_vec(&e.name, settings, out)?;
self.run_vec(&e.content, settings, out)?;
}
Element::TemplateArgument(ref e) => self.run_vec(&e.value, settings, out)?,
Element::InternalReference(ref e) => {
self.run_vec(&e.target, settings, out)?;
for option in &e.options {
self.run_vec(option, settings, out)?;
}
self.run_vec(&e.caption, settings, out)?;
},
Element::ExternalReference(ref e) => self.run_vec(&e.caption, settings, out)?,
Element::Table(ref e) => {
self.run_vec(&e.caption, settings, out)?;
self.run_vec(&e.rows, settings, out)?;
}
Element::TableRow(ref e) => self.run_vec(&e.cells, settings, out)?,
Element::Text(_)
| Element::Comment(_)
| Element::Error(_)
=> (),
}
self.path_pop();
Ok(())
}
}