63 lines
1.9 KiB
Rust
63 lines
1.9 KiB
Rust
use glob::glob;
|
|
use rake::{Rake, StopWords};
|
|
use serde::{Deserialize, Serialize};
|
|
use serde_yml;
|
|
use std::fs;
|
|
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
struct MetaData {
|
|
categories: Vec<String>,
|
|
date: String,
|
|
tags: Vec<String>,
|
|
title: String,
|
|
keywords: Option<Vec<String>>, // Optional field to append keywords
|
|
}
|
|
|
|
pub fn parse(directory_path: &str) -> Result<(), Box<dyn std::error::Error>> {
|
|
let stop_words = StopWords::from_file("static/stoplist.txt")?;
|
|
let rake = Rake::new(stop_words);
|
|
|
|
for entry in glob(format!("{}/**/*.md", directory_path).as_str())? {
|
|
let path = entry?;
|
|
let contents = fs::read_to_string(path.clone())?;
|
|
|
|
// remove leading ---
|
|
let contents = contents.lines().skip(1).collect::<Vec<&str>>().join("\n");
|
|
|
|
// Split the Markdown content from the metadata
|
|
if let Some(split_index) = contents.find("---\n\n") {
|
|
let (front_matter, content) = contents.split_at(split_index);
|
|
|
|
let mut metadata: MetaData = serde_yml::from_str(front_matter)?;
|
|
|
|
// Extract keywords using RAKE
|
|
let keywords = rake.run(content);
|
|
|
|
// Append keywords to metadata
|
|
metadata.keywords = Some(keywords.iter().map(|kw| kw.keyword.to_string()).collect());
|
|
|
|
// Serialize the metadata back to YAML and write to the file
|
|
let new_front_matter = serde_yml::to_string(&metadata)?;
|
|
// add back leading ---
|
|
let new_front_matter = format!("---\n\n{}", new_front_matter);
|
|
|
|
let new_contents = format!("{}\n\n{}", new_front_matter, content);
|
|
fs::write(path, new_contents)?;
|
|
}
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_parse() {
|
|
let directory_path = "static";
|
|
let result = parse(directory_path);
|
|
assert!(result.is_ok());
|
|
}
|
|
}
|