Compare commits
5 commits
b58c5ce8ca
...
3ccaba3104
Author | SHA1 | Date | |
---|---|---|---|
3ccaba3104 | |||
3875e464a6 | |||
7c1887b8b0 | |||
c12e89a3e5 | |||
fadda3c05f |
5 changed files with 85 additions and 25 deletions
2
cli.zig
2
cli.zig
|
@ -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
|
100
parser.zig
100
parser.zig
|
@ -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 {
|
||||||
|
spaces: u2,
|
||||||
|
level: u3,
|
||||||
|
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];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fn parseATXHeading(line: []const u8) ?ATXHeading {
|
||||||
|
var spaces: u2 = 0;
|
||||||
for (line) |char| {
|
for (line) |char| {
|
||||||
if (level == 6) break;
|
if (char == ' ' and spaces != 3)
|
||||||
if (char == '#') level += 1 else break;
|
spaces += 1
|
||||||
|
else if (char == '#')
|
||||||
|
break
|
||||||
|
else
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
return level;
|
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;
|
||||||
}
|
}
|
||||||
fn checkIfBlockStarts(allocator: *std.mem.Allocator, line: *[]const u8) !?Block {
|
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 {
|
||||||
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();
|
||||||
|
|
||||||
|
|
|
@ -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:
|
||||||
|
|
||||||
|
|
|
@ -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:
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue