commit cf2f714a8988b299dff993cbee9ddbf86c8372d2 from: Murilo Ijanc date: Fri Apr 3 18:04:46 2026 UTC parse frontmatter from markdown ast commit - 58c421947dc5b2652691c0e830c78e6d977c9762 commit + cf2f714a8988b299dff993cbee9ddbf86c8372d2 blob - ea8c4bf7f35f6f77f75d92ad8ce8349f6e81ddba blob + 814a7a92844f5ca7540b13920185dadb11dec250 --- .gitignore +++ .gitignore @@ -1 +1,2 @@ -/target +target +public blob - 34829f000703757e6f9a7b21fa38e7a2bfba4c29 blob + ac926753bad217c67bf4ff1f883ebd19e30fa12d --- content/index.md +++ content/index.md @@ -1,8 +1,11 @@ --- title: Hello kssg date: 2026-04-03 +draft: true --- # Bem-Vindo Esse é o **primeiro post** gerado pelo kssg. + +Esse conteúdo não aparece pois está como draft. blob - 9f9c5eb7fb1b43b5b1c28d7f1e62102f998f0159 blob + baa7948ca14aef00755b9ee961de492c7fbcf862 --- src/main.rs +++ src/main.rs @@ -15,7 +15,7 @@ // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. // -use std::{env, fs}; +use std::{env, fs, collections::HashMap}; fn main() { let args: Vec = env::args().collect(); @@ -27,6 +27,56 @@ fn main() { } ////////////////////////////////////////////////////////////////////////////// +// Frontmatter +////////////////////////////////////////////////////////////////////////////// + +#[allow(dead_code)] +struct Metadata { + title: String, + date: String, + draft: bool, + series: Option, + part: Option, +} + +fn parse_options() -> markdown::ParseOptions { + markdown::ParseOptions { + constructs: markdown::Constructs { + frontmatter: true, + ..markdown::Constructs::default() + }, + ..markdown::ParseOptions::default() + } +} + +fn parse_frontmatter(content: &str) -> Metadata { + let tree = markdown::to_mdast(content, &parse_options()) + .expect("parse mdast"); + let mut map = HashMap::new(); + + if let markdown::mdast::Node::Root(root) = tree { + for node in &root.children { + if let markdown::mdast::Node::Yaml(yaml) = node { + for line in yaml.value.lines() { + if let Some((k, v)) = line.split_once(':') { + map.insert(k.trim().to_string(), v.trim().to_string()); + } + } + } + } + } + + Metadata { + title: map.remove("title").unwrap_or_default(), + date: map.remove("date").unwrap_or_default(), + draft: map.get("draft").map(|v| v == "true").unwrap_or(false), + series: map.remove("series"), + part: map.get("part").and_then(|v| v.parse().ok()), + } +} + + +////////////////////////////////////////////////////////////////////////////// // Build ////////////////////////////////////////////////////////////////////////////// @@ -36,9 +86,19 @@ fn build() { let template = fs::read_to_string("templates/base.html") .expect("read templates/base.html"); - let html_content = markdown::to_html(&md); + let meta = parse_frontmatter(&md); - let output = template.replace("{{title}}", "kssg") + if meta.draft { + return; + } + + let html_content = markdown::to_html_with_options(&md, &markdown::Options { + parse: parse_options(), + ..markdown::Options::default() + }).expect("markdown to html"); + + let output = template + .replace("{{title}}", &meta.title) .replace("{{content}}", &html_content); fs::create_dir_all("public").expect("create public/");