summaryrefslogtreecommitdiffstats
path: root/src/pandoc.rs
diff options
context:
space:
mode:
authorMinijackson <minijackson@riseup.net>2019-12-18 20:56:53 +0100
committerMinijackson <minijackson@riseup.net>2019-12-18 20:56:53 +0100
commitde896baff7e97fac4dde79078c9a2fa1c652576b (patch)
tree512b67b91d64e51d63f7ac5ff925a5c96d9aaf3c /src/pandoc.rs
parent860b73f1644ecd6548ae403ec483625fb7b625ea (diff)
downloadposeidoc-de896baff7e97fac4dde79078c9a2fa1c652576b.tar.gz
poseidoc-de896baff7e97fac4dde79078c9a2fa1c652576b.zip
Big refactoring
- entities should be more coherent when parsing multiple files - well defined, language agnostic entity tree - each module has its own configuration - less dead code
Diffstat (limited to 'src/pandoc.rs')
-rw-r--r--src/pandoc.rs166
1 files changed, 0 insertions, 166 deletions
diff --git a/src/pandoc.rs b/src/pandoc.rs
deleted file mode 100644
index 8477f28..0000000
--- a/src/pandoc.rs
+++ /dev/null
@@ -1,166 +0,0 @@
1use crate::entities::*;
2
3use pandoc_types::definition::{Attr, Block, Inline, Meta, MetaValue, Pandoc};
4
5use std::collections::HashMap;
6
7pub(crate) fn into_pandoc<'e>(
8 entity: &'e dyn Entity,
9 description: &Description,
10 descriptions: &HashMap<Usr, Description>,
11) -> (Pandoc, HashMap<&'e Usr, &'e DynEntity>) {
12 let mut meta = Meta::null();
13
14 let title = vec![Inline::Code(Attr::null(), description.name.clone())];
15
16 meta.0.insert(
17 "title".to_string(),
18 MetaValue::MetaString(description.name.clone()),
19 );
20
21 let mut content = Vec::new();
22
23 content.push(Block::Header(1, Attr::null(), title));
24
25 if !description.detailed.is_empty() {
26 content.push(Block::Header(
27 2,
28 Attr::null(),
29 vec![Inline::Str(String::from("Description"))],
30 ));
31
32 content.push(Block::Div(
33 Attr(String::new(), vec![String::from("doc")], vec![]),
34 vec![raw_markdown(description.detailed.clone())],
35 ));
36 }
37
38 let separate_children = entity.separate_children();
39 let embeddable_children = entity.embeddable_children();
40
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 ) {
46 content.push(Block::Header(
47 2,
48 Attr::null(),
49 vec![Inline::Str(String::from(section.name))],
50 ));
51
52 content.push(members_list);
53 }
54 }
55
56 let mut embedded_documentation = Vec::new();
57
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 ) {
63 content.push(Block::Header(
64 2,
65 Attr::null(),
66 vec![Inline::Str(String::from(section.name))],
67 ));
68
69 content.push(members_list);
70
71 embedded_documentation.push(Block::Header(
72 2,
73 Attr::null(),
74 vec![Inline::Str(String::from(section.name) + " Documentation")],
75 ));
76
77 for (usr, _child) in &section.children {
78 let child_doc = descriptions.get(usr).unwrap();
79
80 embedded_documentation.push(Block::Header(
81 3,
82 Attr::null(),
83 vec![Inline::Code(Attr::null(), String::from(&child_doc.name))],
84 ));
85
86 embedded_documentation.push(Block::Div(
87 Attr(String::new(), vec![String::from("doc")], vec![]),
88 vec![raw_markdown(child_doc.detailed.clone())],
89 ));
90 }
91 }
92 }
93
94 content.append(&mut embedded_documentation);
95
96 let leftovers = separate_children
97 .iter()
98 .map(|section| section.children.clone())
99 .flatten()
100 .collect();
101
102 (Pandoc(meta, content), leftovers)
103}
104
105fn str_block(content: String) -> Block {
106 Block::Plain(vec![Inline::Str(content)])
107}
108
109fn entity_link(usr: &Usr, name: String) -> Inline {
110 use pandoc_types::definition::Target;
111 use percent_encoding::{utf8_percent_encode, AsciiSet, CONTROLS};
112
113 use std::iter::once;
114
115 // https://url.spec.whatwg.org/#fragment-percent-encode-set
116 const FRAGMENT: &AsciiSet = &CONTROLS
117 .add(b' ')
118 .add(b'"')
119 .add(b'<')
120 .add(b'>')
121 .add(b'`')
122 .add(b'#')
123 .add(b'?')
124 .add(b'{')
125 .add(b'}');
126
127 Inline::Link(
128 Attr::null(),
129 vec![Inline::Code(Attr::null(), name)],
130 Target(
131 once("./")
132 .chain(utf8_percent_encode(&usr.0, FRAGMENT))
133 .collect(),
134 String::new(),
135 ),
136 )
137}
138
139fn raw_markdown(text: String) -> Block {
140 use pandoc_types::definition::Format;
141 Block::RawBlock(Format(String::from("markdown")), text)
142}
143
144fn member_list<'a>(
145 members: impl IntoIterator<Item = &'a Usr>,
146 descriptions: &HashMap<Usr, Description>,
147) -> Option<Block> {
148 let definitions: Vec<(Vec<Inline>, Vec<Vec<Block>>)> = members
149 .into_iter()
150 .filter_map(|usr| {
151 let name = &descriptions.get(usr)?.name;
152 Some((
153 vec![entity_link(usr, name.clone())],
154 vec![vec![str_block(
155 descriptions.get(usr).unwrap().brief.clone(),
156 )]],
157 ))
158 })
159 .collect();
160
161 if definitions.is_empty() {
162 None
163 } else {
164 Some(Block::DefinitionList(definitions))
165 }
166}