diff options
Diffstat (limited to 'src/generator')
-rw-r--r-- | src/generator/config.rs | 52 | ||||
-rw-r--r-- | src/generator/mod.rs | 42 | ||||
-rw-r--r-- | src/generator/pandoc.rs | 19 |
3 files changed, 73 insertions, 40 deletions
diff --git a/src/generator/config.rs b/src/generator/config.rs index 43fee60..3057fee 100644 --- a/src/generator/config.rs +++ b/src/generator/config.rs | |||
@@ -1,40 +1,58 @@ | |||
1 | use crate::types::*; | ||
2 | |||
1 | use serde_derive::{Deserialize, Serialize}; | 3 | use serde_derive::{Deserialize, Serialize}; |
2 | use structopt::StructOpt; | 4 | use structopt::StructOpt; |
3 | 5 | ||
4 | use std::collections::{HashMap, HashSet}; | 6 | use std::collections::{HashMap, HashSet}; |
5 | 7 | ||
8 | pub(crate) type Inlines = HashMap<Language, HashMap<EntityKind, HashSet<ChildrenKind>>>; | ||
9 | |||
6 | #[derive(Debug, Clone, Serialize)] | 10 | #[derive(Debug, Clone, Serialize)] |
7 | pub(crate) struct Config { | 11 | pub(crate) struct Config { |
12 | pub(super) from: String, | ||
13 | pub(super) to: String, | ||
14 | pub(super) pandoc_filters: Vec<String>, | ||
8 | /// Tells us in which language, which entity types should inline which children entity type in | 15 | /// Tells us in which language, which entity types should inline which children entity type in |
9 | /// their documentation. | 16 | /// their documentation. |
10 | /// | 17 | /// |
11 | /// e.g. in C++, classes should inline their children methods documentation. | 18 | /// e.g. in C++, classes should inline their children methods documentation. |
12 | pub(crate) inlines: HashMap<String, HashMap<String, HashSet<String>>>, | 19 | pub(super) inlines: Inlines, |
13 | } | 20 | } |
14 | 21 | ||
15 | impl Config { | 22 | impl Config { |
16 | pub(crate) fn from_merge(_cli: ProvidedConfig, conf: ProvidedConfig) -> Self { | 23 | pub(crate) fn from_merge(mut cli: ProvidedConfig, mut conf: ProvidedConfig) -> Self { |
24 | conf.pandoc_filters.append(&mut cli.pandoc_filters); | ||
17 | Self { | 25 | Self { |
26 | from: cli | ||
27 | .from | ||
28 | .or(conf.from) | ||
29 | .unwrap_or_else(|| String::from("markdown-raw_tex")), | ||
30 | to: cli.to.or(conf.to).unwrap_or_else(|| String::from("html")), | ||
31 | pandoc_filters: conf.pandoc_filters, | ||
18 | inlines: conf.inlines.unwrap_or_else(default_inlines), | 32 | inlines: conf.inlines.unwrap_or_else(default_inlines), |
19 | } | 33 | } |
20 | } | 34 | } |
21 | } | 35 | } |
22 | 36 | ||
23 | fn default_inlines() -> HashMap<String, HashMap<String, HashSet<String>>> { | 37 | fn default_inlines() -> Inlines { |
24 | let mut clang = HashMap::new(); | 38 | let mut clang = HashMap::new(); |
25 | let mut clang_inline_children = HashSet::new(); | 39 | let mut clang_inline_children = HashSet::new(); |
26 | // TODO: this is not great: no differences between variable/field for children, but differences | 40 | clang_inline_children.insert(ChildrenKind(String::from("variables"))); |
27 | // as a parent... | 41 | clang_inline_children.insert(ChildrenKind(String::from("fields"))); |
28 | clang_inline_children.insert(String::from("variable")); | 42 | clang_inline_children.insert(ChildrenKind(String::from("functions"))); |
29 | //classes.insert(String::from("field")); | 43 | clang_inline_children.insert(ChildrenKind(String::from("methods"))); |
30 | clang_inline_children.insert(String::from("function")); | 44 | clang.insert( |
31 | //classes.insert(String::from("method")); | 45 | EntityKind(String::from("struct")), |
32 | clang.insert(String::from("struct"), clang_inline_children.clone()); | 46 | clang_inline_children.clone(), |
33 | clang.insert(String::from("class"), clang_inline_children.clone()); | 47 | ); |
34 | clang.insert(String::from("namespace"), clang_inline_children); | 48 | clang.insert( |
49 | EntityKind(String::from("class")), | ||
50 | clang_inline_children.clone(), | ||
51 | ); | ||
52 | clang.insert(EntityKind(String::from("namespace")), clang_inline_children); | ||
35 | 53 | ||
36 | let mut inlines = HashMap::new(); | 54 | let mut inlines = HashMap::new(); |
37 | inlines.insert(String::from("clang"), clang); | 55 | inlines.insert(Language::Clang, clang); |
38 | 56 | ||
39 | inlines | 57 | inlines |
40 | } | 58 | } |
@@ -48,6 +66,12 @@ impl Default for Config { | |||
48 | #[derive(Debug, Clone, Default, StructOpt, Deserialize, Serialize)] | 66 | #[derive(Debug, Clone, Default, StructOpt, Deserialize, Serialize)] |
49 | #[serde(rename_all = "kebab-case")] | 67 | #[serde(rename_all = "kebab-case")] |
50 | pub(crate) struct ProvidedConfig { | 68 | pub(crate) struct ProvidedConfig { |
69 | #[structopt(long = "generator-from")] | ||
70 | pub(super) from: Option<String>, | ||
71 | #[structopt(long = "generator-to")] | ||
72 | pub(super) to: Option<String>, | ||
73 | #[structopt(long = "generator-pandoc-filters", number_of_values = 1)] | ||
74 | pub(super) pandoc_filters: Vec<String>, | ||
51 | #[structopt(skip)] | 75 | #[structopt(skip)] |
52 | pub(crate) inlines: Option<HashMap<String, HashMap<String, HashSet<String>>>>, | 76 | pub(super) inlines: Option<Inlines>, |
53 | } | 77 | } |
diff --git a/src/generator/mod.rs b/src/generator/mod.rs index b4e1c94..3f62779 100644 --- a/src/generator/mod.rs +++ b/src/generator/mod.rs | |||
@@ -2,11 +2,8 @@ pub(crate) mod config; | |||
2 | mod pandoc; | 2 | mod pandoc; |
3 | 3 | ||
4 | use self::config::Config; | 4 | use self::config::Config; |
5 | //use crate::entities::{ | ||
6 | // Description, DynEntity, EntitiesManager, EntitiesManagerComponents, Usr, | ||
7 | //}; | ||
8 | use self::pandoc::into_pandoc; | 5 | use self::pandoc::into_pandoc; |
9 | use crate::types::Entity; | 6 | use crate::types::*; |
10 | 7 | ||
11 | use anyhow::{ensure, Context, Result}; | 8 | use anyhow::{ensure, Context, Result}; |
12 | use rayon::Scope; | 9 | use rayon::Scope; |
@@ -18,7 +15,11 @@ use std::path::Path; | |||
18 | 15 | ||
19 | const DEFAULT_CSS: &[u8] = include_bytes!("../../res/style.css"); | 16 | const DEFAULT_CSS: &[u8] = include_bytes!("../../res/style.css"); |
20 | 17 | ||
21 | pub(crate) fn generate(base_dir: &Path, entities: BTreeMap<String, Entity>, config: &Config) -> Result<()> { | 18 | pub(crate) fn generate( |
19 | base_dir: &Path, | ||
20 | entities: BTreeMap<EntityId, Entity>, | ||
21 | config: &Config, | ||
22 | ) -> Result<()> { | ||
22 | let md_output_dir = base_dir.join("markdown"); | 23 | let md_output_dir = base_dir.join("markdown"); |
23 | let html_output_dir = base_dir.join("html"); | 24 | let html_output_dir = base_dir.join("html"); |
24 | 25 | ||
@@ -54,7 +55,7 @@ pub(crate) fn generate(base_dir: &Path, entities: BTreeMap<String, Entity>, conf | |||
54 | } | 55 | } |
55 | 56 | ||
56 | fn generate_recursively<'a>( | 57 | fn generate_recursively<'a>( |
57 | id: String, | 58 | id: EntityId, |
58 | entity: Entity, | 59 | entity: Entity, |
59 | pool: &Scope<'a>, | 60 | pool: &Scope<'a>, |
60 | md_output_dir: &'a Path, | 61 | md_output_dir: &'a Path, |
@@ -63,7 +64,7 @@ fn generate_recursively<'a>( | |||
63 | config: &'a Config, | 64 | config: &'a Config, |
64 | ) { | 65 | ) { |
65 | pool.spawn(move |pool| { | 66 | pool.spawn(move |pool| { |
66 | trace!("Trying to generate {}", id); | 67 | trace!("Trying to generate {}", id.0); |
67 | 68 | ||
68 | let leftovers = generate_single( | 69 | let leftovers = generate_single( |
69 | &id, | 70 | &id, |
@@ -90,18 +91,18 @@ fn generate_recursively<'a>( | |||
90 | } | 91 | } |
91 | 92 | ||
92 | fn generate_single( | 93 | fn generate_single( |
93 | id: &str, | 94 | id: &EntityId, |
94 | entity: Entity, | 95 | entity: Entity, |
95 | md_output_dir: impl AsRef<Path>, | 96 | md_output_dir: impl AsRef<Path>, |
96 | html_output_dir: impl AsRef<Path>, | 97 | html_output_dir: impl AsRef<Path>, |
97 | css_path: impl AsRef<Path>, | 98 | css_path: impl AsRef<Path>, |
98 | config: &Config | 99 | config: &Config, |
99 | ) -> Result<BTreeMap<String, Entity>> { | 100 | ) -> Result<BTreeMap<EntityId, Entity>> { |
100 | use std::io::prelude::*; | 101 | use std::io::prelude::*; |
101 | use std::process::{Command, Stdio}; | 102 | use std::process::{Command, Stdio}; |
102 | 103 | ||
103 | let md_output_file = md_output_dir.as_ref().join(id); | 104 | let md_output_file = md_output_dir.as_ref().join(&id.0); |
104 | let html_output_file = html_output_dir.as_ref().join(id); | 105 | let html_output_file = html_output_dir.as_ref().join(&id.0); |
105 | 106 | ||
106 | let mut command = Command::new("pandoc"); | 107 | let mut command = Command::new("pandoc"); |
107 | 108 | ||
@@ -111,7 +112,10 @@ fn generate_single( | |||
111 | .stderr(Stdio::piped()) | 112 | .stderr(Stdio::piped()) |
112 | .args(&[ | 113 | .args(&[ |
113 | "--from=json", | 114 | "--from=json", |
114 | "--to=markdown", | 115 | // standalone keeps the sent metadat |
116 | "--standalone", | ||
117 | "--to", | ||
118 | &config.from, | ||
115 | "--output", | 119 | "--output", |
116 | md_output_file | 120 | md_output_file |
117 | .to_str() | 121 | .to_str() |
@@ -165,8 +169,10 @@ fn generate_single( | |||
165 | .stdout(Stdio::piped()) | 169 | .stdout(Stdio::piped()) |
166 | .stderr(Stdio::piped()) | 170 | .stderr(Stdio::piped()) |
167 | .args(&[ | 171 | .args(&[ |
168 | "--from=markdown-raw_tex", | 172 | "--from", |
169 | "--to=html", | 173 | &config.from, |
174 | "--to", | ||
175 | &config.to, | ||
170 | "--css", | 176 | "--css", |
171 | css_path | 177 | css_path |
172 | .as_ref() | 178 | .as_ref() |
@@ -183,6 +189,10 @@ fn generate_single( | |||
183 | .context("Entity name is not valid UTF-8")?, | 189 | .context("Entity name is not valid UTF-8")?, |
184 | ]); | 190 | ]); |
185 | 191 | ||
192 | for filter in &config.pandoc_filters { | ||
193 | command.args(&["--filter", filter]); | ||
194 | } | ||
195 | |||
186 | let command_str = format!("{:?}", command); | 196 | let command_str = format!("{:?}", command); |
187 | debug!("Launching command: {}", command_str); | 197 | debug!("Launching command: {}", command_str); |
188 | 198 | ||
@@ -190,6 +200,8 @@ fn generate_single( | |||
190 | .output() | 200 | .output() |
191 | .context("Failed to execute Pandoc command")?; | 201 | .context("Failed to execute Pandoc command")?; |
192 | 202 | ||
203 | std::io::stderr().lock().write_all(&output.stderr)?; | ||
204 | |||
193 | ensure!( | 205 | ensure!( |
194 | output.status.success(), | 206 | output.status.success(), |
195 | CommandError { | 207 | CommandError { |
diff --git a/src/generator/pandoc.rs b/src/generator/pandoc.rs index 1753d34..035acab 100644 --- a/src/generator/pandoc.rs +++ b/src/generator/pandoc.rs | |||
@@ -1,14 +1,11 @@ | |||
1 | use super::config::Config; | 1 | use super::config::Config; |
2 | use crate::types::Entity; | 2 | use crate::types::*; |
3 | 3 | ||
4 | use pandoc_types::definition::{Attr, Block, Inline, Meta, MetaValue, Pandoc}; | 4 | use pandoc_types::definition::{Attr, Block, Inline, Meta, MetaValue, Pandoc}; |
5 | 5 | ||
6 | use std::collections::BTreeMap; | 6 | use std::collections::BTreeMap; |
7 | 7 | ||
8 | pub(crate) fn into_pandoc( | 8 | pub(crate) fn into_pandoc(entity: Entity, config: &Config) -> (Pandoc, BTreeMap<EntityId, Entity>) { |
9 | entity: Entity, | ||
10 | config: &Config, | ||
11 | ) -> (Pandoc, BTreeMap<String, Entity>) { | ||
12 | let mut meta = Meta::null(); | 9 | let mut meta = Meta::null(); |
13 | 10 | ||
14 | let title = vec![Inline::Code(Attr::null(), entity.name.clone())]; | 11 | let title = vec![Inline::Code(Attr::null(), entity.name.clone())]; |
@@ -57,7 +54,7 @@ pub(crate) fn into_pandoc( | |||
57 | content.push(Block::Header( | 54 | content.push(Block::Header( |
58 | 2, | 55 | 2, |
59 | Attr::null(), | 56 | Attr::null(), |
60 | vec![Inline::Str(String::from(section_name))], | 57 | vec![Inline::Str(section_name.0.clone())], |
61 | )); | 58 | )); |
62 | 59 | ||
63 | content.push(members_list); | 60 | content.push(members_list); |
@@ -71,7 +68,7 @@ pub(crate) fn into_pandoc( | |||
71 | content.push(Block::Header( | 68 | content.push(Block::Header( |
72 | 2, | 69 | 2, |
73 | Attr::null(), | 70 | Attr::null(), |
74 | vec![Inline::Str(section_name.clone())], | 71 | vec![Inline::Str(section_name.0.clone())], |
75 | )); | 72 | )); |
76 | 73 | ||
77 | content.push(members_list); | 74 | content.push(members_list); |
@@ -79,7 +76,7 @@ pub(crate) fn into_pandoc( | |||
79 | embedded_documentation.push(Block::Header( | 76 | embedded_documentation.push(Block::Header( |
80 | 2, | 77 | 2, |
81 | Attr::null(), | 78 | Attr::null(), |
82 | vec![Inline::Str(section_name + " Documentation")], | 79 | vec![Inline::Str(section_name.0 + " Documentation")], |
83 | )); | 80 | )); |
84 | 81 | ||
85 | for (_id, child) in children { | 82 | for (_id, child) in children { |
@@ -112,7 +109,7 @@ fn str_block(content: String) -> Block { | |||
112 | Block::Plain(vec![Inline::Str(content)]) | 109 | Block::Plain(vec![Inline::Str(content)]) |
113 | } | 110 | } |
114 | 111 | ||
115 | fn entity_link(id: &str, name: String) -> Inline { | 112 | fn entity_link(id: &EntityId, name: String) -> Inline { |
116 | use pandoc_types::definition::Target; | 113 | use pandoc_types::definition::Target; |
117 | use percent_encoding::{utf8_percent_encode, AsciiSet, CONTROLS}; | 114 | use percent_encoding::{utf8_percent_encode, AsciiSet, CONTROLS}; |
118 | 115 | ||
@@ -135,7 +132,7 @@ fn entity_link(id: &str, name: String) -> Inline { | |||
135 | vec![Inline::Code(Attr::null(), name)], | 132 | vec![Inline::Code(Attr::null(), name)], |
136 | Target( | 133 | Target( |
137 | once("./") | 134 | once("./") |
138 | .chain(utf8_percent_encode(id, FRAGMENT)) | 135 | .chain(utf8_percent_encode(&id.0, FRAGMENT)) |
139 | .collect(), | 136 | .collect(), |
140 | String::new(), | 137 | String::new(), |
141 | ), | 138 | ), |
@@ -147,7 +144,7 @@ fn raw_markdown(text: String) -> Block { | |||
147 | Block::RawBlock(Format(String::from("markdown")), text) | 144 | Block::RawBlock(Format(String::from("markdown")), text) |
148 | } | 145 | } |
149 | 146 | ||
150 | fn member_list<'a>(members: impl IntoIterator<Item = (&'a String, &'a Entity)>) -> Option<Block> { | 147 | fn member_list<'a>(members: impl IntoIterator<Item = (&'a EntityId, &'a Entity)>) -> Option<Block> { |
151 | let definitions: Vec<(Vec<Inline>, Vec<Vec<Block>>)> = members | 148 | let definitions: Vec<(Vec<Inline>, Vec<Vec<Block>>)> = members |
152 | .into_iter() | 149 | .into_iter() |
153 | .map(|(id, entity)| { | 150 | .map(|(id, entity)| { |