Skip to content

Commit f96e7e5

Browse files
committed
Implemented support for additional JS
1 parent 6c27945 commit f96e7e5

File tree

6 files changed

+82
-5
lines changed

6 files changed

+82
-5
lines changed

src/book/mod.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,22 @@ impl MDBook {
487487
None
488488
}
489489

490+
pub fn has_additional_js(&self) -> bool {
491+
if let Some(htmlconfig) = self.config.get_html_config() {
492+
return htmlconfig.has_additional_js();
493+
}
494+
495+
false
496+
}
497+
498+
pub fn get_additional_js(&self) -> &[PathBuf] {
499+
if let Some(htmlconfig) = self.config.get_html_config() {
500+
return htmlconfig.get_additional_js();
501+
}
502+
503+
&[]
504+
}
505+
490506
pub fn has_additional_css(&self) -> bool {
491507
if let Some(htmlconfig) = self.config.get_html_config() {
492508
return htmlconfig.has_additional_css();

src/config/htmlconfig.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ pub struct HtmlConfig {
88
theme: Option<PathBuf>,
99
google_analytics: Option<String>,
1010
additional_css: Vec<PathBuf>,
11+
additional_js: Vec<PathBuf>,
1112
}
1213

1314
impl HtmlConfig {
@@ -28,6 +29,7 @@ impl HtmlConfig {
2829
theme: None,
2930
google_analytics: None,
3031
additional_css: Vec::new(),
32+
additional_js: Vec::new(),
3133
}
3234
}
3335

@@ -64,6 +66,16 @@ impl HtmlConfig {
6466
}
6567
}
6668

69+
if let Some(scriptpaths) = tomlconfig.additional_js {
70+
for path in scriptpaths {
71+
if path.is_relative() {
72+
self.additional_js.push(root.join(path));
73+
} else {
74+
self.additional_js.push(path);
75+
}
76+
}
77+
}
78+
6779
self
6880
}
6981

@@ -114,4 +126,12 @@ impl HtmlConfig {
114126
pub fn get_additional_css(&self) -> &[PathBuf] {
115127
&self.additional_css
116128
}
129+
130+
pub fn has_additional_js(&self) -> bool {
131+
!self.additional_js.is_empty()
132+
}
133+
134+
pub fn get_additional_js(&self) -> &[PathBuf] {
135+
&self.additional_js
136+
}
117137
}

src/config/tomlconfig.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ pub struct TomlHtmlConfig {
2525
pub theme: Option<PathBuf>,
2626
pub google_analytics: Option<String>,
2727
pub additional_css: Option<Vec<PathBuf>>,
28+
pub additional_js: Option<Vec<PathBuf>>,
2829
}
2930

3031
/// Returns a TomlConfig from a TOML string

src/renderer/html_handlebars/hbs_renderer.rs

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -187,14 +187,22 @@ impl Renderer for HtmlHandlebars {
187187
book.write_file("_FontAwesome/fonts/fontawesome-webfont.woff2", theme::FONT_AWESOME_WOFF2)?;
188188
book.write_file("_FontAwesome/fonts/FontAwesome.ttf", theme::FONT_AWESOME_TTF)?;
189189

190-
for style in book.get_additional_css() {
190+
for custom_file in book.get_additional_css()
191+
.iter()
192+
.chain(book.get_additional_js().iter()) {
191193
let mut data = Vec::new();
192-
let mut f = File::open(style)?;
194+
let mut f = File::open(custom_file)?;
193195
f.read_to_end(&mut data)?;
194196

195-
let name = match style.strip_prefix(book.get_root()) {
197+
let name = match custom_file.strip_prefix(book.get_root()) {
196198
Ok(p) => p.to_str().expect("Could not convert to str"),
197-
Err(_) => style.file_name().expect("File has a file name").to_str().expect("Could not convert to str"),
199+
Err(_) => {
200+
custom_file
201+
.file_name()
202+
.expect("File has a file name")
203+
.to_str()
204+
.expect("Could not convert to str")
205+
}
198206
};
199207

200208
book.write_file(name, &data)?;
@@ -240,6 +248,18 @@ fn make_data(book: &MDBook) -> Result<serde_json::Map<String, serde_json::Value>
240248
data.insert("additional_css".to_owned(), json!(css));
241249
}
242250

251+
// Add check to see if there is an additional script
252+
if book.has_additional_js() {
253+
let mut js = Vec::new();
254+
for script in book.get_additional_js() {
255+
match script.strip_prefix(book.get_root()) {
256+
Ok(p) => js.push(p.to_str().expect("Could not convert to str")),
257+
Err(_) => js.push(script.file_name().expect("File has a file name").to_str().expect("Could not convert to str")),
258+
}
259+
}
260+
data.insert("additional_js".to_owned(), json!(js));
261+
}
262+
243263
let mut chapters = vec![];
244264

245265
for item in book.iter() {

src/theme/index.hbs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,12 @@
4444
document.write(unescape("%3Cscript src='jquery.js'%3E%3C/script%3E"));
4545
}
4646
</script>
47+
48+
<!-- Custom JS script -->
49+
{{#each additional_js}}
50+
<script type="text/javascript" src="{{this}}"></script>
51+
{{/each}}
52+
4753
</head>
4854
<body class="light">
4955
<!-- Set the theme before any content is loaded, prevents flash -->

tests/tomlconfig.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,4 +114,18 @@ fn from_toml_output_html_additional_stylesheet() {
114114
let htmlconfig = config.get_html_config().expect("There should be an HtmlConfig");
115115

116116
assert_eq!(htmlconfig.get_additional_css(), &[PathBuf::from("root/custom.css"), PathBuf::from("root/two/custom.css")]);
117-
}
117+
}
118+
119+
// Tests that the `output.html.additional-js` key is correcly parsed in the TOML config
120+
#[test]
121+
fn from_toml_output_html_additional_scripts() {
122+
let toml = r#"[output.html]
123+
additional-js = ["custom.js", "two/custom.js"]"#;
124+
125+
let parsed = TomlConfig::from_toml(&toml).expect("This should parse");
126+
let config = BookConfig::from_tomlconfig("root", parsed);
127+
128+
let htmlconfig = config.get_html_config().expect("There should be an HtmlConfig");
129+
130+
assert_eq!(htmlconfig.get_additional_js(), &[PathBuf::from("root/custom.js"), PathBuf::from("root/two/custom.js")]);
131+
}

0 commit comments

Comments
 (0)