diff options
| author | Robert Günzler <r@gnzler.io> | 2026-04-08 13:29:17 +0900 |
|---|---|---|
| committer | Robert Günzler <r@gnzler.io> | 2026-04-08 13:50:39 +0900 |
| commit | 2200e168cfc35134aec2ccc656ad5419663a973c (patch) | |
| tree | 3b85ec1e701ffad2a519fd5d9c54321be5c3eedf /src/gen.zig | |
| parent | 8bca0ebd8645bf2714035ed61ac140956a83fc21 (diff) | |
| download | site-2200e168cfc35134aec2ccc656ad5419663a973c.tar.gz | |
start refactoring to support multiple page roots
Signed-off-by: Robert Günzler <r@gnzler.io>
Diffstat (limited to '')
| -rw-r--r-- | src/gen.zig | 127 |
1 files changed, 57 insertions, 70 deletions
diff --git a/src/gen.zig b/src/gen.zig index 449342e..fd1dff7 100644 --- a/src/gen.zig +++ b/src/gen.zig @@ -9,21 +9,21 @@ const log = std.log.scoped(.gen); pub fn generate(ctx: *Context) !void { ctx.generated.clearRetainingCapacity(); - ctx.progress_start("generate"); + ctx.progress_start("generate", true); defer ctx.progress_end(); - try genIndex(ctx); + try index(ctx); log.info("Generated index.", .{}); - try genSites(ctx); + try pages(ctx); log.info("Generated {d} files.", .{ctx.generated.items.len}); log.info("Generated {d} tildes.", .{ctx.tilde}); } -fn genIndex(ctx: *Context) !void { - ctx.progress_start("index.htm"); +fn index(ctx: *Context) !void { + ctx.progress_start("index.htm", false); defer ctx.progress_end(); const srcpathIndex = try fs.joinPathAndFilename(ctx.allocator(), &.{Context.params.PAGE_PATH}, &.{"index.htm"}); @@ -40,32 +40,21 @@ fn genIndex(ctx: *Context) !void { \\ ); - // alphanum ascii sort - std.mem.sort( - []const u8, - ctx.pages.items, - {}, - struct { - fn lessthan(_: void, a: []const u8, b: []const u8) bool { - return std.ascii.lessThanIgnoreCase(a, b); + for (ctx.sites.items) |s| { + for (s.pages.items) |p| { + if (p.kind == .Htm) { + const dstpath = try fs.joinPathAndFilename(ctx.allocator(), &.{Context.params.SITE_PATH}, &.{ p.name, ".html" }); + defer ctx.allocator().free(dstpath); + + try w.interface.print( + \\<li><a href="/{[LINK]s}">{[NAME]s}</a></li> + \\ + , .{ + .LINK = dstpath, + .NAME = p.name, + }); } - }.lessthan, - ); - - for (ctx.pages.items) |p| { - if (std.mem.startsWith(u8, p, "meta.")) continue; - - const dstname = try fs.stripExtension(p); - const dstpath = try fs.joinPathAndFilename(ctx.allocator(), &.{Context.params.SITE_PATH}, &.{ dstname, ".html" }); - defer ctx.allocator().free(dstpath); - - try w.interface.print( - \\<li><a href="/{[LINK]s}">{[NAME]s}</a></li> - \\ - , .{ - .LINK = dstpath, - .NAME = dstname, - }); + } } try w.interface.writeAll( @@ -76,27 +65,25 @@ fn genIndex(ctx: *Context) !void { try w.interface.flush(); } -fn genSites(ctx: *Context) !void { - for (ctx.pages.items) |p| { - if (std.mem.startsWith(u8, std.fs.path.basename(p), "meta.")) { - // meta pages - try meta(ctx, p); - continue; +fn pages(ctx: *Context) !void { + for (ctx.sites.items) |s| { + for (s.pages.items) |p| { + if (p.kind == .Meta) { + try meta(ctx, p); + } else if (p.kind == .Htm) { + try page(ctx, p); + } } - - // regular pages - try genSite(ctx, p); } } -fn genSite(ctx: *Context, p: []const u8) !void { - ctx.progress_start(std.fs.path.basename(p)); +fn page(ctx: *Context, p: Context.Site.Page) !void { + ctx.progress_start(p.name, false); defer ctx.progress_end(); - const dstname = try fs.stripExtension(p); - const srcpath = try fs.joinPathAndFilename(ctx.allocator(), &.{Context.params.PAGE_PATH}, &.{ dstname, ".htm" }); + const srcpath = try fs.joinPathAndFilename(ctx.allocator(), &.{Context.params.PAGE_PATH}, &.{ p.name, ".htm" }); defer ctx.allocator().free(srcpath); - const dstpath = try fs.joinPathAndFilename(ctx.allocator(), &.{Context.params.SITE_PATH}, &.{ dstname, ".html" }); + const dstpath = try fs.joinPathAndFilename(ctx.allocator(), &.{Context.params.SITE_PATH}, &.{ p.name, ".html" }); defer ctx.allocator().free(dstpath); const rel_dstpath = try std.fs.path.relative(ctx.allocator(), Context.params.SITE_PATH, dstpath); defer ctx.allocator().free(rel_dstpath); @@ -112,14 +99,14 @@ fn genSite(ctx: *Context, p: []const u8) !void { const dstmtime = try fs.getLastEdit(dstpath); if (!ctx.force and srcmtime.sec < dstmtime.sec) return; - log.debug("generating {s} at {s}", .{ p, rel_dstpath }); + log.debug("generating {s} at {s}", .{ p.path, rel_dstpath }); const f = try fs.FileSwapper.createAt(ctx.allocator(), dstpath); var buffer: [1024]u8 = undefined; var w = f.writer(&buffer); - const page_name = try std.mem.replaceOwned(u8, ctx.allocator(), dstname, "_", " "); + const page_name = try std.mem.replaceOwned(u8, ctx.allocator(), p.name, "_", " "); defer ctx.allocator().free(page_name); try build(ctx.allocator(), &w.interface, page_name, srcpath); @@ -230,19 +217,18 @@ fn build(allocator: std.mem.Allocator, w: *std.Io.Writer, page_name: []const u8, // build a virtual html file, currently either: // - meta.nav: used for populating the global navigation menu // - meta.tilde: used to create ~foobar files -fn meta(ctx: *Context, p: []const u8) !void { - ctx.progress_start(std.fs.path.basename(p)); +fn meta(ctx: *Context, p: Context.Site.Page) !void { + ctx.progress_start(p.name, false); defer ctx.progress_end(); ctx.meta += 1; - if (std.mem.startsWith(u8, p, "meta.nav.")) return; + if (std.mem.startsWith(u8, p.name, "meta.nav")) return; - if (std.mem.startsWith(u8, p, "meta.tilde.")) { - const dot = std.mem.indexOfPosLinear(u8, p, 11, "."); - const dstname = p[11..dot.?]; - const srcpath = try fs.joinPathAndFilename(ctx.allocator(), &.{Context.params.PAGE_PATH}, &.{p}); + if (std.mem.startsWith(u8, p.name, "meta.tilde")) { + const srcpath = try fs.joinPathAndFilename(ctx.allocator(), &.{Context.params.PAGE_PATH}, &.{p.path}); defer ctx.allocator().free(srcpath); + const dstname = p.name[11..]; // trim "meta.tilde." from the name const dstpath = try fs.joinPathAndFilename(ctx.allocator(), &.{Context.params.LINK_PATH}, &.{ "~", dstname }); defer ctx.allocator().free(dstpath); @@ -289,6 +275,7 @@ fn meta(ctx: *Context, p: []const u8) !void { return; } + log.err("unknown meta page type: {s}", .{p.name}); return error.unknownMeta; } @@ -390,49 +377,49 @@ const Page = struct { }; fn portal(allocator: std.mem.Allocator, w: *std.Io.Writer, refname: []const u8, insert_heading: bool) anyerror!void { - const page = try Page.from_ref(allocator, refname); - defer page.deinit(); + const p = try Page.from_ref(allocator, refname); + defer p.deinit(); if (insert_heading) try w.print( \\<h2 id="{[ID]s}"><a href="/{[PATH]s}">{[NAME]s}</a></2> \\ , .{ - .ID = page.ref, - .NAME = page.name, - .PATH = page.html, + .ID = p.ref, + .NAME = p.name, + .PATH = p.html, }); - try inject(allocator, w, page.htm); + try inject(allocator, w, p.htm); // XXX: track ref count? } fn ref(allocator: std.mem.Allocator, w: *std.Io.Writer, refname: []const u8) anyerror!void { - const page = try Page.from_ref(allocator, refname); - defer page.deinit(); + const p = try Page.from_ref(allocator, refname); + defer p.deinit(); try w.print( \\<a href="/{[PATH]s}{[ANCHOR]s}">{[NAME]s}</a> , .{ - .NAME = page.name, - .PATH = page.html, - .ANCHOR = page.anchor, + .NAME = p.name, + .PATH = p.html, + .ANCHOR = p.anchor, }); // XXX: track ref count? } fn ref_link(allocator: std.mem.Allocator, w: *std.Io.Writer, refname: []const u8) anyerror!void { - const page = try Page.from_ref(allocator, refname); - defer page.deinit(); + const p = try Page.from_ref(allocator, refname); + defer p.deinit(); - try w.print("/{s}{s}", .{ page.html, page.anchor }); + try w.print("/{s}{s}", .{ p.html, p.anchor }); } fn ref_name(allocator: std.mem.Allocator, w: *std.Io.Writer, refname: []const u8) anyerror!void { - const page = try Page.from_ref(allocator, refname); - defer page.deinit(); + const p = try Page.from_ref(allocator, refname); + defer p.deinit(); - try w.print("{s}", .{page.ref}); + try w.print("{s}", .{p.ref}); } |