From 8d09cac27163e55e2ea97d63065bee3c9afaa06d Mon Sep 17 00:00:00 2001 From: viridian Date: Mon, 1 Apr 2024 19:05:53 +0200 Subject: [PATCH] Changed usage to generate from dir --- .gitignore | 4 +- Cargo.lock | 135 ++++++++++++++++++++++++++++++++++++++++++++++++-- Cargo.toml | 4 ++ src/config.rs | 14 ++++++ src/lib.rs | 104 ++++++++++++++++++++++++++++++++++++++ src/main.rs | 87 +++++--------------------------- 6 files changed, 267 insertions(+), 81 deletions(-) create mode 100644 src/config.rs create mode 100644 src/lib.rs diff --git a/.gitignore b/.gitignore index b1827b9..d3d6cd7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ /target /templates -test_md.md +/output +/md_src +mlem.toml diff --git a/Cargo.lock b/Cargo.lock index eb5e535..fe33f09 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -83,7 +83,9 @@ checksum = "8a0d04d43504c61aa6c7531f1871dd0d418d91130162063b789da00fd7057a5e" dependencies = [ "android-tzdata", "iana-time-zone", + "js-sys", "num-traits", + "wasm-bindgen", "windows-targets", ] @@ -109,6 +111,12 @@ dependencies = [ "phf_codegen", ] +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + [[package]] name = "core-foundation-sys" version = "0.8.6" @@ -159,6 +167,19 @@ dependencies = [ "typenum", ] +[[package]] +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version", + "syn 1.0.109", +] + [[package]] name = "deunicode" version = "1.4.3" @@ -175,6 +196,12 @@ dependencies = [ "crypto-common", ] +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + [[package]] name = "generic-array" version = "0.14.7" @@ -220,6 +247,12 @@ dependencies = [ "walkdir", ] +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" + [[package]] name = "humansize" version = "2.1.3" @@ -268,6 +301,16 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "indexmap" +version = "2.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +dependencies = [ + "equivalent", + "hashbrown", +] + [[package]] name = "itoa" version = "1.0.11" @@ -326,9 +369,13 @@ checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" name = "mlem" version = "0.1.0" dependencies = [ + "chrono", + "derive_more", "markdown", "regex", + "serde", "tera", + "toml", ] [[package]] @@ -392,7 +439,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn", + "syn 2.0.57", ] [[package]] @@ -527,6 +574,15 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + [[package]] name = "ryu" version = "1.0.17" @@ -542,6 +598,12 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "semver" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" + [[package]] name = "serde" version = "1.0.197" @@ -559,7 +621,7 @@ checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.57", ] [[package]] @@ -573,6 +635,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_spanned" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" +dependencies = [ + "serde", +] + [[package]] name = "sha2" version = "0.10.8" @@ -600,6 +671,17 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "syn" version = "2.0.57" @@ -650,7 +732,41 @@ checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.57", +] + +[[package]] +name = "toml" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e40bb779c5187258fd7aad0eb68cb8706a0a81fa712fbea808ab43c4b8374c4" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", ] [[package]] @@ -770,7 +886,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn", + "syn 2.0.57", "wasm-bindgen-shared", ] @@ -792,7 +908,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.57", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -899,3 +1015,12 @@ name = "windows_x86_64_msvc" version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" + +[[package]] +name = "winnow" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dffa400e67ed5a4dd237983829e66475f0a4a26938c4b04c21baede6262215b8" +dependencies = [ + "memchr", +] diff --git a/Cargo.toml b/Cargo.toml index 465573d..149022d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,3 +9,7 @@ edition = "2021" markdown = "1.0.0-alpha.16" tera = "1.0" regex = "1.0" +toml = "0.8" +serde = { version = "1.0", features = ["derive"]} +chrono = "0.4" +derive_more = "0.99" diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..0643a15 --- /dev/null +++ b/src/config.rs @@ -0,0 +1,14 @@ +use serde::Deserialize; +use std::fs::read_to_string; + +#[derive(Deserialize)] +pub struct Config { + pub output_dir: String, + pub src_dir: String, + pub templates_dir: String, +} + +pub fn read_config() -> Config { + let config_string = read_to_string("mlem.toml").expect("mlem.toml config not found"); + toml::from_str(&config_string).unwrap() +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..c2cc13c --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,104 @@ +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::{read_dir, read_to_string, self}; +use std::path::PathBuf; +use tera::{Context, Tera}; + +pub fn read_src_files(src_dir: &str) -> Vec { + let mut files: Vec = 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, + pub file_name: OsString, +} + +pub fn generate_blog_entry(markdown: String,template_dir: &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::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() +} + +pub 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) +} diff --git a/src/main.rs b/src/main.rs index dc566ca..3d8dd6d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,79 +1,16 @@ -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}; +use std::fs::read_to_string; +mod config; +// mod lib; +use mlem::*; fn main() { - let args: Vec = env::args().collect(); - if args.len() < 2 { - panic!("Please provide md file"); + let config = config::read_config(); + + let raw_files = read_src_files(&config.src_dir); + for file in raw_files { + let markdown = read_to_string(file.path).expect("File does not exist"); + let html = generate_blog_entry(markdown,&config.templates_dir); + write_to_fs(html, &config.output_dir, &file.file_name.into_string().unwrap()); } - 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) + // println!("{}", generate_blog_entry(markdown)); }