authorgravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2021-08-05 03:05:31 -07:00
committergravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2021-08-05 03:05:31 -07:00
log27b00a8788aec21df582dcae38a976edb90bb818
tree8c36ec93fe4914f528cad8bd09b5848fd123ca48
parent19e2662de8b0c9a2e2be28a06cb66f84d961fbf8

add single and multi string replacements


3 files changed, 35 insertions(+), 1 deletions(-)

src/astgen.zig+12
......@@ -8,6 +8,7 @@ pub const Value = union(enum) {
88 element: Element,
99 attr: Attr,
1010 string: []const u8,
11 replacement: []const []const u8,
1112};
1213
1314pub const Element = struct {
......@@ -103,9 +104,20 @@ const Parser = struct {
103104 if (self.tokens[self.index] == .string) {
104105 return Value{ .string = self.eat(.string) };
105106 }
107 if (self.tryEatSymbol("{")) {
108 return Value{ .replacement = self.doReplacement() };
109 }
106110 return Value{ .element = self.doElement() };
107111 }
108112
113 pub fn doReplacement(comptime self: *Parser) []const []const u8 {
114 var ret: []const []const u8 = &.{};
115 while (!self.tryEatSymbol("}")) {
116 ret = ret ++ &[_][]const u8{self.eat(.word)};
117 }
118 return ret;
119 }
120
109121 fn eat(comptime self: *Parser, comptime typ: std.meta.Tag(Token)) []const u8 {
110122 defer self.index += 1;
111123 return @field(self.tokens[self.index], @tagName(typ));
src/lib.zig+14
......@@ -64,6 +64,20 @@ pub fn compile(writer: anytype, comptime value: astgen.Value, data: anytype, ind
6464 .string => |v| {
6565 try writer.writeAll(v[1 .. v.len - 1]);
6666 },
67 .replacement => |v| {
68 const x = @field(data, v[0]);
69 if (v.len == 1) {
70 const TO = @TypeOf(x);
71
72 if (comptime std.meta.trait.isZigString(TO)) {
73 try writer.print("{s}", .{x});
74 return;
75 }
76 @compileError("pek: compile: unsupported type: " ++ @typeName(TO));
77 } else {
78 try compile(writer, astgen.Value{ .replacement = v[1..] }, x, indent, flag1);
79 }
80 },
6781 else => unreachable,
6882 }
6983}
src/main.zig+9-1
......@@ -12,6 +12,8 @@ const example_document =
1212 \\ h1("Pek Example")
1313 \\ hr
1414 \\ p("This is an example HTML document written in "a[href="https://github.com/nektro/zig-pek"]("Pek")".")
15 \\ p("Pek is written by "{author}".")
16 \\ p("Her favorite plant is the "{favorite flower})
1517 \\ )
1618 \\)
1719;
......@@ -21,6 +23,12 @@ pub fn main() !void {
2123 std.debug.print("\n", .{});
2224
2325 const doc = comptime pek.parse(example_document);
24 try pek.compile(std.io.getStdErr().writer(), doc, .{}, 0, false);
26 const data = .{
27 .author = "Meghan D",
28 .favorite = .{
29 .flower = "Sunflower",
30 },
31 };
32 try pek.compile(std.io.getStdErr().writer(), doc, data, 0, false);
2533 std.debug.print("\n", .{});
2634}