authorgravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2026-02-15 16:52:09 -08:00
committergravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2026-02-15 16:52:09 -08:00
log49021184418ec124322660b4efb283481ec254b8
tree38e2c3239bbc40d8fca488a70ed8a2cac59893e8
parent33e66a5d2fb789b9e35ffe7298188dd2710aed5a

redo indentation


2 files changed, 66 insertions(+), 52 deletions(-)

src/lib.zig+32-20
......@@ -32,19 +32,29 @@ pub fn compile(comptime Ctx: type, alloc: std.mem.Allocator, writer: anytype, co
3232 try do(alloc, writer, value, data, data, .{
3333 .Ctx = Ctx,
3434 .indent = 0,
35 .flag1 = false,
35 .doindent = builtin.mode == .Debug,
36 .doindent2 = builtin.mode == .Debug,
3637 });
37 try writer.writeAll("\n");
3838}
3939
4040pub fn compileInner(alloc: std.mem.Allocator, writer: anytype, comptime value: astgen.Value, comptime opts: DoOptions, data: anytype) !void {
4141 try do(alloc, writer, value, data, data, opts);
42 try writer.writeAll("\n");
4342}
4443
4544pub const Writer = std.ArrayList(u8).Writer;
4645
4746fn do(alloc: std.mem.Allocator, writer: anytype, comptime value: astgen.Value, data: anytype, ctx: anytype, comptime opts: DoOptions) callconv(callconv_inline) anyerror!void {
47 comptime var skipindent = false;
48 if (value == .element and comptime std.mem.eql(u8, value.element.name, "pre")) skipindent = true;
49 return doInner(alloc, writer, value, data, ctx, .{
50 .Ctx = opts.Ctx,
51 .indent = opts.indent,
52 .doindent = opts.doindent and !skipindent,
53 .doindent2 = opts.doindent,
54 .escaped = opts.escaped,
55 });
56}
57fn doInner(alloc: std.mem.Allocator, writer: anytype, comptime value: astgen.Value, data: anytype, ctx: anytype, comptime opts: DoOptions) callconv(callconv_inline) anyerror!void {
4858 switch (comptime value) {
4959 .element => |v| {
5060 const hastext = comptime for (v.children) |x| {
......@@ -53,14 +63,15 @@ fn do(alloc: std.mem.Allocator, writer: anytype, comptime value: astgen.Value, d
5363 .element, .attr, .block, .body => {},
5464 }
5565 } else false;
66 _ = hastext;
5667
57 if (opts.flag1) for (0..opts.indent) |_| try writer.writeAll(" ");
68 if (opts.doindent2) for (0..opts.indent) |_| try writer.writeAll(" ");
5869 try writer.writeAll("<");
5970 try writer.writeAll(v.name);
6071
6172 inline for (v.attrs) |it| {
6273 switch (comptime it.value) {
63 .string => try writer.print(" {s}=\"{}\"", .{ it.key, std.zig.fmtEscapes(it.value.string[1 .. it.value.string.len - 1]) }),
74 .string => try writer.print(" {s}={s}", .{ it.key, it.value.string }),
6475 .body => {
6576 try writer.print(" {s}=\"", .{it.key});
6677 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
7182
7283 if (v.children.len == 0) {
7384 if (contains(std.meta.fieldNames(HtmlVoidElements), v.name)) {
74 try writer.writeAll(" />\n");
85 try writer.writeAll(" />");
86 if (opts.doindent2) try writer.writeAll("\n");
7587 } else {
76 try writer.print("></{s}>\n", .{v.name});
88 try writer.print("></{s}>", .{v.name});
89 if (opts.doindent2) try writer.writeAll("\n");
7790 }
7891 } else {
92 const shouldindent = opts.doindent and v.children[0] != .string and v.children[0] != .replacement;
7993 try writer.writeAll(">");
80
81 if (!hastext) try writer.writeAll("\n");
94 if (shouldindent) try writer.writeAll("\n");
8295 inline for (v.children) |it| {
8396 try do(alloc, writer, it, data, ctx, .{
8497 .Ctx = opts.Ctx,
8598 .indent = opts.indent + 1,
86 .flag1 = !hastext,
99 .doindent = shouldindent,
100 .doindent2 = opts.doindent2,
87101 });
88102 }
89 if (!hastext) for (0..opts.indent) |_| try writer.writeAll(" ");
103 if (shouldindent) for (0..opts.indent) |_| try writer.writeAll(" ");
90104 try writer.print("</{s}>", .{v.name});
91 if (opts.flag1) try writer.writeAll("\n");
105 if (opts.doindent2) try writer.writeAll("\n");
92106 }
93107 },
94108 .string => |v| {
......@@ -253,13 +267,10 @@ fn do(alloc: std.mem.Allocator, writer: anytype, comptime value: astgen.Value, d
253267 }
254268 },
255269 .function => |v| {
256 var arena = std.heap.ArenaAllocator.init(alloc);
257 defer arena.deinit();
258
259270 if (!v.raw and @hasDecl(opts.Ctx, "pek_" ++ v.name)) {
260271 const func = @field(opts.Ctx, "pek_" ++ v.name);
261 var list = std.ArrayList(u8).init(arena.allocator());
262 errdefer list.deinit();
272 var list = std.ArrayList(u8).init(alloc);
273 defer list.deinit();
263274 var args: std.meta.ArgsTuple(@TypeOf(func)) = undefined;
264275 comptime std.debug.assert(args.len - 2 == v.args.len);
265276 args.@"0" = alloc;
......@@ -274,8 +285,8 @@ fn do(alloc: std.mem.Allocator, writer: anytype, comptime value: astgen.Value, d
274285 }
275286 if (v.raw and @hasDecl(opts.Ctx, "pek__" ++ v.name)) {
276287 const func = @field(opts.Ctx, "pek__" ++ v.name);
277 var list = std.ArrayList(u8).init(arena.allocator());
278 errdefer list.deinit();
288 var list = std.ArrayList(u8).init(alloc);
289 defer list.deinit();
279290 const AT = std.meta.ArgsTuple(@TypeOf(func));
280291 const ATT = std.meta.fieldInfo(AT, .@"3").type;
281292 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
310321pub const DoOptions = struct {
311322 Ctx: type,
312323 indent: usize,
313 flag1: bool,
324 doindent: bool,
325 doindent2: bool,
314326 escaped: bool = true,
315327};
316328
test.zig+34-32
......@@ -65,7 +65,7 @@ test "fragment" {
6565 alloc,
6666 builder.writer(),
6767 doc,
68 .{ .Ctx = @This(), .indent = 0, .flag1 = false },
68 .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true },
6969 .{},
7070 );
7171 try expect(builder.items).toEqualString(
......@@ -98,7 +98,7 @@ test "if: basic" {
9898 alloc,
9999 builder.writer(),
100100 doc,
101 .{ .Ctx = @This(), .indent = 0, .flag1 = false },
101 .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true },
102102 .{ .foo = false, .bar = true },
103103 );
104104 try expect(builder.items).toEqualString(
......@@ -129,7 +129,7 @@ test "if else + field access" {
129129 alloc,
130130 builder.writer(),
131131 doc,
132 .{ .Ctx = @This(), .indent = 0, .flag1 = false },
132 .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true },
133133 .{ .bar = .{ .qux = false } },
134134 );
135135 try expect(builder.items).toEqualString(
......@@ -158,7 +158,7 @@ test {
158158 alloc,
159159 builder.writer(),
160160 doc,
161 .{ .Ctx = @This(), .indent = 0, .flag1 = false },
161 .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true },
162162 .{ .bar = true },
163163 );
164164 try expect(builder.items).toEqualString(
......@@ -185,7 +185,7 @@ test {
185185 alloc,
186186 builder.writer(),
187187 doc,
188 .{ .Ctx = @This(), .indent = 0, .flag1 = false },
188 .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true },
189189 .{ .bar = false },
190190 );
191191 try expect(builder.items).toEqualString(
......@@ -214,7 +214,7 @@ test { // bool
214214 alloc,
215215 builder.writer(),
216216 doc,
217 .{ .Ctx = @This(), .indent = 0, .flag1 = false },
217 .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true },
218218 .{ .bar = true },
219219 );
220220 try expect(builder.items).toEqualString(
......@@ -241,7 +241,7 @@ test { // bool false
241241 alloc,
242242 builder.writer(),
243243 doc,
244 .{ .Ctx = @This(), .indent = 0, .flag1 = false },
244 .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true },
245245 .{ .bar = false },
246246 );
247247 try expect(builder.items).toEqualString(
......@@ -268,7 +268,7 @@ test { // string
268268 alloc,
269269 builder.writer(),
270270 doc,
271 .{ .Ctx = @This(), .indent = 0, .flag1 = false },
271 .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true },
272272 .{ .bar = @as([]const u8, "foo") },
273273 );
274274 try expect(builder.items).toEqualString(
......@@ -295,7 +295,7 @@ test { // string false
295295 alloc,
296296 builder.writer(),
297297 doc,
298 .{ .Ctx = @This(), .indent = 0, .flag1 = false },
298 .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true },
299299 .{ .bar = @as([]const u8, "qux") },
300300 );
301301 try expect(builder.items).toEqualString(
......@@ -322,7 +322,7 @@ test { // enum
322322 alloc,
323323 builder.writer(),
324324 doc,
325 .{ .Ctx = @This(), .indent = 0, .flag1 = false },
325 .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true },
326326 .{ .bar = @as(enum { foo, bar, qux }, .foo) },
327327 );
328328 try expect(builder.items).toEqualString(
......@@ -349,7 +349,7 @@ test { // enum false
349349 alloc,
350350 builder.writer(),
351351 doc,
352 .{ .Ctx = @This(), .indent = 0, .flag1 = false },
352 .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true },
353353 .{ .bar = @as(enum { foo, bar, qux }, .qux) },
354354 );
355355 try expect(builder.items).toEqualString(
......@@ -378,7 +378,7 @@ test { // bool
378378 alloc,
379379 builder.writer(),
380380 doc,
381 .{ .Ctx = @This(), .indent = 0, .flag1 = false },
381 .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true },
382382 .{ .bar = false },
383383 );
384384 try expect(builder.items).toEqualString(
......@@ -405,7 +405,7 @@ test { // bool false
405405 alloc,
406406 builder.writer(),
407407 doc,
408 .{ .Ctx = @This(), .indent = 0, .flag1 = false },
408 .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true },
409409 .{ .bar = true },
410410 );
411411 try expect(builder.items).toEqualString(
......@@ -432,7 +432,7 @@ test { // string
432432 alloc,
433433 builder.writer(),
434434 doc,
435 .{ .Ctx = @This(), .indent = 0, .flag1 = false },
435 .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true },
436436 .{ .bar = @as([]const u8, "qux") },
437437 );
438438 try expect(builder.items).toEqualString(
......@@ -459,7 +459,7 @@ test { // string false
459459 alloc,
460460 builder.writer(),
461461 doc,
462 .{ .Ctx = @This(), .indent = 0, .flag1 = false },
462 .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true },
463463 .{ .bar = @as([]const u8, "foo") },
464464 );
465465 try expect(builder.items).toEqualString(
......@@ -486,7 +486,7 @@ test { // enum
486486 alloc,
487487 builder.writer(),
488488 doc,
489 .{ .Ctx = @This(), .indent = 0, .flag1 = false },
489 .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true },
490490 .{ .bar = @as(enum { foo, bar, qux }, .qux) },
491491 );
492492 try expect(builder.items).toEqualString(
......@@ -513,7 +513,7 @@ test { // enum false
513513 alloc,
514514 builder.writer(),
515515 doc,
516 .{ .Ctx = @This(), .indent = 0, .flag1 = false },
516 .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true },
517517 .{ .bar = @as(enum { foo, bar, qux }, .foo) },
518518 );
519519 try expect(builder.items).toEqualString(
......@@ -538,7 +538,7 @@ test {
538538 alloc,
539539 builder.writer(),
540540 doc,
541 .{ .Ctx = @This(), .indent = 0, .flag1 = false },
541 .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true },
542542 .{ .text = @as([]const u8, "dynamic") },
543543 );
544544 try expect(builder.items).toEqualString(
......@@ -561,7 +561,7 @@ test {
561561 alloc,
562562 builder.writer(),
563563 doc,
564 .{ .Ctx = @This(), .indent = 0, .flag1 = false },
564 .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true },
565565 .{ .url = @as([]const u8, "https://github.com/nektro/zig-pek") },
566566 );
567567 try expect(builder.items).toEqualString(
......@@ -584,7 +584,7 @@ test {
584584 alloc,
585585 builder.writer(),
586586 doc,
587 .{ .Ctx = @This(), .indent = 0, .flag1 = false },
587 .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true },
588588 .{ .host = @as([]const u8, "github.com") },
589589 );
590590 try expect(builder.items).toEqualString(
......@@ -607,7 +607,7 @@ test {
607607 alloc,
608608 builder.writer(),
609609 doc,
610 .{ .Ctx = @This(), .indent = 0, .flag1 = false },
610 .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true },
611611 .{ .host = "github.com".* },
612612 );
613613 try expect(builder.items).toEqualString(
......@@ -642,7 +642,7 @@ test {
642642 alloc,
643643 builder.writer(),
644644 doc,
645 .{ .Ctx = @This(), .indent = 0, .flag1 = false },
645 .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true },
646646 .{ .host = S{ .name = "github" } },
647647 );
648648 try expect(builder.items).toEqualString(
......@@ -674,7 +674,7 @@ test {
674674 alloc,
675675 builder.writer(),
676676 doc,
677 .{ .Ctx = @This(), .indent = 0, .flag1 = false },
677 .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true },
678678 .{ .host = S{ .name = "github" } },
679679 );
680680 try expect(builder.items).toEqualString(
......@@ -699,7 +699,7 @@ test {
699699 alloc,
700700 builder.writer(),
701701 doc,
702 .{ .Ctx = @This(), .indent = 0, .flag1 = false },
702 .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true },
703703 .{ .url = "https://github.com/nektro/zig-pek".* },
704704 );
705705 try expect(builder.items).toEqualString(
......@@ -722,7 +722,7 @@ test {
722722 alloc,
723723 builder.writer(),
724724 doc,
725 .{ .Ctx = @This(), .indent = 0, .flag1 = false },
725 .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true },
726726 .{ .foo = "contain HTML such as <button>this</button> as an escape hatch when you know content is safe".* },
727727 );
728728 try expect(builder.items).toEqualString(
......@@ -770,16 +770,18 @@ test {
770770 alloc,
771771 builder.writer(),
772772 doc,
773 .{ .Ctx = C, .indent = 0, .flag1 = false },
773 .{ .Ctx = C, .indent = 0, .doindent = true, .doindent2 = true },
774774 .{ .prev = person },
775775 );
776776 try expect(builder.items).toEqualString(
777777 \\<body>
778 \\ <form><label>
778 \\ <form>
779 \\ <label>
779780 \\ <div>Name</div>
780781 \\ <textarea type="text" required="" name="name" placeholder="">meghan</textarea>
781782 \\ </label>
782 \\<button>Submit ▶</button></form>
783 \\ <button>Submit ▶</button>
784 \\ </form>
783785 \\</body>
784786 \\
785787 );
......@@ -816,7 +818,7 @@ test {
816818 alloc,
817819 builder.writer(),
818820 doc,
819 .{ .Ctx = C, .indent = 0, .flag1 = false },
821 .{ .Ctx = C, .indent = 0, .doindent = true, .doindent2 = true },
820822 .{ .user = person },
821823 );
822824 try expect(builder.items).toEqualString(
......@@ -856,7 +858,7 @@ test {
856858 alloc,
857859 builder.writer(),
858860 doc,
859 .{ .Ctx = C, .indent = 0, .flag1 = false },
861 .{ .Ctx = C, .indent = 0, .doindent = true, .doindent2 = true },
860862 .{ .user = person },
861863 );
862864 try expect(builder.items).toEqualString(
......@@ -893,7 +895,7 @@ test {
893895 alloc,
894896 builder.writer(),
895897 doc,
896 .{ .Ctx = @This(), .indent = 0, .flag1 = false },
898 .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true },
897899 .{ .states = &states },
898900 );
899901 try expect(builder.items).toEqualString(
......@@ -932,7 +934,7 @@ test {
932934 alloc,
933935 builder.writer(),
934936 doc,
935 .{ .Ctx = @This(), .indent = 0, .flag1 = false },
937 .{ .Ctx = @This(), .indent = 0, .doindent = true, .doindent2 = true },
936938 .{ .abbrs = states.items.abbr, .names = states.items.name },
937939 );
938940 try expect(builder.items).toEqualString(