Made sure the dummy book can build

This commit is contained in:
Michael Bryan 2017-11-18 22:07:08 +08:00
parent 8b21da9950
commit 21498631b3
No known key found for this signature in database
GPG Key ID: E9C602B0D9A998DC
7 changed files with 57 additions and 64 deletions

View File

@ -1,3 +1,4 @@
[book]
title = "mdBook Documentation"
description = "Create book from markdown files. Like Gitbook but implemented in Rust"
author = "Mathieu David"

View File

@ -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

View File

@ -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<P: AsRef<Path>>(src_dir: P) -> Result<Book> {
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<P: AsRef<Path>>(summary: &Summary, src_dir: P) -> Result<
fn load_summary_item<P: AsRef<Path>>(item: &SummaryItem, src_dir: P) -> Result<BookItem> {
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<P: AsRef<Path>>(link: &Link, src_dir: P) -> Result<Chapter> {
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::<Result<Vec<_>>>()?;
let sub_items = link.nested_items.iter()
.map(|i| load_summary_item(i, src_dir))
.collect::<Result<Vec<_>>>()?;
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<String> = got.into_iter()
.filter_map(|i| match *i {
BookItem::Chapter(ref ch) => Some(ch.name.clone()),
_ => None,
})
.collect();
let chapter_names: Vec<String> = 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"),

View File

@ -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<BookItem>` 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<P: AsRef<Path>>(&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(

View File

@ -370,8 +370,9 @@ impl<'a> SummaryParser<'a> {
}
}
},
Event::End(Tag::Item) => { /* Ignore */ },
other => {
trace!("[*] skipping unexpected token: {:?}", other);
trace!("[*] ignoring token: {:?}", other);
},
}

View File

@ -4,7 +4,6 @@
- [First Chapter](./first/index.md)
- [Nested Chapter](./first/nested.md)
---
- [Second Chapter](./second.md)
[Conclusion](./conclusion.md)

View File

@ -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);