diff --git a/src/config.rs b/src/config.rs index 898ec6b7..291c8a63 100644 --- a/src/config.rs +++ b/src/config.rs @@ -424,6 +424,8 @@ pub struct HtmlConfig { pub livereload_url: Option, /// Should section labels be rendered? pub no_section_label: bool, + /// Filenames listed here would be rewritten to directory index `/`. + pub rewrite_to_dir: Vec, /// Search settings. If `None`, the default will be used. pub search: Option, } diff --git a/src/renderer/html_handlebars/hbs_renderer.rs b/src/renderer/html_handlebars/hbs_renderer.rs index fbaad523..b4d73854 100644 --- a/src/renderer/html_handlebars/hbs_renderer.rs +++ b/src/renderer/html_handlebars/hbs_renderer.rs @@ -219,7 +219,10 @@ impl HtmlHandlebars { } fn register_hbs_helpers(&self, handlebars: &mut Handlebars, html_config: &HtmlConfig) { - handlebars.register_helper("toc", Box::new(helpers::toc::RenderToc {no_section_label: html_config.no_section_label})); + handlebars.register_helper("toc", Box::new(helpers::toc::RenderToc { + no_section_label: html_config.no_section_label, + rewrite_to_dir: html_config.rewrite_to_dir.to_owned(), + })); handlebars.register_helper("previous", Box::new(helpers::navigation::previous)); handlebars.register_helper("next", Box::new(helpers::navigation::next)); } diff --git a/src/renderer/html_handlebars/helpers/toc.rs b/src/renderer/html_handlebars/helpers/toc.rs index f44ea2ac..2ade3e21 100644 --- a/src/renderer/html_handlebars/helpers/toc.rs +++ b/src/renderer/html_handlebars/helpers/toc.rs @@ -1,4 +1,4 @@ -use std::path::Path; +use std::path::{Path, PathBuf}; use std::collections::BTreeMap; use serde_json; @@ -6,9 +6,9 @@ use handlebars::{Handlebars, Helper, HelperDef, RenderContext, RenderError}; use pulldown_cmark::{html, Event, Parser, Tag}; // Handlebars helper to construct TOC -#[derive(Clone, Copy)] pub struct RenderToc { pub no_section_label: bool, + pub rewrite_to_dir: Vec, } impl HelperDef for RenderToc { @@ -69,8 +69,11 @@ impl HelperDef for RenderToc { if !path.is_empty() { rc.writer.write_all(b"")?; Ok(()) } + +} + +impl RenderToc { + // Rewrite filenames matches any in `rewrite_to_dir` to directory index. + fn rewrite_directory_index(&self, path: &Path) -> PathBuf { + for filename in self.rewrite_to_dir.iter() { + if filename.as_str() == path.file_name().unwrap_or_default() { + return path.with_file_name(""); + } + } + return path.to_owned(); + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn rewrite_dir_success() { + let render = RenderToc { + no_section_label: true, + rewrite_to_dir: vec![ + "index.html".to_owned(), + "index.md".to_owned(), + ], + }; + let path = PathBuf::from("index.html"); + assert_eq!(render.rewrite_directory_index(&path), PathBuf::from("")); + + let path = PathBuf::from("index.md"); + assert_eq!(render.rewrite_directory_index(&path), PathBuf::from("")); + + let path = PathBuf::from("index.asp"); + assert_eq!(render.rewrite_directory_index(&path), path); + } }