diff --git a/src/lib.zig b/src/lib.zig index 28b7c483b4a58801e4f7da8a8abc2f850207ed21..e55a52b5f6e569460b44c59c3b9513de391c6e82 100644 --- a/src/lib.zig +++ b/src/lib.zig @@ -32,19 +32,29 @@ pub fn compile(comptime Ctx: type, alloc: std.mem.Allocator, writer: anytype, co try do(alloc, writer, value, data, data, .{ .Ctx = Ctx, .indent = 0, - .flag1 = false, + .doindent = builtin.mode == .Debug, + .doindent2 = builtin.mode == .Debug, }); - try writer.writeAll("\n"); } pub fn compileInner(alloc: std.mem.Allocator, writer: anytype, comptime value: astgen.Value, comptime opts: DoOptions, data: anytype) !void { try do(alloc, writer, value, data, data, opts); - try writer.writeAll("\n"); } pub const Writer = std.ArrayList(u8).Writer; fn do(alloc: std.mem.Allocator, writer: anytype, comptime value: astgen.Value, data: anytype, ctx: anytype, comptime opts: DoOptions) callconv(callconv_inline) anyerror!void { + comptime var skipindent = false; + if (value == .element and comptime std.mem.eql(u8, value.element.name, "pre")) skipindent = true; + return doInner(alloc, writer, value, data, ctx, .{ + .Ctx = opts.Ctx, + .indent = opts.indent, + .doindent = opts.doindent and !skipindent, + .doindent2 = opts.doindent, + .escaped = opts.escaped, + }); +} +fn doInner(alloc: std.mem.Allocator, writer: anytype, comptime value: astgen.Value, data: anytype, ctx: anytype, comptime opts: DoOptions) callconv(callconv_inline) anyerror!void { switch (comptime value) { .element => |v| { const hastext = comptime for (v.children) |x| { @@ -53,14 +63,15 @@ fn do(alloc: std.mem.Allocator, writer: anytype, comptime value: astgen.Value, d .element, .attr, .block, .body => {}, } } else false; + _ = hastext; - if (opts.flag1) for (0..opts.indent) |_| try writer.writeAll(" "); + if (opts.doindent2) for (0..opts.indent) |_| try writer.writeAll(" "); try writer.writeAll("<"); try writer.writeAll(v.name); inline for (v.attrs) |it| { switch (comptime it.value) { - .string => try writer.print(" {s}=\"{}\"", .{ it.key, std.zig.fmtEscapes(it.value.string[1 .. it.value.string.len - 1]) }), + .string => try writer.print(" {s}={s}", .{ it.key, it.value.string }), .body => { try writer.print(" {s}=\"", .{it.key}); inline for (it.value.body) |bval| try do(alloc, writer, bval, data, ctx, opts); @@ -71,24 +82,27 @@ fn do(alloc: std.mem.Allocator, writer: anytype, comptime value: astgen.Value, d if (v.children.len == 0) { if (contains(std.meta.fieldNames(HtmlVoidElements), v.name)) { - try writer.writeAll(" />\n"); + try writer.writeAll(" />"); + if (opts.doindent2) try writer.writeAll("\n"); } else { - try writer.print(">{s}>\n", .{v.name}); + try writer.print(">{s}>", .{v.name}); + if (opts.doindent2) try writer.writeAll("\n"); } } else { + const shouldindent = opts.doindent and v.children[0] != .string and v.children[0] != .replacement; try writer.writeAll(">"); - - if (!hastext) try writer.writeAll("\n"); + if (shouldindent) try writer.writeAll("\n"); inline for (v.children) |it| { try do(alloc, writer, it, data, ctx, .{ .Ctx = opts.Ctx, .indent = opts.indent + 1, - .flag1 = !hastext, + .doindent = shouldindent, + .doindent2 = opts.doindent2, }); } - if (!hastext) for (0..opts.indent) |_| try writer.writeAll(" "); + if (shouldindent) for (0..opts.indent) |_| try writer.writeAll(" "); try writer.print("{s}>", .{v.name}); - if (opts.flag1) try writer.writeAll("\n"); + if (opts.doindent2) try writer.writeAll("\n"); } }, .string => |v| { @@ -253,13 +267,10 @@ fn do(alloc: std.mem.Allocator, writer: anytype, comptime value: astgen.Value, d } }, .function => |v| { - var arena = std.heap.ArenaAllocator.init(alloc); - defer arena.deinit(); - if (!v.raw and @hasDecl(opts.Ctx, "pek_" ++ v.name)) { const func = @field(opts.Ctx, "pek_" ++ v.name); - var list = std.ArrayList(u8).init(arena.allocator()); - errdefer list.deinit(); + var list = std.ArrayList(u8).init(alloc); + defer list.deinit(); var args: std.meta.ArgsTuple(@TypeOf(func)) = undefined; comptime std.debug.assert(args.len - 2 == v.args.len); args.@"0" = alloc; @@ -274,8 +285,8 @@ fn do(alloc: std.mem.Allocator, writer: anytype, comptime value: astgen.Value, d } if (v.raw and @hasDecl(opts.Ctx, "pek__" ++ v.name)) { const func = @field(opts.Ctx, "pek__" ++ v.name); - var list = std.ArrayList(u8).init(arena.allocator()); - errdefer list.deinit(); + var list = std.ArrayList(u8).init(alloc); + defer list.deinit(); const AT = std.meta.ArgsTuple(@TypeOf(func)); const ATT = std.meta.fieldInfo(AT, .@"3").type; if (v.args.len != std.meta.fields(ATT).len) @compileError(std.fmt.comptimePrint("expected:{d} - actual:{d}", .{ std.meta.fields(ATT).len, v.args.len })); @@ -310,7 +321,8 @@ fn do(alloc: std.mem.Allocator, writer: anytype, comptime value: astgen.Value, d pub const DoOptions = struct { Ctx: type, indent: usize, - flag1: bool, + doindent: bool, + doindent2: bool, escaped: bool = true, }; diff --git a/test.zig b/test.zig index 3e094bd07ee144e3eaba0a7f66105f967d476510..6a78079d764880474fd759c7598efb4ce41b2ae3 100644 --- a/test.zig +++ b/test.zig @@ -65,7 +65,7 @@ test "fragment" { alloc, builder.writer(), doc, - .{ .Ctx = @This(), .indent = 0, .flag1 = false }, + .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true }, .{}, ); try expect(builder.items).toEqualString( @@ -98,7 +98,7 @@ test "if: basic" { alloc, builder.writer(), doc, - .{ .Ctx = @This(), .indent = 0, .flag1 = false }, + .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true }, .{ .foo = false, .bar = true }, ); try expect(builder.items).toEqualString( @@ -129,7 +129,7 @@ test "if else + field access" { alloc, builder.writer(), doc, - .{ .Ctx = @This(), .indent = 0, .flag1 = false }, + .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true }, .{ .bar = .{ .qux = false } }, ); try expect(builder.items).toEqualString( @@ -158,7 +158,7 @@ test { alloc, builder.writer(), doc, - .{ .Ctx = @This(), .indent = 0, .flag1 = false }, + .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true }, .{ .bar = true }, ); try expect(builder.items).toEqualString( @@ -185,7 +185,7 @@ test { alloc, builder.writer(), doc, - .{ .Ctx = @This(), .indent = 0, .flag1 = false }, + .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true }, .{ .bar = false }, ); try expect(builder.items).toEqualString( @@ -214,7 +214,7 @@ test { // bool alloc, builder.writer(), doc, - .{ .Ctx = @This(), .indent = 0, .flag1 = false }, + .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true }, .{ .bar = true }, ); try expect(builder.items).toEqualString( @@ -241,7 +241,7 @@ test { // bool false alloc, builder.writer(), doc, - .{ .Ctx = @This(), .indent = 0, .flag1 = false }, + .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true }, .{ .bar = false }, ); try expect(builder.items).toEqualString( @@ -268,7 +268,7 @@ test { // string alloc, builder.writer(), doc, - .{ .Ctx = @This(), .indent = 0, .flag1 = false }, + .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true }, .{ .bar = @as([]const u8, "foo") }, ); try expect(builder.items).toEqualString( @@ -295,7 +295,7 @@ test { // string false alloc, builder.writer(), doc, - .{ .Ctx = @This(), .indent = 0, .flag1 = false }, + .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true }, .{ .bar = @as([]const u8, "qux") }, ); try expect(builder.items).toEqualString( @@ -322,7 +322,7 @@ test { // enum alloc, builder.writer(), doc, - .{ .Ctx = @This(), .indent = 0, .flag1 = false }, + .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true }, .{ .bar = @as(enum { foo, bar, qux }, .foo) }, ); try expect(builder.items).toEqualString( @@ -349,7 +349,7 @@ test { // enum false alloc, builder.writer(), doc, - .{ .Ctx = @This(), .indent = 0, .flag1 = false }, + .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true }, .{ .bar = @as(enum { foo, bar, qux }, .qux) }, ); try expect(builder.items).toEqualString( @@ -378,7 +378,7 @@ test { // bool alloc, builder.writer(), doc, - .{ .Ctx = @This(), .indent = 0, .flag1 = false }, + .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true }, .{ .bar = false }, ); try expect(builder.items).toEqualString( @@ -405,7 +405,7 @@ test { // bool false alloc, builder.writer(), doc, - .{ .Ctx = @This(), .indent = 0, .flag1 = false }, + .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true }, .{ .bar = true }, ); try expect(builder.items).toEqualString( @@ -432,7 +432,7 @@ test { // string alloc, builder.writer(), doc, - .{ .Ctx = @This(), .indent = 0, .flag1 = false }, + .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true }, .{ .bar = @as([]const u8, "qux") }, ); try expect(builder.items).toEqualString( @@ -459,7 +459,7 @@ test { // string false alloc, builder.writer(), doc, - .{ .Ctx = @This(), .indent = 0, .flag1 = false }, + .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true }, .{ .bar = @as([]const u8, "foo") }, ); try expect(builder.items).toEqualString( @@ -486,7 +486,7 @@ test { // enum alloc, builder.writer(), doc, - .{ .Ctx = @This(), .indent = 0, .flag1 = false }, + .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true }, .{ .bar = @as(enum { foo, bar, qux }, .qux) }, ); try expect(builder.items).toEqualString( @@ -513,7 +513,7 @@ test { // enum false alloc, builder.writer(), doc, - .{ .Ctx = @This(), .indent = 0, .flag1 = false }, + .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true }, .{ .bar = @as(enum { foo, bar, qux }, .foo) }, ); try expect(builder.items).toEqualString( @@ -538,7 +538,7 @@ test { alloc, builder.writer(), doc, - .{ .Ctx = @This(), .indent = 0, .flag1 = false }, + .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true }, .{ .text = @as([]const u8, "dynamic") }, ); try expect(builder.items).toEqualString( @@ -561,7 +561,7 @@ test { alloc, builder.writer(), doc, - .{ .Ctx = @This(), .indent = 0, .flag1 = false }, + .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true }, .{ .url = @as([]const u8, "https://github.com/nektro/zig-pek") }, ); try expect(builder.items).toEqualString( @@ -584,7 +584,7 @@ test { alloc, builder.writer(), doc, - .{ .Ctx = @This(), .indent = 0, .flag1 = false }, + .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true }, .{ .host = @as([]const u8, "github.com") }, ); try expect(builder.items).toEqualString( @@ -607,7 +607,7 @@ test { alloc, builder.writer(), doc, - .{ .Ctx = @This(), .indent = 0, .flag1 = false }, + .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true }, .{ .host = "github.com".* }, ); try expect(builder.items).toEqualString( @@ -642,7 +642,7 @@ test { alloc, builder.writer(), doc, - .{ .Ctx = @This(), .indent = 0, .flag1 = false }, + .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true }, .{ .host = S{ .name = "github" } }, ); try expect(builder.items).toEqualString( @@ -674,7 +674,7 @@ test { alloc, builder.writer(), doc, - .{ .Ctx = @This(), .indent = 0, .flag1 = false }, + .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true }, .{ .host = S{ .name = "github" } }, ); try expect(builder.items).toEqualString( @@ -699,7 +699,7 @@ test { alloc, builder.writer(), doc, - .{ .Ctx = @This(), .indent = 0, .flag1 = false }, + .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true }, .{ .url = "https://github.com/nektro/zig-pek".* }, ); try expect(builder.items).toEqualString( @@ -722,7 +722,7 @@ test { alloc, builder.writer(), doc, - .{ .Ctx = @This(), .indent = 0, .flag1 = false }, + .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true }, .{ .foo = "contain HTML such as as an escape hatch when you know content is safe".* }, ); try expect(builder.items).toEqualString( @@ -770,16 +770,18 @@ test { alloc, builder.writer(), doc, - .{ .Ctx = C, .indent = 0, .flag1 = false }, + .{ .Ctx = C, .indent = 0, .doindent = true, .doindent2 = true }, .{ .prev = person }, ); try expect(builder.items).toEqualString( \\
- \\ \\ \\ ); @@ -816,7 +818,7 @@ test { alloc, builder.writer(), doc, - .{ .Ctx = C, .indent = 0, .flag1 = false }, + .{ .Ctx = C, .indent = 0, .doindent = true, .doindent2 = true }, .{ .user = person }, ); try expect(builder.items).toEqualString( @@ -856,7 +858,7 @@ test { alloc, builder.writer(), doc, - .{ .Ctx = C, .indent = 0, .flag1 = false }, + .{ .Ctx = C, .indent = 0, .doindent = true, .doindent2 = true }, .{ .user = person }, ); try expect(builder.items).toEqualString( @@ -893,7 +895,7 @@ test { alloc, builder.writer(), doc, - .{ .Ctx = @This(), .indent = 0, .flag1 = false }, + .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true }, .{ .states = &states }, ); try expect(builder.items).toEqualString( @@ -932,7 +934,7 @@ test { alloc, builder.writer(), doc, - .{ .Ctx = @This(), .indent = 0, .flag1 = false }, + .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true }, .{ .abbrs = states.items.abbr, .names = states.items.name }, ); try expect(builder.items).toEqualString(