Factor out common module prefix when all modules are under a same namespace.
This commit is contained in:
parent
600c7747da
commit
5c0920d6bb
|
@ -34,6 +34,7 @@ struct ModuleTemplate<'a> {
|
||||||
project_name: &'a str,
|
project_name: &'a str,
|
||||||
project_version: &'a str,
|
project_version: &'a str,
|
||||||
links: &'a Vec<DocLink>,
|
links: &'a Vec<DocLink>,
|
||||||
|
modules_prefix: String,
|
||||||
modules: &'a Vec<DocLink>,
|
modules: &'a Vec<DocLink>,
|
||||||
functions: Vec<DocFunction>,
|
functions: Vec<DocFunction>,
|
||||||
types: Vec<DocType>,
|
types: Vec<DocType>,
|
||||||
|
@ -51,6 +52,7 @@ struct PageTemplate<'a> {
|
||||||
project_name: &'a str,
|
project_name: &'a str,
|
||||||
project_version: &'a str,
|
project_version: &'a str,
|
||||||
links: &'a Vec<DocLink>,
|
links: &'a Vec<DocLink>,
|
||||||
|
modules_prefix: String,
|
||||||
modules: &'a Vec<DocLink>,
|
modules: &'a Vec<DocLink>,
|
||||||
content: String,
|
content: String,
|
||||||
timestamp: &'a str,
|
timestamp: &'a str,
|
||||||
|
@ -69,26 +71,37 @@ struct DocLink {
|
||||||
/// across multiple modules.
|
/// across multiple modules.
|
||||||
pub fn generate_all(root: &Path, config: &Config, modules: Vec<&CheckedModule>) -> Vec<DocFile> {
|
pub fn generate_all(root: &Path, config: &Config, modules: Vec<&CheckedModule>) -> Vec<DocFile> {
|
||||||
let timestamp = new_timestamp();
|
let timestamp = new_timestamp();
|
||||||
let modules_links = generate_modules_links(&modules);
|
let (modules_prefix, modules_links) = generate_modules_links(&modules);
|
||||||
|
|
||||||
let mut output_files: Vec<DocFile> = vec![];
|
let mut output_files: Vec<DocFile> = vec![];
|
||||||
let mut search_indexes: Vec<SearchIndex> = vec![];
|
let mut search_indexes: Vec<SearchIndex> = vec![];
|
||||||
|
|
||||||
for module in &modules {
|
for module in &modules {
|
||||||
let (indexes, file) = generate_module(config, module, &modules_links, ×tamp);
|
let (indexes, file) = generate_module(
|
||||||
|
config,
|
||||||
|
module,
|
||||||
|
(&modules_prefix, &modules_links),
|
||||||
|
×tamp,
|
||||||
|
);
|
||||||
search_indexes.extend(indexes);
|
search_indexes.extend(indexes);
|
||||||
output_files.push(file);
|
output_files.push(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
output_files.extend(generate_static_assets(search_indexes));
|
output_files.extend(generate_static_assets(search_indexes));
|
||||||
output_files.push(generate_readme(root, config, &modules_links, ×tamp));
|
output_files.push(generate_readme(
|
||||||
|
root,
|
||||||
|
config,
|
||||||
|
(&modules_prefix, &modules_links),
|
||||||
|
×tamp,
|
||||||
|
));
|
||||||
|
|
||||||
output_files
|
output_files
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_module(
|
fn generate_module(
|
||||||
config: &Config,
|
config: &Config,
|
||||||
module: &CheckedModule,
|
module: &CheckedModule,
|
||||||
modules: &Vec<DocLink>,
|
(modules_prefix, modules): (&str, &Vec<DocLink>),
|
||||||
timestamp: &Duration,
|
timestamp: &Duration,
|
||||||
) -> (Vec<SearchIndex>, DocFile) {
|
) -> (Vec<SearchIndex>, DocFile) {
|
||||||
let mut search_indexes = vec![];
|
let mut search_indexes = vec![];
|
||||||
|
@ -101,7 +114,6 @@ fn generate_module(
|
||||||
.flat_map(DocFunction::from_definition)
|
.flat_map(DocFunction::from_definition)
|
||||||
.sorted()
|
.sorted()
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
functions
|
functions
|
||||||
.iter()
|
.iter()
|
||||||
.for_each(|function| search_indexes.push(SearchIndex::from_function(module, function)));
|
.for_each(|function| search_indexes.push(SearchIndex::from_function(module, function)));
|
||||||
|
@ -114,7 +126,6 @@ fn generate_module(
|
||||||
.flat_map(DocType::from_definition)
|
.flat_map(DocType::from_definition)
|
||||||
.sorted()
|
.sorted()
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
types
|
types
|
||||||
.iter()
|
.iter()
|
||||||
.for_each(|type_info| search_indexes.push(SearchIndex::from_type(module, type_info)));
|
.for_each(|type_info| search_indexes.push(SearchIndex::from_type(module, type_info)));
|
||||||
|
@ -133,12 +144,12 @@ fn generate_module(
|
||||||
|
|
||||||
// Module
|
// Module
|
||||||
search_indexes.push(SearchIndex::from_module(module));
|
search_indexes.push(SearchIndex::from_module(module));
|
||||||
|
let module = ModuleTemplate {
|
||||||
let template = ModuleTemplate {
|
|
||||||
aiken_version: VERSION,
|
aiken_version: VERSION,
|
||||||
breadcrumbs: to_breadcrumbs(&module.name),
|
breadcrumbs: to_breadcrumbs(&module.name),
|
||||||
links: &vec![],
|
links: &vec![],
|
||||||
documentation: render_markdown(&module.ast.docs.iter().join("\n")),
|
documentation: render_markdown(&module.ast.docs.iter().join("\n")),
|
||||||
|
modules_prefix: modules_prefix.to_string(),
|
||||||
modules,
|
modules,
|
||||||
project_name: &config.name,
|
project_name: &config.name,
|
||||||
page_title: &format!("{} - {}", module.name, config.name),
|
page_title: &format!("{} - {}", module.name, config.name),
|
||||||
|
@ -153,8 +164,8 @@ fn generate_module(
|
||||||
(
|
(
|
||||||
search_indexes,
|
search_indexes,
|
||||||
DocFile {
|
DocFile {
|
||||||
path: PathBuf::from(format!("{}.html", module.name)),
|
path: PathBuf::from(format!("{}.html", module.module_name)),
|
||||||
content: template
|
content: module
|
||||||
.render()
|
.render()
|
||||||
.expect("Module documentation template rendering"),
|
.expect("Module documentation template rendering"),
|
||||||
},
|
},
|
||||||
|
@ -214,7 +225,7 @@ fn generate_static_assets(search_indexes: Vec<SearchIndex>) -> Vec<DocFile> {
|
||||||
fn generate_readme(
|
fn generate_readme(
|
||||||
root: &Path,
|
root: &Path,
|
||||||
config: &Config,
|
config: &Config,
|
||||||
modules: &Vec<DocLink>,
|
(modules_prefix, modules): (&str, &Vec<DocLink>),
|
||||||
timestamp: &Duration,
|
timestamp: &Duration,
|
||||||
) -> DocFile {
|
) -> DocFile {
|
||||||
let path = PathBuf::from("index.html");
|
let path = PathBuf::from("index.html");
|
||||||
|
@ -225,6 +236,7 @@ fn generate_readme(
|
||||||
aiken_version: VERSION,
|
aiken_version: VERSION,
|
||||||
breadcrumbs: ".",
|
breadcrumbs: ".",
|
||||||
links: &vec![],
|
links: &vec![],
|
||||||
|
modules_prefix: modules_prefix.to_string(),
|
||||||
modules,
|
modules,
|
||||||
project_name: &config.name,
|
project_name: &config.name,
|
||||||
page_title: &config.name,
|
page_title: &config.name,
|
||||||
|
@ -239,7 +251,7 @@ fn generate_readme(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_modules_links(modules: &Vec<&CheckedModule>) -> Vec<DocLink> {
|
fn generate_modules_links(modules: &Vec<&CheckedModule>) -> (String, Vec<DocLink>) {
|
||||||
let mut modules_links = vec![];
|
let mut modules_links = vec![];
|
||||||
for module in modules {
|
for module in modules {
|
||||||
let module_path = [&module.name.clone(), ".html"].concat();
|
let module_path = [&module.name.clone(), ".html"].concat();
|
||||||
|
@ -249,7 +261,18 @@ fn generate_modules_links(modules: &Vec<&CheckedModule>) -> Vec<DocLink> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
modules_links.sort();
|
modules_links.sort();
|
||||||
modules_links
|
|
||||||
|
let prefix = find_modules_prefix(&modules_links);
|
||||||
|
|
||||||
|
for module in &mut modules_links {
|
||||||
|
let name = module.name.strip_prefix(&prefix).unwrap_or_default();
|
||||||
|
module.name = name.strip_prefix('/').unwrap_or(name).to_string();
|
||||||
|
if module.name == String::new() {
|
||||||
|
module.name = "/".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(prefix, modules_links)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, PartialEq, Eq, PartialOrd, Ord, Clone)]
|
#[derive(Serialize, PartialEq, Eq, PartialOrd, Ord, Clone)]
|
||||||
|
@ -510,18 +533,86 @@ fn new_timestamp() -> Duration {
|
||||||
.expect("get current timestamp")
|
.expect("get current timestamp")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn find_modules_prefix(modules: &[DocLink]) -> String {
|
||||||
|
modules
|
||||||
|
.iter()
|
||||||
|
.fold(None, |previous_prefix, module| {
|
||||||
|
let prefix = module
|
||||||
|
.name
|
||||||
|
.split('/')
|
||||||
|
.next()
|
||||||
|
.unwrap_or_default()
|
||||||
|
.to_string();
|
||||||
|
match previous_prefix {
|
||||||
|
None if prefix != module.name => Some(prefix),
|
||||||
|
Some(..) if Some(prefix) == previous_prefix => previous_prefix,
|
||||||
|
_ => Some(String::new()),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.unwrap_or_default()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn find_modules_prefix_test() {
|
||||||
|
assert_eq!(find_modules_prefix(&vec![]), "".to_string());
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
find_modules_prefix(&vec![DocLink {
|
||||||
|
name: "aiken/list".to_string(),
|
||||||
|
path: String::new()
|
||||||
|
}]),
|
||||||
|
"aiken".to_string()
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
find_modules_prefix(&vec![DocLink {
|
||||||
|
name: "my_module".to_string(),
|
||||||
|
path: String::new()
|
||||||
|
}]),
|
||||||
|
"".to_string()
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
find_modules_prefix(&vec![
|
||||||
|
DocLink {
|
||||||
|
name: "aiken/list".to_string(),
|
||||||
|
path: String::new()
|
||||||
|
},
|
||||||
|
DocLink {
|
||||||
|
name: "aiken/byte_array".to_string(),
|
||||||
|
path: String::new(),
|
||||||
|
}
|
||||||
|
]),
|
||||||
|
"aiken".to_string()
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
find_modules_prefix(&vec![
|
||||||
|
DocLink {
|
||||||
|
name: "aiken/list".to_string(),
|
||||||
|
path: String::new()
|
||||||
|
},
|
||||||
|
DocLink {
|
||||||
|
name: "foo/byte_array".to_string(),
|
||||||
|
path: String::new(),
|
||||||
|
}
|
||||||
|
]),
|
||||||
|
"".to_string()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
fn to_breadcrumbs(path: &str) -> String {
|
fn to_breadcrumbs(path: &str) -> String {
|
||||||
let unnest = path
|
let breadcrumbs = path
|
||||||
.strip_prefix('/')
|
.strip_prefix('/')
|
||||||
.unwrap_or(path)
|
.unwrap_or(path)
|
||||||
.split('/')
|
.split('/')
|
||||||
.skip(1)
|
.skip(1)
|
||||||
.map(|_| "..")
|
.map(|_| "..")
|
||||||
.join("/");
|
.join("/");
|
||||||
if unnest.is_empty() {
|
if breadcrumbs.is_empty() {
|
||||||
".".to_string()
|
".".to_string()
|
||||||
} else {
|
} else {
|
||||||
unnest
|
breadcrumbs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -185,6 +185,9 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<h2>Modules</h2>
|
<h2>Modules</h2>
|
||||||
|
{% if !modules_prefix.is_empty() %}
|
||||||
|
<h3 class="modules-prefix">{{ modules_prefix }}/</h3>
|
||||||
|
{% endif %}
|
||||||
<ul>
|
<ul>
|
||||||
{% for module in modules %}
|
{% for module in modules %}
|
||||||
<li><a href="{{ breadcrumbs }}/{{ module.path }}">{{ module.name }}</a></li>
|
<li><a href="{{ breadcrumbs }}/{{ module.path }}">{{ module.name }}</a></li>
|
||||||
|
|
|
@ -305,12 +305,21 @@ p code {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sidebar h3.modules-prefix {
|
||||||
|
color: var(--pink);
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.sidebar ul {
|
.sidebar ul {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
margin: var(--small-gap) 0;
|
margin: var(--small-gap) 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sidebar h3.modules-prefix + ul {
|
||||||
|
margin-left: var(--tiny-gap);
|
||||||
|
}
|
||||||
|
|
||||||
.sidebar li {
|
.sidebar li {
|
||||||
line-height: 1.2;
|
line-height: 1.2;
|
||||||
margin-bottom: 4px;
|
margin-bottom: 4px;
|
||||||
|
|
Loading…
Reference in New Issue