aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAnhgelus Morhtuuzh <william@herges.fr>2026-04-26 22:07:03 +0200
committerAnhgelus Morhtuuzh <william@herges.fr>2026-04-26 22:07:03 +0200
commit1ce415538f202bf1319ebb0ff6e76aa54f983343 (patch)
treede7febaf453855229581fdc2dbcc92fd2bd1bed3 /src
parentdca42e27fe9c7d28c72bb6cb8e5cc4ec481572e8 (diff)
perf(parse): reduce realloc for figcaptions
Diffstat (limited to 'src')
-rw-r--r--src/eval/Element.zig18
-rw-r--r--src/eval/Image.zig9
-rw-r--r--src/link.zig15
3 files changed, 35 insertions, 7 deletions
diff --git a/src/eval/Element.zig b/src/eval/Element.zig
index a8b424d..355e971 100644
--- a/src/eval/Element.zig
+++ b/src/eval/Element.zig
@@ -113,6 +113,24 @@ pub fn Simple(comptime tag: []const u8) type {
destroy(self, alloc);
}
+ pub fn toTag(self: *Self, alloc: Allocator, comptime target: []const u8) !*Simple(target) {
+ const el = try Simple(target).init(alloc);
+ self.conv(alloc, &el.content);
+ return el;
+ }
+
+ pub fn toEmpty(self: *Self, alloc: Allocator) !*Empty {
+ const el = try Empty.init(alloc);
+ self.conv(alloc, &el.content);
+ return el;
+ }
+
+ fn conv(self: *Self, alloc: Allocator, arr: *std.ArrayList(Element)) void {
+ arr.deinit(alloc);
+ arr.* = self.content;
+ alloc.destroy(self);
+ }
+
fn destroy(context: *anyopaque, alloc: Allocator) void {
var self: *Self = @ptrCast(@alignCast(context));
for (self.content.items) |it| it.deinit(alloc);
diff --git a/src/eval/Image.zig b/src/eval/Image.zig
index 771c8ee..7991d69 100644
--- a/src/eval/Image.zig
+++ b/src/eval/Image.zig
@@ -45,7 +45,7 @@ fn html(context: *anyopaque, alloc: Allocator) HTML.Error!HTML {
const source = self.source orelse return el;
var caption = try HTML.init(alloc, .content, "figcaption");
errdefer caption.deinit();
- try caption.content.append(alloc, try source.html(alloc));
+ try caption.appendContent(try source.html(alloc));
try el.appendContent(caption);
return el;
}
@@ -65,4 +65,11 @@ test "html" {
const h2 = try img.element().renderHTML(alloc);
defer alloc.free(h2);
try expect(eql(u8, h2, "<figure><img src=\"foo\" alt=\"bar\"></figure>"));
+
+ const in = try Element.Empty.init(alloc);
+ try in.content.append(alloc, (try Element.Literal.init(alloc, "caption")).element());
+ img.source = in.element();
+ const h3 = try img.element().renderHTML(alloc);
+ defer alloc.free(h3);
+ try expect(eql(u8, h3, "<figure><img src=\"foo\" alt=\"bar\"><figcaption>caption</figcaption></figure>"));
}
diff --git a/src/link.zig b/src/link.zig
index 50e89f5..3333e76 100644
--- a/src/link.zig
+++ b/src/link.zig
@@ -81,13 +81,8 @@ pub fn parseImage(alloc: Allocator, l: *Lexer) ImageError!Element {
}
const p = try paragraph.parse(alloc, l);
errdefer p.deinit(alloc);
- el.source = p;
const p_el: *Element.paragraph.Block = @ptrCast(@alignCast(p.ptr));
- defer p_el.deinit(alloc);
- const in = try Element.Empty.init(alloc);
- errdefer in.deinit(alloc);
- in.content = try p_el.content.clone(alloc);
- el.source = in.element();
+ el.source = (try p_el.toEmpty(alloc)).element();
return el.element();
}
@@ -110,4 +105,12 @@ test "parse image" {
try doTest(parseImage, alloc, "![](src)", "<figure><img src=\"src\"></figure>");
try doTest(parseImage, alloc, "![alt](src)", "<figure><img src=\"src\" alt=\"alt\"></figure>");
+
+ try doTest(parseImage, alloc,
+ \\![bar](foo)
+ \\caption
+ \\on multiple lines!
+ \\
+ \\not in
+ , "<figure><img src=\"foo\" alt=\"bar\"><figcaption>caption on multiple lines!</figcaption></figure>");
}