diff --git a/build.zig b/build.zig index 0272f9f..0a6a141 100644 --- a/build.zig +++ b/build.zig @@ -84,15 +84,6 @@ pub fn build(b: *std.Build) void { .use_llvm = true, }); - // const lib = b.addLibrary(.{ - // .name = "zdt_prov", - // .root_module = mod, - // }); - // - // lib.root_module.addIncludePath(b.path("src/svg")); - // - // b.installArtifact(lib); - // This declares intent for the executable to be installed into the // install prefix when running `zig build` (i.e. when executing the default // step). By default the install prefix is `zig-out/` but can be overridden diff --git a/src/cache.zig b/src/cache.zig index 2543d8a..0a78820 100644 --- a/src/cache.zig +++ b/src/cache.zig @@ -2,13 +2,11 @@ const std = @import("std"); const Allocator = std.heap.ArenaAllocator; const parser = @import("parser.zig"); -const icons = @import("svg/icons.zig"); pub const TemplateCache = struct { arena: Allocator, cache: std.StringHashMapUnmanaged([]parser.Node), default_path: ?[]const u8 = "templates", - icons: ?icons.SvgIcon =null, pub fn init(child_allocator: std.mem.Allocator) TemplateCache { const arena = std.heap.ArenaAllocator.init(child_allocator); @@ -18,6 +16,7 @@ pub const TemplateCache = struct { }; } + pub fn deinit(self: *TemplateCache) void { self.arena.deinit(); } @@ -52,10 +51,6 @@ pub const TemplateCache = struct { } } - pub fn initIcons(self: *TemplateCache) !void { - self.icons = icons.SvgIcon.init(self.allocator()) catch null; - } - pub fn clear(self: *TemplateCache) void { self.deinit(); self.cache = .{}; diff --git a/src/context.zig b/src/context.zig index 6cf1744..a555794 100644 --- a/src/context.zig +++ b/src/context.zig @@ -42,18 +42,6 @@ pub const Context = struct { return Value{ .string = try time.formatDateTime(self.allocator(), value, "Y-m-d H:i:s") }; } - if (@typeInfo(T) == .pointer) { - if (@typeInfo(T).pointer.size == .slice) { - if (@typeInfo(@typeInfo(T).pointer.child) == .@"struct") { - var list = try self.allocator().alloc(Value, value.len); - for (value, 0..) |item, i| { - list[i] = try self.toValue(item); - } - return Value{ .list = list }; - } - } - } - return switch (@typeInfo(T)) { .bool => Value{ .bool = value }, .int, .comptime_int => Value{ .int = @intCast(value) }, diff --git a/src/context_test.zig b/src/context_test.zig index 25080b6..899284a 100644 --- a/src/context_test.zig +++ b/src/context_test.zig @@ -4,9 +4,6 @@ const Context = @import("context.zig").Context; const Value = @import("context.zig").Value; test "context set amigável e get com ponto" { - std.debug.print("____________________________________________________\n", .{}); - std.debug.print("1 - context set amigável e get com ponto\n", .{}); - const allocator = testing.allocator; var ctx = Context.init(allocator); defer ctx.deinit(); @@ -20,26 +17,17 @@ test "context set amigável e get com ponto" { // struct const Person = struct { nome: []const u8, idade: i64 }; const p = Person{ .nome = "Ana", .idade = 25 }; - const p2 = Person{ .nome = "Fulana", .idade = 28 }; - - const people = [_]Person{ p, p2 }; - - // try ctx.set("user", p); - try ctx.set("user", people); + try ctx.set("user", p); // list const numeros = [_]i64{ 1, 2, 3 }; try ctx.set("lista", numeros); - for (ctx.get("user").?.list) |item| { - std.debug.print("user {any}\n", .{item.dict.get("nome").?}); - } - // acesso try testing.expectEqualStrings("Lucas", ctx.get("nome").?.string); try testing.expect(ctx.get("idade").?.int == 30); - // try testing.expectEqualStrings("Ana", ctx.get("user.nome").?.string); - // try testing.expect(ctx.get("user.idade").?.int == 25); + try testing.expectEqualStrings("Ana", ctx.get("user.nome").?.string); + try testing.expect(ctx.get("user.idade").?.int == 25); try testing.expect(ctx.get("lista.1").?.int == 2); try testing.expect(ctx.get("vazio").?.string.len == 0); try testing.expect(ctx.get("preco").?.float == 99.99); diff --git a/src/delta_test.zig b/src/delta_test.zig index 496443b..4f3a08e 100644 --- a/src/delta_test.zig +++ b/src/delta_test.zig @@ -5,9 +5,6 @@ const Context = @import("context.zig").Context; const RelativeDelta = @import("delta.zig").RelativeDelta; test "relativedelta rigoroso - meses" { - std.debug.print("____________________________________________________\n", .{}); - std.debug.print("1 - context set amigável e get com ponto\n", .{}); - const a = try Time.parse("2025-03-31"); const b = try Time.parse("2025-01-31"); const delta = a.subRelative(b); @@ -20,9 +17,6 @@ test "relativedelta rigoroso - meses" { } test "relativedelta - overflow de dia" { - std.debug.print("____________________________________________________\n", .{}); - std.debug.print("2 - relativedelta - overflow de dia\n", .{}); - const jan31 = try Time.parse("2023-01-31"); const mar01 = try Time.parse("2023-03-01"); @@ -33,9 +27,6 @@ test "relativedelta - overflow de dia" { } test "bissexto: 2021-02-28 - 2020-02-29" { - std.debug.print("____________________________________________________\n", .{}); - std.debug.print("3 - bissexto: 2021-02-28 - 2020-02-29\n", .{}); - const a = try Time.parse("2021-02-28"); const b = try Time.parse("2020-02-29"); const delta = a.subRelative(b); @@ -45,9 +36,6 @@ test "bissexto: 2021-02-28 - 2020-02-29" { } test "bissexto: 2021-03-01 - 2020-02-29" { - std.debug.print("____________________________________________________\n", .{}); - std.debug.print("4 - bissexto: 2021-03-01 - 2020-02-29\n", .{}); - const a = try Time.parse("2021-03-01"); const b = try Time.parse("2020-02-29"); const delta = a.subRelative(b); @@ -57,9 +45,6 @@ test "bissexto: 2021-03-01 - 2020-02-29" { } test "bissexto: 2021-02-27 - 2020-02-29" { - std.debug.print("____________________________________________________\n", .{}); - std.debug.print("5 - bissexto: 2021-02-27 - 2020-02-29\n", .{}); - const a = try Time.parse("2021-02-27"); const b = try Time.parse("2020-02-29"); const delta = a.subRelative(b); @@ -69,9 +54,6 @@ test "bissexto: 2021-02-27 - 2020-02-29" { } test "bissexto reverso: 2020-02-29 - 2021-02-28" { - std.debug.print("____________________________________________________\n", .{}); - std.debug.print("6 - bissexto reverso: 2020-02-29 - 2021-02-28\n", .{}); - const a = try Time.parse("2020-02-29"); const b = try Time.parse("2021-02-28"); const delta = a.subRelative(b); @@ -81,9 +63,6 @@ test "bissexto reverso: 2020-02-29 - 2021-02-28" { } test "addRelative: anos normais (não bissexto)" { - std.debug.print("____________________________________________________\n", .{}); - std.debug.print("7 - addRelative: anos normais (não bissexto)\n", .{}); - // 2023 não é bissexto const base = try Time.parse("2023-06-15"); const expected = try Time.parse("2026-06-15"); @@ -98,9 +77,6 @@ test "addRelative: anos normais (não bissexto)" { } test "addRelative: anos normais com overflow de dia" { - std.debug.print("____________________________________________________\n", .{}); - std.debug.print("8 - addRelative: anos normais com overflow de dia\n", .{}); - // Janeiro 31 + 2 anos → deve ir para 31/jan (2025 não bissexto) const base = try Time.parse("2023-01-31"); const expected = try Time.parse("2025-01-31"); @@ -115,9 +91,6 @@ test "addRelative: anos normais com overflow de dia" { } test "addRelative: de 29/fev bissexto + 1 ano (vai para 28/fev)" { - std.debug.print("____________________________________________________\n", .{}); - std.debug.print("9 - addRelative: de 29/fev bissexto + 1 ano (vai para 28/fev)\n", .{}); - // 2020 foi bissexto → +1 ano deve ir para 2021-02-28 (não bissexto) const base = try Time.parse("2020-02-29"); const expected = try Time.parse("2021-02-28"); @@ -132,9 +105,6 @@ test "addRelative: de 29/fev bissexto + 1 ano (vai para 28/fev)" { } test "addRelative: de 29/fev bissexto + 4 anos (permanece 29/fev)" { - std.debug.print("____________________________________________________\n", .{}); - std.debug.print("10 - addRelative: de 29/fev bissexto + 4 anos (permanece 29/fev)\n", .{}); - // 2020 → 2024 (ambos bissextos) const base = try Time.parse("2020-02-29"); const expected = try Time.parse("2024-02-29"); @@ -149,9 +119,6 @@ test "addRelative: de 29/fev bissexto + 4 anos (permanece 29/fev)" { } test "addRelative: de 29/fev + 1 ano + 1 mês (vai para março)" { - std.debug.print("____________________________________________________\n", .{}); - std.debug.print("11 - addRelative: de 29/fev + 1 ano + 1 mês (vai para março)\n", .{}); - // 2020-02-29 + 1 ano → 2021-02-28 + 1 mês → 2021-03-28 const base = try Time.parse("2020-02-29"); const expected = try Time.parse("2021-03-28"); @@ -166,9 +133,6 @@ test "addRelative: de 29/fev + 1 ano + 1 mês (vai para março)" { } test "addRelative: meses com overflow (31 → 28/30)" { - std.debug.print("____________________________________________________\n", .{}); - std.debug.print("12 - addRelative: meses com overflow (31 → 28/30)\n", .{}); - const cases = [_]struct { base: []const u8, months: i32, expected: []const u8 }{ .{ .base = "2023-01-31", .months = 1, .expected = "2023-02-28" }, // não bissexto .{ .base = "2024-01-31", .months = 1, .expected = "2024-02-29" }, // bissexto @@ -192,9 +156,6 @@ test "addRelative: meses com overflow (31 → 28/30)" { } test "addRelative: combinação anos + meses + dias (bissexto envolvido)" { - std.debug.print("____________________________________________________\n", .{}); - std.debug.print("13 - addRelative: combinação anos + meses + dias (bissexto envolvido)\n", .{}); - // 2024-02-29 + 1 ano + 2 meses + 3 dias // → 2025-02-28 + 2 meses → 2025-04-28 + 3 dias → 2025-05-01 const base = try Time.parse("2024-02-29"); @@ -210,9 +171,6 @@ test "addRelative: combinação anos + meses + dias (bissexto envolvido)" { } test "addRelative: delta zero não altera data" { - std.debug.print("____________________________________________________\n", .{}); - std.debug.print("14 - addRelative: delta zero não altera data\n", .{}); - const base = try Time.parse("2025-07-20"); const delta = RelativeDelta.init(.{}); const result = base.addRelative(delta); diff --git a/src/parser.zig b/src/parser.zig index c87158e..f2f7c3e 100644 --- a/src/parser.zig +++ b/src/parser.zig @@ -45,7 +45,6 @@ pub const TagNodeBody = union(enum) { resetcycle: ResetCycleNode, spaceless: SpacelessNode, super: bool, - svg: SvgNode, templatetag: TemplateTagNode, url: UrlNode, verbatim: VerbatimNode, @@ -89,7 +88,6 @@ pub const TagKind = enum { resetcycle, spaceless, super, - svg, templatetag, url, verbatim, @@ -137,7 +135,6 @@ fn getTagKindByName(name: []const u8) TagKind { if (std.mem.eql(u8, name, "resetcycle")) return .resetcycle; if (std.mem.eql(u8, name, "spaceless")) return .spaceless; if (std.mem.eql(u8, name, "super")) return .super; - if (std.mem.eql(u8, name, "svg")) return .svg; if (std.mem.eql(u8, name, "templatetag")) return .templatetag; if (std.mem.eql(u8, name, "url")) return .url; if (std.mem.eql(u8, name, "verbatim")) return .verbatim; @@ -274,11 +271,6 @@ pub const SpacelessNode = struct { raw_close: []const u8, }; -pub const SvgNode = struct { - kind: []const u8, - name: []const u8, -}; - pub const TagNode = struct { kind: TagKind, args: []const u8, @@ -387,10 +379,6 @@ pub const Node = struct { for (body_copy) |n| n.deinit(allocator); allocator.free(body_copy); }, - .svg => { - allocator.free(t.body.svg.kind); - allocator.free(t.body.svg.name); - }, .url => { allocator.free(t.body.url.args); }, @@ -709,23 +697,6 @@ pub const Node = struct { }, }; }, - .svg => { - return Node{ - .type = .tag, - .tag = .{ - .kind = .svg, - .args = try allocator.dupe(u8, self.tag.?.args), - .raw = try allocator.dupe(u8, self.tag.?.raw), - - .body = .{ - .svg = .{ - .name = try allocator.dupe(u8, self.tag.?.body.svg.name), - .kind = try allocator.dupe(u8, self.tag.?.body.svg.kind), - }, - }, - }, - }; - }, .url => { const args_copy = try allocator.alloc([]const u8, self.tag.?.body.url.args.len); errdefer allocator.free(args_copy); @@ -960,7 +931,7 @@ pub const Node = struct { }, }; }, - else => {}, + else => unreachable, } }, } @@ -1696,19 +1667,6 @@ pub const Parser = struct { current_body = &false_body; continue; } - - var tag: Node = tag_node; - if (tag_node.tag.?.kind == .comment) { - try self.parseComment(); - continue; - } else { - if (try self.parseTagContent(allocator, tag_node)) |tn| { - tag.tag.?.body = tn; - try current_body.append(allocator, tag); - continue; - } - } - // Qualquer outra tag try current_body.append(allocator, tag_node); } else { @@ -1776,18 +1734,6 @@ pub const Parser = struct { continue; } - var tag: Node = tag_node; - if (tag_node.tag.?.kind == .comment) { - try self.parseComment(); - continue; - } else { - if (try self.parseTagContent(allocator, tag_node)) |tn| { - tag.tag.?.body = tn; - try body.append(allocator, tag); - continue; - } - } - try current_body.append(allocator, tag_node); } else { self.advance(1); @@ -2142,50 +2088,6 @@ pub const Parser = struct { const spaceless_node = try self.parseSpacelessBlock(allocator, raw_open); return spaceless_node; }, - .svg => { - const args = tag_node.tag.?.args; - - var values = std.ArrayList([]const u8){}; - defer values.deinit(allocator); - - var i: usize = 0; - while (i < args.len) { - while (i < args.len and std.ascii.isWhitespace(args[i])) : (i += 1) {} - - if (i >= args.len) break; - - const start = i; - var in_quote = false; - var quote_char: u8 = 0; - if (args[i] == '"' or args[i] == '\'') { - in_quote = true; - quote_char = args[i]; - i += 1; - } - - while (i < args.len) { - if (in_quote) { - if (args[i] == quote_char) { - i += 1; - break; - } - } else { - if (std.ascii.isWhitespace(args[i])) break; - } - i += 1; - } - - const value = std.mem.trim(u8, args[start..i], " \t\r\n\"'"); - // std.debug.print("value: {s}\n", .{value}); - try values.append(allocator, value); - } - return TagNodeBody{ - .svg = .{ - .kind = try allocator.dupe(u8, values.items[0]), - .name = try allocator.dupe(u8, values.items[1]), - }, - }; - }, .templatetag => { const args = tag_node.tag.?.args; const templatetag = TemplateTagNode.parse(args); @@ -2318,7 +2220,7 @@ pub const Parser = struct { try self.parseComment(); continue; } else { - // std.log.debug("Tag: {s}", .{tag.?.tag.?.raw}); + std.log.debug("Tag: {s}", .{tag.?.tag.?.raw}); if (try self.parseTagContent(allocator, tag.?)) |tn| { tag.?.tag.?.body = tn; try list.append(allocator, tag.?); diff --git a/src/parser_test.zig b/src/parser_test.zig index 02fef3b..bb515f3 100644 --- a/src/parser_test.zig +++ b/src/parser_test.zig @@ -712,7 +712,7 @@ test "parse simple lorem" { const l = nodes[0].tag.?.body.lorem; try testing.expect(l.count == null); try testing.expect(l.method == null); - try testing.expect(l.random == false); + try testing.expect(l.format == null); } test "parse lorem with arguments" { @@ -720,7 +720,7 @@ test "parse lorem with arguments" { std.debug.print("32 - parse lorem with arguments\n", .{}); const allocator = testing.allocator; - const template = "{% lorem 5 p true %}"; + const template = "{% lorem 5 p html %}"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { @@ -734,7 +734,7 @@ test "parse lorem with arguments" { const l = nodes[0].tag.?.body.lorem; try testing.expectEqualStrings("5", l.count.?); try testing.expectEqualStrings("p", l.method.?); - try testing.expect(l.random == true); + try testing.expectEqualStrings("html", l.format.?); } test "parse simple now" { @@ -1225,22 +1225,6 @@ test "parse simple with block" { try testing.expect(w.body[0].type == .text); } - -test "parse svg" { - std.debug.print("____________________________________________________\n", .{}); - std.debug.print("54 - parse svg\n", .{}); - - const allocator = testing.allocator; - const template = "{% svg \"material\" \"account_arrow_left\" %}"; - var p = parser.Parser.init(template); - const nodes = try p.parse(allocator); - defer { - for (nodes) |node| node.deinit(allocator); - allocator.free(nodes); - } - -} - // test "parse simple tag" { // std.debug.print("____________________________________________________\n", .{}); // std.debug.print("54 - parse simple tag\n", .{}); diff --git a/src/renderer.zig b/src/renderer.zig index c899961..d317617 100644 --- a/src/renderer.zig +++ b/src/renderer.zig @@ -12,7 +12,6 @@ const parser = @import("parser.zig"); const TemplateCache = @import("cache.zig").TemplateCache; const time = @import("time.zig"); const lorem = @import("lorem.zig"); -const icons = @import("svg/icons.zig"); pub const RenderError = error{ InvalidCharacter, @@ -21,7 +20,6 @@ pub const RenderError = error{ Overflow, Unexpected, UnsupportedExpression, - // } || FilterError || parser.ParserError || icons.SvgError || std.fs.File.OpenError; } || FilterError || parser.ParserError || std.fs.File.OpenError; pub const Renderer = struct { @@ -84,17 +82,16 @@ pub const Renderer = struct { } fn renderTemplate(self: *const Renderer, template: []const u8, writer: anytype, cache_key: ?[]const u8) RenderError!void { - _ = cache_key; var arena = std.heap.ArenaAllocator.init(self.allocator); defer arena.deinit(); const alloc = arena.allocator(); - // if (cache_key) |ck| { - // if (self.cache.get(ck)) |cached_nodes| { - // try self.renderNodes(alloc, cached_nodes, writer); - // return; - // } - // } + if (cache_key) |ck| { + if (self.cache.get(ck)) |cached_nodes| { + try self.renderNodes(alloc, cached_nodes, writer); + return; + } + } var p = parser.Parser.init(template); const nodes = try p.parse(alloc); @@ -103,15 +100,15 @@ pub const Renderer = struct { alloc.free(nodes); } - // if (cache_key) |ck| { - // var alc = self.cache.allocator(); - // var cached_nodes = try alc.alloc(parser.Node, nodes.len); - // errdefer alc.free(cached_nodes); - // for (nodes, 0..) |node, i| { - // cached_nodes[i] = try node.clone(self.allocator); - // } - // try self.cache.add(ck, nodes); - // } + if (cache_key) |ck| { + var alc = self.cache.allocator(); + var cached_nodes = try alc.alloc(parser.Node, nodes.len); + errdefer alc.free(cached_nodes); + for (nodes, 0..) |node, i| { + cached_nodes[i] = try node.clone(self.allocator); + } + try self.cache.add(ck, nodes); + } return try self.renderNodes(alloc, nodes, writer); } @@ -195,15 +192,15 @@ pub const Renderer = struct { .tag => { switch (node.tag.?.kind) { .if_block => { - const condition = try self.evaluateCondition(alloc, node.tag.?.body.@"if".condition, context); + const condition = try self.evaluateCondition(alloc, node.tag.?.body.@"if".condition); if (condition) { for (node.tag.?.body.@"if".true_body) |child| { - try self.renderNode(alloc, nodes, child, writer, context, null); + try self.renderNode(alloc, nodes, child, writer, null, null); } } else { for (node.tag.?.body.@"if".false_body) |child| { - try self.renderNode(alloc, nodes, child, writer, context, null); + try self.renderNode(alloc, nodes, child, writer, null, null); } } }, @@ -230,31 +227,11 @@ pub const Renderer = struct { else => return, }; - for (list, 0..) |item, i| { + for (list) |item| { var ctx = Context.init(alloc); defer ctx.deinit(); try ctx.set(node.tag.?.body.@"for".loop_var, item); - try ctx.set("forloop.counter", i + 1); - try ctx.set("forloop.counter0", i); - try ctx.set("forloop.revcounter", (list.len - i)); - try ctx.set("forloop.revcounter0", (list.len - i) - 1); - try ctx.set("forloop.first", i == 0); - try ctx.set("forloop.last", i == (list.len - 1)); - try ctx.set("forloop.length", list.len); - // forloop.counter - // The current iteration of the loop (1-indexed) - // forloop.counter0 - // The current iteration of the loop (0-indexed) - // forloop.revcounter - // The number of iterations from the end of the loop (1-indexed) - // forloop.revcounter0 - // The number of iterations from the end of the loop (0-indexed) - // forloop.first - // True if this is the first time through the loop - // forloop.last - // True if this is the last time through the loop - // forloop.length for (node.tag.?.body.@"for".body) |child| { try self.renderNode(alloc, nodes, child, writer, &ctx, null); @@ -380,7 +357,7 @@ pub const Renderer = struct { if (random == false) { try writer.writeAll(lorem.LOREM_COMMON_P); return; - } else { + }else { try writer.writeAll(try lorem.sentence(alloc)); return; } @@ -397,28 +374,7 @@ pub const Renderer = struct { return; } }, - .svg => { - const svg_kind = node.tag.?.body.svg.kind; - const svg_name = node.tag.?.body.svg.name; - - if (self.cache.icons.?.getIcon(alloc, svg_kind, svg_name)) |svg_content| { - try writer.writeAll("
"); - try writer.writeAll(svg_content); - try writer.writeAll("
"); - } else { - try writer.writeAll(icons.fallback_svg); - // Opcional: log ou comentário de debug - // try writer.print("", .{svg_kind, svg_name}); - } - return; - }, - else => { - std.debug.print("PANIC: unknown node type {d}\n", .{@intFromEnum(node.type)}); - // @panic("unknown node type"); - try writer.writeAll(""); - }, + else => {}, } }, } @@ -477,7 +433,7 @@ pub const Renderer = struct { _ = self; var w = buf.writer(alloc); switch (value) { - .null => try w.writeAll(""), + .null => try w.writeAll("null"), .bool => |b| try w.print("{}", .{b}), .int => |n| try w.print("{d}", .{n}), .float => |f| try w.print("{d}", .{f}), @@ -500,7 +456,7 @@ pub const Renderer = struct { }; } - fn evaluateCondition(self: *const Renderer, allocator: Allocator, expr: []const u8, context: ?*Context) RenderError!bool { + fn evaluateCondition(self: *const Renderer, allocator: Allocator, expr: []const u8) RenderError!bool { const trimmed = std.mem.trim(u8, expr, " \t\r\n"); if (trimmed.len == 0) return false; @@ -533,12 +489,7 @@ pub const Renderer = struct { const op = tokens.items[1]; const right_str = tokens.items[2]; - var left_value: Value = Value.null; - if (context) |ctx| { - left_value = ctx.get(left) orelse Value.null; - } - if (left_value == Value.null) left_value = self.context.get(left) orelse Value.null; - + const left_value = self.context.get(left) orelse Value.null; const right_value = parseLiteral(right_str); if (std.mem.eql(u8, op, ">")) return compare(left_value, right_value, .gt); diff --git a/src/renderer_test.zig b/src/renderer_test.zig index c37560d..2c5a847 100644 --- a/src/renderer_test.zig +++ b/src/renderer_test.zig @@ -1068,33 +1068,3 @@ test "renderer - lorem paragraphs random" { const spaces = std.mem.count(u8, buf.items, "

"); try testing.expect(spaces == 3); } - -test "renderer - svg" { - std.debug.print("____________________________________________________\n", .{}); - std.debug.print("27 - svg\n", .{}); - - const alloc = testing.allocator; - var ctx = Context.init(alloc); - defer ctx.deinit(); - - var cache = TemplateCache.init(alloc); - try cache.initIcons(); - defer cache.deinit(); - - const renderer = Renderer.init(&ctx, &cache); - - const template = - \\{% svg material kangaroo %} - ; - - var buf = std.ArrayList(u8){}; - defer buf.deinit(alloc); - - try renderer.renderString(template, buf.writer(alloc)); - - std.debug.print("OUTPUT:\n\n{s}\n", .{buf.items}); - - try testing.expect(std.mem.indexOf(u8, buf.items, "

") != null); - // const spaces = std.mem.count(u8, buf.items, "

"); - // try testing.expect(spaces == 3); -} diff --git a/src/root.zig b/src/root.zig index ff490a0..9b0e42f 100644 --- a/src/root.zig +++ b/src/root.zig @@ -2,7 +2,6 @@ pub const cache = @import("cache.zig"); pub const context = @import("context.zig"); pub const delta = @import("delta.zig"); pub const filters = @import("filters.zig"); -pub const icons = @import("svg/icons.zig"); pub const lorem = @import("lorem.zig"); pub const meta = @import("meta.zig"); pub const parser = @import("parser.zig"); diff --git a/src/svg/icons.zig b/src/svg/icons.zig deleted file mode 100644 index 5b4ad4f..0000000 --- a/src/svg/icons.zig +++ /dev/null @@ -1,117 +0,0 @@ -const std = @import("std"); - -pub const IconSet = enum { - bootstrap, - dripicons, - hero_outline, - hero_solid, - material, -}; - -pub const embedded_data = std.EnumMap(IconSet, []const u8).init(.{ - .bootstrap = @embedFile("bootstrap.svgs.bin"), - .dripicons = @embedFile("dripicons.svgs.bin"), - .hero_outline = @embedFile("hero_outline.svgs.bin"), - .hero_solid = @embedFile("hero_solid.svgs.bin"), - .material = @embedFile("material.svgs.bin"), -}); - -pub const SvgIcon = struct { - icon_map: std.StringHashMapUnmanaged([]const u8) = .{}, - - pub fn init(allocator: std.mem.Allocator) !SvgIcon { - var self = SvgIcon{}; - - inline for (std.meta.fields(IconSet)) |field| { - const set = @field(IconSet, field.name); - const data = embedded_data.get(set); - - try self.loadSet(allocator, set, data.?); - } - - return self; - } - - pub fn deinit(self: *SvgIcon, allocator: std.mem.Allocator) void { - var it = self.icon_map.iterator(); - while (it.next()) |entry| { - allocator.free(entry.key_ptr.*); - allocator.free(entry.value_ptr.*); - } - self.icon_map.deinit(allocator); - self.* = .{}; - } - - pub fn get(self: *const SvgIcon, key: []const u8) ?[]const u8 { - return self.icon_map.get(key); - } - - pub fn getIcon(self: *const SvgIcon,allocator: std.mem.Allocator, kind: []const u8, name: []const u8) ?[]const u8 { - const key = std.fmt.allocPrint(allocator, "{s}:{s}", .{ kind, name }) catch return null; - defer allocator.free(key); - return self.icon_map.get(key); - } - - pub fn count(self: *const SvgIcon) usize { - return self.icon_map.count(); - } - - fn loadSet( - self: *SvgIcon, - allocator: std.mem.Allocator, - set: IconSet, - data: []const u8, - ) !void { - if (data.len < 12) return error.InvalidEmbeddedData; - - var pos: usize = 0; - - const magic = std.mem.readInt(u32, data[pos..][0..4], .little); - pos += 4; - if (magic != 0x53564749) return error.InvalidMagic; - - const version = std.mem.readInt(u32, data[pos..][0..4], .little); - pos += 4; - if (version != 1) return error.UnsupportedVersion; - - const num_entries = std.mem.readInt(u32, data[pos..][0..4], .little); - pos += 4; - - const prefix = @tagName(set); - - var i: u32 = 0; - while (i < num_entries) : (i += 1) { - const name_len = std.mem.readInt(u32, data[pos..][0..4], .little); - pos += 4; - - if (pos + name_len > data.len) return error.CorruptedNameLength; - const name_slice = data[pos .. pos + name_len]; - pos += name_len; - - const svg_len = std.mem.readInt(u32, data[pos..][0..4], .little); - pos += 4; - - if (pos + svg_len > data.len) return error.CorruptedSvgLength; - const svg_slice = data[pos .. pos + svg_len]; - pos += svg_len; - - // Monta a chave com prefixo do set - const key = try std.fmt.allocPrint(allocator, "{s}:{s}", .{ prefix, name_slice }); - - // Duplica o conteúdo SVG (o map assume ownership) - const value = try allocator.dupe(u8, svg_slice); - - // Insere no mapa unmanaged - try self.icon_map.put(allocator, key, value); - } - } -}; - -pub const fallback_svg = - \\

- \\ - \\ - \\ ? - \\ - \\
-; diff --git a/src/time.zig b/src/time.zig index e27da58..a8a803b 100644 --- a/src/time.zig +++ b/src/time.zig @@ -350,10 +350,6 @@ pub const Time = struct { return unix(std.time.timestamp()); } - pub fn now_offset(offset: i64) Time { - return unix(std.time.timestamp() + (offset * std.time.s_per_hour)); - } - pub fn today() Time { return unix(0).setDate(.today()); }