aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/paragraph.zig26
-rw-r--r--src/parser.zig3
-rw-r--r--src/root.zig2
-rw-r--r--src/title.zig5
4 files changed, 31 insertions, 5 deletions
diff --git a/src/paragraph.zig b/src/paragraph.zig
index 8cdaeb0..222f376 100644
--- a/src/paragraph.zig
+++ b/src/paragraph.zig
@@ -5,10 +5,11 @@ const Lexer = @import("lexer/Lexer.zig");
const Element = @import("dom/Element.zig");
const parser = @import("parser.zig");
-pub const Error = error{ModifierNotClosed} || Lexer.Error;
+pub const Error = error{ModifierNotClosed, IllegalPlacement} || Lexer.Error;
pub fn parse(alloc: Allocator, l: *Lexer) Error!Element {
var el = try Element.init(alloc, .content, "p");
+ errdefer el.deinit();
while (l.nextKind()) |kind| {
switch (kind) {
// because nextKind returns only an hint for the next rune
@@ -22,14 +23,30 @@ pub fn parse(alloc: Allocator, l: *Lexer) Error!Element {
else => return el,
}
},
- else => try el.appendContent(try parseContent(alloc, l)),
+ else => try el.appendContent(try parseLine(alloc, l)),
}
}
return el;
}
-pub fn parseContent(alloc: Allocator, l: *Lexer) Error!Element {
+pub fn parseLine(alloc: Allocator, l: *Lexer) Error!Element {
var content = Element.initEmpty(alloc);
+ errdefer content.deinit();
+ while (l.nextKind()) |kind| {
+ switch (kind) {
+ .weak_delimiter, .strong_delimiter => return content,
+ else => {
+ const el = try parseContent(alloc, l);
+ try content.appendContent(el);
+ },
+ }
+ }
+ return content;
+}
+
+fn parseContent(alloc: Allocator, l: *Lexer) Error!Element {
+ var content = Element.initEmpty(alloc);
+ errdefer content.deinit();
const v = (try l.next(alloc)).?;
switch (v.kind) {
.literal => {
@@ -39,13 +56,14 @@ 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 => unreachable,
+ else => return Error.IllegalPlacement,
}
return content;
}
fn parseModifier(alloc: Allocator, l: *Lexer, knd: Lexed.Kind, tag: []const u8) Error!Element {
var el = try Element.init(alloc, .content, tag);
+ errdefer el.deinit();
while (l.nextKind()) |it| {
if (it == knd) {
// consuming the finisher
diff --git a/src/parser.zig b/src/parser.zig
index af571d4..442d823 100644
--- a/src/parser.zig
+++ b/src/parser.zig
@@ -74,6 +74,7 @@ test "parse paragraphs" {
try doTestError(alloc, "hello *world", Error.ModifierNotClosed);
try doTestError(alloc, "hello *wo_rld*", Error.ModifierNotClosed);
try doTestError(alloc, "*hell*o *wo_rld*", Error.ModifierNotClosed);
+ try doTestError(alloc, "hello ::: world", Error.IllegalPlacement);
}
test "parse title" {
@@ -85,6 +86,8 @@ test "parse title" {
try doTest(alloc, "## hey", "<h2>hey</h2>");
try doTest(alloc, "### hey", "<h3>hey</h3>");
+ try doTest(alloc, "# hello *world*", "<h1>hello <b>world</b></h1>");
+
try doTest(alloc,
\\# title
\\hello world ;3
diff --git a/src/root.zig b/src/root.zig
index bd183ff..830ba1c 100644
--- a/src/root.zig
+++ b/src/root.zig
@@ -9,6 +9,7 @@ fn getErrorCode(err: Error) u8 {
Error.FeatureNotSupported => 3,
Error.ModifierNotClosed => 4,
Error.InvalidTitleContent => 5,
+ Error.IllegalPlacement => 6,
};
}
@@ -20,6 +21,7 @@ export fn getErrorString(code: u8) [*:0]const u8 {
3 => "feature not supported",
4 => "modifier not closed",
5 => "invalid title content",
+ 6 => "illegal placement",
else => unreachable,
};
}
diff --git a/src/title.zig b/src/title.zig
index d9b5612..de88c67 100644
--- a/src/title.zig
+++ b/src/title.zig
@@ -18,7 +18,10 @@ pub fn parse(alloc: Allocator, l: *Lexer) Error!Element {
6 => "h6",
else => unreachable,
});
- try el.appendContent(try paragraph.parseContent(alloc, l));
+ try el.appendContent(paragraph.parseLine(alloc, l) catch |err| switch (err) {
+ paragraph.Error.IllegalPlacement => return Error.InvalidTitleContent,
+ else => return err,
+ });
v = (try l.next(alloc)) orelse return el;
if (!v.kind.isDelimiter()) return Error.InvalidTitleContent;
v.deinit();