summaryrefslogtreecommitdiffstats
path: root/src/generator
diff options
context:
space:
mode:
authorMinijackson <minijackson@riseup.net>2019-12-21 12:13:21 +0100
committerMinijackson <minijackson@riseup.net>2019-12-21 12:13:21 +0100
commite773caea8010b87726ea524d31798fb2e43e12f4 (patch)
tree9034295831afb25f4bfea5a05d9f83d03e69e86c /src/generator
parentde896baff7e97fac4dde79078c9a2fa1c652576b (diff)
downloadposeidoc-e773caea8010b87726ea524d31798fb2e43e12f4.tar.gz
poseidoc-e773caea8010b87726ea524d31798fb2e43e12f4.zip
newtype in types, more generator config, parsing -> parser
Diffstat (limited to 'src/generator')
-rw-r--r--src/generator/config.rs52
-rw-r--r--src/generator/mod.rs42
-rw-r--r--src/generator/pandoc.rs19
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 @@
1use crate::types::*;
2
1use serde_derive::{Deserialize, Serialize}; 3use serde_derive::{Deserialize, Serialize};
2use structopt::StructOpt; 4use structopt::StructOpt;
3 5
4use std::collections::{HashMap, HashSet}; 6use std::collections::{HashMap, HashSet};
5 7
8pub(crate) type Inlines = HashMap<Language, HashMap<EntityKind, HashSet<ChildrenKind>>>;
9
6#[derive(Debug, Clone, Serialize)] 10#[derive(Debug, Clone, Serialize)]
7pub(crate) struct Config { 11pub(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
15impl Config { 22impl 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
23fn default_inlines() -> HashMap<String, HashMap<String, HashSet<String>>> { 37fn 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")]
50pub(crate) struct ProvidedConfig { 68pub(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;
2mod pandoc; 2mod pandoc;
3 3
4use self::config::Config; 4use self::config::Config;
5//use crate::entities::{
6// Description, DynEntity, EntitiesManager, EntitiesManagerComponents, Usr,
7//};
8use self::pandoc::into_pandoc; 5use self::pandoc::into_pandoc;
9use crate::types::Entity; 6use crate::types::*;
10 7
11use anyhow::{ensure, Context, Result}; 8use anyhow::{ensure, Context, Result};
12use rayon::Scope; 9use rayon::Scope;
@@ -18,7 +15,11 @@ use std::path::Path;
18 15
19const DEFAULT_CSS: &[u8] = include_bytes!("../../res/style.css"); 16const DEFAULT_CSS: &[u8] = include_bytes!("../../res/style.css");
20 17
21pub(crate) fn generate(base_dir: &Path, entities: BTreeMap<String, Entity>, config: &Config) -> Result<()> { 18pub(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
56fn generate_recursively<'a>( 57fn 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
92fn generate_single( 93fn 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 @@
1use super::config::Config; 1use super::config::Config;
2use crate::types::Entity; 2use crate::types::*;
3 3
4use pandoc_types::definition::{Attr, Block, Inline, Meta, MetaValue, Pandoc}; 4use pandoc_types::definition::{Attr, Block, Inline, Meta, MetaValue, Pandoc};
5 5
6use std::collections::BTreeMap; 6use std::collections::BTreeMap;
7 7
8pub(crate) fn into_pandoc( 8pub(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
115fn entity_link(id: &str, name: String) -> Inline { 112fn 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
150fn member_list<'a>(members: impl IntoIterator<Item = (&'a String, &'a Entity)>) -> Option<Block> { 147fn 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)| {