Skip to content

Implemented support for additional JS #316

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 12, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions src/book/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
20 changes: 20 additions & 0 deletions src/config/htmlconfig.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub struct HtmlConfig {
theme: Option<PathBuf>,
google_analytics: Option<String>,
additional_css: Vec<PathBuf>,
additional_js: Vec<PathBuf>,
}

impl HtmlConfig {
Expand All @@ -28,6 +29,7 @@ impl HtmlConfig {
theme: None,
google_analytics: None,
additional_css: Vec::new(),
additional_js: Vec::new(),
}
}

Expand Down Expand Up @@ -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
}

Expand Down Expand Up @@ -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
}
}
1 change: 1 addition & 0 deletions src/config/tomlconfig.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ pub struct TomlHtmlConfig {
pub theme: Option<PathBuf>,
pub google_analytics: Option<String>,
pub additional_css: Option<Vec<PathBuf>>,
pub additional_js: Option<Vec<PathBuf>>,
}

/// Returns a TomlConfig from a TOML string
Expand Down
28 changes: 24 additions & 4 deletions src/renderer/html_handlebars/hbs_renderer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,14 +187,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)?;
Expand Down Expand Up @@ -240,6 +248,18 @@ fn make_data(book: &MDBook) -> Result<serde_json::Map<String, serde_json::Value>
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() {
Expand Down
6 changes: 6 additions & 0 deletions src/theme/index.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@
document.write(unescape("%3Cscript src='jquery.js'%3E%3C/script%3E"));
}
</script>

<!-- Custom JS script -->
{{#each additional_js}}
<script type="text/javascript" src="{{this}}"></script>
{{/each}}

</head>
<body class="light">
<!-- Set the theme before any content is loaded, prevents flash -->
Expand Down
16 changes: 15 additions & 1 deletion tests/tomlconfig.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")]);
}
}

// 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")]);
}