Made sure the dummy book can build
This commit is contained in:
parent
8b21da9950
commit
21498631b3
|
@ -1,3 +1,4 @@
|
|||
[book]
|
||||
title = "mdBook Documentation"
|
||||
description = "Create book from markdown files. Like Gitbook but implemented in Rust"
|
||||
author = "Mathieu David"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"),
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -370,8 +370,9 @@ impl<'a> SummaryParser<'a> {
|
|||
}
|
||||
}
|
||||
},
|
||||
Event::End(Tag::Item) => { /* Ignore */ },
|
||||
other => {
|
||||
trace!("[*] skipping unexpected token: {:?}", other);
|
||||
trace!("[*] ignoring token: {:?}", other);
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
- [First Chapter](./first/index.md)
|
||||
- [Nested Chapter](./first/nested.md)
|
||||
---
|
||||
- [Second Chapter](./second.md)
|
||||
|
||||
[Conclusion](./conclusion.md)
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue