aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build.zig6
-rw-r--r--src/paragraph.zig38
-rw-r--r--src/parser.zig30
-rw-r--r--src/title.zig40
4 files changed, 78 insertions, 36 deletions
diff --git a/build.zig b/build.zig
index 57e8ff1..d00aedd 100644
--- a/build.zig
+++ b/build.zig
@@ -15,7 +15,9 @@ pub fn build(b: *std.Build) void {
.linkage = .dynamic,
.root_module = mod,
});
- b.installArtifact(lib);
+ const installed_lib = b.addInstallArtifact(lib, .{});
+ // when emitting headers will be fixed
+ //installed_lib.emitted_h = lib.getEmittedH();
const example = b.addExecutable(.{
.name = "example",
@@ -29,7 +31,6 @@ pub fn build(b: *std.Build) void {
.file = b.path("examples/main.c"),
});
example.root_module.linkLibrary(lib);
- // manually writing headers because lib.getEmittedH() doesn't work.
example.root_module.addIncludePath(b.path("include"));
const mod_tests = b.addTest(.{
@@ -41,6 +42,7 @@ pub fn build(b: *std.Build) void {
test_step.dependOn(&run_mod_tests.step);
const examples_step = b.step("examples", "Run examples");
+ examples_step.dependOn(&installed_lib.step);
const example_run = b.addRunArtifact(example);
examples_step.dependOn(&example_run.step);
}
diff --git a/src/paragraph.zig b/src/paragraph.zig
index 222f376..caee73e 100644
--- a/src/paragraph.zig
+++ b/src/paragraph.zig
@@ -5,7 +5,7 @@ const Lexer = @import("lexer/Lexer.zig");
const Element = @import("dom/Element.zig");
const parser = @import("parser.zig");
-pub const Error = error{ModifierNotClosed, IllegalPlacement} || 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");
@@ -47,7 +47,8 @@ pub fn parseLine(alloc: Allocator, l: *Lexer) Error!Element {
fn parseContent(alloc: Allocator, l: *Lexer) Error!Element {
var content = Element.initEmpty(alloc);
errdefer content.deinit();
- const v = (try l.next(alloc)).?;
+ var v = (try l.next(alloc)).?;
+ defer v.deinit();
switch (v.kind) {
.literal => {
const el = try Element.initLitEscaped(alloc, v.content.items);
@@ -76,3 +77,36 @@ fn parseModifier(alloc: Allocator, l: *Lexer, knd: Lexed.Kind, tag: []const u8)
}
return Error.ModifierNotClosed;
}
+
+fn doTest(alloc: Allocator, t: []const u8, v: []const u8) !void {
+ var l = try Lexer.init(t);
+ var p = try parse(alloc, &l);
+ defer p.deinit();
+ const g = try p.render(alloc);
+ defer alloc.free(g);
+ std.testing.expect(std.mem.eql(u8, g, v)) catch |err| {
+ std.debug.print("{s}\n", .{g});
+ return err;
+ };
+}
+
+fn doTestError(alloc: Allocator, t: []const u8, err: Error) !void {
+ var l = try Lexer.init(t);
+ _ = parse(alloc, &l) catch |e| return std.testing.expect(err == e);
+ return std.testing.expect(false);
+}
+
+test "parse paragraphs" {
+ var arena = std.heap.DebugAllocator(.{}).init;
+ defer if (arena.deinit() == .leak) std.debug.print("leaking!\n", .{});
+ const alloc = arena.allocator();
+
+ try doTest(alloc, "hello world", "<p>hello world</p>");
+ try doTest(alloc, "*hello* world", "<p><b>hello</b> world</p>");
+ try doTest(alloc, "*he_ll_o* world", "<p><b>he<em>ll</em>o</b> world</p>");
+
+ 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);
+}
diff --git a/src/parser.zig b/src/parser.zig
index 442d823..f109a88 100644
--- a/src/parser.zig
+++ b/src/parser.zig
@@ -49,20 +49,11 @@ fn doTest(alloc: Allocator, t: []const u8, v: []const u8) !void {
};
}
-fn doTestError(alloc: Allocator, t: []const u8, err: Error) !void {
- _ = parse(alloc, t) catch |e| return std.testing.expect(err == e);
- return std.testing.expect(false);
-}
-
-test "parse paragraphs" {
+test "parse multilines" {
var arena = std.heap.DebugAllocator(.{}).init;
defer if (arena.deinit() == .leak) std.debug.print("leaking!\n", .{});
const alloc = arena.allocator();
- try doTest(alloc, "hello world", "<p>hello world</p>");
- try doTest(alloc, "*hello* world", "<p><b>hello</b> world</p>");
- try doTest(alloc, "*he_ll_o* world", "<p><b>he<em>ll</em>o</b> world</p>");
-
try doTest(alloc,
\\hello
\\world
@@ -71,29 +62,10 @@ test "parse paragraphs" {
\\in new paragraph
, "<p>hello world</p><p>foo bar in new paragraph</p>");
- 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" {
- 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, "# hello *world*", "<h1>hello <b>world</b></h1>");
-
try doTest(alloc,
\\# title
\\hello world ;3
\\## subtitle
\\hehe
, "<h1>title</h1><p>hello world ;3</p><h2>subtitle</h2><p>hehe</p>");
-
- try doTestError(alloc, "# aa :::", Error.InvalidTitleContent);
}
diff --git a/src/title.zig b/src/title.zig
index de88c67..62d7929 100644
--- a/src/title.zig
+++ b/src/title.zig
@@ -9,6 +9,7 @@ pub const Error = error{InvalidTitleContent} || paragraph.Error || Lexer.Error;
pub fn parse(alloc: Allocator, l: *Lexer) Error!Element {
var v = (try l.next(alloc)).?;
+ defer v.deinit();
var el = try Element.init(alloc, .content, switch (v.content.items.len) {
1 => "h1",
2 => "h2",
@@ -18,12 +19,45 @@ pub fn parse(alloc: Allocator, l: *Lexer) Error!Element {
6 => "h6",
else => unreachable,
});
+ errdefer el.deinit();
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();
+ var next = (try l.next(alloc)) orelse return el;
+ defer next.deinit();
+ if (!next.kind.isDelimiter()) return Error.InvalidTitleContent;
return el;
}
+
+fn doTest(alloc: Allocator, t: []const u8, v: []const u8) !void {
+ var l = try Lexer.init(t);
+ var p = try parse(alloc, &l);
+ defer p.deinit();
+ const g = try p.render(alloc);
+ defer alloc.free(g);
+ std.testing.expect(std.mem.eql(u8, g, v)) catch |err| {
+ std.debug.print("{s}\n", .{g});
+ return err;
+ };
+}
+
+fn doTestError(alloc: Allocator, t: []const u8, err: Error) !void {
+ var l = try Lexer.init(t);
+ _ = parse(alloc, &l) catch |e| return std.testing.expect(err == e);
+ return std.testing.expect(false);
+}
+
+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, "# hello *world*", "<h1>hello <b>world</b></h1>");
+
+ try doTestError(alloc, "# aa :::", Error.InvalidTitleContent);
+}