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) {...@@ -8,6 +8,7 @@ pub const Value = union(enum) {
8 element: Element,8 element: Element,
9 attr: Attr,9 attr: Attr,
10 string: []const u8,10 string: []const u8,
11 replacement: []const []const u8,
11};12};
1213
13pub const Element = struct {14pub const Element = struct {
...@@ -103,9 +104,20 @@ const Parser = struct {...@@ -103,9 +104,20 @@ const Parser = struct {
103 if (self.tokens[self.index] == .string) {104 if (self.tokens[self.index] == .string) {
104 return Value{ .string = self.eat(.string) };105 return Value{ .string = self.eat(.string) };
105 }106 }
107 if (self.tryEatSymbol("{")) {
108 return Value{ .replacement = self.doReplacement() };
109 }
106 return Value{ .element = self.doElement() };110 return Value{ .element = self.doElement() };
107 }111 }
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
109 fn eat(comptime self: *Parser, comptime typ: std.meta.Tag(Token)) []const u8 {121 fn eat(comptime self: *Parser, comptime typ: std.meta.Tag(Token)) []const u8 {
110 defer self.index += 1;122 defer self.index += 1;
111 return @field(self.tokens[self.index], @tagName(typ));123 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...@@ -64,6 +64,20 @@ pub fn compile(writer: anytype, comptime value: astgen.Value, data: anytype, ind
64 .string => |v| {64 .string => |v| {
65 try writer.writeAll(v[1 .. v.len - 1]);65 try writer.writeAll(v[1 .. v.len - 1]);
66 },66 },
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 },
67 else => unreachable,81 else => unreachable,
68 }82 }
69}83}
src/main.zig+9-1
...@@ -12,6 +12,8 @@ const example_document =...@@ -12,6 +12,8 @@ const example_document =
12 \\ h1("Pek Example")12 \\ h1("Pek Example")
13 \\ hr13 \\ hr
14 \\ p("This is an example HTML document written in "a[href="https://github.com/nektro/zig-pek"]("Pek")".")14 \\ 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})
15 \\ )17 \\ )
16 \\)18 \\)
17;19;
...@@ -21,6 +23,12 @@ pub fn main() !void {...@@ -21,6 +23,12 @@ pub fn main() !void {
21 std.debug.print("\n", .{});23 std.debug.print("\n", .{});
2224
23 const doc = comptime pek.parse(example_document);25 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);
25 std.debug.print("\n", .{});33 std.debug.print("\n", .{});
26}34}