diff --git a/src/postprocessors.rs b/src/postprocessors.rs index 5537b00..2ca4183 100644 --- a/src/postprocessors.rs +++ b/src/postprocessors.rs @@ -23,26 +23,84 @@ pub fn filter_by_tags( only_tags: Vec, ) -> impl Fn(&mut Context, &mut MarkdownEvents) -> PostprocessorResult { move |context: &mut Context, _events: &mut MarkdownEvents| -> PostprocessorResult { - if !skip_tags.is_empty() || !only_tags.is_empty() { - match context.frontmatter.get("tags") { - Some(Value::Sequence(tags)) => { - let skip = skip_tags - .iter() - .any(|tag| tags.contains(&Value::String(tag.to_string()))); - let include = only_tags.is_empty() - || only_tags - .iter() - .any(|tag| tags.contains(&Value::String(tag.to_string()))); - if skip || !include { - PostprocessorResult::StopAndSkipNote - } else { - PostprocessorResult::Continue - } - } - _ => PostprocessorResult::Continue, - } - } else { - PostprocessorResult::Continue + match context.frontmatter.get("tags") { + None => filter_by_tags_(&[], &skip_tags, &only_tags), + Some(Value::Sequence(tags)) => filter_by_tags_(tags, &skip_tags, &only_tags), + _ => PostprocessorResult::Continue, } } } + +fn filter_by_tags_( + tags: &[Value], + skip_tags: &[String], + only_tags: &[String], +) -> PostprocessorResult { + let skip = skip_tags + .iter() + .any(|tag| tags.contains(&Value::String(tag.to_string()))); + let include = only_tags.is_empty() + || only_tags + .iter() + .any(|tag| tags.contains(&Value::String(tag.to_string()))); + + if skip || !include { + PostprocessorResult::StopAndSkipNote + } else { + PostprocessorResult::Continue + } +} + +#[test] +fn test_filter_tags() { + let tags = vec![ + Value::String("skip".to_string()), + Value::String("publish".to_string()), + ]; + let empty_tags = vec![]; + assert_eq!( + filter_by_tags_(&empty_tags, &[], &[]), + PostprocessorResult::Continue, + "When no exclusion & inclusion are specified, files without tags are included" + ); + assert_eq!( + filter_by_tags_(&tags, &[], &[]), + PostprocessorResult::Continue, + "When no exclusion & inclusion are specified, files with tags are included" + ); + assert_eq!( + filter_by_tags_(&tags, &["exclude".to_string()], &[]), + PostprocessorResult::Continue, + "When exclusion tags don't match files with tags are included" + ); + assert_eq!( + filter_by_tags_(&empty_tags, &["exclude".to_string()], &[]), + PostprocessorResult::Continue, + "When exclusion tags don't match files without tags are included" + ); + assert_eq!( + filter_by_tags_(&tags, &[], &["publish".to_string()]), + PostprocessorResult::Continue, + "When exclusion tags don't match files with tags are included" + ); + assert_eq!( + filter_by_tags_(&empty_tags, &[], &["include".to_string()]), + PostprocessorResult::StopAndSkipNote, + "When inclusion tags are specified files without tags are excluded" + ); + assert_eq!( + filter_by_tags_(&tags, &[], &["include".to_string()]), + PostprocessorResult::StopAndSkipNote, + "When exclusion tags don't match files with tags are exluded" + ); + assert_eq!( + filter_by_tags_(&tags, &["skip".to_string()], &["skip".to_string()]), + PostprocessorResult::StopAndSkipNote, + "When both inclusion and exclusion tags are the same exclusion wins" + ); + assert_eq!( + filter_by_tags_(&tags, &["skip".to_string()], &["publish".to_string()]), + PostprocessorResult::StopAndSkipNote, + "When both inclusion and exclusion tags match exclusion wins" + ); +} diff --git a/tests/testdata/expected/filter-by-tags/no-frontmatter.md b/tests/testdata/expected/filter-by-tags/no-frontmatter.md deleted file mode 100644 index 427b0ea..0000000 --- a/tests/testdata/expected/filter-by-tags/no-frontmatter.md +++ /dev/null @@ -1 +0,0 @@ -A note without frontmatter should be exported. diff --git a/tests/testdata/expected/filter-by-tags/no-tags.md b/tests/testdata/expected/filter-by-tags/no-tags.md deleted file mode 100644 index fdc5f81..0000000 --- a/tests/testdata/expected/filter-by-tags/no-tags.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: foo ---- - -A public note.