update: add debug, partialdef and partial
This commit is contained in:
parent
b09da93f0d
commit
1e0329a597
3 changed files with 207 additions and 7 deletions
141
src/parser.zig
141
src/parser.zig
|
|
@ -21,6 +21,20 @@ pub const NodeType = enum {
|
|||
load,
|
||||
csrf_token,
|
||||
lorem,
|
||||
debug,
|
||||
partialdef,
|
||||
partial,
|
||||
};
|
||||
|
||||
pub const PartialDefNode = struct {
|
||||
name: []const u8,
|
||||
body: []Node,
|
||||
raw_open: []const u8,
|
||||
raw_close: []const u8,
|
||||
};
|
||||
|
||||
pub const PartialNode = struct {
|
||||
name: []const u8,
|
||||
};
|
||||
|
||||
pub const LoremNode = struct {
|
||||
|
|
@ -156,7 +170,10 @@ pub const Node = struct {
|
|||
firstof: ?FirstOfNode = null,
|
||||
load: ?LoadNode = null,
|
||||
lorem: ?LoremNode = null,
|
||||
partialdef: ?PartialDefNode = null,
|
||||
partial: ?PartialNode = null,
|
||||
csrf_token: bool = false,
|
||||
debug: bool = false,
|
||||
|
||||
pub fn deinit(self: Node, allocator: std.mem.Allocator) void {
|
||||
switch (self.type) {
|
||||
|
|
@ -251,6 +268,15 @@ pub const Node = struct {
|
|||
if (l.method) |m| allocator.free(m);
|
||||
if (l.format) |f| allocator.free(f);
|
||||
},
|
||||
.debug => {},
|
||||
.partialdef => if (self.partialdef) |pd| {
|
||||
allocator.free(pd.name);
|
||||
for (pd.body) |n| n.deinit(allocator);
|
||||
allocator.free(pd.body);
|
||||
},
|
||||
.partial => if (self.partial) |p| {
|
||||
allocator.free(p.name);
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -340,6 +366,64 @@ pub const Parser = struct {
|
|||
return try list.toOwnedSlice(allocator);
|
||||
}
|
||||
|
||||
fn parsePartialDefBlock(self: *Parser, allocator: std.mem.Allocator, name: []const u8, raw_open: []const u8) !Node {
|
||||
var body = std.ArrayList(Node){};
|
||||
defer body.deinit(allocator);
|
||||
|
||||
var depth: usize = 1;
|
||||
|
||||
while (self.pos < self.template.len and depth > 0) {
|
||||
if (try self.parseText(allocator)) |node| {
|
||||
try body.append(allocator, node);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (try self.parseVariable(allocator)) |node| {
|
||||
try body.append(allocator, node);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (try self.parseTag(allocator)) |tag_node| {
|
||||
const tag_name = tag_node.tag.?.name;
|
||||
|
||||
if (std.mem.eql(u8, tag_name, "partialdef")) {
|
||||
depth += 1;
|
||||
try body.append(allocator, tag_node);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (std.mem.eql(u8, tag_name, "endpartialdef")) {
|
||||
depth -= 1;
|
||||
const raw_close = tag_node.tag.?.raw;
|
||||
|
||||
allocator.free(tag_node.tag.?.name);
|
||||
allocator.free(tag_node.tag.?.args);
|
||||
|
||||
if (depth == 0) {
|
||||
return Node{
|
||||
.type = .partialdef,
|
||||
.partialdef = .{
|
||||
.name = try allocator.dupe(u8, name),
|
||||
.body = try body.toOwnedSlice(allocator),
|
||||
.raw_open = raw_open,
|
||||
.raw_close = raw_close,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
try body.append(allocator, tag_node);
|
||||
continue;
|
||||
}
|
||||
|
||||
try body.append(allocator, tag_node);
|
||||
} else {
|
||||
self.advance(1);
|
||||
}
|
||||
}
|
||||
|
||||
return error.UnclosedBlock;
|
||||
}
|
||||
|
||||
fn parseAutoescapeBlock(self: *Parser, allocator: std.mem.Allocator, enabled: bool, raw_open: []const u8) !Node {
|
||||
var body = std.ArrayList(Node){};
|
||||
defer body.deinit(allocator);
|
||||
|
|
@ -1106,6 +1190,41 @@ pub const Parser = struct {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (std.mem.eql(u8, tag_name, "partialdef")) {
|
||||
const partial_name = std.mem.trim(u8, node.tag.?.args, " \t\r\n");
|
||||
const raw_open = node.tag.?.raw;
|
||||
|
||||
const duped_name = try allocator.dupe(u8, partial_name);
|
||||
|
||||
allocator.free(node.tag.?.name);
|
||||
allocator.free(node.tag.?.args);
|
||||
|
||||
std.debug.print("3.0 - na real sou um partialdef\n", .{});
|
||||
std.debug.print("===================================\n", .{});
|
||||
|
||||
const partialdef_node = try self.parsePartialDefBlock(allocator, duped_name, raw_open);
|
||||
try list.append(allocator, partialdef_node);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (std.mem.eql(u8, tag_name, "partial")) {
|
||||
const partial_name = std.mem.trim(u8, node.tag.?.args, " \t\r\n\"'");
|
||||
|
||||
const duped_name = try allocator.dupe(u8, partial_name);
|
||||
|
||||
allocator.free(node.tag.?.name);
|
||||
allocator.free(node.tag.?.args);
|
||||
|
||||
std.debug.print("3.0 - na real sou um partial\n", .{});
|
||||
std.debug.print("===================================\n", .{});
|
||||
|
||||
try list.append(allocator, Node{
|
||||
.type = .partial,
|
||||
.partial = .{ .name = duped_name },
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
if (std.mem.eql(u8, tag_name, "lorem")) {
|
||||
const args = node.tag.?.args;
|
||||
|
||||
|
|
@ -1129,9 +1248,8 @@ pub const Parser = struct {
|
|||
method = try allocator.dupe(u8, trimmed);
|
||||
} else if (std.mem.eql(u8, trimmed, "html")) {
|
||||
std.debug.print("trimmed: {s}\n", .{trimmed});
|
||||
format = try allocator.dupe(u8, trimmed);
|
||||
format = try allocator.dupe(u8, trimmed);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
allocator.free(node.tag.?.name);
|
||||
|
|
@ -1515,6 +1633,25 @@ pub const Parser = struct {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (std.mem.eql(u8, tag_name, "debug")) {
|
||||
// Verifica se tem argumentos (não deve ter)
|
||||
if (node.tag.?.args.len > 0 and !std.mem.allEqual(u8, node.tag.?.args, ' ')) {
|
||||
return error.InvalidDebugArgs;
|
||||
}
|
||||
|
||||
allocator.free(node.tag.?.name);
|
||||
allocator.free(node.tag.?.args);
|
||||
|
||||
std.debug.print("3.0 - na real sou um debug\n", .{});
|
||||
std.debug.print("===================================\n", .{});
|
||||
|
||||
try list.append(allocator, Node{
|
||||
.type = .debug,
|
||||
.debug = true,
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
if (std.mem.eql(u8, tag_name, "csrf_token")) {
|
||||
// Verifica se tem argumentos (não deve ter)
|
||||
if (node.tag.?.args.len > 0 and !std.mem.allEqual(u8, node.tag.?.args, ' ')) {
|
||||
|
|
|
|||
|
|
@ -709,3 +709,66 @@ test "parse lorem com argumentos" {
|
|||
try testing.expectEqualStrings("p", l.method.?);
|
||||
try testing.expectEqualStrings("html", l.format.?);
|
||||
}
|
||||
|
||||
test "parse debug simples" {
|
||||
const allocator = testing.allocator;
|
||||
const template = "Antes {% debug %} Depois";
|
||||
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.expect(nodes[0].type == .text);
|
||||
try testing.expectEqualStrings("Antes ", nodes[0].text.?.content);
|
||||
|
||||
try testing.expect(nodes[1].type == .debug);
|
||||
|
||||
try testing.expect(nodes[2].type == .text);
|
||||
try testing.expectEqualStrings(" Depois", nodes[2].text.?.content);
|
||||
}
|
||||
|
||||
test "parse debug sozinho" {
|
||||
const allocator = testing.allocator;
|
||||
const template = "{% debug %}";
|
||||
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 == .debug);
|
||||
}
|
||||
|
||||
test "parse partialdef simples" {
|
||||
const allocator = testing.allocator;
|
||||
const template = "{% partialdef cabecalho %}Cabeçalho{% endpartialdef %}";
|
||||
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 == .partialdef);
|
||||
const pd = nodes[0].partialdef.?;
|
||||
try testing.expectEqualStrings("cabecalho", pd.name);
|
||||
try testing.expectEqual(@as(usize, 1), pd.body.len);
|
||||
try testing.expectEqualStrings("Cabeçalho", pd.body[0].text.?.content);
|
||||
}
|
||||
|
||||
test "parse partial uso" {
|
||||
const allocator = testing.allocator;
|
||||
const template = "Início {% partial \"cabecalho\" %} Fim";
|
||||
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.expect(nodes[1].type == .partial);
|
||||
try testing.expectEqualStrings("cabecalho", nodes[1].partial.?.name);
|
||||
}
|
||||
|
|
|
|||
10
todo.md
10
todo.md
|
|
@ -5,7 +5,7 @@
|
|||
- [x] comment
|
||||
- [x] csrf_token
|
||||
- [x] cycle
|
||||
- [ ] debug
|
||||
- [x] debug
|
||||
- [x] extends
|
||||
- [x] filter
|
||||
- [x] firstof
|
||||
|
|
@ -16,8 +16,8 @@
|
|||
- [x] load
|
||||
- [x] lorem
|
||||
- [x] now
|
||||
- [ ] partial
|
||||
- [ ] partialdef
|
||||
- [x] partial
|
||||
- [x] partialdef
|
||||
- [ ] querystring
|
||||
- [ ] regroup
|
||||
- [ ] resetcycle
|
||||
|
|
@ -108,9 +108,9 @@ ___
|
|||
## To do
|
||||
|
||||
1 - Finalizar o parser — completar as tags que faltam da lista:
|
||||
- [ ] debug
|
||||
- [x] debug
|
||||
- [x] lorem
|
||||
- [ ] partial / partialdef
|
||||
- [x] partial / partialdef
|
||||
- [ ] querystring
|
||||
- [ ] regroup
|
||||
- [ ] resetcycle
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue