Compare commits

..

5 commits

5 changed files with 85 additions and 25 deletions

View file

@ -4,7 +4,7 @@ const aaronsw = @import("main.zig");
pub fn main() !void { pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){}; var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit(); defer _ = gpa.deinit();
const allocator = &gpa.allocator; const allocator = gpa.allocator();
const str = try std.io.getStdIn().reader().readAllAlloc(allocator, 10241024); const str = try std.io.getStdIn().reader().readAllAlloc(allocator, 10241024);
defer allocator.free(str); defer allocator.free(str);

@ -1 +1 @@
Subproject commit 499ebbad90163881f51498c4c620652d0c66fb2e Subproject commit 3e26d562b76deaa634676b86ebdeeb2ed0e419d2

View file

@ -37,20 +37,20 @@ const Document = struct {
}; };
const Paragraph = struct { const Paragraph = struct {
text: []u8, text: []u8,
pub fn deinit(self: *Paragraph, allocator: *std.mem.Allocator) void { pub fn deinit(self: *Paragraph, allocator: std.mem.Allocator) void {
allocator.free(self.text); allocator.free(self.text);
} }
}; };
const Heading = struct { const Heading = struct {
level: u8, level: u8,
text: []u8, text: []u8,
pub fn deinit(self: *Heading, allocator: *std.mem.Allocator) void { pub fn deinit(self: *Heading, allocator: std.mem.Allocator) void {
allocator.free(self.text); allocator.free(self.text);
} }
}; };
const BlockQuote = struct { const BlockQuote = struct {
children: Children, children: Children,
pub fn deinit(self: *BlockQuote, _: *std.mem.Allocator) void { pub fn deinit(self: *BlockQuote, _: std.mem.Allocator) void {
deinitChildren(&self.children); deinitChildren(&self.children);
} }
}; };
@ -61,13 +61,13 @@ const List = struct {
kind: Kind, kind: Kind,
tight: bool, tight: bool,
children: Children, children: Children,
pub fn deinit(self: *List, _: *std.mem.Allocator) void { pub fn deinit(self: *List, _: std.mem.Allocator) void {
deinitChildren(&self.children); deinitChildren(&self.children);
} }
}; };
const ListItem = struct { const ListItem = struct {
children: Children, children: Children,
pub fn deinit(self: *ListItem, _: *std.mem.Allocator) void { pub fn deinit(self: *ListItem, _: std.mem.Allocator) void {
deinitChildren(&self.children); deinitChildren(&self.children);
} }
}; };
@ -79,7 +79,7 @@ fn arrayListAppend(comptime T: type, list: *std.ArrayList(T), item: T) !*T {
} }
fn reallocAppend( fn reallocAppend(
allocator: *std.mem.Allocator, allocator: std.mem.Allocator,
alloc_str: []u8, alloc_str: []u8,
append_str: []const u8, append_str: []const u8,
) ![]u8 { ) ![]u8 {
@ -131,15 +131,79 @@ fn checkIfBlockStillMatches(line: *[]const u8, block: Block) bool {
}, },
}; };
} }
fn getHeadingLevel(line: []const u8) u8 {
var level: u8 = 0; const ATXHeading = struct {
for (line) |char| { spaces: u2,
if (level == 6) break; level: u3,
if (char == '#') level += 1 else break; closing_sequence: usize,
closing_sequence_spaces: usize,
pub fn content(self: ATXHeading, line: []const u8) []const u8 {
// It's possible it might not have a space after the heading as it can
// be an empty heading.
const has_space: u1 = if (line.len > self.spaces + self.level) 1 else 0;
return line[self.spaces + self.level + has_space .. line.len - self.closing_sequence - self.closing_sequence_spaces];
} }
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;
var heading = ATXHeading{
.level = level,
.spaces = spaces,
.closing_sequence = 0,
.closing_sequence_spaces = 0,
};
closing_sequence_block: {
const rest = heading.content(line);
var closing_sequence: usize = 0;
var closing_sequence_spaces: usize = 0;
if (rest.len == 0) break :closing_sequence_block;
var i: usize = rest.len - 1;
while (i >= 0) : (i -= 1) {
const char = rest[i];
if (char == ' ')
closing_sequence_spaces += 1
else if (char == '#')
break
else
break :closing_sequence_block;
if (i == 0) break;
}
while (i >= 0) : (i -= 1) {
const char = rest[i];
if (char == '#')
closing_sequence += 1
else if (char == ' ' or char == '\t')
break
else
break :closing_sequence_block;
if (i == 0) break;
}
heading.closing_sequence = closing_sequence;
heading.closing_sequence_spaces = closing_sequence_spaces;
}
return heading;
} }
fn checkIfBlockStarts(allocator: *std.mem.Allocator, line: *[]const u8) !?Block { fn checkIfBlockStarts(allocator: std.mem.Allocator, line: *[]const u8) !?Block {
if (std.mem.startsWith(u8, line.*, ">")) { if (std.mem.startsWith(u8, line.*, ">")) {
line.* = line.*[1..]; line.* = line.*[1..];
const indent = detectIndent(line.*); const indent = detectIndent(line.*);
@ -152,15 +216,11 @@ fn checkIfBlockStarts(allocator: *std.mem.Allocator, line: *[]const u8) !?Block
.kind = .{ .bullet = '*' }, .kind = .{ .bullet = '*' },
.tight = false, .tight = false,
} }; } };
} else if (std.mem.startsWith(u8, line.*, "#")) { } else if (parseATXHeading(line.*)) |heading| {
const level = getHeadingLevel(line.*); line.* = heading.content(line.*);
if (line.*[level..].len != 0) {
if (line.*[level] != ' ' or line.*[level] != '\t') return null;
line.* = line.*[level + 1 ..];
}
return Block{ .heading = .{ return Block{ .heading = .{
.text = try allocator.alloc(u8, 0), .text = try allocator.alloc(u8, 0),
.level = level, .level = heading.level,
} }; } };
} }
return null; return null;
@ -193,7 +253,7 @@ fn verifyStack(stack: Stack) void {
} }
} }
pub fn parse(allocator: *std.mem.Allocator, str: []const u8) !Document { pub fn parse(allocator: std.mem.Allocator, str: []const u8) !Document {
var doc_block = Block{ .document = Document{ .children = Children.init(allocator) } }; var doc_block = Block{ .document = Document{ .children = Children.init(allocator) } };
errdefer doc_block.document.deinit(); errdefer doc_block.document.deinit();

View file

@ -19,7 +19,7 @@ Ver [cli.zig](cli.zig)
## CommonMark ## CommonMark
Actualmente: `114 passed, 538 failed, 0 errored, 0 skipped` Actualmente: `127 passed, 525 failed, 0 errored, 0 skipped`
Para correr los tests: Para correr los tests:

View file

@ -17,7 +17,7 @@ See [cli.zig](cli.zig)
## CommonMark ## CommonMark
Currently: `114 passed, 538 failed, 0 errored, 0 skipped` Currently: `127 passed, 525 failed, 0 errored, 0 skipped`
To run the tests: To run the tests: