109 lines
3.1 KiB
Rust
109 lines
3.1 KiB
Rust
use chrono::prelude::*;
|
|
use derive_more::Constructor;
|
|
use markdown::{to_html_with_options, CompileOptions, Options};
|
|
use regex::Regex;
|
|
use std::collections::HashMap;
|
|
use std::ffi::OsString;
|
|
use std::fs::{self, read_dir, read_to_string};
|
|
use std::path::PathBuf;
|
|
use tera::{Context, Tera};
|
|
|
|
pub fn read_src_files(src_dir: &str) -> Vec<SrcMD> {
|
|
let mut files: Vec<SrcMD> = Vec::new();
|
|
for file in read_dir(src_dir).expect("Cant read src dir") {
|
|
let file = file.unwrap();
|
|
let kv = get_kv(read_to_string(file.path()).unwrap()).0;
|
|
let title = kv.get("title").unwrap();
|
|
let date = kv.get("date").unwrap();
|
|
files.push(SrcMD::new(
|
|
file.path(),
|
|
title.to_string(),
|
|
DateTime::parse_from_str(&format!("{date} 00:00:00 +00:00"), "%Y-%m-%d %H:%M:%S %z")
|
|
.unwrap(),
|
|
file.path().file_stem().unwrap().to_os_string(),
|
|
))
|
|
}
|
|
|
|
files
|
|
}
|
|
|
|
pub fn write_to_fs(html: String, output_dir: &String, file_name: &String) {
|
|
fs::write(format!("{output_dir}/{file_name}.html"), html)
|
|
.unwrap_or_else(|_| panic!("Error writing {file_name}"));
|
|
}
|
|
|
|
#[derive(Constructor)]
|
|
pub struct SrcMD {
|
|
pub path: PathBuf,
|
|
pub title: String,
|
|
pub date: DateTime<FixedOffset>,
|
|
pub file_name: OsString,
|
|
}
|
|
|
|
pub fn generate_blog_entry(markdown: String, template_dir: &String) -> (String, String) {
|
|
let markdown = markdown.clone();
|
|
|
|
let mut tera = Tera::new(&format!("{template_dir}/*")).unwrap();
|
|
tera.autoescape_on(vec![]);
|
|
|
|
let (mut key_value, markdown) = get_kv(markdown);
|
|
|
|
let html_markdown = to_html_with_options(
|
|
&markdown,
|
|
&Options {
|
|
compile: CompileOptions {
|
|
allow_dangerous_html: true,
|
|
allow_dangerous_protocol: true,
|
|
..CompileOptions::default()
|
|
},
|
|
..Options::gfm()
|
|
},
|
|
)
|
|
.unwrap();
|
|
|
|
key_value.insert("blog_content".to_string(), html_markdown.clone());
|
|
|
|
let context = Context::from_serialize(&key_value).unwrap();
|
|
|
|
let templated_html = tera
|
|
.render(key_value.get("template").unwrap(), &context)
|
|
.unwrap();
|
|
(templated_html, html_markdown)
|
|
}
|
|
|
|
pub fn get_kv(markdown: String) -> (HashMap<String, String>, String) {
|
|
let re_key_value = Regex::new(r"(?ms)---(.*)---(?:\n)").unwrap();
|
|
|
|
let key_value_string = re_key_value
|
|
.find(markdown.as_str())
|
|
.expect("Can't find key value map in markdown");
|
|
|
|
let content_markdown = re_key_value
|
|
.replace(markdown.clone().as_str(), "")
|
|
.to_string();
|
|
|
|
let mut key_value: HashMap<String, String> = HashMap::new();
|
|
|
|
for line in key_value_string.as_str().lines() {
|
|
if line == "---" {
|
|
continue;
|
|
}
|
|
key_value.insert(
|
|
line.split(':')
|
|
.collect::<Vec<&str>>()
|
|
.first()
|
|
.unwrap()
|
|
.trim()
|
|
.to_string(),
|
|
line.split(':')
|
|
.collect::<Vec<&str>>()
|
|
.get(1)
|
|
.unwrap()
|
|
.trim()
|
|
.to_string(),
|
|
);
|
|
}
|
|
|
|
(key_value, content_markdown)
|
|
}
|