2015-08-06 18:38:48 +08:00
|
|
|
//! # mdBook
|
|
|
|
//!
|
2018-03-14 23:45:20 +08:00
|
|
|
//! **mdBook** is a tool for rendering a collection of markdown documents into
|
|
|
|
//! a form more suitable for end users like HTML or EPUB. It offers a command
|
|
|
|
//! line interface, but this crate can be used if more control is required.
|
2015-08-06 18:38:48 +08:00
|
|
|
//!
|
2017-12-11 15:50:31 +08:00
|
|
|
//! This is the API doc, the [user guide] is also available if you want
|
|
|
|
//! information about the command line tool, format, structure etc. It is also
|
|
|
|
//! rendered with mdBook to showcase the features and default theme.
|
2015-08-06 18:38:48 +08:00
|
|
|
//!
|
|
|
|
//! Some reasons why you would want to use the crate (over the cli):
|
|
|
|
//!
|
|
|
|
//! - Integrate mdbook in a current project
|
|
|
|
//! - Extend the capabilities of mdBook
|
|
|
|
//! - Do some processing or test before building your book
|
2018-01-21 22:35:11 +08:00
|
|
|
//! - Accessing the public API to help create a new Renderer
|
2015-08-06 18:38:48 +08:00
|
|
|
//! - ...
|
|
|
|
//!
|
2018-03-14 23:45:20 +08:00
|
|
|
//! > **Note:** While we try to ensure `mdbook`'s command-line interface and
|
|
|
|
//! > behaviour are backwards compatible, the tool's internals are still
|
|
|
|
//! > evolving and being iterated on. If you wish to prevent accidental
|
|
|
|
//! > breakages it is recommended to pin any tools building on top of the
|
|
|
|
//! > `mdbook` crate to a specific release.
|
|
|
|
//!
|
2017-12-11 08:29:30 +08:00
|
|
|
//! # Examples
|
2015-08-06 18:38:48 +08:00
|
|
|
//!
|
2017-12-11 08:29:30 +08:00
|
|
|
//! 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";
|
|
|
|
//!
|
|
|
|
//! // create a default config and change a couple things
|
|
|
|
//! let mut cfg = Config::default();
|
|
|
|
//! cfg.book.title = Some("My Book".to_string());
|
|
|
|
//! cfg.book.authors.push("Michael-F-Bryan".to_string());
|
2015-08-06 18:38:48 +08:00
|
|
|
//!
|
2017-12-11 08:29:30 +08:00
|
|
|
//! 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
|
2015-08-06 18:38:48 +08:00
|
|
|
//! use mdbook::MDBook;
|
2017-12-11 08:29:30 +08:00
|
|
|
//!
|
|
|
|
//! 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");
|
2015-08-06 18:38:48 +08:00
|
|
|
//! ```
|
|
|
|
//!
|
2018-01-21 22:35:11 +08:00
|
|
|
//! ## Implementing a new Backend
|
|
|
|
//!
|
2018-03-07 21:02:06 +08:00
|
|
|
//! `mdbook` has a fairly flexible mechanism for creating additional backends
|
2018-01-21 22:35:11 +08:00
|
|
|
//! for your book. The general idea is you'll add an extra table in the book's
|
|
|
|
//! `book.toml` which specifies an executable to be invoked by `mdbook`. This
|
2018-03-07 21:02:06 +08:00
|
|
|
//! executable will then be called during a build, with an in-memory
|
2018-01-21 22:35:11 +08:00
|
|
|
//! representation ([`RenderContext`]) of the book being passed to the
|
2018-03-07 21:02:06 +08:00
|
|
|
//! subprocess via `stdin`.
|
|
|
|
//!
|
|
|
|
//! The [`RenderContext`] gives the backend access to the contents of
|
2018-01-21 22:35:11 +08:00
|
|
|
//! `book.toml` and lets it know which directory all generated artefacts should
|
|
|
|
//! be placed in. For a much more in-depth explanation, consult the [relevant
|
|
|
|
//! chapter] in the *For Developers* section of the user guide.
|
2018-03-07 21:02:06 +08:00
|
|
|
//!
|
|
|
|
//! To make creating a backend easier, the `mdbook` crate can be imported
|
|
|
|
//! directly, making deserializing the `RenderContext` easy and giving you
|
2018-01-21 22:35:11 +08:00
|
|
|
//! access to the various methods for working with the [`Config`].
|
2017-12-11 15:50:31 +08:00
|
|
|
//!
|
|
|
|
//! [user guide]: https://rust-lang-nursery.github.io/mdBook/
|
2018-01-21 22:35:11 +08:00
|
|
|
//! [`RenderContext`]: renderer/struct.RenderContext.html
|
|
|
|
//! [relevant chapter]: https://rust-lang-nursery.github.io/mdBook/for_developers/backends.html
|
|
|
|
//! [`Config`]: config/struct.Config.html
|
|
|
|
|
|
|
|
#![deny(missing_docs)]
|
2015-08-06 18:38:48 +08:00
|
|
|
|
2017-06-24 23:48:50 +08:00
|
|
|
#[macro_use]
|
|
|
|
extern crate error_chain;
|
2017-07-04 07:04:18 +08:00
|
|
|
extern crate handlebars;
|
2018-01-06 05:03:30 +08:00
|
|
|
extern crate itertools;
|
2017-07-04 07:04:18 +08:00
|
|
|
#[macro_use]
|
|
|
|
extern crate lazy_static;
|
|
|
|
#[macro_use]
|
|
|
|
extern crate log;
|
2017-12-11 14:20:05 +08:00
|
|
|
extern crate memchr;
|
2017-07-04 07:04:18 +08:00
|
|
|
extern crate pulldown_cmark;
|
|
|
|
extern crate regex;
|
2017-10-03 19:40:23 +08:00
|
|
|
extern crate serde;
|
2017-02-16 11:34:37 +08:00
|
|
|
#[macro_use]
|
2017-05-19 01:32:08 +08:00
|
|
|
extern crate serde_derive;
|
2017-07-04 07:04:18 +08:00
|
|
|
#[macro_use]
|
2017-06-24 23:48:50 +08:00
|
|
|
extern crate serde_json;
|
2018-01-07 22:10:48 +08:00
|
|
|
extern crate shlex;
|
2018-03-27 07:47:37 +08:00
|
|
|
extern crate tempfile;
|
2017-09-30 20:11:24 +08:00
|
|
|
extern crate toml;
|
2018-01-14 02:38:43 +08:00
|
|
|
extern crate toml_query;
|
2017-07-10 19:26:43 +08:00
|
|
|
|
2017-12-11 12:17:20 +08:00
|
|
|
#[cfg(test)]
|
|
|
|
#[macro_use]
|
|
|
|
extern crate pretty_assertions;
|
|
|
|
|
2018-01-17 06:13:47 +08:00
|
|
|
pub mod preprocess;
|
2017-07-04 07:04:18 +08:00
|
|
|
pub mod book;
|
|
|
|
pub mod config;
|
2015-07-19 06:08:38 +08:00
|
|
|
pub mod renderer;
|
|
|
|
pub mod theme;
|
2015-07-30 21:20:55 +08:00
|
|
|
pub mod utils;
|
2015-07-07 08:56:19 +08:00
|
|
|
|
2015-07-19 06:08:38 +08:00
|
|
|
pub use book::MDBook;
|
|
|
|
pub use book::BookItem;
|
2015-08-06 04:35:26 +08:00
|
|
|
pub use renderer::Renderer;
|
2018-01-21 22:35:11 +08:00
|
|
|
pub use config::Config;
|
2017-06-24 23:48:50 +08:00
|
|
|
|
|
|
|
/// The error types used through out this crate.
|
|
|
|
pub mod errors {
|
2018-01-07 00:02:23 +08:00
|
|
|
use std::path::PathBuf;
|
|
|
|
|
2017-06-24 23:48:50 +08:00
|
|
|
error_chain!{
|
|
|
|
foreign_links {
|
2018-01-21 22:35:11 +08:00
|
|
|
Io(::std::io::Error) #[doc = "A wrapper around `std::io::Error`"];
|
|
|
|
HandlebarsRender(::handlebars::RenderError) #[doc = "Handlebars rendering failed"];
|
|
|
|
HandlebarsTemplate(Box<::handlebars::TemplateError>) #[doc = "Unable to parse the template"];
|
|
|
|
Utf8(::std::string::FromUtf8Error) #[doc = "Invalid UTF-8"];
|
2018-03-07 21:02:06 +08:00
|
|
|
SerdeJson(::serde_json::Error) #[doc = "JSON conversion failed"];
|
2017-06-24 23:48:50 +08:00
|
|
|
}
|
2017-06-25 00:04:57 +08:00
|
|
|
|
2018-01-14 02:38:43 +08:00
|
|
|
links {
|
2018-01-21 22:35:11 +08:00
|
|
|
TomlQuery(::toml_query::error::Error, ::toml_query::error::ErrorKind) #[doc = "A TomlQuery error"];
|
2018-01-14 02:38:43 +08:00
|
|
|
}
|
|
|
|
|
2017-06-25 00:04:57 +08:00
|
|
|
errors {
|
2018-01-21 22:35:11 +08:00
|
|
|
/// A subprocess exited with an unsuccessful return code.
|
2017-06-25 00:04:57 +08:00
|
|
|
Subprocess(message: String, output: ::std::process::Output) {
|
|
|
|
description("A subprocess failed")
|
2017-06-28 10:28:50 +08:00
|
|
|
display("{}: {}", message, String::from_utf8_lossy(&output.stdout))
|
2017-06-25 00:04:57 +08:00
|
|
|
}
|
2017-12-11 12:17:20 +08:00
|
|
|
|
2018-01-21 22:35:11 +08:00
|
|
|
/// An error was encountered while parsing the `SUMMARY.md` file.
|
2017-12-11 12:17:20 +08:00
|
|
|
ParseError(line: usize, col: usize, message: String) {
|
|
|
|
description("A SUMMARY.md parsing error")
|
|
|
|
display("Error at line {}, column {}: {}", line, col, message)
|
|
|
|
}
|
2018-01-07 00:02:23 +08:00
|
|
|
|
2018-01-21 22:35:11 +08:00
|
|
|
/// The user tried to use a reserved filename.
|
2018-01-07 00:02:23 +08:00
|
|
|
ReservedFilenameError(filename: PathBuf) {
|
|
|
|
description("Reserved Filename")
|
|
|
|
display("{} is reserved for internal use", filename.display())
|
|
|
|
}
|
2017-06-25 00:04:57 +08:00
|
|
|
}
|
2017-06-24 23:48:50 +08:00
|
|
|
}
|
2017-10-13 03:50:33 +08:00
|
|
|
|
|
|
|
// Box to halve the size of Error
|
|
|
|
impl From<::handlebars::TemplateError> for Error {
|
|
|
|
fn from(e: ::handlebars::TemplateError) -> Error {
|
|
|
|
From::from(Box::new(e))
|
|
|
|
}
|
|
|
|
}
|
2017-06-28 10:28:50 +08:00
|
|
|
}
|