Removed all references to old the configuration from the html renderer

This commit is contained in:
Michael Bryan 2017-09-30 21:36:03 +08:00
parent c056b5cbd0
commit b74c2c18ef
No known key found for this signature in database
GPG Key ID: E9C602B0D9A998DC
3 changed files with 63 additions and 45 deletions

View File

@ -17,12 +17,12 @@ use config::Config;
pub struct MDBook { pub struct MDBook {
pub root: PathBuf, pub root: PathBuf,
config: Config, pub config: Config,
pub content: Vec<BookItem>, pub content: Vec<BookItem>,
renderer: Box<Renderer>, renderer: Box<Renderer>,
livereload: Option<String>, pub livereload: Option<String>,
/// Should `mdbook build` create files referenced from SUMMARY.md if they /// Should `mdbook build` create files referenced from SUMMARY.md if they
/// don't exist /// don't exist
@ -146,7 +146,7 @@ impl MDBook {
let src = self.get_source(); let src = self.get_source();
if !src.exists() { if !src.exists() {
debug!("[*]: {} does not exist, trying to create directory", src.display()); debug!("[*]: {} does not exist, trying to create directory", src.display());
fs::create_dir_all(src)?; fs::create_dir_all(&src)?;
} }
let summary = src.join("SUMMARY.md"); let summary = src.join("SUMMARY.md");
@ -383,20 +383,18 @@ impl MDBook {
Ok(()) Ok(())
} }
fn get_destination(&self) -> PathBuf { pub fn get_destination(&self) -> PathBuf {
self.root.join(&self.config.book.build_dir) self.root.join(&self.config.book.build_dir)
} }
fn get_source(&self) -> PathBuf { pub fn get_source(&self) -> PathBuf {
self.root.join(&self.config.book.src) self.root.join(&self.config.book.src)
} }
fn theme_dir(&self) -> PathBuf { pub fn theme_dir(&self) -> PathBuf {
let relative_to_book = match self.config.html_config().and_then(|h| h.theme) { match self.config.html_config().and_then(|h| h.theme) {
Some(ref d) => d, Some(d) => self.root.join(d),
None => Path::new("theme"), None => self.root.join("theme"),
}; }
self.root.join(relative_to_book)
} }
} }

View File

@ -137,7 +137,10 @@ pub struct HtmlConfig {
} }
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
pub struct Playpen; pub struct Playpen {
pub editor: PathBuf,
pub editable: bool,
}
#[cfg(test)] #[cfg(test)]

View File

@ -3,9 +3,9 @@ use preprocess;
use renderer::Renderer; use renderer::Renderer;
use book::MDBook; use book::MDBook;
use book::bookitem::{BookItem, Chapter}; use book::bookitem::{BookItem, Chapter};
use config::PlaypenConfig; use config::{Config, Playpen, HtmlConfig};
use {theme, utils}; use {utils, theme};
use theme::{playpen_editor, Theme}; use theme::{Theme, playpen_editor};
use errors::*; use errors::*;
use regex::{Captures, Regex}; use regex::{Captures, Regex};
@ -45,7 +45,7 @@ impl HtmlHandlebars {
// Parse and expand links // Parse and expand links
let content = preprocess::links::replace_all(&content, base)?; let content = preprocess::links::replace_all(&content, base)?;
let content = utils::render_markdown(&content, ctx.book.get_curly_quotes()); let content = utils::render_markdown(&content, ctx.html_config.curly_quotes);
print_content.push_str(&content); print_content.push_str(&content);
// Update the context with data for this file // Update the context with data for this file
@ -138,7 +138,7 @@ impl HtmlHandlebars {
rendered rendered
} }
fn copy_static_files(&self, book: &MDBook, theme: &Theme) -> Result<()> { fn copy_static_files(&self, book: &MDBook, theme: &Theme, html_config: &HtmlConfig) -> Result<()> {
book.write_file("book.js", &theme.js)?; book.write_file("book.js", &theme.js)?;
book.write_file("book.css", &theme.css)?; book.write_file("book.css", &theme.css)?;
book.write_file("favicon.png", &theme.favicon)?; book.write_file("favicon.png", &theme.favicon)?;
@ -163,12 +163,12 @@ impl HtmlHandlebars {
book.write_file("_FontAwesome/fonts/FontAwesome.ttf", book.write_file("_FontAwesome/fonts/FontAwesome.ttf",
theme::FONT_AWESOME_TTF)?; theme::FONT_AWESOME_TTF)?;
let playpen_config = book.get_html_config().get_playpen_config(); let playpen_config = &html_config.playpen;
// Ace is a very large dependency, so only load it when requested // Ace is a very large dependency, so only load it when requested
if playpen_config.is_editable() { if playpen_config.editable {
// Load the editor // Load the editor
let editor = playpen_editor::PlaypenEditor::new(playpen_config.get_editor()); let editor = playpen_editor::PlaypenEditor::new(&playpen_config.editor);
book.write_file("editor.js", &editor.js)?; book.write_file("editor.js", &editor.js)?;
book.write_file("ace.js", &editor.ace_js)?; book.write_file("ace.js", &editor.ace_js)?;
book.write_file("mode-rust.js", &editor.mode_rust_js)?; book.write_file("mode-rust.js", &editor.mode_rust_js)?;
@ -186,7 +186,7 @@ impl HtmlHandlebars {
let mut f = File::open(custom_file)?; let mut f = File::open(custom_file)?;
f.read_to_end(&mut data)?; f.read_to_end(&mut data)?;
let name = match custom_file.strip_prefix(book.get_root()) { let name = match custom_file.strip_prefix(&book.root) {
Ok(p) => p.to_str().expect("Could not convert to str"), Ok(p) => p.to_str().expect("Could not convert to str"),
Err(_) => { Err(_) => {
custom_file.file_name() custom_file.file_name()
@ -224,9 +224,11 @@ impl HtmlHandlebars {
/// Copy across any additional CSS and JavaScript files which the book /// Copy across any additional CSS and JavaScript files which the book
/// has been configured to use. /// has been configured to use.
fn copy_additional_css_and_js(&self, book: &MDBook) -> Result<()> { fn copy_additional_css_and_js(&self, book: &MDBook) -> Result<()> {
let custom_files = book.get_additional_css() let html = book.config.html_config().unwrap_or_default();
let custom_files = html.additional_css
.iter() .iter()
.chain(book.get_additional_js().iter()); .chain(html.additional_js.iter());
for custom_file in custom_files { for custom_file in custom_files {
self.write_custom_file(custom_file, book)?; self.write_custom_file(custom_file, book)?;
@ -239,10 +241,17 @@ impl HtmlHandlebars {
impl Renderer for HtmlHandlebars { impl Renderer for HtmlHandlebars {
fn render(&self, book: &MDBook) -> Result<()> { fn render(&self, book: &MDBook) -> Result<()> {
let html_config = book.config.html_config().unwrap_or_default();
debug!("[fn]: render"); debug!("[fn]: render");
let mut handlebars = Handlebars::new(); let mut handlebars = Handlebars::new();
let theme = theme::Theme::new(book.get_theme_path()); let theme_dir = match html_config.theme {
Some(ref theme) => theme,
None => Path::new("theme"),
};
let theme = theme::Theme::new(theme_dir);
debug!("[*]: Register handlebars template"); debug!("[*]: Register handlebars template");
handlebars.register_template_string("index", String::from_utf8(theme.index.clone())?)?; handlebars.register_template_string("index", String::from_utf8(theme.index.clone())?)?;
@ -250,12 +259,13 @@ impl Renderer for HtmlHandlebars {
debug!("[*]: Register handlebars helpers"); debug!("[*]: Register handlebars helpers");
self.register_hbs_helpers(&mut handlebars); self.register_hbs_helpers(&mut handlebars);
let mut data = make_data(book)?; let mut data = make_data(book, &book.config)?;
// Print version // Print version
let mut print_content = String::new(); let mut print_content = String::new();
let destination = book.get_destination(); // TODO: The Renderer trait should really pass in where it wants us to build to...
let destination = book.root.join(&book.config.book.build_dir);
debug!("[*]: Check if destination directory exists"); debug!("[*]: Check if destination directory exists");
if fs::create_dir_all(&destination).is_err() { if fs::create_dir_all(&destination).is_err() {
@ -269,13 +279,16 @@ impl Renderer for HtmlHandlebars {
destination: destination.to_path_buf(), destination: destination.to_path_buf(),
data: data.clone(), data: data.clone(),
is_index: i == 0, is_index: i == 0,
html_config: html_config.clone(),
}; };
self.render_item(item, ctx, &mut print_content)?; self.render_item(item, ctx, &mut print_content)?;
} }
// Print version // Print version
self.configure_print_version(&mut data, &print_content); self.configure_print_version(&mut data, &print_content);
data.insert("title".to_owned(), json!(book.get_title())); if let Some(ref title) = book.config.book.title {
data.insert("title".to_owned(), json!(title));
}
// Render the handlebars template with the data // Render the handlebars template with the data
debug!("[*]: Render template"); debug!("[*]: Render template");
@ -292,42 +305,44 @@ impl Renderer for HtmlHandlebars {
// Copy static files (js, css, images, ...) // Copy static files (js, css, images, ...)
debug!("[*] Copy static files"); debug!("[*] Copy static files");
self.copy_static_files(book, &theme)?; self.copy_static_files(book, &theme, &html_config)?;
self.copy_additional_css_and_js(book)?; self.copy_additional_css_and_js(book)?;
// Copy all remaining files // Copy all remaining files
utils::fs::copy_files_except_ext(book.get_source(), destination, true, &["md"])?; let src = book.get_source();
utils::fs::copy_files_except_ext(&src, &destination, true, &["md"])?;
Ok(()) Ok(())
} }
} }
fn make_data(book: &MDBook) -> Result<serde_json::Map<String, serde_json::Value>> { fn make_data(book: &MDBook, config: &Config) -> Result<serde_json::Map<String, serde_json::Value>> {
debug!("[fn]: make_data"); debug!("[fn]: make_data");
let html = config.html_config().unwrap_or_default();
let mut data = serde_json::Map::new(); let mut data = serde_json::Map::new();
data.insert("language".to_owned(), json!("en")); data.insert("language".to_owned(), json!("en"));
data.insert("book_title".to_owned(), json!(book.get_title())); data.insert("book_title".to_owned(), json!(config.book.title.clone().unwrap_or_default()));
data.insert("description".to_owned(), json!(book.get_description())); data.insert("description".to_owned(), json!(config.book.description.clone().unwrap_or_default()));
data.insert("favicon".to_owned(), json!("favicon.png")); data.insert("favicon".to_owned(), json!("favicon.png"));
if let Some(livereload) = book.get_livereload() { if let Some(ref livereload) = book.livereload {
data.insert("livereload".to_owned(), json!(livereload)); data.insert("livereload".to_owned(), json!(livereload));
} }
// Add google analytics tag // Add google analytics tag
if let Some(ref ga) = book.get_google_analytics_id() { if let Some(ref ga) = book.config.html_config().and_then(|html| html.google_analytics) {
data.insert("google_analytics".to_owned(), json!(ga)); data.insert("google_analytics".to_owned(), json!(ga));
} }
if book.get_mathjax_support() { if html.mathjax_support {
data.insert("mathjax_support".to_owned(), json!(true)); data.insert("mathjax_support".to_owned(), json!(true));
} }
// Add check to see if there is an additional style // Add check to see if there is an additional style
if book.has_additional_css() { if !html.additional_css.is_empty() {
let mut css = Vec::new(); let mut css = Vec::new();
for style in book.get_additional_css() { for style in &html.additional_css {
match style.strip_prefix(book.get_root()) { match style.strip_prefix(&book.root) {
Ok(p) => css.push(p.to_str().expect("Could not convert to str")), Ok(p) => css.push(p.to_str().expect("Could not convert to str")),
Err(_) => { Err(_) => {
css.push(style.file_name() css.push(style.file_name()
@ -341,10 +356,10 @@ fn make_data(book: &MDBook) -> Result<serde_json::Map<String, serde_json::Value>
} }
// Add check to see if there is an additional script // Add check to see if there is an additional script
if book.has_additional_js() { if !html.additional_js.is_empty() {
let mut js = Vec::new(); let mut js = Vec::new();
for script in book.get_additional_js() { for script in &html.additional_js {
match script.strip_prefix(book.get_root()) { match script.strip_prefix(&book.root) {
Ok(p) => js.push(p.to_str().expect("Could not convert to str")), Ok(p) => js.push(p.to_str().expect("Could not convert to str")),
Err(_) => { Err(_) => {
js.push(script.file_name() js.push(script.file_name()
@ -357,7 +372,7 @@ fn make_data(book: &MDBook) -> Result<serde_json::Map<String, serde_json::Value>
data.insert("additional_js".to_owned(), json!(js)); data.insert("additional_js".to_owned(), json!(js));
} }
if book.get_html_config().get_playpen_config().is_editable() { if html.playpen.editable {
data.insert("playpens_editable".to_owned(), json!(true)); data.insert("playpens_editable".to_owned(), json!(true));
data.insert("editor_js".to_owned(), json!("editor.js")); data.insert("editor_js".to_owned(), json!("editor.js"));
data.insert("ace_js".to_owned(), json!("ace.js")); data.insert("ace_js".to_owned(), json!("ace.js"));
@ -519,8 +534,9 @@ fn fix_code_blocks(html: &str) -> String {
.into_owned() .into_owned()
} }
fn add_playpen_pre(html: &str, playpen_config: &PlaypenConfig) -> String { fn add_playpen_pre(html: &str, playpen_config: &Playpen) -> String {
let regex = Regex::new(r##"((?s)<code[^>]?class="([^"]+)".*?>(.*?)</code>)"##).unwrap(); let regex = Regex::new(r##"((?s)<code[^>]?class="([^"]+)".*?>(.*?)</code>)"##).unwrap();
<<<<<<< HEAD
regex.replace_all(html, |caps: &Captures| { regex.replace_all(html, |caps: &Captures| {
let text = &caps[1]; let text = &caps[1];
let classes = &caps[2]; let classes = &caps[2];
@ -530,7 +546,7 @@ fn add_playpen_pre(html: &str, playpen_config: &PlaypenConfig) -> String {
classes.contains("mdbook-runnable") classes.contains("mdbook-runnable")
{ {
// wrap the contents in an external pre block // wrap the contents in an external pre block
if playpen_config.is_editable() && classes.contains("editable") || if playpen_config.editable && classes.contains("editable") ||
text.contains("fn main") || text.contains("quick_main!") text.contains("fn main") || text.contains("quick_main!")
{ {
format!("<pre class=\"playpen\">{}</pre>", text) format!("<pre class=\"playpen\">{}</pre>", text)
@ -583,6 +599,7 @@ struct RenderItemContext<'a> {
destination: PathBuf, destination: PathBuf,
data: serde_json::Map<String, serde_json::Value>, data: serde_json::Map<String, serde_json::Value>,
is_index: bool, is_index: bool,
html_config: HtmlConfig,
} }
pub fn normalize_path(path: &str) -> String { pub fn normalize_path(path: &str) -> String {