From 64b42058dbf7fa1a40d95265ff3f75a0b604c8d8 Mon Sep 17 00:00:00 2001 From: Robert Günzler Date: Tue, 7 Jan 2025 14:50:08 +0100 Subject: cleanup templating code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Robert Günzler --- src/main.zig | 70 ++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 37 insertions(+), 33 deletions(-) (limited to 'src') diff --git a/src/main.zig b/src/main.zig index 3e2fa7e..1a4a86c 100644 --- a/src/main.zig +++ b/src/main.zig @@ -16,8 +16,6 @@ const LICENSE_NAME = "BY-NC-SA 4.0"; const LICENSE_URL = "https://git.sr.ht/~robertgzr/site/blob/rabbits/LICENSE.content"; const SOURCE_URL = "https://git.sr.ht/~robertgzr/site/tree/rabbits"; -const BuildErrors = (std.fs.File.OpenError || std.fs.File.WriteError || std.mem.Allocator.Error); - // tune std.log options pub const std_options = .{ .log_level = .info, @@ -56,7 +54,7 @@ fn joinIn(allocator: std.mem.Allocator, paths: []const []const u8, filename_part return try std.fs.path.join(allocator, paths2); } -fn portal(allocator: std.mem.Allocator, f: std.fs.File, refname: []const u8, insert_heading: bool) BuildErrors!void { +fn portal(allocator: std.mem.Allocator, w: std.io.AnyWriter, refname: []const u8, insert_heading: bool) anyerror!void { const basename = try std.mem.replaceOwned(u8, allocator, refname, " ", "_"); defer allocator.free(basename); const refpathPage = try joinIn(allocator, &.{PAGE_PATH}, &.{ basename, ".htm" }); @@ -65,7 +63,7 @@ fn portal(allocator: std.mem.Allocator, f: std.fs.File, refname: []const u8, ins defer allocator.free(refpathSite); if (insert_heading) - try f.writer().print( + try w.print( \\

{[NAME]s} \\ , .{ @@ -74,21 +72,18 @@ fn portal(allocator: std.mem.Allocator, f: std.fs.File, refname: []const u8, ins .PATH = refpathSite, }); - try inject(allocator, f, refpathPage); + try inject(allocator, w, refpathPage); // XXX: track ref count? } -fn template(allocator: std.mem.Allocator, f: std.fs.File, refname: []const u8) BuildErrors!void { - if (std.mem.startsWith(u8, refname, "/")) - return try portal(allocator, f, refname[1..], false); - +fn ref(allocator: std.mem.Allocator, w: std.io.AnyWriter, refname: []const u8) anyerror!void { const basename = try std.mem.replaceOwned(u8, allocator, refname, " ", "_"); defer allocator.free(basename); const refpathSite = try joinIn(allocator, &.{SITE_PATH}, &.{ basename, ".html" }); defer allocator.free(refpathSite); - try f.writer().print( + try w.print( \\{[NAME]s} \\ , .{ @@ -99,7 +94,16 @@ fn template(allocator: std.mem.Allocator, f: std.fs.File, refname: []const u8) B // XXX: track ref count? } -fn inject(allocator: std.mem.Allocator, f: std.fs.File, srcpath: []const u8) BuildErrors!void { +fn template(allocator: std.mem.Allocator, w: std.io.AnyWriter, refname: []const u8) anyerror!void { + if (std.mem.startsWith(u8, refname, "/")) { + return try portal(allocator, w, refname[1..], false); + } else { + return try ref(allocator, w, refname); + } +} + +// Parses srcpath, resolves refs and portals and writes everything to w +fn inject(allocator: std.mem.Allocator, w: std.io.AnyWriter, srcpath: []const u8) !void { const inc = std.fs.cwd().openFile(srcpath, .{ .mode = .read_only }) catch |err| { if (err == error.FileNotFound) std.log.warn("Missing {s} include.", .{srcpath}); @@ -108,7 +112,7 @@ fn inject(allocator: std.mem.Allocator, f: std.fs.File, srcpath: []const u8) Bui }; defer inc.close(); - var buf_writer = std.io.bufferedWriter(f.writer()); + var buf_writer = std.io.bufferedWriter(w); var out_stream = buf_writer.writer(); var buf_reader = std.io.bufferedReader(inc.reader()); @@ -116,37 +120,36 @@ fn inject(allocator: std.mem.Allocator, f: std.fs.File, srcpath: []const u8) Bui var arena = std.heap.ArenaAllocator.init(allocator); defer arena.deinit(); + while (in_stream.readUntilDelimiterOrEofAlloc( arena.allocator(), '\n', buf_reader.buf.len, - ) catch @panic("Failed to read from stream")) |chunk| { - if (std.mem.indexOfPosLinear(u8, chunk, 0, "{")) |start| { - try out_stream.writeAll(chunk[0..start]); - try buf_writer.flush(); + ) catch { + @panic("Failed to read from stream"); + }) |chunk| { + defer _ = arena.reset(.free_all); + if (std.mem.indexOfPosLinear(u8, chunk, 0, "{")) |start| { if (std.mem.indexOfPosLinear(u8, chunk, start + 1, "}")) |end| { - try template(allocator, f, chunk[start + 1 .. end]); - try buf_writer.flush(); - + try out_stream.writeAll(chunk[0..start]); + template(allocator, out_stream.any(), chunk[start + 1 .. end]) catch + @panic("Failed to resolve template"); try out_stream.writeAll(chunk[end + 1 ..]); - try buf_writer.flush(); - } else { - // NOTE: we need to print the opening brace. we did not find a - // closing brace on the same line, so this isn't a ref - try out_stream.writeAll("{"); + try out_stream.writeByte('\n'); + continue; } - } else { - try out_stream.writeAll(chunk); - try out_stream.writeByte('\n'); } - _ = arena.reset(.free_all); + + try out_stream.writeAll(chunk); + try out_stream.writeByte('\n'); + try buf_writer.flush(); } try buf_writer.flush(); } -fn build(allocator: std.mem.Allocator, f: std.fs.File, page_name: []const u8, srcpath: []const u8) BuildErrors!void { +fn build(allocator: std.mem.Allocator, f: std.fs.File, page_name: []const u8, srcpath: []const u8) !void { const mtime = blk: { const attr = try allocator.create(std.os.linux.Stat); defer allocator.destroy(attr); @@ -193,7 +196,7 @@ fn build(allocator: std.mem.Allocator, f: std.fs.File, page_name: []const u8, sr \\ \\ @@ -210,7 +213,7 @@ fn build(allocator: std.mem.Allocator, f: std.fs.File, page_name: []const u8, sr , .{ .PAGE_NAME = page_name, }); - try inject(allocator, f, srcpath); + try inject(allocator, f.writer().any(), srcpath); try f.writer().writeAll( \\ \\ @@ -432,14 +435,15 @@ pub fn main() !void { std.log.info("Indexed {d} pages.", .{pages.len}); - std.log.info("Generated index.", .{}); - var ctx = Context{ .allocator = allocator, .pages = pages, }; try genIndexHtml(&ctx); + + std.log.info("Generated index.", .{}); + try genSite(&ctx); std.log.info("Generated {d} files.", .{ctx.generated}); -- cgit 1.4.1