1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
//! # mdBook //! //! **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. //! //! 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. //! //! 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 //! - Accessing the public API to help create a new Renderer //! - ... //! //! > **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. //! //! # 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"; //! //! // 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()); //! //! 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"); //! ``` //! //! ## Implementing a new Backend //! //! `mdbook` has a fairly flexible mechanism for creating additional backends //! 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 //! executable will then be called during a build, with an in-memory //! representation ([`RenderContext`]) of the book being passed to the //! subprocess via `stdin`. //! //! The [`RenderContext`] gives the backend access to the contents of //! `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. //! //! To make creating a backend easier, the `mdbook` crate can be imported //! directly, making deserializing the `RenderContext` easy and giving you //! access to the various methods for working with the [`Config`]. //! //! [user guide]: https://rust-lang.github.io/mdBook/ //! [`RenderContext`]: renderer/struct.RenderContext.html //! [relevant chapter]: https://rust-lang.github.io/mdBook/for_developers/backends.html //! [`Config`]: config/struct.Config.html #![deny(missing_docs)] #![deny(rust_2018_idioms)] #[macro_use] extern crate error_chain; #[macro_use] extern crate lazy_static; #[macro_use] extern crate log; #[macro_use] extern crate serde_derive; #[macro_use] extern crate serde_json; #[cfg(test)] #[macro_use] extern crate pretty_assertions; pub mod book; pub mod config; pub mod preprocess; pub mod renderer; pub mod theme; pub mod utils; /// The current version of `mdbook`. /// /// This is provided as a way for custom preprocessors and renderers to do /// compatibility checks. pub const MDBOOK_VERSION: &str = env!("CARGO_PKG_VERSION"); pub use crate::book::BookItem; pub use crate::book::MDBook; pub use crate::config::Config; pub use crate::renderer::Renderer; /// The error types used through out this crate. pub mod errors { use std::path::PathBuf; error_chain! { foreign_links { 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"]; SerdeJson(serde_json::Error) #[doc = "JSON conversion failed"]; } errors { /// A subprocess exited with an unsuccessful return code. Subprocess(message: String, output: std::process::Output) { description("A subprocess failed") display("{}: {}", message, String::from_utf8_lossy(&output.stdout)) } /// An error was encountered while parsing the `SUMMARY.md` file. ParseError(line: usize, col: usize, message: String) { description("A SUMMARY.md parsing error") display("Error at line {}, column {}: {}", line, col, message) } /// The user tried to use a reserved filename. ReservedFilenameError(filename: PathBuf) { description("Reserved Filename") display("{} is reserved for internal use", filename.display()) } /// Error with a TOML file. TomlQueryError(inner: toml_query::error::Error) { description("toml_query error") display("{}", inner) } } } // Box to halve the size of Error impl From<handlebars::TemplateError> for Error { fn from(e: handlebars::TemplateError) -> Error { From::from(Box::new(e)) } } }