49 lines
1.6 KiB
Rust
49 lines
1.6 KiB
Rust
use anyhow::Result;
|
|
use serde::{Serialize, Deserialize};
|
|
use regex::Regex;
|
|
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
pub struct Metadata {
|
|
title: Option<String>,
|
|
date: Option<toml::value::Datetime>,
|
|
}
|
|
|
|
|
|
/// Return the extracted content (without the frontmatter)
|
|
/// and an array of key/value pairs to set as pandoc metadata
|
|
/// We don't rely on inline metadata block (YAML frontmatter)
|
|
/// because pandoc does not support it with CommonMark
|
|
pub fn extract(content: &str) -> Result<(String, Vec<(String, String)>)> {
|
|
let toml_regex = Regex::new(r"^[[:space:]]*\+\+\+\r?\n((?s).*?(?-s))\+\+\+\r?\n?((?s).*(?-s))$").unwrap();
|
|
if !toml_regex.is_match(content) {
|
|
return Ok((content.to_string(), Vec::new()));
|
|
}
|
|
|
|
let caps = toml_regex.captures(content).unwrap();
|
|
// caps[0] is the full match
|
|
// caps[1] => front matter
|
|
// caps[2] => content
|
|
|
|
let content = caps[2].to_string();
|
|
|
|
// Naively, i wanted to turn the TOML to YAML directly
|
|
// However, TOML dates produce weird YAML so let's go manual
|
|
|
|
/*let mut values: toml::Value = toml::from_str(&caps[1])?;
|
|
let table = values.as_table_mut().unwrap();
|
|
let date = */
|
|
//println!("{:?}", &caps[1]);
|
|
//let metadata: Metadata = toml::from_str(&caps[1])?;
|
|
//println!("ok");
|
|
|
|
let frontmatter: toml::Value = toml::from_str(&caps[1])?;
|
|
let table = frontmatter.as_table().unwrap();
|
|
|
|
let mut metadata: Vec<(String, String)> = Vec::new();
|
|
for (key, value) in table.iter() {
|
|
metadata.push((key.to_string(), value.to_string()));
|
|
}
|
|
|
|
Ok((content, metadata))
|
|
}
|