Move preprocess field location and add tests

This commit is contained in:
Jaime Valdemoros 2018-01-15 22:54:14 +00:00
parent 08027b86cc
commit b599956516
4 changed files with 90 additions and 15 deletions

View File

@ -88,7 +88,7 @@ impl MDBook {
let livereload = None;
let renderers = determine_renderers(&config);
let preprocessors = determine_preprocessors(&config);
let preprocessors = determine_preprocessors(&config)?;
Ok(MDBook {
root,
@ -334,25 +334,26 @@ fn determine_renderers(config: &Config) -> Vec<Box<Renderer>> {
}
/// Look at the `MDBook` and try to figure out what preprocessors to run.
fn determine_preprocessors(config: &Config) -> Vec<Box<Preprocessor>> {
fn determine_preprocessors(config: &Config) -> Result<Vec<Box<Preprocessor>>> {
let preprocess_list = match config.build.preprocess {
Some(ref p) => p,
// If no preprocessor field is set, default to the LinkPreprocessor. This allows you
// to disable the LinkPreprocessor by setting "preprocess" to an empty list.
None => return Ok(vec![Box::new(LinkPreprocessor::new())])
};
let mut preprocessors: Vec<Box<Preprocessor>> = Vec::new();
if let Some(preprocess_array) = config.get("preprocess").and_then(|o| o.as_array()) {
for key in preprocess_array.iter() {
match key.as_str() {
Some(key) if key == "links" => {
preprocessors.push(Box::new(LinkPreprocessor::new()))
}
_ => {}
}
for key in preprocess_list {
if key == "links" {
preprocessors.push(Box::new(LinkPreprocessor::new()))
} else {
bail!("{:?} is not a recognised preprocessor", key);
}
}
if preprocessors.is_empty() {
preprocessors.push(Box::new(LinkPreprocessor::new()))
}
preprocessors
Ok(preprocessors)
}
fn interpret_custom_renderer(key: &str, table: &Value) -> Box<Renderer> {
@ -410,4 +411,65 @@ mod tests {
assert_eq!(got.len(), 1);
assert_eq!(got[0].name(), "random");
}
#[test]
fn config_defaults_to_link_preprocessor_if_not_set() {
let cfg = Config::default();
// make sure we haven't got anything in the `output` table
assert!(cfg.build.preprocess.is_none());
let got = determine_preprocessors(&cfg);
assert!(got.is_ok());
assert_eq!(got.as_ref().unwrap().len(), 1);
assert_eq!(got.as_ref().unwrap()[0].name(), "links");
}
#[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]
fn config_complains_if_unimplemented_preprocessor() {
let cfg_str: &'static str = r#"
[book]
title = "Some Book"
[build]
build-dir = "outputs"
create-missing = false
preprocess = ["random"]
"#;
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_err());
}
}

View File

@ -329,6 +329,9 @@ pub struct BuildConfig {
/// Should non-existent markdown files specified in `SETTINGS.md` be created
/// if they don't exist?
pub create_missing: bool,
/// Which preprocessors should be applied
pub preprocess: Option<Vec<String>>,
}
impl Default for BuildConfig {
@ -336,6 +339,7 @@ impl Default for BuildConfig {
BuildConfig {
build_dir: PathBuf::from("book"),
create_missing: true,
preprocess: None,
}
}
}
@ -422,6 +426,7 @@ mod tests {
[build]
build-dir = "outputs"
create-missing = false
preprocess = ["first_preprocessor", "second_preprocessor"]
[output.html]
theme = "./themedir"
@ -449,6 +454,8 @@ mod tests {
let build_should_be = BuildConfig {
build_dir: PathBuf::from("outputs"),
create_missing: false,
preprocess: Some(vec!["first_preprocessor".to_string(),
"second_preprocessor".to_string()]),
};
let playpen_should_be = Playpen {
editable: true,
@ -550,6 +557,7 @@ mod tests {
let build_should_be = BuildConfig {
build_dir: PathBuf::from("my-book"),
create_missing: true,
preprocess: None,
};
let html_should_be = HtmlConfig {

View File

@ -19,6 +19,10 @@ impl LinkPreprocessor {
}
impl Preprocessor for LinkPreprocessor {
fn name(&self) -> &str {
"links"
}
fn run(&self, ctx: &PreprocessorContext, book: &mut Book) -> Result<()> {
for section in &mut book.sections {
match *section {

View File

@ -12,5 +12,6 @@ pub struct PreprocessorContext {
}
pub trait Preprocessor {
fn name(&self) -> &str;
fn run(&self, ctx: &PreprocessorContext, book: &mut Book) -> Result<()>;
}