Hey :slight_smile: this is my first Post and also my first attempts at metaprogramming.

For my Project im working on, i needed some icons and found them in the form of SVGs.
Because i want this project to be small and minimal, and because i need the icons the whole time the Program is running, i want to embed these.
… so far so easy …
But DVUI (the UI lib im using) only talks TVG not SVG.
There is a function provided by DVUI dvui.svgToTvg(...) which works fine, but it wants to alloc those, that way my program would have the SVGs embedded and the TVGs on the heap, also … i would create the TVGs every time the Program is setting up.
I don’t want this.

I could just convert all of my assets by hand,… but i also dont like this. I want my assets to be just a folder of SVGs!

So… i managed to get the following working and would like to know if there is anything bad/dirty with it and most importantly: Is there an easier way? :slight_smile: (comptime blocks dont support Io in my findings, right?)
Also, are my generated TVGs really embedded this way?

My meta file:

const std = @import("std");
const dvui = @import("dvui");

pub fn main(init: std.process.Init) !void {
    const arena = init.arena.allocator();

    const args = try init.minimal.args.toSlice(arena);
    const cwd = std.Io.Dir.cwd();

    const assets = try cwd.openDir(init.io, "src/assets", .{ .iterate = true });
    defer assets.close(init.io);

    var output: std.ArrayList(u8) = try .initCapacity(arena, 100 * 1024);

    try output.print(
        arena,
        "pub const Tvgs = struct {s}\n",
        .{"{"},
    );

    var names: std.ArrayList([]const u8) = .empty;

    var asset_iter = try assets.walk(arena);
    while (try asset_iter.next(init.io)) |svg| {
        const svg_data = try assets.readFileAlloc(init.io, svg.path, arena, .unlimited);
        const tvg = try dvui.svgToTvg(arena, svg_data);
        var name_buf: [1024]u8 = undefined;
        _ = std.mem.replace(u8, svg.basename, "-", "_", &name_buf);
        const name = try arena.alloc(u8, name_buf[0 .. svg.basename.len - 4].len);
        std.mem.copyForwards(u8, name, name_buf[0 .. svg.basename.len - 4]);
        try output.print(
            arena,
            "const {s}_const: [{d}]u8 = .{s} ",
            .{ name, tvg.len, "{" },
        );
        try names.append(arena, name);

        for (tvg) |b| {
            try output.print(
                arena,
                "{d}, ",
                .{b},
            );
        }

        try output.print(
            arena,
            "{s};\n",
            .{"}"},
        );
    }

    for (names.items) |name| {
        try output.print(
            arena,
            "{s}: []const u8 = &Tvgs.{s}_const,\n",
            .{ name, name },
        );
    }

    try output.print(
        arena,
        "{s};\n",
        .{"}"},
    );

    var output_file = try cwd.createFile(init.io, args[1], .{});
    defer output_file.close(init.io);

    try output_file.writeStreamingAll(init.io, output.items);

    return std.process.cleanExit(init.io);
}

it gets embedded like this example here.