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,
|
load,
|
||||||
csrf_token,
|
csrf_token,
|
||||||
lorem,
|
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 {
|
pub const LoremNode = struct {
|
||||||
|
|
@ -156,7 +170,10 @@ pub const Node = struct {
|
||||||
firstof: ?FirstOfNode = null,
|
firstof: ?FirstOfNode = null,
|
||||||
load: ?LoadNode = null,
|
load: ?LoadNode = null,
|
||||||
lorem: ?LoremNode = null,
|
lorem: ?LoremNode = null,
|
||||||
|
partialdef: ?PartialDefNode = null,
|
||||||
|
partial: ?PartialNode = null,
|
||||||
csrf_token: bool = false,
|
csrf_token: bool = false,
|
||||||
|
debug: bool = false,
|
||||||
|
|
||||||
pub fn deinit(self: Node, allocator: std.mem.Allocator) void {
|
pub fn deinit(self: Node, allocator: std.mem.Allocator) void {
|
||||||
switch (self.type) {
|
switch (self.type) {
|
||||||
|
|
@ -251,6 +268,15 @@ pub const Node = struct {
|
||||||
if (l.method) |m| allocator.free(m);
|
if (l.method) |m| allocator.free(m);
|
||||||
if (l.format) |f| allocator.free(f);
|
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);
|
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 {
|
fn parseAutoescapeBlock(self: *Parser, allocator: std.mem.Allocator, enabled: bool, raw_open: []const u8) !Node {
|
||||||
var body = std.ArrayList(Node){};
|
var body = std.ArrayList(Node){};
|
||||||
defer body.deinit(allocator);
|
defer body.deinit(allocator);
|
||||||
|
|
@ -1106,6 +1190,41 @@ pub const Parser = struct {
|
||||||
continue;
|
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")) {
|
if (std.mem.eql(u8, tag_name, "lorem")) {
|
||||||
const args = node.tag.?.args;
|
const args = node.tag.?.args;
|
||||||
|
|
||||||
|
|
@ -1129,9 +1248,8 @@ pub const Parser = struct {
|
||||||
method = try allocator.dupe(u8, trimmed);
|
method = try allocator.dupe(u8, trimmed);
|
||||||
} else if (std.mem.eql(u8, trimmed, "html")) {
|
} else if (std.mem.eql(u8, trimmed, "html")) {
|
||||||
std.debug.print("trimmed: {s}\n", .{trimmed});
|
std.debug.print("trimmed: {s}\n", .{trimmed});
|
||||||
format = try allocator.dupe(u8, trimmed);
|
format = try allocator.dupe(u8, trimmed);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
allocator.free(node.tag.?.name);
|
allocator.free(node.tag.?.name);
|
||||||
|
|
@ -1515,6 +1633,25 @@ pub const Parser = struct {
|
||||||
continue;
|
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")) {
|
if (std.mem.eql(u8, tag_name, "csrf_token")) {
|
||||||
// Verifica se tem argumentos (não deve ter)
|
// Verifica se tem argumentos (não deve ter)
|
||||||
if (node.tag.?.args.len > 0 and !std.mem.allEqual(u8, node.tag.?.args, ' ')) {
|
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("p", l.method.?);
|
||||||
try testing.expectEqualStrings("html", l.format.?);
|
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] comment
|
||||||
- [x] csrf_token
|
- [x] csrf_token
|
||||||
- [x] cycle
|
- [x] cycle
|
||||||
- [ ] debug
|
- [x] debug
|
||||||
- [x] extends
|
- [x] extends
|
||||||
- [x] filter
|
- [x] filter
|
||||||
- [x] firstof
|
- [x] firstof
|
||||||
|
|
@ -16,8 +16,8 @@
|
||||||
- [x] load
|
- [x] load
|
||||||
- [x] lorem
|
- [x] lorem
|
||||||
- [x] now
|
- [x] now
|
||||||
- [ ] partial
|
- [x] partial
|
||||||
- [ ] partialdef
|
- [x] partialdef
|
||||||
- [ ] querystring
|
- [ ] querystring
|
||||||
- [ ] regroup
|
- [ ] regroup
|
||||||
- [ ] resetcycle
|
- [ ] resetcycle
|
||||||
|
|
@ -108,9 +108,9 @@ ___
|
||||||
## To do
|
## To do
|
||||||
|
|
||||||
1 - Finalizar o parser — completar as tags que faltam da lista:
|
1 - Finalizar o parser — completar as tags que faltam da lista:
|
||||||
- [ ] debug
|
- [x] debug
|
||||||
- [x] lorem
|
- [x] lorem
|
||||||
- [ ] partial / partialdef
|
- [x] partial / partialdef
|
||||||
- [ ] querystring
|
- [ ] querystring
|
||||||
- [ ] regroup
|
- [ ] regroup
|
||||||
- [ ] resetcycle
|
- [ ] resetcycle
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue