You can normally use default preprocessors by default

This commit is contained in:
Michael Bryan 2018-08-30 22:51:46 +08:00
parent d0a6d7c87c
commit 4d7027f8a7
No known key found for this signature in database
GPG Key ID: E9C602B0D9A998DC
4 changed files with 39 additions and 41 deletions

View File

@ -349,10 +349,19 @@ fn default_preprocessors() -> Vec<Box<Preprocessor>> {
] ]
} }
fn is_default_preprocessor(pre: &Preprocessor) -> bool {
let name = pre.name();
name == LinkPreprocessor::NAME || name == IndexPreprocessor::NAME
}
/// Look at the `MDBook` and try to figure out what preprocessors to run. /// Look at the `MDBook` and try to figure out what preprocessors to run.
fn determine_preprocessors(config: &Config) -> Result<Vec<Box<Preprocessor>>> { fn determine_preprocessors(config: &Config) -> Result<Vec<Box<Preprocessor>>> {
let preprocess_list = match config.build.preprocess { let preprocessor_keys = config.get("preprocessor")
Some(ref p) => p, .and_then(|value| value.as_table())
.map(|table| table.keys());
let preprocessor_keys = match preprocessor_keys {
Some(keys) => keys,
// If no preprocessor field is set, default to the LinkPreprocessor and // If no preprocessor field is set, default to the LinkPreprocessor and
// IndexPreprocessor. This allows you to disable default preprocessors // IndexPreprocessor. This allows you to disable default preprocessors
// by setting "preprocess" to an empty list. // by setting "preprocess" to an empty list.
@ -361,7 +370,7 @@ fn determine_preprocessors(config: &Config) -> Result<Vec<Box<Preprocessor>>> {
let mut preprocessors: Vec<Box<Preprocessor>> = Vec::new(); let mut preprocessors: Vec<Box<Preprocessor>> = Vec::new();
for key in preprocess_list { for key in preprocessor_keys {
match key.as_ref() { match key.as_ref() {
"links" => preprocessors.push(Box::new(LinkPreprocessor::new())), "links" => preprocessors.push(Box::new(LinkPreprocessor::new())),
"index" => preprocessors.push(Box::new(IndexPreprocessor::new())), "index" => preprocessors.push(Box::new(IndexPreprocessor::new())),
@ -388,7 +397,16 @@ fn interpret_custom_renderer(key: &str, table: &Value) -> Box<Renderer> {
/// Check whether we should run a particular `Preprocessor` in combination /// Check whether we should run a particular `Preprocessor` in combination
/// with the renderer, falling back to `Preprocessor::supports_renderer()` /// with the renderer, falling back to `Preprocessor::supports_renderer()`
/// method if the user doesn't say anything. /// method if the user doesn't say anything.
///
/// The `build.use-default-preprocessors` config option can be used to ensure
/// default preprocessors always run if they support the renderer.
fn preprocessor_should_run(preprocessor: &Preprocessor, renderer: &Renderer, cfg: &Config) -> bool { fn preprocessor_should_run(preprocessor: &Preprocessor, renderer: &Renderer, cfg: &Config) -> bool {
if cfg.build.use_default_preprocessors &&
is_default_preprocessor(preprocessor) &&
preprocessor.supports_renderer(renderer.name()) {
return true;
}
let key = format!("preprocessor.{}.renderers", preprocessor.name()); let key = format!("preprocessor.{}.renderers", preprocessor.name());
let renderer_name = renderer.name(); let renderer_name = renderer.name();
@ -449,8 +467,8 @@ mod tests {
fn config_defaults_to_link_and_index_preprocessor_if_not_set() { fn config_defaults_to_link_and_index_preprocessor_if_not_set() {
let cfg = Config::default(); let cfg = Config::default();
// make sure we haven't got anything in the `output` table // make sure we haven't got anything in the `preprocessor` table
assert!(cfg.build.preprocess.is_none()); assert!(cfg.get("preprocessor").is_none());
let got = determine_preprocessors(&cfg); let got = determine_preprocessors(&cfg);
@ -460,45 +478,23 @@ mod tests {
assert_eq!(got.as_ref().unwrap()[1].name(), "index"); assert_eq!(got.as_ref().unwrap()[1].name(), "index");
} }
#[test]
fn config_doesnt_default_if_empty() {
let cfg_str: &'static str = r#"
[book]
title = "Some Book"
[build]
build-dir = "outputs"
create-missing = false
preprocess = []
"#;
let cfg = Config::from_str(cfg_str).unwrap();
// make sure we have something in the `output` table
assert!(cfg.build.preprocess.is_some());
let got = determine_preprocessors(&cfg);
assert!(got.is_ok());
assert!(got.unwrap().is_empty());
}
#[test] #[test]
fn config_complains_if_unimplemented_preprocessor() { fn config_complains_if_unimplemented_preprocessor() {
let cfg_str: &'static str = r#" let cfg_str: &'static str = r#"
[book] [book]
title = "Some Book" title = "Some Book"
[preprocessor.random]
[build] [build]
build-dir = "outputs" build-dir = "outputs"
create-missing = false create-missing = false
preprocess = ["random"]
"#; "#;
let cfg = Config::from_str(cfg_str).unwrap(); let cfg = Config::from_str(cfg_str).unwrap();
// make sure we have something in the `output` table // make sure the `preprocessor.random` table exists
assert!(cfg.build.preprocess.is_some()); assert!(cfg.get_preprocessor("random").is_some());
let got = determine_preprocessors(&cfg); let got = determine_preprocessors(&cfg);

View File

@ -394,8 +394,9 @@ pub struct BuildConfig {
/// Should non-existent markdown files specified in `SETTINGS.md` be created /// Should non-existent markdown files specified in `SETTINGS.md` be created
/// if they don't exist? /// if they don't exist?
pub create_missing: bool, pub create_missing: bool,
/// Which preprocessors should be applied /// Should the default preprocessors always be used when they are
pub preprocess: Option<Vec<String>>, /// compatible with the renderer?
pub use_default_preprocessors: bool,
} }
impl Default for BuildConfig { impl Default for BuildConfig {
@ -403,7 +404,7 @@ impl Default for BuildConfig {
BuildConfig { BuildConfig {
build_dir: PathBuf::from("book"), build_dir: PathBuf::from("book"),
create_missing: true, create_missing: true,
preprocess: None, use_default_preprocessors: true,
} }
} }
} }
@ -591,10 +592,7 @@ mod tests {
let build_should_be = BuildConfig { let build_should_be = BuildConfig {
build_dir: PathBuf::from("outputs"), build_dir: PathBuf::from("outputs"),
create_missing: false, create_missing: false,
preprocess: Some(vec![ use_default_preprocessors: true,
"first_preprocessor".to_string(),
"second_preprocessor".to_string(),
]),
}; };
let playpen_should_be = Playpen { let playpen_should_be = Playpen {
editable: true, editable: true,
@ -696,7 +694,7 @@ mod tests {
let build_should_be = BuildConfig { let build_should_be = BuildConfig {
build_dir: PathBuf::from("my-book"), build_dir: PathBuf::from("my-book"),
create_missing: true, create_missing: true,
preprocess: None, use_default_preprocessors: true,
}; };
let html_should_be = HtmlConfig { let html_should_be = HtmlConfig {

View File

@ -11,6 +11,8 @@ use book::{Book, BookItem};
pub struct IndexPreprocessor; pub struct IndexPreprocessor;
impl IndexPreprocessor { impl IndexPreprocessor {
pub(crate) const NAME: &'static str = "index";
/// Create a new `IndexPreprocessor`. /// Create a new `IndexPreprocessor`.
pub fn new() -> Self { pub fn new() -> Self {
IndexPreprocessor IndexPreprocessor
@ -19,7 +21,7 @@ impl IndexPreprocessor {
impl Preprocessor for IndexPreprocessor { impl Preprocessor for IndexPreprocessor {
fn name(&self) -> &str { fn name(&self) -> &str {
"index" Self::NAME
} }
fn run(&self, ctx: &PreprocessorContext, mut book: Book) -> Result<Book> { fn run(&self, ctx: &PreprocessorContext, mut book: Book) -> Result<Book> {

View File

@ -16,6 +16,8 @@ const MAX_LINK_NESTED_DEPTH: usize = 10;
pub struct LinkPreprocessor; pub struct LinkPreprocessor;
impl LinkPreprocessor { impl LinkPreprocessor {
pub(crate) const NAME: &'static str = "links";
/// Create a new `LinkPreprocessor`. /// Create a new `LinkPreprocessor`.
pub fn new() -> Self { pub fn new() -> Self {
LinkPreprocessor LinkPreprocessor
@ -24,7 +26,7 @@ impl LinkPreprocessor {
impl Preprocessor for LinkPreprocessor { impl Preprocessor for LinkPreprocessor {
fn name(&self) -> &str { fn name(&self) -> &str {
"links" Self::NAME
} }
fn run(&self, ctx: &PreprocessorContext, mut book: Book) -> Result<Book> { fn run(&self, ctx: &PreprocessorContext, mut book: Book) -> Result<Book> {