diff options
| -rw-r--r-- | src/lexer/Lexed.zig | 3 | ||||
| -rw-r--r-- | src/paragraph.zig | 11 | ||||
| -rw-r--r-- | src/parser.zig | 35 | ||||
| -rw-r--r-- | src/title.zig | 23 |
4 files changed, 59 insertions, 13 deletions
diff --git a/src/lexer/Lexed.zig b/src/lexer/Lexed.zig index 4101953..46fd552 100644 --- a/src/lexer/Lexed.zig +++ b/src/lexer/Lexed.zig @@ -23,8 +23,7 @@ pub const Kind = enum { pub fn isDelimiter(self: @This()) bool { return switch (self) { - .weak_delimiter => true, - .strong_delimiter => true, + .weak_delimiter, .strong_delimiter => true, else => false, }; } diff --git a/src/paragraph.zig b/src/paragraph.zig index 75651f4..86d074b 100644 --- a/src/paragraph.zig +++ b/src/paragraph.zig @@ -1,12 +1,13 @@ const std = @import("std"); +const Allocator = std.mem.Allocator; const Lexed = @import("lexer/Lexed.zig"); const Lexer = @import("lexer/Lexer.zig"); const Element = @import("dom/Element.zig"); -const Allocator = std.mem.Allocator; -const ast = @import("ast.zig"); -const Error = ast.Error; +const parser = @import("parser.zig"); + +pub const Error = error{UnclosedModifier} || Lexer.Error; -pub fn parseParagraph(alloc: Allocator, l: *Lexer) Error!Element { +pub fn parse(alloc: Allocator, l: *Lexer) Error!Element { var el = try Element.init(alloc, .content, "p"); while (l.nextKind()) |kind| { switch (kind) { @@ -38,7 +39,7 @@ pub fn parseContent(alloc: Allocator, l: *Lexer) Error!Element { .bold => try content.appendContent(try parseModifier(alloc, l, .bold, "b")), .italic => try content.appendContent(try parseModifier(alloc, l, .italic, "em")), .code => try content.appendContent(try parseModifier(alloc, l, .code, "code")), - else => return Error.InvalidSequence, + else => unreachable, } return content; } diff --git a/src/parser.zig b/src/parser.zig index e5a9ea2..5f8c676 100644 --- a/src/parser.zig +++ b/src/parser.zig @@ -1,15 +1,15 @@ const std = @import("std"); +const Allocator = std.mem.Allocator; const Lexed = @import("lexer/Lexed.zig"); const Lexer = @import("lexer/Lexer.zig"); const Element = @import("dom/Element.zig"); -const Allocator = std.mem.Allocator; const paragraph = @import("paragraph.zig"); +const title = @import("title.zig"); pub const Error = error{ InvalidSequence, - UnclosedModifier, FeatureNotSupported, -} || Lexer.Error; +} || Lexer.Error || paragraph.Error; pub fn parse(parent: Allocator, content: []const u8) Error![]const u8 { var arena = std.heap.ArenaAllocator.init(parent); @@ -20,10 +20,16 @@ pub fn parse(parent: Allocator, content: []const u8) Error![]const u8 { var l = try Lexer.init(content); while (l.nextKind()) |it| { - switch (it) { - .literal, .bold, .italic, .code => try elements.append(alloc, try paragraph.parseParagraph(alloc, &l)), + try elements.append(alloc, switch (it) { + .literal, .bold, .italic, .code => try paragraph.parse(alloc, &l), + .title => try title.parse(alloc, &l), + .weak_delimiter, .strong_delimiter => { + var v = (try l.next(alloc)).?; + v.deinit(); + continue; + }, else => return Error.FeatureNotSupported, - } + }); } var res = try std.ArrayList(u8).initCapacity(parent, elements.items.len); @@ -60,3 +66,20 @@ test "parse paragraphs" { \\in new paragraph , "<p>hello world</p><p>foo bar in new paragraph</p>"); } + +test "parse title" { + var arena = std.heap.DebugAllocator(.{}).init; + defer if (arena.deinit() == .leak) std.debug.print("leaking!\n", .{}); + const alloc = arena.allocator(); + + try doTest(alloc, "# hey", "<h1>hey</h1>"); + try doTest(alloc, "## hey", "<h2>hey</h2>"); + try doTest(alloc, "### hey", "<h3>hey</h3>"); + + try doTest(alloc, + \\# title + \\hello world ;3 + \\## subtitle + \\hehe + , "<h1>title</h1><p>hello world ;3</p><h2>subtitle</h2><p>hehe</p>"); +} diff --git a/src/title.zig b/src/title.zig new file mode 100644 index 0000000..88848e5 --- /dev/null +++ b/src/title.zig @@ -0,0 +1,23 @@ +const std = @import("std"); +const Allocator = std.mem.Allocator; +const Lexed = @import("lexer/Lexed.zig"); +const Lexer = @import("lexer/Lexer.zig"); +const Element = @import("dom/Element.zig"); +const paragraph = @import("paragraph.zig"); + +pub const Error = paragraph.Error || Lexer.Error; + +pub fn parse(alloc: Allocator, l: *Lexer) Error!Element { + const v = (try l.next(alloc)).?; + var el = try Element.init(alloc, .content, switch (v.content.items.len) { + 1 => "h1", + 2 => "h2", + 3 => "h3", + 4 => "h4", + 5 => "h5", + 6 => "h6", + else => unreachable, + }); + try el.appendContent(try paragraph.parseContent(alloc, l)); + return el; +} |
