aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/eval/Element.zig3
-rw-r--r--src/eval/Image.zig24
-rw-r--r--src/eval/blocks.zig47
-rw-r--r--src/link.zig8
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();
}