diff --git a/src/book/mod.rs b/src/book/mod.rs index 82699a7a..920c5cda 100644 --- a/src/book/mod.rs +++ b/src/book/mod.rs @@ -13,13 +13,11 @@ use renderer::{HtmlHandlebars, Renderer}; use preprocess; use errors::*; -use config::BookConfig; -use config::tomlconfig::TomlConfig; -use config::htmlconfig::HtmlConfig; -use config::jsonconfig::JsonConfig; +use config::Config; pub struct MDBook { - config: BookConfig, + pub root: PathBuf, + config: Config, pub content: Vec, renderer: Box, @@ -66,7 +64,8 @@ impl MDBook { } MDBook { - config: BookConfig::new(root), + root: root, + config: Config::default(), content: vec![], renderer: Box::new(HtmlHandlebars::new()), @@ -131,26 +130,26 @@ impl MDBook { pub fn init(&mut self) -> Result<()> { debug!("[fn]: init"); - if !self.config.get_root().exists() { - fs::create_dir_all(&self.config.get_root()).unwrap(); - info!("{:?} created", &self.config.get_root()); + if !self.root.exists() { + fs::create_dir_all(&self.root).unwrap(); + info!("{:?} created", self.root.display()); } { - if !self.get_destination().exists() { - debug!("[*]: {:?} does not exist, trying to create directory", - self.get_destination()); - fs::create_dir_all(self.get_destination())?; + let dest = &self.config.book.build_dir; + if !dest.exists() { + debug!("[*]: {} does not exist, trying to create directory", dest.display()); + fs::create_dir_all(dest)?; } - if !self.config.get_source().exists() { - debug!("[*]: {:?} does not exist, trying to create directory", - self.config.get_source()); - fs::create_dir_all(self.config.get_source())?; + let src = self.get_source(); + if !src.exists() { + debug!("[*]: {} does not exist, trying to create directory", src.display()); + fs::create_dir_all(src)?; } - let summary = self.config.get_source().join("SUMMARY.md"); + let summary = src.join("SUMMARY.md"); if !summary.exists() { // Summary does not exist, create it @@ -177,12 +176,13 @@ impl MDBook { BookItem::Chapter(_, ref ch) | BookItem::Affix(ref ch) => ch, }; if !ch.path.as_os_str().is_empty() { - let path = self.config.get_source().join(&ch.path); + let path = self.config.book.src.join(&ch.path); if !path.exists() { if !self.create_missing { - return Err(format!("'{}' referenced from SUMMARY.md does not exist.", - path.to_string_lossy()).into()); + return Err( + format!("'{}' referenced from SUMMARY.md does not exist.", path.to_string_lossy()).into(), + ); } debug!("[*]: {:?} does not exist, trying to create file", path); ::std::fs::create_dir_all(path.parent().unwrap())?; @@ -201,22 +201,22 @@ impl MDBook { pub fn create_gitignore(&self) { let gitignore = self.get_gitignore(); - let destination = self.config.get_html_config().get_destination(); + let destination = self.get_destination(); - // Check that the gitignore does not extist and - // that the destination path begins with the root path - // We assume tha if it does begin with the root path it is contained within. This assumption - // will not hold true for paths containing double dots to go back up - // e.g. `root/../destination` - if !gitignore.exists() && destination.starts_with(self.config.get_root()) { - let relative = destination.strip_prefix(self.config.get_root()) - .expect("Could not strip the root prefix, path is not \ - relative to root") - .to_str() - .expect("Could not convert to &str"); + // Check that the gitignore does not extist and that the destination path + // begins with the root path + // We assume tha if it does begin with the root path it is contained within. + // This assumption + // will not hold true for paths containing double dots to go back up e.g. + // `root/../destination` + if !gitignore.exists() && destination.starts_with(&self.root) { + let relative = destination + .strip_prefix(&self.root) + .expect("Could not strip the root prefix, path is not relative to root") + .to_str() + .expect("Could not convert to &str"); - debug!("[*]: {:?} does not exist, trying to create .gitignore", - gitignore); + debug!("[*]: {:?} does not exist, trying to create .gitignore", gitignore); let mut f = File::create(&gitignore).expect("Could not create file."); @@ -238,20 +238,21 @@ impl MDBook { self.init()?; // Clean output directory - utils::fs::remove_dir_content(self.config.get_html_config().get_destination())?; + utils::fs::remove_dir_content(&self.config.book.build_dir)?; self.renderer.render(self) } pub fn get_gitignore(&self) -> PathBuf { - self.config.get_root().join(".gitignore") + self.root.join(".gitignore") } pub fn copy_theme(&self) -> Result<()> { debug!("[fn]: copy_theme"); - let themedir = self.config.get_html_config().get_theme(); + let themedir = self.theme_dir(); + if !themedir.exists() { debug!("[*]: {:?} does not exist, trying to create directory", themedir); @@ -259,27 +260,27 @@ impl MDBook { } // index.hbs - let mut index = File::create(&themedir.join("index.hbs"))?; + let mut index = File::create(themedir.join("index.hbs"))?; index.write_all(theme::INDEX)?; // book.css - let mut css = File::create(&themedir.join("book.css"))?; + let mut css = File::create(themedir.join("book.css"))?; css.write_all(theme::CSS)?; // favicon.png - let mut favicon = File::create(&themedir.join("favicon.png"))?; + let mut favicon = File::create(themedir.join("favicon.png"))?; favicon.write_all(theme::FAVICON)?; // book.js - let mut js = File::create(&themedir.join("book.js"))?; + let mut js = File::create(themedir.join("book.js"))?; js.write_all(theme::JS)?; // highlight.css - let mut highlight_css = File::create(&themedir.join("highlight.css"))?; + let mut highlight_css = File::create(themedir.join("highlight.css"))?; highlight_css.write_all(theme::HIGHLIGHT_CSS)?; // highlight.js - let mut highlight_js = File::create(&themedir.join("highlight.js"))?; + let mut highlight_js = File::create(themedir.join("highlight.js"))?; highlight_js.write_all(theme::HIGHLIGHT_JS)?; Ok(()) @@ -298,25 +299,9 @@ impl MDBook { /// The root directory is the one specified when creating a new `MDBook` pub fn read_config(mut self) -> Result { - let toml = self.get_root().join("book.toml"); - let json = self.get_root().join("book.json"); - - if toml.exists() { - let mut file = File::open(toml)?; - let mut content = String::new(); - file.read_to_string(&mut content)?; - - let parsed_config = TomlConfig::from_toml(&content)?; - self.config.fill_from_tomlconfig(parsed_config); - } else if json.exists() { - warn!("The JSON configuration file is deprecated, please use the TOML configuration."); - let mut file = File::open(json)?; - let mut content = String::new(); - file.read_to_string(&mut content)?; - - let parsed_config = JsonConfig::from_json(&content)?; - self.config.fill_from_jsonconfig(parsed_config); - } + let config_path = self.root.join("book.toml"); + debug!("[*] Loading the config from {}", config_path.display()); + self.config = Config::from_disk(&config_path)?; Ok(self) } @@ -353,10 +338,11 @@ impl MDBook { pub fn test(&mut self, library_paths: Vec<&str>) -> Result<()> { // read in the chapters self.parse_summary().chain_err(|| "Couldn't parse summary")?; - let library_args: Vec<&str> = (0..library_paths.len()).map(|_| "-L") - .zip(library_paths.into_iter()) - .flat_map(|x| vec![x.0, x.1]) - .collect(); + let library_args: Vec<&str> = (0..library_paths.len()) + .map(|_| "-L") + .zip(library_paths.into_iter()) + .flat_map(|x| vec![x.0, x.1]) + .collect(); let temp_dir = TempDir::new("mdbook")?; for item in self.iter() { if let BookItem::Chapter(_, ref ch) = *item { @@ -369,7 +355,7 @@ impl MDBook { let content = preprocess::links::replace_all(&content, base)?; println!("[*]: Testing file: {:?}", path); - //write preprocessed file to tempdir + // write preprocessed file to tempdir let path = temp_dir.path().join(&ch.path); let mut tmpf = utils::fs::create_file(&path)?; tmpf.write_all(content.as_bytes())?; @@ -389,127 +375,28 @@ impl MDBook { Ok(()) } - pub fn get_root(&self) -> &Path { - self.config.get_root() - } - - - pub fn with_destination>(mut self, destination: T) -> Self { - let root = self.config.get_root().to_owned(); - self.config - .get_mut_html_config() - .set_destination(&root, &destination.into()); - self - } - - - pub fn get_destination(&self) -> &Path { - self.config.get_html_config().get_destination() - } - - pub fn with_source>(mut self, source: T) -> Self { - self.config.set_source(source); - self - } - - pub fn get_source(&self) -> &Path { - self.config.get_source() - } - - pub fn with_title>(mut self, title: T) -> Self { - self.config.set_title(title); - self - } - - pub fn get_title(&self) -> &str { - self.config.get_title() - } - - pub fn with_description>(mut self, description: T) -> Self { - self.config.set_description(description); - self - } - - pub fn get_description(&self) -> &str { - self.config.get_description() - } - - pub fn set_livereload(&mut self, livereload: String) -> &mut Self { - self.livereload = Some(livereload); - self - } - - pub fn unset_livereload(&mut self) -> &Self { - self.livereload = None; - self - } - - pub fn get_livereload(&self) -> Option<&String> { - self.livereload.as_ref() - } - - pub fn with_theme_path>(mut self, theme_path: T) -> Self { - let root = self.config.get_root().to_owned(); - self.config - .get_mut_html_config() - .set_theme(&root, &theme_path.into()); - self - } - - pub fn get_theme_path(&self) -> &Path { - self.config.get_html_config().get_theme() - } - - pub fn with_curly_quotes(mut self, curly_quotes: bool) -> Self { - self.config - .get_mut_html_config() - .set_curly_quotes(curly_quotes); - self - } - - pub fn get_curly_quotes(&self) -> bool { - self.config.get_html_config().get_curly_quotes() - } - - pub fn with_mathjax_support(mut self, mathjax_support: bool) -> Self { - self.config - .get_mut_html_config() - .set_mathjax_support(mathjax_support); - self - } - - pub fn get_mathjax_support(&self) -> bool { - self.config.get_html_config().get_mathjax_support() - } - - pub fn get_google_analytics_id(&self) -> Option { - self.config.get_html_config().get_google_analytics_id() - } - - pub fn has_additional_js(&self) -> bool { - self.config.get_html_config().has_additional_js() - } - - pub fn get_additional_js(&self) -> &[PathBuf] { - self.config.get_html_config().get_additional_js() - } - - pub fn has_additional_css(&self) -> bool { - self.config.get_html_config().has_additional_css() - } - - pub fn get_additional_css(&self) -> &[PathBuf] { - self.config.get_html_config().get_additional_css() - } - - pub fn get_html_config(&self) -> &HtmlConfig { - self.config.get_html_config() - } - // Construct book fn parse_summary(&mut self) -> Result<()> { // When append becomes stable, use self.content.append() ... - self.content = parse::construct_bookitems(&self.get_source().join("SUMMARY.md"))?; + let summary = self.get_source().join("SUMMARY.md"); + self.content = parse::construct_bookitems(&summary)?; Ok(()) } + + fn get_destination(&self) -> PathBuf { + self.root.join(&self.config.book.build_dir) + } + + fn get_source(&self) -> PathBuf { + self.root.join(&self.config.book.src) + } + + fn theme_dir(&self) -> PathBuf { + let relative_to_book = match self.config.html_config().and_then(|h| h.theme) { + Some(ref d) => d, + None => Path::new("theme"), + }; + + self.root.join(relative_to_book) + } }