Fleshed out the docs for the book module
This commit is contained in:
parent
ace0b51fb6
commit
be4654c9c2
|
@ -69,8 +69,8 @@ where
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add the source directory to the watcher
|
// Add the source directory to the watcher
|
||||||
if let Err(e) = watcher.watch(book.get_source(), Recursive) {
|
if let Err(e) = watcher.watch(book.source_dir(), Recursive) {
|
||||||
println!("Error while watching {:?}:\n {:?}", book.get_source(), e);
|
println!("Error while watching {:?}:\n {:?}", book.source_dir(), e);
|
||||||
::std::process::exit(0);
|
::std::process::exit(0);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,8 @@ pub struct BookBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BookBuilder {
|
impl BookBuilder {
|
||||||
|
/// Create a new `BookBuilder` which will generate a book in the provided
|
||||||
|
/// root directory.
|
||||||
pub fn new<P: Into<PathBuf>>(root: P) -> BookBuilder {
|
pub fn new<P: Into<PathBuf>>(root: P) -> BookBuilder {
|
||||||
BookBuilder {
|
BookBuilder {
|
||||||
root: root.into(),
|
root: root.into(),
|
||||||
|
@ -34,20 +36,32 @@ impl BookBuilder {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the config used by the `BookBuilder`.
|
||||||
|
pub fn config(&self) -> &Config {
|
||||||
|
&self.config
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Should the theme be copied into the generated book (so users can tweak
|
||||||
|
/// it)?
|
||||||
pub fn copy_theme(&mut self, copy: bool) -> &mut BookBuilder {
|
pub fn copy_theme(&mut self, copy: bool) -> &mut BookBuilder {
|
||||||
self.copy_theme = copy;
|
self.copy_theme = copy;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Should we create a `.gitignore` file?
|
||||||
pub fn create_gitignore(&mut self, create: bool) -> &mut BookBuilder {
|
pub fn create_gitignore(&mut self, create: bool) -> &mut BookBuilder {
|
||||||
self.create_gitignore = create;
|
self.create_gitignore = create;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn config(&self) -> &Config {
|
/// Generate the actual book. This will:
|
||||||
&self.config
|
///
|
||||||
}
|
/// - Create the directory structure.
|
||||||
|
/// - Stub out some dummy chapters and the `SUMMARY.md`.
|
||||||
|
/// - Create a `.gitignore` (if applicable)
|
||||||
|
/// - Create a themes directory and populate it (if applicable)
|
||||||
|
/// - Generate a `book.toml` file,
|
||||||
|
/// - Then load the book so we can
|
||||||
pub fn build(&self) -> Result<MDBook> {
|
pub fn build(&self) -> Result<MDBook> {
|
||||||
info!("Creating a new book with stub content");
|
info!("Creating a new book with stub content");
|
||||||
|
|
||||||
|
@ -69,18 +83,23 @@ impl BookBuilder {
|
||||||
|
|
||||||
self.write_book_toml()?;
|
self.write_book_toml()?;
|
||||||
|
|
||||||
let book = MDBook::load(&self.root)
|
match MDBook::load(&self.root) {
|
||||||
.expect("The BookBuilder should always create a valid book. \
|
Ok(book) => Ok(book),
|
||||||
If you are seeing this it is a bug and should be reported.");
|
Err(e) => {
|
||||||
|
error!("{}", e);
|
||||||
|
|
||||||
Ok(book)
|
panic!(
|
||||||
|
"The BookBuilder should always create a valid book. If you are seeing this it \
|
||||||
|
is a bug and should be reported."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_book_toml(&self) -> Result<()> {
|
fn write_book_toml(&self) -> Result<()> {
|
||||||
debug!("[*] Writing book.toml");
|
debug!("[*] Writing book.toml");
|
||||||
let book_toml = self.root.join("book.toml");
|
let book_toml = self.root.join("book.toml");
|
||||||
let cfg = toml::to_vec(&self.config)
|
let cfg = toml::to_vec(&self.config).chain_err(|| "Unable to serialize the config")?;
|
||||||
.chain_err(|| "Unable to serialize the config")?;
|
|
||||||
|
|
||||||
File::create(book_toml)
|
File::create(book_toml)
|
||||||
.chain_err(|| "Couldn't create book.toml")?
|
.chain_err(|| "Couldn't create book.toml")?
|
||||||
|
@ -92,14 +111,15 @@ impl BookBuilder {
|
||||||
fn copy_across_theme(&self) -> Result<()> {
|
fn copy_across_theme(&self) -> Result<()> {
|
||||||
debug!("[*] Copying theme");
|
debug!("[*] Copying theme");
|
||||||
|
|
||||||
let themedir = self.config.html_config()
|
let themedir = self.config
|
||||||
|
.html_config()
|
||||||
.and_then(|html| html.theme)
|
.and_then(|html| html.theme)
|
||||||
.unwrap_or_else(|| self.config.book.src.join("theme"));
|
.unwrap_or_else(|| self.config.book.src.join("theme"));
|
||||||
let themedir = self.root.join(themedir);
|
let themedir = self.root.join(themedir);
|
||||||
|
|
||||||
if !themedir.exists() {
|
if !themedir.exists() {
|
||||||
debug!("[*]: {:?} does not exist, creating the directory",
|
debug!("[*]: {:?} does not exist, creating the directory", themedir);
|
||||||
themedir); fs::create_dir(&themedir)?;
|
fs::create_dir(&themedir)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut index = File::create(themedir.join("index.hbs"))?;
|
let mut index = File::create(themedir.join("index.hbs"))?;
|
||||||
|
|
|
@ -1,3 +1,42 @@
|
||||||
|
//! The internal representation of a book and infrastructure for loading it from
|
||||||
|
//! disk and building it.
|
||||||
|
//!
|
||||||
|
//! # Examples
|
||||||
|
//!
|
||||||
|
//! If creating a new book from scratch, you'll want to get a `BookBuilder` via
|
||||||
|
//! the `MDBook::init()` method.
|
||||||
|
//!
|
||||||
|
//! ```rust,no_run
|
||||||
|
//! use mdbook::MDBook;
|
||||||
|
//! use mdbook::config::Config;
|
||||||
|
//!
|
||||||
|
//! let root_dir = "/path/to/book/root";
|
||||||
|
//!
|
||||||
|
//! let mut cfg = Config::default();
|
||||||
|
//! cfg.book.title = Some("My Book".to_string());
|
||||||
|
//! cfg.book.authors.push("Michael-F-Bryan".to_string());
|
||||||
|
//!
|
||||||
|
//! MDBook::init(root_dir)
|
||||||
|
//! .create_gitignore(true)
|
||||||
|
//! .with_config(cfg)
|
||||||
|
//! .build()
|
||||||
|
//! .expect("Book generation failed");
|
||||||
|
//! ```
|
||||||
|
//!
|
||||||
|
//! You can also load an existing book and build it.
|
||||||
|
//!
|
||||||
|
//! ```rust,no_run
|
||||||
|
//! use mdbook::MDBook;
|
||||||
|
//!
|
||||||
|
//! let root_dir = "/path/to/book/root";
|
||||||
|
//!
|
||||||
|
//! let mut md = MDBook::load(root_dir)
|
||||||
|
//! .expect("Unable to load the book");
|
||||||
|
//! md.build().expect("Building failed");
|
||||||
|
//! ```
|
||||||
|
|
||||||
|
#![deny(missing_docs)]
|
||||||
|
|
||||||
mod summary;
|
mod summary;
|
||||||
mod book;
|
mod book;
|
||||||
mod init;
|
mod init;
|
||||||
|
@ -18,13 +57,17 @@ use errors::*;
|
||||||
|
|
||||||
use config::Config;
|
use config::Config;
|
||||||
|
|
||||||
|
/// The object used to manage and build a book.
|
||||||
pub struct MDBook {
|
pub struct MDBook {
|
||||||
|
/// The book's root directory.
|
||||||
pub root: PathBuf,
|
pub root: PathBuf,
|
||||||
|
/// The configuration used to tweak now a book is built.
|
||||||
pub config: Config,
|
pub config: Config,
|
||||||
|
|
||||||
book: Book,
|
book: Book,
|
||||||
renderer: Box<Renderer>,
|
renderer: Box<Renderer>,
|
||||||
|
|
||||||
|
/// The URL used for live reloading when serving up the book.
|
||||||
pub livereload: Option<String>,
|
pub livereload: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,6 +166,8 @@ impl MDBook {
|
||||||
self.renderer.render(self)
|
self.renderer.render(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: This doesn't belong as part of `MDBook`. It is only used by the HTML renderer
|
||||||
|
#[doc(hidden)]
|
||||||
pub fn write_file<P: AsRef<Path>>(&self, filename: P, content: &[u8]) -> Result<()> {
|
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);
|
||||||
|
|
||||||
|
@ -139,6 +184,7 @@ impl MDBook {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Run `rustdoc` tests on the book, linking against the provided libraries.
|
||||||
pub fn test(&mut self, library_paths: Vec<&str>) -> Result<()> {
|
pub fn test(&mut self, library_paths: Vec<&str>) -> Result<()> {
|
||||||
let library_args: Vec<&str> = (0..library_paths.len())
|
let library_args: Vec<&str> = (0..library_paths.len())
|
||||||
.map(|_| "-L")
|
.map(|_| "-L")
|
||||||
|
@ -151,7 +197,7 @@ impl MDBook {
|
||||||
for item in self.iter() {
|
for item in self.iter() {
|
||||||
if let BookItem::Chapter(ref ch) = *item {
|
if let BookItem::Chapter(ref ch) = *item {
|
||||||
if !ch.path.as_os_str().is_empty() {
|
if !ch.path.as_os_str().is_empty() {
|
||||||
let path = self.get_source().join(&ch.path);
|
let path = self.source_dir().join(&ch.path);
|
||||||
let base = path.parent()
|
let base = path.parent()
|
||||||
.ok_or_else(|| String::from("Invalid bookitem path!"))?;
|
.ok_or_else(|| String::from("Invalid bookitem path!"))?;
|
||||||
let content = utils::fs::file_to_string(&path)?;
|
let content = utils::fs::file_to_string(&path)?;
|
||||||
|
@ -182,14 +228,19 @@ impl MDBook {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: This doesn't belong under `MDBook`, it should really be passed to the renderer directly.
|
||||||
|
#[doc(hidden)]
|
||||||
pub fn get_destination(&self) -> PathBuf {
|
pub fn get_destination(&self) -> PathBuf {
|
||||||
self.root.join(&self.config.build.build_dir)
|
self.root.join(&self.config.build.build_dir)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_source(&self) -> PathBuf {
|
/// Get the directory containing this book's source files.
|
||||||
|
pub fn source_dir(&self) -> PathBuf {
|
||||||
self.root.join(&self.config.book.src)
|
self.root.join(&self.config.book.src)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: This belongs as part of the `HtmlConfig`.
|
||||||
|
#[doc(hidden)]
|
||||||
pub fn theme_dir(&self) -> PathBuf {
|
pub fn theme_dir(&self) -> PathBuf {
|
||||||
match self.config.html_config().and_then(|h| h.theme) {
|
match self.config.html_config().and_then(|h| h.theme) {
|
||||||
Some(d) => self.root.join(d),
|
Some(d) => self.root.join(d),
|
||||||
|
|
|
@ -318,7 +318,7 @@ impl Renderer for HtmlHandlebars {
|
||||||
self.copy_additional_css_and_js(book)?;
|
self.copy_additional_css_and_js(book)?;
|
||||||
|
|
||||||
// Copy all remaining files
|
// Copy all remaining files
|
||||||
let src = book.get_source();
|
let src = book.source_dir();
|
||||||
utils::fs::copy_files_except_ext(&src, &destination, true, &["md"])?;
|
utils::fs::copy_files_except_ext(&src, &destination, true, &["md"])?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
Loading…
Reference in New Issue