update: add verbatim

This commit is contained in:
Lucas F. 2026-01-03 18:38:25 -03:00
parent 0192ad0b64
commit b7550e9b01
3 changed files with 89 additions and 1 deletions

View file

@ -340,6 +340,52 @@ pub const Parser = struct {
return error.UnclosedBlock;
}
fn parseVerbatim(self: *Parser, allocator: std.mem.Allocator) !Node {
const start = self.pos;
var depth: usize = 1;
while (self.pos < self.template.len and depth > 0) {
if (self.peek(2)) |p| {
if (std.mem.eql(u8, p, "{%")) {
self.advance(2);
self.skipWhitespace();
const content_start = self.pos;
while (self.pos < self.template.len and !std.mem.eql(u8, self.peek(2) orelse "", "%}")) : (self.advance(1)) {}
if (self.pos + 2 > self.template.len or !std.mem.eql(u8, self.template[self.pos .. self.pos + 2], "%}")) {
return error.UnclosedTag;
}
const inner = std.mem.trim(u8, self.template[content_start..self.pos], " \t\r\n");
if (std.mem.eql(u8, inner, "verbatim")) {
depth += 1;
} else if (std.mem.eql(u8, inner, "endverbatim")) {
depth -= 1;
if (depth == 0) {
// Copia até o início da tag endverbatim
const content_end = content_start - 3; // retrocede "{% "
const content = try allocator.dupe(u8, self.template[start..content_end]);
self.advance(2); // consome %}
return Node{
.type = .text,
.text = .{ .content = content },
};
}
}
self.advance(2);
continue;
}
}
self.advance(1);
}
return error.UnclosedVerbatim;
}
fn parseSpacelessBlock(self: *Parser, allocator: std.mem.Allocator, raw_open: []const u8) !Node {
var body = std.ArrayList(Node){};
defer body.deinit(allocator);
@ -525,6 +571,7 @@ pub const Parser = struct {
return error.UnclosedBlock;
}
fn parseWithBlock(self: *Parser, allocator: std.mem.Allocator, assignments: []const Assignment, raw_open: []const u8) !Node {
std.debug.print("Vou verificar se sou bloco with\n", .{});
var body = std.ArrayList(Node){};
@ -1164,6 +1211,18 @@ pub const Parser = struct {
continue;
}
if (std.mem.eql(u8, tag_name, "verbatim")) {
allocator.free(node.tag.?.name);
allocator.free(node.tag.?.args);
std.debug.print("3.0 - na real sou um verbatim\n", .{});
std.debug.print("===================================\n", .{});
const verbatim_node = try self.parseVerbatim(allocator);
try list.append(allocator, verbatim_node);
continue;
}
// Para tags normais
std.debug.print("===================================\n", .{});
try list.append(allocator, node);

View file

@ -471,3 +471,32 @@ test "parse spaceless aninhado" {
}
try testing.expectEqual(@as(usize, 3), sl.body.len);
}
test "parse verbatim simples" {
const allocator = testing.allocator;
const template = "Texto {% verbatim %}{{ variável }}{% endblock %}{% endverbatim %} Texto";
const nodes = try parser.parse(allocator, template);
defer {
for (nodes) |node| node.deinit(allocator);
allocator.free(nodes);
}
try testing.expectEqual(@as(usize, 3), nodes.len);
try testing.expectEqualStrings("Texto ", nodes[0].text.?.content);
try testing.expectEqualStrings("{{ variável }}{% endblock %}", nodes[1].text.?.content);
try testing.expectEqualStrings(" Texto", nodes[2].text.?.content);
}
test "parse verbatim aninhado" {
const allocator = testing.allocator;
const template = "{% verbatim %}Outer {% verbatim %}Inner{% endverbatim %} Outer{% endverbatim %}";
const nodes = try parser.parse(allocator, template);
defer {
for (nodes) |node| node.deinit(allocator);
allocator.free(nodes);
}
try testing.expectEqual(@as(usize, 1), nodes.len);
try testing.expect(nodes[0].type == .text);
try testing.expectEqualStrings("Outer {% verbatim %}Inner{% endverbatim %} Outer", nodes[0].text.?.content);
}

View file

@ -96,7 +96,7 @@ ___
- [x] filter — super útil (ex.: {{ var|upper }})
- [x] autoescape — segurança importante
- [x] spaceless — remove espaços em branco
- [ ] verbatim — como raw
- [x] verbatim — como raw
- [ ] url — reverse de URLs (quando tiver routing)
- [ ] cycle — alternar valores em loop
- [ ] firstof — fallback de variáveis