aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lexer/Lexed.zig3
-rw-r--r--src/paragraph.zig11
-rw-r--r--src/parser.zig35
-rw-r--r--src/title.zig23
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;
+}