diff options
| author | Anhgelus Morhtuuzh <william@herges.fr> | 2026-04-26 22:29:40 +0200 |
|---|---|---|
| committer | Anhgelus Morhtuuzh <william@herges.fr> | 2026-04-26 22:29:40 +0200 |
| commit | ae6ee68d6f4ef79fef609b4d09b543fc06326e95 (patch) | |
| tree | 04f7059b0ed5bb1323280ce9c910f8f154af5eac /src | |
| parent | 1ce415538f202bf1319ebb0ff6e76aa54f983343 (diff) | |
refactor(eval): generalize figure
Diffstat (limited to 'src')
| -rw-r--r-- | src/eval/Element.zig | 3 | ||||
| -rw-r--r-- | src/eval/Image.zig | 24 | ||||
| -rw-r--r-- | src/eval/blocks.zig | 47 | ||||
| -rw-r--r-- | src/link.zig | 8 |
4 files changed, 58 insertions, 24 deletions
diff --git a/src/eval/Element.zig b/src/eval/Element.zig index 355e971..0dbba59 100644 --- a/src/eval/Element.zig +++ b/src/eval/Element.zig @@ -5,6 +5,9 @@ pub const paragraph = @import("paragraph.zig"); pub const Title = @import("Title.zig"); pub const list = @import("list.zig"); pub const Image = @import("Image.zig"); +const blocks = @import("blocks.zig"); +pub const Code = blocks.Code; +pub const Figure = blocks.Figure; const Element = @This(); diff --git a/src/eval/Image.zig b/src/eval/Image.zig index 7991d69..740d876 100644 --- a/src/eval/Image.zig +++ b/src/eval/Image.zig @@ -7,7 +7,6 @@ const Self = @This(); src: []const u8, alt: ?[]const u8 = null, -source: ?Element = null, pub fn init(alloc: Allocator, src: []const u8) !*Self { const v = try alloc.create(Self); @@ -27,7 +26,6 @@ pub fn deinit(self: *Self, alloc: Allocator) void { fn destroy(context: *anyopaque, alloc: Allocator) void { const self: *Self = @ptrCast(@alignCast(context)); - if (self.source) |it| it.deinit(alloc); alloc.destroy(self); } @@ -38,16 +36,7 @@ fn html(context: *anyopaque, alloc: Allocator) HTML.Error!HTML { errdefer img.deinit(); try img.setAttribute("src", self.src); if (self.alt) |it| try img.setAttribute("alt", it); - var el = try HTML.init(alloc, .content, "figure"); - errdefer el.deinit(); - try el.appendContent(img); - - const source = self.source orelse return el; - var caption = try HTML.init(alloc, .content, "figcaption"); - errdefer caption.deinit(); - try caption.appendContent(try source.html(alloc)); - try el.appendContent(caption); - return el; + return img; } test "html" { @@ -59,17 +48,10 @@ test "html" { defer img.deinit(alloc); const h = try img.element().renderHTML(alloc); defer alloc.free(h); - try expect(eql(u8, h, "<figure><img src=\"foo\"></figure>")); + try expect(eql(u8, h, "<img src=\"foo\">")); img.alt = "bar"; 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>")); + try expect(eql(u8, h2, "<img src=\"foo\" alt=\"bar\">")); } diff --git a/src/eval/blocks.zig b/src/eval/blocks.zig new file mode 100644 index 0000000..9ad10ba --- /dev/null +++ b/src/eval/blocks.zig @@ -0,0 +1,47 @@ +const std = @import("std"); +const Allocator = std.mem.Allocator; +const HTML = @import("html/Element.zig"); +const Element = @import("Element.zig"); + +pub const Code = Element.Simple("pre"); + +pub const Figure = struct { + content: Element, + caption: ?Element = null, + + const Self = @This(); + + pub fn init(alloc: Allocator, content: Element) !*Self { + const v = try alloc.create(Self); + v.* = .{ .content = content }; + return v; + } + + pub fn element(self: *Self) Element { + return .{ .ptr = self, .vtable = .{ .deinit = destroy, .html = Self.html } }; + } + + pub fn deinit(self: *Self, alloc: Allocator) void { + destroy(self, alloc); + } + + fn destroy(context: *anyopaque, alloc: Allocator) void { + const self: *Self = @ptrCast(@alignCast(context)); + self.content.deinit(alloc); + if (self.caption) |cap| cap.deinit(alloc); + alloc.destroy(self); + } + + fn html(context: *anyopaque, alloc: Allocator) HTML.Error!HTML { + const self: *Self = @ptrCast(@alignCast(context)); + var el = try HTML.init(alloc, .content, "figure"); + errdefer el.deinit(); + try el.appendContent(try self.content.html(alloc)); + const caption = self.caption orelse return el; + var figcap = try HTML.init(alloc, .content, "figcaption"); + errdefer figcap.deinit(); + try figcap.appendContent(try caption.html(alloc)); + try el.appendContent(figcap); + return el; + } +}; diff --git a/src/link.zig b/src/link.zig index 3333e76..9bfbde5 100644 --- a/src/link.zig +++ b/src/link.zig @@ -70,9 +70,11 @@ pub fn parseImage(alloc: Allocator, l: *Lexer) ImageError!Element { const src = it.content; it = l.next() orelse return ImageError.InvalidImage; if (!it.equals(.link, ")")) return ImageError.InvalidImage; - const el = try Element.Image.init(alloc, src); + const img = try Element.Image.init(alloc, src); + errdefer img.deinit(alloc); + img.alt = alt; + const el = try Element.Figure.init(alloc, img.element()); errdefer el.deinit(alloc); - el.alt = alt; it = l.peek() orelse return el.element(); switch (it.kind) { .strong_delimiter => return el.element(), @@ -82,7 +84,7 @@ pub fn parseImage(alloc: Allocator, l: *Lexer) ImageError!Element { const p = try paragraph.parse(alloc, l); errdefer p.deinit(alloc); const p_el: *Element.paragraph.Block = @ptrCast(@alignCast(p.ptr)); - el.source = (try p_el.toEmpty(alloc)).element(); + el.caption = (try p_el.toEmpty(alloc)).element(); return el.element(); } |
