Impl `rewrite_to_dir` config for navigations
This commit is contained in:
parent
9b2ab45eaf
commit
996ecf478e
|
@ -219,12 +219,17 @@ impl HtmlHandlebars {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn register_hbs_helpers(&self, handlebars: &mut Handlebars, html_config: &HtmlConfig) {
|
fn register_hbs_helpers(&self, handlebars: &mut Handlebars, html_config: &HtmlConfig) {
|
||||||
|
let HtmlConfig { no_section_label, ref rewrite_to_dir, .. } = *html_config;
|
||||||
handlebars.register_helper("toc", Box::new(helpers::toc::RenderToc {
|
handlebars.register_helper("toc", Box::new(helpers::toc::RenderToc {
|
||||||
no_section_label: html_config.no_section_label,
|
no_section_label,
|
||||||
rewrite_to_dir: html_config.rewrite_to_dir.to_owned(),
|
rewrite_to_dir: rewrite_to_dir.to_owned(),
|
||||||
|
}));
|
||||||
|
handlebars.register_helper("previous", Box::new(helpers::navigation::Previous {
|
||||||
|
rewrite_to_dir: rewrite_to_dir.to_owned(),
|
||||||
|
}));
|
||||||
|
handlebars.register_helper("next", Box::new(helpers::navigation::Next {
|
||||||
|
rewrite_to_dir: rewrite_to_dir.to_owned(),
|
||||||
}));
|
}));
|
||||||
handlebars.register_helper("previous", Box::new(helpers::navigation::previous));
|
|
||||||
handlebars.register_helper("next", Box::new(helpers::navigation::next));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Copy across any additional CSS and JavaScript files which the book
|
/// Copy across any additional CSS and JavaScript files which the book
|
||||||
|
|
|
@ -1,2 +1,38 @@
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
pub mod toc;
|
pub mod toc;
|
||||||
pub mod navigation;
|
pub mod navigation;
|
||||||
|
|
||||||
|
/// Rewrite filename of path to directory index if matches any of filename
|
||||||
|
/// pattern in `rewrite_names`.
|
||||||
|
///
|
||||||
|
/// * `path` - Path reference.
|
||||||
|
/// * `rewrite_names` - Array of filename pattern to be rewritten.
|
||||||
|
pub fn rewrite_to_dir_index<P: AsRef<Path>>(path: P, rewrite_names: &[String]) -> PathBuf {
|
||||||
|
let p = path.as_ref();
|
||||||
|
for name in rewrite_names.iter() {
|
||||||
|
if name.as_str() == p.file_name().unwrap_or_default() {
|
||||||
|
return p.with_file_name("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return p.to_owned();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rewrite_to_dir_success() {
|
||||||
|
let names = vec!["index.html".to_owned(), "index.md".to_owned()];
|
||||||
|
|
||||||
|
let path = PathBuf::from("index.html");
|
||||||
|
assert_eq!(rewrite_to_dir_index(&path, &names), PathBuf::from(""));
|
||||||
|
|
||||||
|
let path = PathBuf::from("index.md");
|
||||||
|
assert_eq!(rewrite_to_dir_index(&path, &names), PathBuf::from(""));
|
||||||
|
|
||||||
|
let path = PathBuf::from("index.asp");
|
||||||
|
assert_eq!(rewrite_to_dir_index(&path, &names), path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -2,7 +2,10 @@ use std::path::Path;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
use serde_json;
|
use serde_json;
|
||||||
use handlebars::{Context, Handlebars, Helper, RenderContext, RenderError, Renderable};
|
use handlebars::{Context, Handlebars, Helper, HelperDef, RenderContext, RenderError, Renderable};
|
||||||
|
|
||||||
|
use super::rewrite_to_dir_index;
|
||||||
|
|
||||||
|
|
||||||
type StringMap = BTreeMap<String, String>;
|
type StringMap = BTreeMap<String, String>;
|
||||||
|
|
||||||
|
@ -83,6 +86,7 @@ fn render(
|
||||||
r: &Handlebars,
|
r: &Handlebars,
|
||||||
rc: &mut RenderContext,
|
rc: &mut RenderContext,
|
||||||
chapter: &StringMap,
|
chapter: &StringMap,
|
||||||
|
rewrite_names: &[String],
|
||||||
) -> Result<(), RenderError> {
|
) -> Result<(), RenderError> {
|
||||||
trace!("Creating BTreeMap to inject in context");
|
trace!("Creating BTreeMap to inject in context");
|
||||||
|
|
||||||
|
@ -97,8 +101,7 @@ fn render(
|
||||||
.get("path")
|
.get("path")
|
||||||
.ok_or_else(|| RenderError::new("No path found for chapter in JSON data"))
|
.ok_or_else(|| RenderError::new("No path found for chapter in JSON data"))
|
||||||
.and_then(|p| {
|
.and_then(|p| {
|
||||||
Path::new(p)
|
rewrite_to_dir_index(Path::new(p).with_extension("html"), rewrite_names)
|
||||||
.with_extension("html")
|
|
||||||
.to_str()
|
.to_str()
|
||||||
.ok_or_else(|| RenderError::new("Link could not be converted to str"))
|
.ok_or_else(|| RenderError::new("Link could not be converted to str"))
|
||||||
.map(|p| context.insert("link".to_owned(), json!(p.replace("\\", "/"))))
|
.map(|p| context.insert("link".to_owned(), json!(p.replace("\\", "/"))))
|
||||||
|
@ -116,25 +119,49 @@ fn render(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn previous(_h: &Helper, r: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> {
|
pub struct Previous {
|
||||||
|
pub rewrite_to_dir: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Previous {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self { rewrite_to_dir: vec![] }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HelperDef for Previous {
|
||||||
|
fn call(&self, _h: &Helper, r: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> {
|
||||||
trace!("previous (handlebars helper)");
|
trace!("previous (handlebars helper)");
|
||||||
|
|
||||||
if let Some(previous) = find_chapter(rc, Target::Previous)? {
|
if let Some(previous) = find_chapter(rc, Target::Previous)? {
|
||||||
render(_h, r, rc, &previous)?;
|
render(_h, r, rc, &previous, &self.rewrite_to_dir)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn next(_h: &Helper, r: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> {
|
pub struct Next {
|
||||||
|
pub rewrite_to_dir: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Next {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self { rewrite_to_dir: vec![] }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HelperDef for Next {
|
||||||
|
fn call(&self, _h: &Helper, r: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> {
|
||||||
trace!("next (handlebars helper)");
|
trace!("next (handlebars helper)");
|
||||||
|
|
||||||
if let Some(next) = find_chapter(rc, Target::Next)? {
|
if let Some(next) = find_chapter(rc, Target::Next)? {
|
||||||
render(_h, r, rc, &next)?;
|
render(_h, r, rc, &next, &self.rewrite_to_dir)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
@ -165,8 +192,8 @@ mod tests {
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut h = Handlebars::new();
|
let mut h = Handlebars::new();
|
||||||
h.register_helper("previous", Box::new(previous));
|
h.register_helper("previous", Box::new(Previous::default()));
|
||||||
h.register_helper("next", Box::new(next));
|
h.register_helper("next", Box::new(Next::default()));
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
h.render_template(TEMPLATE, &data).unwrap(),
|
h.render_template(TEMPLATE, &data).unwrap(),
|
||||||
|
@ -196,8 +223,8 @@ mod tests {
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut h = Handlebars::new();
|
let mut h = Handlebars::new();
|
||||||
h.register_helper("previous", Box::new(previous));
|
h.register_helper("previous", Box::new(Previous::default()));
|
||||||
h.register_helper("next", Box::new(next));
|
h.register_helper("next", Box::new(Next::default()));
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
h.render_template(TEMPLATE, &data).unwrap(),
|
h.render_template(TEMPLATE, &data).unwrap(),
|
||||||
|
@ -226,8 +253,8 @@ mod tests {
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut h = Handlebars::new();
|
let mut h = Handlebars::new();
|
||||||
h.register_helper("previous", Box::new(previous));
|
h.register_helper("previous", Box::new(Previous::default()));
|
||||||
h.register_helper("next", Box::new(next));
|
h.register_helper("next", Box::new(Next::default()));
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
h.render_template(TEMPLATE, &data).unwrap(),
|
h.render_template(TEMPLATE, &data).unwrap(),
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::Path;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
use serde_json;
|
use serde_json;
|
||||||
use handlebars::{Handlebars, Helper, HelperDef, RenderContext, RenderError};
|
use handlebars::{Handlebars, Helper, HelperDef, RenderContext, RenderError};
|
||||||
use pulldown_cmark::{html, Event, Parser, Tag};
|
use pulldown_cmark::{html, Event, Parser, Tag};
|
||||||
|
|
||||||
|
use super::rewrite_to_dir_index;
|
||||||
|
|
||||||
// Handlebars helper to construct TOC
|
// Handlebars helper to construct TOC
|
||||||
pub struct RenderToc {
|
pub struct RenderToc {
|
||||||
pub no_section_label: bool,
|
pub no_section_label: bool,
|
||||||
|
@ -72,7 +74,7 @@ impl HelperDef for RenderToc {
|
||||||
let tmp = {
|
let tmp = {
|
||||||
// To be recognized by browsers, rewrite extenstion to `.html`.
|
// To be recognized by browsers, rewrite extenstion to `.html`.
|
||||||
let path = Path::new(path).with_extension("html");
|
let path = Path::new(path).with_extension("html");
|
||||||
self.rewrite_directory_index(&path)
|
rewrite_to_dir_index(&path, &self.rewrite_to_dir)
|
||||||
}
|
}
|
||||||
.to_str()
|
.to_str()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
@ -140,41 +142,4 @@ impl HelperDef for RenderToc {
|
||||||
rc.writer.write_all(b"</ol>")?;
|
rc.writer.write_all(b"</ol>")?;
|
||||||
Ok(())
|
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue