diff --git a/parser.zig b/parser.zig index 42a4ac7..7edd7ea 100644 --- a/parser.zig +++ b/parser.zig @@ -131,13 +131,41 @@ fn checkIfBlockStillMatches(line: *[]const u8, block: Block) bool { }, }; } -fn getHeadingLevel(line: []const u8) u8 { - var level: u8 = 0; - for (line) |char| { - if (level == 6) break; - if (char == '#') level += 1 else break; + +const ATXHeading = struct { + spaces: u2, + level: u3, + pub fn content(self: ATXHeading, line: []const u8) []const u8 { + if (line.len > self.spaces + self.level) { + return line[self.spaces + self.level + 1 ..]; + } else { + // If it's an empty heading without a space (example 79) + return line[self.spaces + self.level ..]; + } } - return level; +}; + +fn parseATXHeading(line: []const u8) ?ATXHeading { + var spaces: u2 = 0; + for (line) |char| { + if (char == ' ' and spaces != 3) + spaces += 1 + else if (char == '#') + break + else + return null; + } + var level: u3 = 0; + for (line[spaces..]) |char| { + if (char == '#' and level != 6) + level += 1 + else if (char == ' ' or char == '\t' or char == '\n') + break + else + return null; + } + if (level == 0) return null; + return ATXHeading{ .level = level, .spaces = spaces }; } fn checkIfBlockStarts(allocator: std.mem.Allocator, line: *[]const u8) !?Block { if (std.mem.startsWith(u8, line.*, ">")) { @@ -152,15 +180,11 @@ fn checkIfBlockStarts(allocator: std.mem.Allocator, line: *[]const u8) !?Block { .kind = .{ .bullet = '*' }, .tight = false, } }; - } else if (std.mem.startsWith(u8, line.*, "#")) { - const level = getHeadingLevel(line.*); - if (line.*[level..].len != 0) { - if (line.*[level] != ' ' and line.*[level] != '\t') return null; - line.* = line.*[level + 1 ..]; - } + } else if (parseATXHeading(line.*)) |heading| { + line.* = heading.content(line.*); return Block{ .heading = .{ .text = try allocator.alloc(u8, 0), - .level = level, + .level = heading.level, } }; } return null; diff --git a/readme.md b/readme.md index 9368c91..97861e0 100644 --- a/readme.md +++ b/readme.md @@ -19,7 +19,7 @@ Ver [cli.zig](cli.zig) ## CommonMark -Actualmente: `122 passed, 530 failed, 0 errored, 0 skipped` +Actualmente: `123 passed, 529 failed, 0 errored, 0 skipped` Para correr los tests: