Return closing block from parseTemplate

This commit is contained in:
jaina heartles 2022-12-07 17:10:53 -08:00
parent 795f7983f8
commit b0864b29d8
2 changed files with 22 additions and 14 deletions

View file

@ -18,7 +18,7 @@ pub fn execute(writer: anytype, comptime template: []const u8, args: anytype) !v
const tokens = comptime parseTemplateTokens(ControlTokenIter{ .text = template }); const tokens = comptime parseTemplateTokens(ControlTokenIter{ .text = template });
const tmpl = comptime parseTemplate(tokens, 0, .root); const tmpl = comptime parseTemplate(tokens, 0, .root);
try executeTemplate(writer, tmpl.item, args, .{}); try executeTemplate(writer, tmpl.items, args, .{});
} }
fn executeTemplate(writer: anytype, comptime items: []const TemplateItem, args: anytype, captures: anytype) !void { fn executeTemplate(writer: anytype, comptime items: []const TemplateItem, args: anytype, captures: anytype) !void {
@ -130,17 +130,23 @@ const TemplateType = enum {
if_block, if_block,
}; };
const TemplateParseResult = struct {
new_idx: usize,
items: []const TemplateItem,
closing_block: ?ControlBlock,
};
fn parseTemplate( fn parseTemplate(
comptime tokens: []const TemplateToken, comptime tokens: []const TemplateToken,
comptime start: usize, comptime start: usize,
comptime template_type: TemplateType, comptime template_type: TemplateType,
) ParseResult(usize, []const TemplateItem) { ) TemplateParseResult {
comptime { comptime {
var i: usize = start; var i: usize = start;
var current_text: []const u8 = ""; var current_text: []const u8 = "";
var items: []const TemplateItem = &.{}; var items: []const TemplateItem = &.{};
while (i < tokens.len) : (i += 1) { const closing_block: ?ControlBlock = while (i < tokens.len) : (i += 1) {
switch (tokens[i]) { switch (tokens[i]) {
.text => |text| current_text = current_text ++ text, .text => |text| current_text = current_text ++ text,
.whitespace => |wsp| { .whitespace => |wsp| {
@ -163,12 +169,12 @@ fn parseTemplate(
items = items ++ [_]TemplateItem{.{ items = items ++ [_]TemplateItem{.{
.statement = .{ .statement = .{
.@"if" = .{ .@"if" = .{
.subtemplate = subtemplate.item, .subtemplate = subtemplate.items,
.header = header, .header = header,
}, },
}, },
}}; }};
i = subtemplate.new_iter; i = subtemplate.new_idx;
}, },
.for_header => |header| { .for_header => |header| {
if (i != tokens.len - 1 and tokens[i + 1] == .whitespace and cb.strip_after) i += 1; if (i != tokens.len - 1 and tokens[i + 1] == .whitespace and cb.strip_after) i += 1;
@ -176,19 +182,19 @@ fn parseTemplate(
items = items ++ [_]TemplateItem{.{ items = items ++ [_]TemplateItem{.{
.statement = .{ .statement = .{
.@"for" = .{ .@"for" = .{
.subtemplate = subtemplate.item, .subtemplate = subtemplate.items,
.header = header, .header = header,
}, },
}, },
}}; }};
i = subtemplate.new_iter; i = subtemplate.new_idx;
}, },
.end_for => if (template_type == .for_block) .end_for => if (template_type == .for_block)
break break cb
else else
@compileError("Unexpected /for tag"), @compileError("Unexpected /for tag"),
.end_if => if (template_type == .if_block) .end_if => if (template_type == .if_block)
break break cb
else else
@compileError("Unexpected /if tag"), @compileError("Unexpected /if tag"),
} }
@ -200,13 +206,16 @@ fn parseTemplate(
} }
}, },
} }
} else if (template_type != .root) @compileError("End tag not found"); } else null;
if (current_text.len != 0) items = items ++ [_]TemplateItem{.{ .text = current_text }}; if (current_text.len != 0) items = items ++ [_]TemplateItem{.{ .text = current_text }};
if (template_type != .root and closing_block == null) @compileError("End tag not found");
return .{ return .{
.new_iter = i, .new_idx = i,
.item = items, .items = items,
.closing_block = closing_block,
}; };
} }
} }

View file

@ -14,8 +14,7 @@
{$b}: {$b}:
{= /for =} {= /for =}
{= /for} {= /for}
{#if .qux}qux!{/if=} {#if .qux}qux!{#elif .quxx}quxx!{/if=}
{#if .quxx}quxx!{/if}
</section> </section>
</body> </body>
</html> </html>