From 93874edebf7dbd6252b3346cb15162f0f7121867 Mon Sep 17 00:00:00 2001 From: Chris Spiegel Date: Wed, 29 Nov 2017 20:02:58 -0800 Subject: [PATCH] Add a create-missing option to book.toml. --- book-example/src/format/config.md | 19 ++++++++++++++++++- src/bin/build.rs | 4 ++-- src/book/mod.rs | 12 ++++++++---- src/config.rs | 31 +++++++++++++++++++++++++++++++ 4 files changed, 59 insertions(+), 7 deletions(-) diff --git a/book-example/src/format/config.md b/book-example/src/format/config.md index 8b7bdd00..3100b930 100644 --- a/book-example/src/format/config.md +++ b/book-example/src/format/config.md @@ -10,6 +10,9 @@ title = "Example book" author = "John Doe" description = "The example book covers examples." +[build] +create-missing = false + [output.html] destination = "my-example-book" additional-css = ["custom.css"] @@ -45,6 +48,20 @@ src = "my-src" # the source files will be found in `root/my-src` instead of `ro build-dir = "build" ``` +### Build options + +This controls the build process of your book. + +- **create-missing:** By default, any missing files specified in `SUMMARY.md` + will be created when the book is built. If this is `false` then the build + process will instead exit with an error if any files do not exist. + +**book.toml** +```toml +[build] +create-missing = false +``` + ### HTML renderer options The HTML renderer has a couple of options as well. All the options for the renderer need to be specified under the TOML table `[output.html]`. @@ -134,4 +151,4 @@ if let Some(baz) = book_config.get_deserialized::>("output.random.baz" } // start the rendering process -``` \ No newline at end of file +``` diff --git a/src/bin/build.rs b/src/bin/build.rs index f3b595e1..a7278c66 100644 --- a/src/bin/build.rs +++ b/src/bin/build.rs @@ -14,7 +14,7 @@ pub fn make_subcommand<'a, 'b>() -> App<'a, 'b> { book{n}(Defaults to ./book when omitted)'", ) .arg_from_usage( - "--no-create 'Will not create non-existent files linked from SUMMARY.md'", + "--no-create 'Will not create non-existent files linked from SUMMARY.md (deprecated: use book.toml instead)'", ) .arg_from_usage( "[dir] 'A directory for your book{n}(Defaults to Current Directory \ @@ -32,7 +32,7 @@ pub fn execute(args: &ArgMatches) -> Result<()> { } if args.is_present("no-create") { - book.create_missing = false; + book.create_missing = Some(false); } book.build()?; diff --git a/src/book/mod.rs b/src/book/mod.rs index fc757a90..a412bc55 100644 --- a/src/book/mod.rs +++ b/src/book/mod.rs @@ -25,8 +25,10 @@ pub struct MDBook { pub livereload: Option, /// Should `mdbook build` create files referenced from SUMMARY.md if they - /// don't exist - pub create_missing: bool, + /// don't exist? If `None`, use the setting specified in `book.toml`, + /// otherwise use this. + /// This is for backward compatibility only. + pub create_missing: Option, } impl MDBook { @@ -71,7 +73,7 @@ impl MDBook { renderer: Box::new(HtmlHandlebars::new()), livereload: None, - create_missing: true, + create_missing: None, } } @@ -179,7 +181,9 @@ impl MDBook { let path = self.get_source().join(&ch.path); if !path.exists() { - if !self.create_missing { + let create_missing = self.create_missing.unwrap_or(self.config.build.create_missing); + + if !create_missing { return Err( format!("'{}' referenced from SUMMARY.md does not exist.", path.to_string_lossy()).into(), ); diff --git a/src/config.rs b/src/config.rs index fd2ed2f0..dac67b66 100644 --- a/src/config.rs +++ b/src/config.rs @@ -12,6 +12,7 @@ use errors::*; pub struct Config { /// Metadata about the book. pub book: BookConfig, + pub build: BuildConfig, rest: Table, } @@ -171,8 +172,14 @@ impl<'de> Deserialize<'de> for Config { let book: BookConfig = table.remove("book") .and_then(|value| value.try_into().ok()) .unwrap_or_default(); + + let build: BuildConfig = table.remove("build") + .and_then(|value| value.try_into().ok()) + .unwrap_or_default(); + Ok(Config { book: book, + build: build, rest: table, }) } @@ -217,6 +224,23 @@ impl Default for BookConfig { } } +/// Configuration for the build procedure. +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[serde(default, rename_all = "kebab-case")] +pub struct BuildConfig { + /// Should non-existent markdown files specified in `SETTINGS.md` be created + /// if they don't exist? + pub create_missing: bool, +} + +impl Default for BuildConfig { + fn default() -> BuildConfig { + BuildConfig { + create_missing: true, + } + } +} + #[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)] #[serde(default, rename_all = "kebab-case")] pub struct HtmlConfig { @@ -250,6 +274,9 @@ mod tests { src = "source" build-dir = "outputs" + [build] + create-missing = false + [output.html] theme = "./themedir" curly-quotes = true @@ -274,6 +301,9 @@ mod tests { build_dir: PathBuf::from("outputs"), ..Default::default() }; + let build_should_be = BuildConfig { + create_missing: false, + }; let playpen_should_be = Playpen { editable: true, editor: PathBuf::from("ace"), @@ -290,6 +320,7 @@ mod tests { let got = Config::from_str(src).unwrap(); assert_eq!(got.book, book_should_be); + assert_eq!(got.build, build_should_be); assert_eq!(got.html_config().unwrap(), html_should_be); }