use markdown::{to_html_with_options, CompileOptions, Options}; use regex::Regex; use std::collections::HashMap; use std::{env, fs::read_to_string}; use tera::{Context, Tera}; fn main() { let args: Vec = env::args().collect(); if args.len() < 2 { panic!("Please provide md file"); } let markdown = read_to_string(args.get(1).unwrap()).expect("File does not exist"); println!("{}", generate_blog_entry(markdown)); } fn generate_blog_entry(markdown: String) -> String { let markdown = markdown.clone(); let mut tera = Tera::new("templates/*").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::default() }, ) .unwrap(); key_value.insert("blog_content".to_string(), html_markdown); let context = Context::from_serialize(&key_value).unwrap(); tera.render(key_value.get("template").unwrap(), &context) .unwrap() } fn get_kv(markdown: String) -> (HashMap, 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 = HashMap::new(); for line in key_value_string.as_str().lines() { if line == "---" { continue; } key_value.insert( line.split(':') .collect::>().first() .unwrap() .trim() .to_string(), line.split(':') .collect::>() .get(1) .unwrap() .trim() .to_string(), ); } (key_value, content_markdown) }