Everything compiles and all the tests pass.
This commit is contained in:
parent
d39352aa45
commit
3a51e4a27c
|
@ -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 {
|
||||
|
|
100
src/book/mod.rs
100
src/book/mod.rs
|
@ -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())?;
|
||||
}
|
||||
let necessary_folders = &[root, dest, src];
|
||||
|
||||
|
||||
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)?;
|
||||
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(())
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
|
Loading…
Reference in New Issue