diff --git a/src/book/mod.rs b/src/book/mod.rs index cdcb3358..88d0e804 100644 --- a/src/book/mod.rs +++ b/src/book/mod.rs @@ -487,6 +487,22 @@ impl MDBook { None } + pub fn has_additional_js(&self) -> bool { + if let Some(htmlconfig) = self.config.get_html_config() { + return htmlconfig.has_additional_js(); + } + + false + } + + pub fn get_additional_js(&self) -> &[PathBuf] { + if let Some(htmlconfig) = self.config.get_html_config() { + return htmlconfig.get_additional_js(); + } + + &[] + } + pub fn has_additional_css(&self) -> bool { if let Some(htmlconfig) = self.config.get_html_config() { return htmlconfig.has_additional_css(); diff --git a/src/config/htmlconfig.rs b/src/config/htmlconfig.rs index 4beb14c4..8ea1f08f 100644 --- a/src/config/htmlconfig.rs +++ b/src/config/htmlconfig.rs @@ -8,6 +8,7 @@ pub struct HtmlConfig { theme: Option, google_analytics: Option, additional_css: Vec, + additional_js: Vec, } impl HtmlConfig { @@ -28,6 +29,7 @@ impl HtmlConfig { theme: None, google_analytics: None, additional_css: Vec::new(), + additional_js: Vec::new(), } } @@ -64,6 +66,16 @@ impl HtmlConfig { } } + if let Some(scriptpaths) = tomlconfig.additional_js { + for path in scriptpaths { + if path.is_relative() { + self.additional_js.push(root.join(path)); + } else { + self.additional_js.push(path); + } + } + } + self } @@ -114,4 +126,12 @@ impl HtmlConfig { pub fn get_additional_css(&self) -> &[PathBuf] { &self.additional_css } + + pub fn has_additional_js(&self) -> bool { + !self.additional_js.is_empty() + } + + pub fn get_additional_js(&self) -> &[PathBuf] { + &self.additional_js + } } diff --git a/src/config/tomlconfig.rs b/src/config/tomlconfig.rs index 2a08fa84..ca7388bd 100644 --- a/src/config/tomlconfig.rs +++ b/src/config/tomlconfig.rs @@ -25,6 +25,7 @@ pub struct TomlHtmlConfig { pub theme: Option, pub google_analytics: Option, pub additional_css: Option>, + pub additional_js: Option>, } /// Returns a TomlConfig from a TOML string diff --git a/src/renderer/html_handlebars/hbs_renderer.rs b/src/renderer/html_handlebars/hbs_renderer.rs index f64ae6f5..8429fa16 100644 --- a/src/renderer/html_handlebars/hbs_renderer.rs +++ b/src/renderer/html_handlebars/hbs_renderer.rs @@ -188,14 +188,22 @@ impl Renderer for HtmlHandlebars { book.write_file("_FontAwesome/fonts/fontawesome-webfont.woff2", theme::FONT_AWESOME_WOFF2)?; book.write_file("_FontAwesome/fonts/FontAwesome.ttf", theme::FONT_AWESOME_TTF)?; - for style in book.get_additional_css() { + for custom_file in book.get_additional_css() + .iter() + .chain(book.get_additional_js().iter()) { let mut data = Vec::new(); - let mut f = File::open(style)?; + let mut f = File::open(custom_file)?; f.read_to_end(&mut data)?; - let name = match style.strip_prefix(book.get_root()) { + let name = match custom_file.strip_prefix(book.get_root()) { Ok(p) => p.to_str().expect("Could not convert to str"), - Err(_) => style.file_name().expect("File has a file name").to_str().expect("Could not convert to str"), + Err(_) => { + custom_file + .file_name() + .expect("File has a file name") + .to_str() + .expect("Could not convert to str") + } }; book.write_file(name, &data)?; @@ -241,6 +249,18 @@ fn make_data(book: &MDBook) -> Result data.insert("additional_css".to_owned(), json!(css)); } + // Add check to see if there is an additional script + if book.has_additional_js() { + let mut js = Vec::new(); + for script in book.get_additional_js() { + match script.strip_prefix(book.get_root()) { + Ok(p) => js.push(p.to_str().expect("Could not convert to str")), + Err(_) => js.push(script.file_name().expect("File has a file name").to_str().expect("Could not convert to str")), + } + } + data.insert("additional_js".to_owned(), json!(js)); + } + let mut chapters = vec![]; for item in book.iter() { diff --git a/src/theme/index.hbs b/src/theme/index.hbs index b8076d16..27464213 100644 --- a/src/theme/index.hbs +++ b/src/theme/index.hbs @@ -44,8 +44,15 @@ document.write(unescape("%3Cscript src='jquery.js'%3E%3C/script%3E")); } + + + + {{#each additional_js}} + + {{/each}} + diff --git a/tests/tomlconfig.rs b/tests/tomlconfig.rs index 91c40016..e4398495 100644 --- a/tests/tomlconfig.rs +++ b/tests/tomlconfig.rs @@ -114,4 +114,18 @@ fn from_toml_output_html_additional_stylesheet() { let htmlconfig = config.get_html_config().expect("There should be an HtmlConfig"); assert_eq!(htmlconfig.get_additional_css(), &[PathBuf::from("root/custom.css"), PathBuf::from("root/two/custom.css")]); -} \ No newline at end of file +} + +// Tests that the `output.html.additional-js` key is correcly parsed in the TOML config +#[test] +fn from_toml_output_html_additional_scripts() { + let toml = r#"[output.html] + additional-js = ["custom.js", "two/custom.js"]"#; + + let parsed = TomlConfig::from_toml(&toml).expect("This should parse"); + let config = BookConfig::from_tomlconfig("root", parsed); + + let htmlconfig = config.get_html_config().expect("There should be an HtmlConfig"); + + assert_eq!(htmlconfig.get_additional_js(), &[PathBuf::from("root/custom.js"), PathBuf::from("root/two/custom.js")]); +}