]> git.frustrated-labs.net Git - frustrated-functor.dev.git/commitdiff
add parsing for h2 in markdown
authorAlexander Goussas <[email protected]>
Thu, 16 Apr 2026 02:57:32 +0000 (21:57 -0500)
committerAlexander Goussas <[email protected]>
Thu, 16 Apr 2026 02:57:32 +0000 (21:57 -0500)
bin/blog-processor/src/markdown_parser.zig

index 738d021447842f2fdbf78fe91c44786bf0813cfb..c4b8901e355943ca67313f74619862ca33b52de9 100644 (file)
@@ -53,7 +53,7 @@ pub const MarkdownDoc = struct {
             switch (doc[current.*]) {
                 '#' => {
                     if (current.* + 1 < doc.len and doc[current.* + 1] == '#') {
-                        try parse_header_2(doc, current, nodes);
+                        try parse_header_2(alloc, doc, current, nodes);
                     } else {
                         try parse_header_1(alloc, doc, current, nodes);
                     }
@@ -64,25 +64,42 @@ pub const MarkdownDoc = struct {
     }
 
     fn parse_header_1(alloc: std.mem.Allocator, doc: []const u8, current: *usize, nodes: *std.ArrayList(MarkdownNode)) !void {
+        try parse_header(alloc, doc, current, nodes, struct {
+            fn call(slice: []const u8) MarkdownNode {
+                return .{ .h1 = slice };
+            }
+        });
+    }
+
+    fn parse_header_2(alloc: std.mem.Allocator, doc: []const u8, current: *usize, nodes: *std.ArrayList(MarkdownNode)) !void {
+        try parse_header(alloc, doc, current, nodes, struct {
+            fn call(slice: []const u8) MarkdownNode {
+                return .{ .h2 = slice };
+            }
+        });
+    }
+
+    fn parse_header(
+        alloc: std.mem.Allocator,
+        doc: []const u8, 
+        current: *usize, 
+        nodes: *std.ArrayList(MarkdownNode),
+        headerFn: anytype
+    ) !void {
         try expectToken(doc, '#', current);
+        advanceWhile(doc, current, '#');
         advanceWhile(doc, current, ' ');
 
         const start = current.*;
 
         advanceWhileNot(doc, current, '\n');
-        try nodes.append(alloc, .{ .h1 = doc[start..current.*] });
+        try nodes.append(alloc, headerFn.call(doc[start..current.*]));
 
         if (current.* < doc.len and doc[current.*] == '\n') {
             current.* += 1;
         }
     }
 
-    fn parse_header_2(doc: []const u8, current: *usize, nodes: *std.ArrayList(MarkdownNode)) !void {
-        _ = doc;
-        _ = current;
-        _ = nodes;
-    }
-
     fn parse_paragraph(doc: []const u8, current: *usize, nodes: *std.ArrayList(MarkdownNode)) !void {
         _ = doc;
         _ = current;
@@ -203,3 +220,22 @@ test "can parse h1 in body without newline at end" {
     try std.testing.expectEqual(1, result.content.items.len);
     try std.testing.expectEqualStrings("The Post's Title", result.content.items[0].h1);
 }
+
+test "can parse h2 in body without newline at end" {
+    const doc =
+        \\----
+        \\date: 12/04/2026
+        \\summary: This is the shit!
+        \\----
+        \\
+        \\## The Post's Subtitle
+        ;
+
+    const alloc = std.testing.allocator;
+
+    var result = MarkdownDoc.parse(doc, alloc) catch unreachable;
+    defer result.deinit(alloc);
+
+    try std.testing.expectEqual(1, result.content.items.len);
+    try std.testing.expectEqualStrings("The Post's Subtitle", result.content.items[0].h2);
+}