From 9eebe4751a969dba19e9200ecf2c821f061580ea Mon Sep 17 00:00:00 2001 From: Max Schrader Date: Tue, 11 Jan 2022 16:04:32 -0600 Subject: [PATCH] rebased implementation done --- src/main.rs | 35 ++++++++++++++++++++++++++++++++++- src/postprocessors.rs | 24 ++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/src/main.rs b/src/main.rs index 902783d..ce35bfc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,6 @@ use eyre::{eyre, Result}; use gumdrop::Options; -use obsidian_export::postprocessors::softbreaks_to_hardbreaks; +use obsidian_export::postprocessors::{softbreaks_to_hardbreaks, create_yaml_includer}; use obsidian_export::{ExportError, Exporter, FrontmatterStrategy, WalkOptions}; use std::{env, path::PathBuf}; @@ -54,6 +54,30 @@ struct Opts { default = "false" )] hard_linebreaks: bool, + + #[options( + no_short, + long="front-matter-export-filtering", + help="Enables selectively exporting files only if they have matching YAML key set to true in the frontmatter", + default="false" + )] + front_matter_export_filtering: bool, + + #[options( + no_short, + long = "front-matter-filter-key", + help = "YAML key to use if front-matter-filtering is enables", + default = "export" + )] + front_matter_filter_key: String, + + #[options( + no_short, + long = "front-matter-filter-embeds", + help = "Exclude all embeds that do not have the front-matter-inclusion-key", + default = "false" + )] + front_matter_filter_embeds: bool, } fn frontmatter_strategy_from_str(input: &str) -> Result { @@ -90,6 +114,15 @@ fn main() { exporter.process_embeds_recursively(!args.no_recursive_embeds); exporter.walk_options(walk_options); + // Adding YAML export filter if + let yaml_postprocessor = create_yaml_includer(&args.front_matter_filter_key); + if args.front_matter_export_filtering { + exporter.add_postprocessor(&yaml_postprocessor); + if args.front_matter_filter_embeds { + exporter.add_embed_postprocessor(&yaml_postprocessor); + } + } + if args.hard_linebreaks { exporter.add_postprocessor(&softbreaks_to_hardbreaks); } diff --git a/src/postprocessors.rs b/src/postprocessors.rs index 0e8141e..7a0bbf9 100644 --- a/src/postprocessors.rs +++ b/src/postprocessors.rs @@ -2,6 +2,7 @@ use super::{Context, MarkdownEvents, PostprocessorResult}; use pulldown_cmark::Event; +use serde_yaml::Value; /// This postprocessor converts all soft line breaks to hard line breaks. Enabling this mimics /// Obsidian's _'Strict line breaks'_ setting. @@ -16,3 +17,26 @@ pub fn softbreaks_to_hardbreaks( } PostprocessorResult::Continue } + +// This function takes as input the YAML key to look for, then returns a new function (technically: +// a closure) which matches the signature of a postprocessor. +// +// This use of dynamic function building allows the capturing of the configuration (in this case +// the YAML key) without needing to store this data within the Exporter struct. +// +// (Ideally we could mark the return value as `-> impl Postprocessor` for readability, but we +// cannot use a type alias here, which is what `Postprocessor` is) +pub fn create_yaml_includer( + yaml_inclusion_key: &str, +) -> impl Fn(&mut Context, &mut MarkdownEvents) -> PostprocessorResult { + let key = serde_yaml::Value::String(yaml_inclusion_key.to_string()); + + // This bit creates and returns the closure. The `move` statement is needed to make it take + // ownership of `key` above. + move |context: &mut Context, _events: &mut MarkdownEvents| { + match context.frontmatter.get(&key) { + Some(Value::Bool(true)) => PostprocessorResult::Continue, + _ => PostprocessorResult::StopAndSkipNote, + } + } +}