diff options
Diffstat (limited to 'src/skaldpress/metadata_parser.rs')
| -rw-r--r-- | src/skaldpress/metadata_parser.rs | 71 | 
1 files changed, 71 insertions, 0 deletions
diff --git a/src/skaldpress/metadata_parser.rs b/src/skaldpress/metadata_parser.rs new file mode 100644 index 0000000..7a91b74 --- /dev/null +++ b/src/skaldpress/metadata_parser.rs @@ -0,0 +1,71 @@ +use std::collections::HashMap; +use std::fmt; + +#[derive(Debug)] +pub enum YamlValue { +    Scalar(String), +    List(Vec<String>), +} + +impl fmt::Display for YamlValue { +    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +        match self { +            YamlValue::Scalar(x) => write!(f, "{}", x), +            YamlValue::List(_l) => write!(f, "List<String>"), +        } +    } +} + +/// Currently, all files MUST have a metadata block, or this will fail completely +pub fn extract_parse_yaml_metadata<'a>(markdown: &'a str) -> (HashMap<String, YamlValue>, &'a str) { +    let mut yaml_map = HashMap::new(); +    let lines = markdown.lines(); +    let mut yaml_started = false; +    let mut yaml_ended = false; +    let mut end_index = 0; +    let mut current_key: Option<String> = None; +    let mut current_list: Vec<String> = Vec::new(); + +    for (i, line) in lines.enumerate() { +        if line.trim() == "---" { +            if yaml_started { +                yaml_ended = true; +                end_index = markdown.lines().take(i + 1).map(|l| l.len() + 1).sum(); +                break; +            } else { +                yaml_started = true; +            } +        } else if yaml_started && !yaml_ended { +            if line.trim().starts_with('-') && current_key.is_some() { +                current_list.push(line.trim().trim_start_matches('-').trim().to_string()); +            } else if let Some((key, value)) = line.split_once(':') { +                if let Some(key) = current_key.take() { +                    if !current_list.is_empty() { +                        yaml_map.insert(key, YamlValue::List(current_list.clone())); +                        current_list.clear(); +                    } +                } +                current_key = Some(key.trim().to_string()); +                if !value.trim().is_empty() { +                    yaml_map.insert( +                        current_key.clone().unwrap(), +                        YamlValue::Scalar(value.trim().to_string()), +                    ); +                    current_key = None; +                } +            } +        } +    } + +    if let Some(key) = current_key.take() { +        if !current_list.is_empty() { +            yaml_map.insert(key, YamlValue::List(current_list)); +        } +    } + +    if !yaml_ended { +        end_index = markdown.len(); +    } + +    (yaml_map, &markdown[end_index..]) +}  | 
