Commit Diff


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<String> = env::args().collect();
@@ -27,6 +27,56 @@ fn main() {
 }
 
 //////////////////////////////////////////////////////////////////////////////
+// Frontmatter
+//////////////////////////////////////////////////////////////////////////////
+
+#[allow(dead_code)]
+struct Metadata {
+    title: String,
+    date: String,
+    draft: bool,
+    series: Option<String>,
+    part: Option<u32>,
+}
+
+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/");