diff --git a/book-example/book.toml b/book-example/book.toml index 4dbc659c..e730b43e 100644 --- a/book-example/book.toml +++ b/book-example/book.toml @@ -1,6 +1,7 @@ +[book] title = "mdBook Documentation" description = "Create book from markdown files. Like Gitbook but implemented in Rust" author = "Mathieu David" [output.html] -mathjax-support = true \ No newline at end of file +mathjax-support = true diff --git a/src/bin/init.rs b/src/bin/init.rs index cbc08291..3a14d9c0 100644 --- a/src/bin/init.rs +++ b/src/bin/init.rs @@ -3,7 +3,6 @@ use std::io::Write; use clap::{App, ArgMatches, SubCommand}; use mdbook::MDBook; use mdbook::errors::Result; -use mdbook::config::Config; use get_book_dir; // Create clap subcommand arguments diff --git a/src/book/book.rs b/src/book/book.rs index 0824bd06..8ec2e5ca 100644 --- a/src/book/book.rs +++ b/src/book/book.rs @@ -2,7 +2,7 @@ use std::fmt::{self, Display, Formatter}; use std::path::{Path, PathBuf}; use std::collections::VecDeque; use std::fs::File; -use std::io::{Read, Write}; +use std::io::Read; use super::summary::{parse_summary, Link, SectionNumber, Summary, SummaryItem}; use errors::*; @@ -14,9 +14,8 @@ pub fn load_book>(src_dir: P) -> Result { let summary_md = src_dir.join("SUMMARY.md"); let mut summary_content = String::new(); - File::open(summary_md) - .chain_err(|| "Couldn't open SUMMARY.md")? - .read_to_string(&mut summary_content)?; + File::open(summary_md).chain_err(|| "Couldn't open SUMMARY.md")? + .read_to_string(&mut summary_content)?; let summary = parse_summary(&summary_content).chain_err(|| "Summary parsing failed")?; @@ -111,10 +110,7 @@ fn load_book_from_disk>(summary: &Summary, src_dir: P) -> Result< fn load_summary_item>(item: &SummaryItem, src_dir: P) -> Result { match *item { SummaryItem::Separator => Ok(BookItem::Separator), - SummaryItem::Link(ref link) => { - let file = src_dir.as_ref().join(&link.location); - load_chapter(link, src_dir).map(|c| BookItem::Chapter(c)) - }, + SummaryItem::Link(ref link) => load_chapter(link, src_dir).map(|c| BookItem::Chapter(c)), } } @@ -128,22 +124,22 @@ fn load_chapter>(link: &Link, src_dir: P) -> Result { src_dir.join(&link.location) }; - let mut f = File::open(&location).chain_err(|| format!("Chapter file not found, {}", link.location.display()))?; + let mut f = File::open(&location).chain_err(|| { + format!("Chapter file not found, {}", link.location.display()) + })?; let mut content = String::new(); f.read_to_string(&mut content)?; - let stripped = location - .strip_prefix(&src_dir) - .expect("Chapters are always inside a book"); + let stripped = location.strip_prefix(&src_dir) + .expect("Chapters are always inside a book"); let mut ch = Chapter::new(&link.name, content, stripped); ch.number = link.number.clone(); - let sub_items = link.nested_items - .iter() - .map(|i| load_summary_item(i, src_dir)) - .collect::>>()?; + let sub_items = link.nested_items.iter() + .map(|i| load_summary_item(i, src_dir)) + .collect::>>()?; ch.sub_items = sub_items; @@ -195,14 +191,14 @@ mod tests { use super::*; use tempdir::TempDir; use std::io::Write; - use std::fs; const DUMMY_SRC: &'static str = " # Dummy Chapter this is some dummy text. -And here is some more text. +And here is some \ + more text. "; /// Create a dummy `Link` in a temporary directory. @@ -210,10 +206,9 @@ And here is some more text. let temp = TempDir::new("book").unwrap(); let chapter_path = temp.path().join("chapter_1.md"); - File::create(&chapter_path) - .unwrap() - .write(DUMMY_SRC.as_bytes()) - .unwrap(); + File::create(&chapter_path).unwrap() + .write(DUMMY_SRC.as_bytes()) + .unwrap(); let link = Link::new("Chapter 1", chapter_path); @@ -226,10 +221,9 @@ And here is some more text. let second_path = temp_dir.path().join("second.md"); - File::create(&second_path) - .unwrap() - .write_all("Hello World!".as_bytes()) - .unwrap(); + File::create(&second_path).unwrap() + .write_all("Hello World!".as_bytes()) + .unwrap(); let mut second = Link::new("Nested Chapter 1", &second_path); @@ -339,9 +333,17 @@ And here is some more text. number: None, path: PathBuf::from("Chapter_1/index.md"), sub_items: vec![ - BookItem::Chapter(Chapter::new("Hello World", String::new(), "Chapter_1/hello.md")), + BookItem::Chapter(Chapter::new( + "Hello World", + String::new(), + "Chapter_1/hello.md", + )), BookItem::Separator, - BookItem::Chapter(Chapter::new("Goodbye World", String::new(), "Chapter_1/goodbye.md")), + BookItem::Chapter(Chapter::new( + "Goodbye World", + String::new(), + "Chapter_1/goodbye.md", + )), ], }), BookItem::Separator, @@ -354,12 +356,11 @@ And here is some more text. assert_eq!(got.len(), 5); // checking the chapter names are in the order should be sufficient here... - let chapter_names: Vec = got.into_iter() - .filter_map(|i| match *i { - BookItem::Chapter(ref ch) => Some(ch.name.clone()), - _ => None, - }) - .collect(); + let chapter_names: Vec = got.into_iter().filter_map(|i| match *i { + BookItem::Chapter(ref ch) => Some(ch.name.clone()), + _ => None, + }) + .collect(); let should_be: Vec<_> = vec![ String::from("Chapter 1"), String::from("Hello World"), diff --git a/src/book/mod.rs b/src/book/mod.rs index 0cec49cc..b42a66cd 100644 --- a/src/book/mod.rs +++ b/src/book/mod.rs @@ -6,12 +6,11 @@ pub use self::book::{Book, BookItem, BookItems, Chapter}; pub use self::init::BookBuilder; use std::path::{Path, PathBuf}; -use std::fs::{self, File}; use std::io::Write; use std::process::Command; use tempdir::TempDir; -use {theme, utils}; +use utils; use renderer::{HtmlHandlebars, Renderer}; use preprocess; use errors::*; @@ -104,17 +103,14 @@ impl MDBook { BookBuilder::new(book_root) } - /// The `build()` method is the one where everything happens. - /// First it parses `SUMMARY.md` to construct the book's structure - /// in the form of a `Vec` and then calls `render()` - /// method of the current renderer. - /// - /// It is the renderer who generates all the output files. + /// Tells the renderer to build our book and put it in the build directory. pub fn build(&mut self) -> Result<()> { debug!("[fn]: build"); - // Clean output directory - utils::fs::remove_dir_content(&self.get_destination())?; + let dest = self.get_destination(); + if dest.exists() { + utils::fs::remove_dir_content(&dest).chain_err(|| "Unable to clear output directory")?; + } self.renderer.render(self) } @@ -122,9 +118,8 @@ impl MDBook { pub fn write_file>(&self, filename: P, content: &[u8]) -> Result<()> { let path = self.get_destination().join(filename); - utils::fs::create_file(&path)? - .write_all(content) - .map_err(|e| e.into()) + utils::fs::create_file(&path)?.write_all(content) + .map_err(|e| e.into()) } /// Parses the `book.json` file (if it exists) to extract @@ -175,18 +170,16 @@ impl MDBook { } pub fn test(&mut self, library_paths: Vec<&str>) -> Result<()> { - 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 { if !ch.path.as_os_str().is_empty() { let path = self.get_source().join(&ch.path); - let base = path.parent() - .ok_or_else(|| String::from("Invalid bookitem path!"))?; + let base = path.parent().ok_or_else(|| String::from("Invalid bookitem path!"))?; let content = utils::fs::file_to_string(&path)?; // Parse and expand links let content = preprocess::links::replace_all(&content, base)?; @@ -197,11 +190,10 @@ impl MDBook { let mut tmpf = utils::fs::create_file(&path)?; tmpf.write_all(content.as_bytes())?; - let output = Command::new("rustdoc") - .arg(&path) - .arg("--test") - .args(&library_args) - .output()?; + let output = Command::new("rustdoc").arg(&path) + .arg("--test") + .args(&library_args) + .output()?; if !output.status.success() { bail!(ErrorKind::Subprocess( diff --git a/src/book/summary.rs b/src/book/summary.rs index 46f477e5..8c1d5b05 100644 --- a/src/book/summary.rs +++ b/src/book/summary.rs @@ -370,8 +370,9 @@ impl<'a> SummaryParser<'a> { } } }, + Event::End(Tag::Item) => { /* Ignore */ }, other => { - trace!("[*] skipping unexpected token: {:?}", other); + trace!("[*] ignoring token: {:?}", other); }, } diff --git a/tests/dummy_book/src/SUMMARY.md b/tests/dummy_book/src/SUMMARY.md index 24471f53..f5f3a4c4 100644 --- a/tests/dummy_book/src/SUMMARY.md +++ b/tests/dummy_book/src/SUMMARY.md @@ -4,7 +4,6 @@ - [First Chapter](./first/index.md) - [Nested Chapter](./first/nested.md) ---- - [Second Chapter](./second.md) [Conclusion](./conclusion.md) diff --git a/tests/init.rs b/tests/init.rs index 655f292a..56faf6bb 100644 --- a/tests/init.rs +++ b/tests/init.rs @@ -18,7 +18,7 @@ fn base_mdbook_init_should_create_default_content() { assert!(!temp.path().join(file).exists()); } - let md = MDBook::init(temp.path()).build().unwrap(); + MDBook::init(temp.path()).build().unwrap(); for file in &created_files { let target = temp.path().join(file);