58eb79e53d
Add support for postprocessing of Markdown prior to writing converted notes to disk. Postprocessors may be used when making use of Obsidian export as a Rust library to do the following: 1. Modify a note's `Context`, for example to change the destination filename or update its Frontmatter. 2. Change a note's contents by altering `MarkdownEvents`. 3. Prevent later postprocessors from running or cause a note to be skipped entirely. Future releases of Obsidian export may come with built-in postprocessors for users of the command-line tool to use, if general use-cases can be identified. For example, a future release might include functionality to make notes more suitable for the Hugo static site generator. This functionality would be implemented as a postprocessor that could be enabled through command-line flags.
93 lines
2.3 KiB
Rust
93 lines
2.3 KiB
Rust
use serde_yaml::Result;
|
|
|
|
/// YAML front matter from an Obsidian note.
|
|
///
|
|
/// This is essentially an alias of [serde_yaml::Mapping] so all the methods available on that type
|
|
/// are available with `Frontmatter` as well.
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```
|
|
/// # use obsidian_export::Frontmatter;
|
|
/// use serde_yaml::Value;
|
|
///
|
|
/// let mut frontmatter = Frontmatter::new();
|
|
/// let key = Value::String("foo".to_string());
|
|
///
|
|
/// frontmatter.insert(
|
|
/// key.clone(),
|
|
/// Value::String("bar".to_string()),
|
|
/// );
|
|
///
|
|
/// assert_eq!(
|
|
/// frontmatter.get(&key),
|
|
/// Some(&Value::String("bar".to_string())),
|
|
/// )
|
|
/// ```
|
|
pub type Frontmatter = serde_yaml::Mapping;
|
|
|
|
pub fn frontmatter_from_str(mut s: &str) -> Result<Frontmatter> {
|
|
if s.is_empty() {
|
|
s = "{}";
|
|
}
|
|
let frontmatter: Frontmatter = serde_yaml::from_str(s)?;
|
|
Ok(frontmatter)
|
|
}
|
|
|
|
pub fn frontmatter_to_str(frontmatter: Frontmatter) -> Result<String> {
|
|
if frontmatter.is_empty() {
|
|
return Ok("---\n---\n".to_string());
|
|
}
|
|
|
|
let mut buffer = String::new();
|
|
buffer.push_str(&serde_yaml::to_string(&frontmatter)?);
|
|
buffer.push_str("---\n");
|
|
Ok(buffer)
|
|
}
|
|
|
|
#[derive(Debug, Clone, Copy)]
|
|
/// Available strategies for the inclusion of frontmatter in notes.
|
|
pub enum FrontmatterStrategy {
|
|
/// Copy frontmatter when a note has frontmatter defined.
|
|
Auto,
|
|
/// Always add frontmatter header, including empty frontmatter when none was originally
|
|
/// specified.
|
|
Always,
|
|
/// Never add any frontmatter to notes.
|
|
Never,
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
use pretty_assertions::assert_eq;
|
|
use serde_yaml::Value;
|
|
|
|
#[test]
|
|
fn empty_string_should_yield_empty_frontmatter() {
|
|
assert_eq!(frontmatter_from_str("").unwrap(), Frontmatter::new())
|
|
}
|
|
|
|
#[test]
|
|
fn empty_frontmatter_to_str() {
|
|
let frontmatter = Frontmatter::new();
|
|
assert_eq!(
|
|
frontmatter_to_str(frontmatter).unwrap(),
|
|
format!("---\n---\n")
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
fn nonempty_frontmatter_to_str() {
|
|
let mut frontmatter = Frontmatter::new();
|
|
frontmatter.insert(
|
|
Value::String("foo".to_string()),
|
|
Value::String("bar".to_string()),
|
|
);
|
|
assert_eq!(
|
|
frontmatter_to_str(frontmatter).unwrap(),
|
|
format!("---\nfoo: bar\n---\n")
|
|
)
|
|
}
|
|
}
|