Everything compiles and all the tests pass.

This commit is contained in:
Michael Bryan 2017-08-21 11:34:34 +08:00
parent d39352aa45
commit 3a51e4a27c
5 changed files with 66 additions and 96 deletions

View File

@ -1,3 +1,4 @@
use std::fmt::{self, Display, Formatter};
use std::path::{Path, PathBuf};
use std::collections::VecDeque;
use std::fs::File;
@ -130,7 +131,6 @@ fn load_chapter<P: AsRef<Path>>(link: &Link, src_dir: P) -> Result<Chapter> {
f.read_to_string(&mut content)?;
let stripped = location.strip_prefix(&src_dir).expect("Chapters are always inside a book");
println!("{} {} => {}", src_dir.display(), location.display(), stripped.display());
let mut ch = Chapter::new(&link.name, content, stripped);
ch.number = link.number.clone();
@ -174,6 +174,16 @@ impl<'a> Iterator for BookItems<'a> {
}
}
impl Display for Chapter {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
if let Some(ref section_number) = self.number {
write!(f, "{} ", section_number)?;
}
write!(f, "{}", self.name)
}
}
#[cfg(test)]
mod tests {

View File

@ -85,17 +85,17 @@ impl MDBook {
/// ```no_run
/// # extern crate mdbook;
/// # use mdbook::MDBook;
/// # use mdbook::BookItem;
/// # use mdbook::book::book::BookItem;
/// # #[allow(unused_variables)]
/// # fn main() {
/// # let book = MDBook::new("mybook");
/// for item in book.iter() {
/// match item {
/// &BookItem::Chapter(ref section, ref chapter) => {},
/// &BookItem::Affix(ref chapter) => {},
/// &BookItem::Spacer => {},
/// match *item {
/// BookItem::Chapter(ref chapter) => println!("{}", chapter),
/// BookItem::Separator => {},
/// }
/// }
/// panic!();
///
/// // would print something like this:
/// // 1. Chapter 1
@ -131,68 +131,44 @@ impl MDBook {
debug!("[fn]: init");
if !self.config.get_root().exists() {
fs::create_dir_all(&self.config.get_root()).unwrap();
info!("{:?} created", &self.config.get_root());
}
{
let root = self.config.get_root();
let dest = self.get_destination();
let src = self.config.get_source();
if !self.get_destination().exists() {
debug!("[*]: {:?} does not exist, trying to create directory", self.get_destination());
fs::create_dir_all(self.get_destination())?;
}
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 summary = self.config.get_source().join("SUMMARY.md");
if !summary.exists() {
// Summary does not exist, create it
debug!("[*]: {:?} does not exist, trying to create SUMMARY.md", &summary);
let mut f = File::create(&summary)?;
debug!("[*]: Writing to SUMMARY.md");
writeln!(f, "# Summary")?;
writeln!(f, "")?;
writeln!(f, "- [Chapter 1](./chapter_1.md)")?;
}
}
// parse SUMMARY.md, and create the missing item related file
self.parse_summary()?;
debug!("[*]: constructing paths for missing files");
for item in self.iter() {
debug!("[*]: item: {:?}", item);
let ch = match *item {
BookItem::Separator => continue,
BookItem::Chapter(ref ch) => ch,
};
if !ch.path.as_os_str().is_empty() {
let path = self.config.get_source().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());
}
debug!("[*]: {:?} does not exist, trying to create file", path);
::std::fs::create_dir_all(path.parent().unwrap())?;
let mut f = File::create(path)?;
// debug!("[*]: Writing to {:?}", path);
writeln!(f, "# {}", ch.name)?;
let necessary_folders = &[root, dest, src];
for folder in necessary_folders {
if !folder.exists() {
fs::create_dir_all(folder)?;
debug!("{} created", folder.display());
}
}
let summary = src.join("SUMMARY.md");
if !summary.exists() {
debug!("[*]: Creating SUMMARY.md");
let mut f = File::create(&summary)?;
writeln!(f, "# Summary")?;
writeln!(f)?;
writeln!(f, "- [Chapter 1](./chapter_1.md)")?;
}
let ch_1 = src.join("chapter_1.md");
if !ch_1.exists() {
debug!("[*] Creating {}", ch_1.display());
let mut f = File::create(&ch_1)?;
writeln!(f, "# Chapter 1")?;
}
}
// parse SUMMARY.md and load the newly created files into memory
self.parse_summary().chain_err(|| "Couldn't parse the SUMMARY.md file")?;
debug!("[*]: init done");
Ok(())
}
@ -512,7 +488,9 @@ impl MDBook {
// Construct book
fn parse_summary(&mut self) -> Result<()> {
let book = load_book(self.get_source().join("SUMMARY.md"))?;
let src = self.config.get_source();
let book = load_book(&src)?;
self.content = Some(book);
Ok(())
}

View File

@ -264,6 +264,7 @@ impl<'a> SummaryParser<'a> {
fn step_start(&mut self, event: Event<'a>) -> Result<()> {
match event {
Event::Start(Tag::Paragraph) => self.state = State::PrefixChapters,
Event::Start(Tag::List(_)) => self.state = State::NumberedChapters(0),
other => bail!("Expected a start of paragraph but got {:?}", other),
}

View File

@ -87,8 +87,6 @@ extern crate serde;
extern crate serde_json;
extern crate tempdir;
#[cfg(test)]
extern crate tempdir;
#[cfg(test)]
#[macro_use]
extern crate pretty_assertions;

View File

@ -3,10 +3,9 @@ use preprocess;
use renderer::Renderer;
use book::MDBook;
use config::PlaypenConfig;
use theme::{Theme, playpen_editor};
use theme::{self, Theme, playpen_editor};
use book::book::{BookItem, Chapter};
use utils;
use theme::{self, Theme};
use errors::*;
use regex::{Regex, Captures};
@ -33,25 +32,9 @@ impl HtmlHandlebars {
-> Result<()> {
// FIXME: This should be made DRY-er and rely less on mutable state
match *item {
<<<<<<< HEAD
BookItem::Chapter(_, ref ch) |
BookItem::Affix(ref ch) if !ch.path.as_os_str().is_empty() => {
=======
BookItem::Chapter(ref ch) => {
if ch.path != PathBuf::new() {
let path = ctx.book.get_source().join(&ch.path);
debug!("[*]: Opening file: {:?}", path);
let mut f = File::open(&path)?;
let mut content: String = String::new();
debug!("[*]: Reading file");
f.read_to_string(&mut content)?;
>>>>>>> Removed old bookitem.md, now everyone uses the correct BookItem
let path = ctx.book.get_source().join(&ch.path);
let content = utils::fs::file_to_string(&path)?;
let content = ch.content.clone();
let base = path.parent().ok_or_else(
|| String::from("Invalid bookitem path!"),
)?;
@ -62,9 +45,7 @@ impl HtmlHandlebars {
print_content.push_str(&content);
// Update the context with data for this file
let path = ch.path.to_str().ok_or_else(|| {
io::Error::new(io::ErrorKind::Other, "Could not convert path to str")
})?;
let path = ch.path.to_str().ok_or_else(|| Error::from("Could not convert path to str"))?;
// Non-lexical lifetimes needed :'(
let title: String;
@ -407,24 +388,26 @@ fn make_data(book: &MDBook) -> Result<serde_json::Map<String, serde_json::Value>
for item in book.iter() {
// Create the data to inject in the template
let mut chapter = BTreeMap::new();
let mut chapter_data = BTreeMap::new();
match *item {
BookItem::Chapter(ref ch) => {
chapter.insert("section".to_owned(), json!(ch.number.clone()));
chapter.insert("name".to_owned(), json!(ch.name));
let path = ch.path.to_str().ok_or_else(|| {
io::Error::new(io::ErrorKind::Other, "Could not convert path to str")
})?;
chapter.insert("path".to_owned(), json!(path));
if let Some(ref section_number) = ch.number {
chapter_data.insert("section".to_owned(), json!(section_number.to_string()));
}
chapter_data.insert("name".to_owned(), json!(ch.name));
let path = ch.path.to_str()
.ok_or_else(|| Error::from("Could not convert path to str"))?;
chapter_data.insert("path".to_owned(), json!(path));
},
BookItem::Separator => {
chapter.insert("spacer".to_owned(), json!("_spacer_"));
chapter_data.insert("spacer".to_owned(), json!("_spacer_"));
},
}
chapters.push(chapter);
chapters.push(chapter_data);
}
data.insert("chapters".to_owned(), json!(chapters));