diff --git a/src/config/mod.rs b/src/config/mod.rs index 412bcc54..be74b7fc 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -1,3 +1,11 @@ +use std::collections::BTreeMap; +use std::path::{Path, PathBuf}; +use std::fs::File; +use std::io::Read; +use toml::{self, Value}; + +use errors::*; + pub mod bookconfig; pub mod htmlconfig; pub mod playpenconfig; @@ -9,3 +17,93 @@ pub use self::bookconfig::BookConfig; pub use self::htmlconfig::HtmlConfig; pub use self::playpenconfig::PlaypenConfig; pub use self::tomlconfig::TomlConfig; + + +/// The overall configuration object for MDBook. +#[derive(Clone, Default, PartialEq, Serialize, Deserialize)] +#[serde(default)] +pub struct Config { + /// Metadata about the book. + pub book: BookConfig_, + /// Arbitrary information which renderers can use during the rendering + /// stage. + pub output: BTreeMap, + /// Information for use by preprocessors. + pub preprocess: BTreeMap, + /// Information for use by postprocessors. + pub postprocess: BTreeMap, +} + +impl Config { + /// Load a `Config` from some string. + pub fn from_str(src: &str) -> Result { + toml::from_str(src).chain_err(|| Error::from("Invalid configuration file")) + } + + /// Load the configuration file from disk. + pub fn from_disk>(config_file: P) -> Result { + let mut buffer = String::new(); + File::open(config_file) + .chain_err(|| "Unable to open the configuration file")? + .read_to_string(&mut buffer) + .chain_err(|| "Couldn't read the file")?; + + Config::from_str(&buffer) + } + + /// Convenience method for getting the html renderer's configuration. + /// + /// # Note + /// + /// This is for compatibility only. It will be removed completely once the + /// rendering and plugin system is established. + pub fn html_config(&self) -> Option { + self.output + .get("html") + .and_then(|value| HtmlConfig_::from_toml(value).ok()) + } +} + + +/// Configuration options which are specific to the book and required for +/// loading it from disk. +#[derive(Clone, Default, PartialEq, Serialize, Deserialize)] +#[serde(default, rename_all = "kebab-case")] +pub struct BookConfig_ { + /// The book's title. + pub title: Option, + /// The book's authors. + pub authors: Vec, + /// An optional description for the book. + pub description: Option, + /// Location of the book source, relative to the book's root directory. + pub src: PathBuf, + /// Where to put built artefacts, relative to the book's root directory. + pub build_dir: PathBuf, + /// Does this book support more than one language? + pub multilingual: bool, +} + +#[derive(Clone, Default, PartialEq, Serialize, Deserialize)] +#[serde(default, rename_all = "kebab-case")] +pub struct HtmlConfig_ { + pub theme: Option, + pub curly_quotes: bool, + pub mathjax_support: bool, + pub google_analytics: Option, + pub additional_css: Vec, + pub additional_js: Vec, + pub playpen: Playpen, +} + +impl HtmlConfig_ { + pub fn from_toml(value: &Value) -> Result { + value + .clone() + .try_into() + .chain_err(|| "Unable to deserialize the HTML config") + } +} + +#[derive(Clone, Default, PartialEq, Serialize, Deserialize)] +pub struct Playpen; diff --git a/src/lib.rs b/src/lib.rs index cec4617d..ad5cdc08 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -86,6 +86,7 @@ extern crate serde_derive; #[macro_use] extern crate serde_json; extern crate tempdir; +extern crate toml; mod parse; mod preprocess;