diff options
Diffstat (limited to 'src/pandoc.rs')
-rw-r--r-- | src/pandoc.rs | 204 |
1 files changed, 62 insertions, 142 deletions
diff --git a/src/pandoc.rs b/src/pandoc.rs index 5ca84e7..8477f28 100644 --- a/src/pandoc.rs +++ b/src/pandoc.rs | |||
@@ -1,186 +1,106 @@ | |||
1 | //mod types; | ||
2 | |||
3 | use crate::entities::*; | 1 | use crate::entities::*; |
4 | 2 | ||
5 | use pandoc_types::definition::{Attr, Block, Inline, Meta, MetaValue, Pandoc}; | 3 | use pandoc_types::definition::{Attr, Block, Inline, Meta, MetaValue, Pandoc}; |
6 | 4 | ||
7 | use std::collections::HashMap; | 5 | use std::collections::HashMap; |
8 | 6 | ||
9 | impl Described<Entity> { | 7 | pub(crate) fn into_pandoc<'e>( |
10 | pub fn into_pandoc( | 8 | entity: &'e dyn Entity, |
11 | self, | 9 | description: &Description, |
12 | descriptions: &HashMap<Usr, Description>, | 10 | descriptions: &HashMap<Usr, Description>, |
13 | ) -> (Pandoc, HashMap<Usr, Entity>) { | 11 | ) -> (Pandoc, HashMap<&'e Usr, &'e DynEntity>) { |
14 | let mut meta = Meta::null(); | 12 | let mut meta = Meta::null(); |
15 | |||
16 | let title = self.title(); | ||
17 | let mut content_before = self.content_before(&descriptions); | ||
18 | let mut content_after = self.content_after(&descriptions); | ||
19 | let leftovers = self.leftovers(); | ||
20 | |||
21 | meta.0.insert( | ||
22 | "title".to_string(), | ||
23 | MetaValue::MetaString(self.description.name), | ||
24 | ); | ||
25 | |||
26 | let mut content = Vec::new(); | ||
27 | |||
28 | content.push(Block::Header(1, Attr::null(), title)); | ||
29 | |||
30 | content.append(&mut content_before); | ||
31 | |||
32 | if !self.description.detailed.is_empty() { | ||
33 | content.push(Block::Header( | ||
34 | 2, | ||
35 | Attr::null(), | ||
36 | vec![Inline::Str(String::from("Description"))], | ||
37 | )); | ||
38 | |||
39 | content.push(Block::Div( | ||
40 | Attr(String::new(), vec![String::from("doc")], vec![]), | ||
41 | vec![raw_markdown(self.description.detailed)], | ||
42 | )); | ||
43 | } | ||
44 | |||
45 | content.append(&mut content_after); | ||
46 | |||
47 | (Pandoc(meta, content), leftovers) | ||
48 | } | ||
49 | } | ||
50 | |||
51 | // TODO: replace with single function so we can move out, and remove all of those clones | ||
52 | trait PandocDisplay { | ||
53 | fn content_before(&self, _descriptions: &HashMap<Usr, Description>) -> Vec<Block> { | ||
54 | vec![] | ||
55 | } | ||
56 | |||
57 | fn content_after(&self, _descriptions: &HashMap<Usr, Description>) -> Vec<Block> { | ||
58 | vec![] | ||
59 | } | ||
60 | |||
61 | fn leftovers(&self) -> HashMap<Usr, Entity> { | ||
62 | HashMap::new() | ||
63 | } | ||
64 | } | ||
65 | |||
66 | impl Described<Entity> { | ||
67 | fn title(&self) -> Vec<Inline> { | ||
68 | match &self.entity { | ||
69 | Entity::Variable(variable) => vec![Inline::Code( | ||
70 | Attr(String::new(), vec![String::from("cpp")], vec![]), | ||
71 | variable.r#type.clone() + " " + &self.description.name, | ||
72 | )], | ||
73 | _ => vec![Inline::Code(Attr::null(), self.description.name.clone())], | ||
74 | } | ||
75 | } | ||
76 | } | ||
77 | 13 | ||
78 | impl PandocDisplay for Described<Entity> { | 14 | let title = vec![Inline::Code(Attr::null(), description.name.clone())]; |
79 | fn content_before(&self, descriptions: &HashMap<Usr, Description>) -> Vec<Block> { | ||
80 | match &self.entity { | ||
81 | Entity::NameSpace(ns) => ns.content_before(descriptions), | ||
82 | Entity::Variable(var) => var.content_before(descriptions), | ||
83 | Entity::Function(func) => func.content_before(descriptions), | ||
84 | Entity::Class(class) => class.content_before(descriptions), | ||
85 | } | ||
86 | } | ||
87 | 15 | ||
88 | fn content_after(&self, descriptions: &HashMap<Usr, Description>) -> Vec<Block> { | 16 | meta.0.insert( |
89 | match &self.entity { | 17 | "title".to_string(), |
90 | Entity::NameSpace(ns) => ns.content_after(descriptions), | 18 | MetaValue::MetaString(description.name.clone()), |
91 | Entity::Variable(var) => var.content_after(descriptions), | 19 | ); |
92 | Entity::Function(func) => func.content_after(descriptions), | ||
93 | Entity::Class(class) => class.content_after(descriptions), | ||
94 | } | ||
95 | } | ||
96 | 20 | ||
97 | fn leftovers(&self) -> HashMap<Usr, Entity> { | 21 | let mut content = Vec::new(); |
98 | match &self.entity { | ||
99 | Entity::NameSpace(ns) => ns.leftovers(), | ||
100 | Entity::Variable(var) => var.leftovers(), | ||
101 | Entity::Function(func) => func.leftovers(), | ||
102 | Entity::Class(class) => class.leftovers(), | ||
103 | } | ||
104 | } | ||
105 | } | ||
106 | 22 | ||
107 | impl PandocDisplay for NameSpace { | 23 | content.push(Block::Header(1, Attr::null(), title)); |
108 | fn content_after(&self, descriptions: &HashMap<Usr, Description>) -> Vec<Block> { | ||
109 | let mut content = Vec::new(); | ||
110 | 24 | ||
25 | if !description.detailed.is_empty() { | ||
111 | content.push(Block::Header( | 26 | content.push(Block::Header( |
112 | 2, | 27 | 2, |
113 | Attr::null(), | 28 | Attr::null(), |
114 | vec![Inline::Str("Members".to_string())], | 29 | vec![Inline::Str(String::from("Description"))], |
115 | )); | 30 | )); |
116 | 31 | ||
117 | if let Some(member_list) = member_list(self.members.keys(), descriptions) { | 32 | content.push(Block::Div( |
118 | content.push(member_list); | 33 | Attr(String::new(), vec![String::from("doc")], vec![]), |
119 | } else { | 34 | vec![raw_markdown(description.detailed.clone())], |
120 | content.push(str_block(String::from("None"))); | 35 | )); |
121 | } | ||
122 | |||
123 | content | ||
124 | } | ||
125 | |||
126 | fn leftovers(&self) -> HashMap<Usr, Entity> { | ||
127 | self.members.clone() | ||
128 | } | 36 | } |
129 | } | ||
130 | 37 | ||
131 | impl PandocDisplay for Class { | 38 | let separate_children = entity.separate_children(); |
132 | fn content_after(&self, descriptions: &HashMap<Usr, Description>) -> Vec<Block> { | 39 | let embeddable_children = entity.embeddable_children(); |
133 | let mut content = Vec::new(); | ||
134 | 40 | ||
135 | if let Some(member_types) = member_list(&self.member_types, descriptions) { | 41 | for section in &separate_children { |
42 | if let Some(members_list) = member_list( | ||
43 | section.children.iter().map(|&(usr, _child)| usr), | ||
44 | descriptions, | ||
45 | ) { | ||
136 | content.push(Block::Header( | 46 | content.push(Block::Header( |
137 | 2, | 47 | 2, |
138 | Attr::null(), | 48 | Attr::null(), |
139 | vec![Inline::Str("Member Types".to_string())], | 49 | vec![Inline::Str(String::from(section.name))], |
140 | )); | 50 | )); |
141 | 51 | ||
142 | content.push(member_types); | 52 | content.push(members_list); |
143 | } | 53 | } |
54 | } | ||
55 | |||
56 | let mut embedded_documentation = Vec::new(); | ||
144 | 57 | ||
145 | if let Some(member_functions) = member_list(self.member_functions.keys(), descriptions) { | 58 | for section in &embeddable_children { |
59 | if let Some(members_list) = member_list( | ||
60 | section.children.iter().map(|&(usr, _child)| usr), | ||
61 | descriptions, | ||
62 | ) { | ||
146 | content.push(Block::Header( | 63 | content.push(Block::Header( |
147 | 2, | 64 | 2, |
148 | Attr::null(), | 65 | Attr::null(), |
149 | vec![Inline::Str("Member Functions".to_string())], | 66 | vec![Inline::Str(String::from(section.name))], |
150 | )); | 67 | )); |
151 | 68 | ||
152 | content.push(member_functions); | 69 | content.push(members_list); |
153 | } | ||
154 | 70 | ||
155 | if let Some(member_variables) = member_list(self.member_variables.keys(), descriptions) { | 71 | embedded_documentation.push(Block::Header( |
156 | content.push(Block::Header( | ||
157 | 2, | 72 | 2, |
158 | Attr::null(), | 73 | Attr::null(), |
159 | vec![Inline::Str("Member Variables".to_string())], | 74 | vec![Inline::Str(String::from(section.name) + " Documentation")], |
160 | )); | 75 | )); |
161 | 76 | ||
162 | content.push(member_variables); | 77 | for (usr, _child) in §ion.children { |
163 | } | 78 | let child_doc = descriptions.get(usr).unwrap(); |
164 | 79 | ||
165 | content | 80 | embedded_documentation.push(Block::Header( |
166 | } | 81 | 3, |
82 | Attr::null(), | ||
83 | vec![Inline::Code(Attr::null(), String::from(&child_doc.name))], | ||
84 | )); | ||
167 | 85 | ||
168 | fn leftovers(&self) -> HashMap<Usr, Entity> { | 86 | embedded_documentation.push(Block::Div( |
169 | self.member_functions | 87 | Attr(String::new(), vec![String::from("doc")], vec![]), |
170 | .iter() | 88 | vec![raw_markdown(child_doc.detailed.clone())], |
171 | .map(|(usr, func)| (usr.clone(), Entity::from(func.clone()))) | 89 | )); |
172 | .chain( | 90 | } |
173 | self.member_variables | 91 | } |
174 | .iter() | ||
175 | .map(|(usr, var)| (usr.clone(), Entity::from(var.clone()))), | ||
176 | ) | ||
177 | .collect() | ||
178 | } | 92 | } |
179 | } | ||
180 | 93 | ||
181 | impl PandocDisplay for Variable {} | 94 | content.append(&mut embedded_documentation); |
182 | 95 | ||
183 | impl PandocDisplay for Function {} | 96 | let leftovers = separate_children |
97 | .iter() | ||
98 | .map(|section| section.children.clone()) | ||
99 | .flatten() | ||
100 | .collect(); | ||
101 | |||
102 | (Pandoc(meta, content), leftovers) | ||
103 | } | ||
184 | 104 | ||
185 | fn str_block(content: String) -> Block { | 105 | fn str_block(content: String) -> Block { |
186 | Block::Plain(vec![Inline::Str(content)]) | 106 | Block::Plain(vec![Inline::Str(content)]) |