Incorporated Budziq's feedback
This commit is contained in:
parent
98a8ce934b
commit
f8cec4cef3
|
@ -44,7 +44,7 @@ ws = { version = "0.7", optional = true}
|
|||
error-chain = "0.11"
|
||||
|
||||
[dev-dependencies]
|
||||
pretty_assertions = "0.2.1"
|
||||
pretty_assertions = "0.2"
|
||||
|
||||
[features]
|
||||
default = ["output", "watch", "serve"]
|
||||
|
|
|
@ -24,9 +24,7 @@ pub fn execute(args: &ArgMatches) -> Result<()> {
|
|||
None => book,
|
||||
};
|
||||
|
||||
if args.is_present("create") {
|
||||
book.create_missing = true;
|
||||
}
|
||||
book.create_missing = args.is_present("create");
|
||||
|
||||
if args.is_present("curly-quotes") {
|
||||
book = book.with_curly_quotes(true);
|
||||
|
|
132
src/book/mod.rs
132
src/book/mod.rs
|
@ -13,7 +13,7 @@ use std::process::Command;
|
|||
use tempdir::TempDir;
|
||||
|
||||
use {theme, utils};
|
||||
use renderer::{Renderer, HtmlHandlebars};
|
||||
use renderer::{HtmlHandlebars, Renderer};
|
||||
use preprocess;
|
||||
use errors::*;
|
||||
|
||||
|
@ -23,7 +23,10 @@ use config::htmlconfig::HtmlConfig;
|
|||
use config::jsonconfig::JsonConfig;
|
||||
|
||||
|
||||
/// A helper for managing the `Book`, its configuration, and the rendering
|
||||
const STUB_SUMMARY_CONTENTS: &'static str = "# Summary\n\n- [Chapter 1](./chapter_1.md)]";
|
||||
const STUB_CHAPTER_1: &'static str = "# Chapter 1\n";
|
||||
|
||||
/// A helper for managing the `Book`, its configuration, and the rendering
|
||||
/// process.
|
||||
pub struct MDBook {
|
||||
config: BookConfig,
|
||||
|
@ -67,7 +70,6 @@ impl MDBook {
|
|||
/// [`set_dest()`](#method.set_dest)
|
||||
|
||||
pub fn new<P: Into<PathBuf>>(root: P) -> MDBook {
|
||||
|
||||
let root = root.into();
|
||||
if !root.exists() || !root.is_dir() {
|
||||
warn!("{:?} No directory with that name", root);
|
||||
|
@ -114,8 +116,10 @@ impl MDBook {
|
|||
/// ```
|
||||
|
||||
pub fn iter(&self) -> BookItems {
|
||||
self.content.as_ref().expect("Trying to iterate over a book before it is loaded. This is a bug")
|
||||
.iter()
|
||||
self.content
|
||||
.as_ref()
|
||||
.expect("Trying to iterate over a book before it is loaded. This is a bug")
|
||||
.iter()
|
||||
}
|
||||
|
||||
/// `init()` creates some boilerplate files and directories
|
||||
|
@ -132,64 +136,73 @@ impl MDBook {
|
|||
/// It uses the paths given as source and output directories
|
||||
/// and adds a `SUMMARY.md` and a
|
||||
/// `chapter_1.md` to the source directory.
|
||||
|
||||
pub fn init(&mut self) -> Result<()> {
|
||||
|
||||
debug!("[fn]: init");
|
||||
|
||||
{
|
||||
let root = self.config.get_root();
|
||||
let dest = self.get_destination();
|
||||
let src = self.config.get_source();
|
||||
self.create_book_directories()?;
|
||||
self.create_stub_files()?;
|
||||
|
||||
let necessary_folders = &[root, dest, src];
|
||||
|
||||
for folder in necessary_folders {
|
||||
if !folder.exists() {
|
||||
fs::create_dir_all(folder)?;
|
||||
debug!("{} created", folder.display());
|
||||
}
|
||||
}
|
||||
self.parse_summary()
|
||||
.chain_err(|| "Couldn't parse the SUMMARY.md file")?;
|
||||
|
||||
let summary = src.join("SUMMARY.md");
|
||||
debug!("[*]: init done");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
if !summary.exists() {
|
||||
debug!("[*]: Creating SUMMARY.md");
|
||||
fn create_book_directories(&self) -> Result<()> {
|
||||
debug!("[*] Creating directories");
|
||||
|
||||
let mut f = File::create(&summary)?;
|
||||
let root = self.config.get_root();
|
||||
let dest = self.get_destination();
|
||||
let src = self.config.get_source();
|
||||
|
||||
writeln!(f, "# Summary")?;
|
||||
writeln!(f)?;
|
||||
writeln!(f, "- [Chapter 1](./chapter_1.md)")?;
|
||||
}
|
||||
let necessary_folders = &[root, dest, src];
|
||||
|
||||
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")?;
|
||||
for folder in necessary_folders {
|
||||
if !folder.exists() {
|
||||
fs::create_dir_all(folder)?;
|
||||
debug!("{} created", folder.display());
|
||||
}
|
||||
}
|
||||
|
||||
// parse SUMMARY.md and load the newly created files into memory
|
||||
self.parse_summary().chain_err(|| "Couldn't parse the SUMMARY.md file")?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn create_stub_files(&self) -> Result<()> {
|
||||
debug!("[*] Creating stub files");
|
||||
|
||||
let src = self.config.get_source();
|
||||
let summary = src.join("SUMMARY.md");
|
||||
|
||||
if !summary.exists() {
|
||||
debug!("[*]: Creating SUMMARY.md");
|
||||
let mut f = File::create(&summary)?;
|
||||
writeln!(f, "{}", STUB_SUMMARY_CONTENTS)?;
|
||||
}
|
||||
|
||||
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, "{}", STUB_CHAPTER_1)?;
|
||||
}
|
||||
|
||||
debug!("[*]: init done");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn create_gitignore(&self) {
|
||||
let gitignore = self.get_gitignore();
|
||||
|
||||
let destination = self.config.get_html_config()
|
||||
.get_destination();
|
||||
let destination = self.config.get_html_config().get_destination();
|
||||
|
||||
// Check that the gitignore does not extist and that the destination path begins with the root path
|
||||
// We assume tha if it does begin with the root path it is contained within. This assumption
|
||||
// will not hold true for paths containing double dots to go back up e.g. `root/../destination`
|
||||
// Check that the gitignore does not exist and that the destination path
|
||||
// begins with the root path
|
||||
// We assume tha if it does begin with the root path it is contained within.
|
||||
// This assumption
|
||||
// will not hold true for paths containing double dots to go back up e.g.
|
||||
// `root/../destination`
|
||||
if !gitignore.exists() && destination.starts_with(self.config.get_root()) {
|
||||
|
||||
let relative = destination
|
||||
.strip_prefix(self.config.get_root())
|
||||
.expect("Could not strip the root prefix, path is not relative to root")
|
||||
|
@ -223,7 +236,6 @@ impl MDBook {
|
|||
self.renderer.render(self)
|
||||
}
|
||||
|
||||
|
||||
pub fn get_gitignore(&self) -> PathBuf {
|
||||
self.config.get_root().join(".gitignore")
|
||||
}
|
||||
|
@ -265,8 +277,7 @@ impl MDBook {
|
|||
}
|
||||
|
||||
pub fn write_file<P: AsRef<Path>>(&self, filename: P, content: &[u8]) -> Result<()> {
|
||||
let path = self.get_destination()
|
||||
.join(filename);
|
||||
let path = self.get_destination().join(filename);
|
||||
|
||||
utils::fs::create_file(&path)?
|
||||
.write_all(content)
|
||||
|
@ -279,7 +290,6 @@ impl MDBook {
|
|||
/// The root directory is the one specified when creating a new `MDBook`
|
||||
|
||||
pub fn read_config(mut self) -> Result<Self> {
|
||||
|
||||
let toml = self.get_root().join("book.toml");
|
||||
let json = self.get_root().join("book.json");
|
||||
|
||||
|
@ -335,31 +345,33 @@ impl MDBook {
|
|||
pub fn test(&mut self, library_paths: Vec<&str>) -> Result<()> {
|
||||
// read in the chapters
|
||||
self.parse_summary().chain_err(|| "Couldn't parse summary")?;
|
||||
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 != PathBuf::new() {
|
||||
|
||||
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)?;
|
||||
println!("[*]: Testing file: {:?}", path);
|
||||
|
||||
//write preprocessed file to tempdir
|
||||
// write preprocessed file to tempdir
|
||||
let path = temp_dir.path().join(&ch.path);
|
||||
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("Rustdoc returned an error".to_string(), output));
|
||||
|
@ -377,15 +389,15 @@ impl MDBook {
|
|||
|
||||
pub fn with_destination<T: Into<PathBuf>>(mut self, destination: T) -> Self {
|
||||
let root = self.config.get_root().to_owned();
|
||||
self.config.get_mut_html_config()
|
||||
self.config
|
||||
.get_mut_html_config()
|
||||
.set_destination(&root, &destination.into());
|
||||
self
|
||||
}
|
||||
|
||||
|
||||
pub fn get_destination(&self) -> &Path {
|
||||
self.config.get_html_config()
|
||||
.get_destination()
|
||||
self.config.get_html_config().get_destination()
|
||||
}
|
||||
|
||||
pub fn with_source<T: Into<PathBuf>>(mut self, source: T) -> Self {
|
||||
|
|
|
@ -322,6 +322,11 @@ impl<'a> SummaryParser<'a> {
|
|||
let section_number = self.push_numbered_section(SummaryItem::Link(it));
|
||||
trace!("[*] Section number is {}", section_number);
|
||||
},
|
||||
Event::End(Tag::Rule) => {
|
||||
debug!("[*] Found a numbered chapter separator");
|
||||
self.summary.numbered_chapters.push(SummaryItem::Separator);
|
||||
self.state = State::NumberedChapters(0);
|
||||
},
|
||||
Event::Start(Tag::List(_)) => {
|
||||
if let State::NumberedChapters(n) = self.state {
|
||||
self.state = State::NumberedChapters(n + 1);
|
||||
|
|
Loading…
Reference in New Issue