]> git.frustrated-labs.net Git - frustrated-functor.dev.git/commitdiff
parse paragraphs
authorAlexander Goussas <[email protected]>
Thu, 16 Apr 2026 03:30:08 +0000 (22:30 -0500)
committerAlexander Goussas <[email protected]>
Thu, 16 Apr 2026 03:30:08 +0000 (22:30 -0500)
bin/blog-processor/src/markdown_parser.zig

index c4b8901e355943ca67313f74619862ca33b52de9..f4722eda26c4f5817bdec583b9da7be1aa91dd24 100644 (file)
@@ -58,7 +58,7 @@ pub const MarkdownDoc = struct {
                         try parse_header_1(alloc, doc, current, nodes);
                     }
                 },
-                else => try parse_paragraph(doc, current, nodes),
+                else => try parse_paragraph(alloc, doc, current, nodes),
             }
         }
     }
@@ -100,10 +100,31 @@ pub const MarkdownDoc = struct {
         }
     }
 
-    fn parse_paragraph(doc: []const u8, current: *usize, nodes: *std.ArrayList(MarkdownNode)) !void {
-        _ = doc;
-        _ = current;
-        _ = nodes;
+    fn parse_paragraph(alloc: std.mem.Allocator, doc: []const u8, current: *usize, nodes: *std.ArrayList(MarkdownNode)) !void {
+        const start = current.*;
+        var end = start;
+
+        while (current.* < doc.len) {
+            if (doc[current.*] != '\n') {
+                current.* += 1;
+                continue;
+            }
+
+            current.* += 1;
+
+            if (current.* < doc.len and doc[current.*] == '\n') {
+                end = current.* - 1;
+                break;
+            }
+        }
+
+        if (current.* >= doc.len) {
+            end = doc.len;
+        }
+
+        try nodes.append(alloc, .{ .p = doc[start .. end] });
+
+        advanceWhile(doc, current, '\n');
     }
 
     fn parse_frontmatter(
@@ -239,3 +260,68 @@ test "can parse h2 in body without newline at end" {
     try std.testing.expectEqual(1, result.content.items.len);
     try std.testing.expectEqualStrings("The Post's Subtitle", result.content.items[0].h2);
 }
+
+test "can parse single multi-line paragraph at the beginning of document" {
+    const doc =
+        \\----
+        \\date: 12/04/2026
+        \\summary: This is the shit!
+        \\----
+        \\
+        \\Hello world,
+        \\this is my first post!
+        ;
+
+    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("Hello world,\nthis is my first post!", result.content.items[0].p);
+}
+
+test "can parse two single-line paragraphs at the beginning of document" {
+    const doc =
+        \\----
+        \\date: 12/04/2026
+        \\summary: This is the shit!
+        \\----
+        \\
+        \\Hello world,
+        \\
+        \\this is my first post!
+        ;
+
+    const alloc = std.testing.allocator;
+
+    var result = MarkdownDoc.parse(doc, alloc) catch unreachable;
+    defer result.deinit(alloc);
+
+    try std.testing.expectEqual(2, result.content.items.len);
+    try std.testing.expectEqualStrings("Hello world,", result.content.items[0].p);
+    try std.testing.expectEqualStrings("this is my first post!", result.content.items[1].p);
+}
+
+test "can parse single-line paragraph and multi-line parapgraphs at once at the beginning of document" {
+    const doc =
+        \\----
+        \\date: 12/04/2026
+        \\summary: This is the shit!
+        \\----
+        \\
+        \\Hello world,
+        \\
+        \\this is my first post!
+        \\Bye.
+        ;
+
+    const alloc = std.testing.allocator;
+
+    var result = MarkdownDoc.parse(doc, alloc) catch unreachable;
+    defer result.deinit(alloc);
+
+    try std.testing.expectEqual(2, result.content.items.len);
+    try std.testing.expectEqualStrings("Hello world,", result.content.items[0].p);
+    try std.testing.expectEqualStrings("this is my first post!\nBye.", result.content.items[1].p);
+}