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);
}
}
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;
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);
+}