diff options
| author | Robert Günzler <r@gnzler.io> | 2026-09-24 20:58:42 +0200 |
|---|---|---|
| committer | Robert Günzler <r@gnzler.io> | 2026-10-02 10:39:48 +0200 |
| commit | 9ffcffa27189dcc5fea1986cb9fdfc8ea396602c (patch) | |
| tree | f15cc2b28f14ca641f33c4e325075452ca46db72 /src | |
| parent | 5d9e4743e9ddb637997fc3a5f9a7f5193b5874fb (diff) | |
| download | site-9ffcffa27189dcc5fea1986cb9fdfc8ea396602c.tar.gz | |
share logic between index and backrefs
Signed-off-by: Robert Günzler <r@gnzler.io>
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.zig | 142 |
1 files changed, 74 insertions, 68 deletions
diff --git a/src/main.zig b/src/main.zig index 8781f8d..0d9f9a7 100644 --- a/src/main.zig +++ b/src/main.zig @@ -288,20 +288,28 @@ const Cli = struct { { var pn = if (!DEBUG) progress.start("Generating index", 0); defer if (!DEBUG) pn.end(); - try genIndex(io, gpa, root_dir, target_dir, index); + try genIndex(io, gpa, target_dir, index); } { var pn = if (!DEBUG) progress.start("Generating backrefs", index.items.len); defer if (!DEBUG) pn.end(); - try genBackrefs(io, gpa, target_dir, target_path, index, outgoingRefs); + try genBackrefs(io, gpa, target_dir, index, outgoingRefs); } } + fn inject(io: Io, gpa: Allocator, target: File, needle: []const u8, buf: []const u8) !void { + const offset = std.mem.indexOf(u8, target.mmap.memory, needle) orelse return; + const remainder = try gpa.dupe(u8, target.mmap.memory[offset + needle.len ..]); + defer gpa.free(remainder); + // insert it into the target document + try target.fd.writePositionalAll(io, buf, offset); + try target.fd.writePositionalAll(io, remainder, offset + buf.len); + } + fn genBackrefs( io: Io, gpa: Allocator, target_dir: Dir, - target_path: []const u8, work: std.ArrayList([]const u8), outgoingRefs: std.StringHashMapUnmanaged([][]const u8), ) !void { @@ -338,13 +346,7 @@ const Cli = struct { var target = try File.init(io, target_dir, target_name, null); defer target.close(io); - const BACKREFS = "{[builtin.backrefs]}"; - const offset = std.mem.indexOf(u8, target.mmap.memory, BACKREFS) orelse continue; - const remainder = try gpa.dupe(u8, target.mmap.memory[offset + BACKREFS.len ..]); - defer gpa.free(remainder); - - // create the backref list - const buf = blk: { + try inject(io, gpa, target, "{[builtin.backrefs]}", blk: { var buf = Io.Writer.Allocating.init(gpa); defer buf.deinit(); @@ -353,53 +355,73 @@ const Cli = struct { if (back_refs == null) break :blk "<!-- no backrefs -->"; try buf.writer.writeAll( - \\<p>incoming:</p> - \\<nav> - \\<ul> + \\<span>incoming:</span><nav> \\ ); for (back_refs.?) |back_ref| { - const back_ref_name = try std.fmt.allocPrint(gpa, "{s}.html", .{back_ref}); - const back_ref_path = try std.fs.path.join(gpa, &.{ "/", target_path, back_ref_name }); + log.debug("{s}: backref path={s}", .{ target.path, back_ref }); + const back_ref_ = try formatRef(gpa, back_ref, LINK_PREFIX, ""); + defer gpa.free(back_ref_); try buf.writer.print( - \\<li><a href="{s}">{s}</a></li> + \\{s} \\ - , .{ back_ref_path, back_ref }); + , .{back_ref_}); } try buf.writer.writeAll( - \\</ul> \\</nav> \\ ); break :blk try buf.toOwnedSlice(); - }; - - // insert it into the target document - try target.fd.writePositionalAll(io, buf, offset); - try target.fd.writePositionalAll(io, remainder, offset + buf.len); + }); } } fn genIndex( io: Io, gpa: Allocator, - root_dir: Dir, target_dir: Dir, index: std.ArrayList([]const u8), ) !void { log.info("Generating index", .{}); - var source = File.init(io, root_dir, "index.htm", null) catch |err| + var target = File.init(io, target_dir, "index.html", null) catch |err| switch (err) { error.FileNotFound => return, else => return err, }; - defer source.close(io); + defer target.close(io); - const b = try Builder.init(gpa, root_dir, source, target_dir, .{}); - b.index = index; - defer b.deinit(gpa); - try b.build(io, gpa); + log.debug("{s}: index n={d}", .{ target.path, index.items.len }); + + try inject(io, gpa, target, "{[builtin.index]}", blk: { + var buf = Io.Writer.Allocating.init(gpa); + defer buf.deinit(); + + // write a comment when we dont have pages + if (index.items.len == 0) break :blk "<!-- no index -->"; + + try buf.writer.writeAll( + \\<nav> + \\<ul> + \\ + ); + for (index.items) |e| { + if (std.mem.eql(u8, std.fs.path.stem(e), std.fs.path.stem(target.path))) continue; + log.debug("{s}: index path={s}", .{ target.path, e }); + const e_ = try formatRef(gpa, std.fs.path.stem(e), LINK_PREFIX, ""); + defer gpa.free(e_); + try buf.writer.print( + \\<li>{s}</li> + \\ + , .{e_}); + } + try buf.writer.writeAll( + \\</ul> + \\</nav> + \\ + ); + break :blk try buf.toOwnedSlice(); + }); } fn serve(io: Io, _: Allocator, _: FlagSet, args: [][]const u8) !void { @@ -418,7 +440,7 @@ const Cli = struct { break :blk "caddy fmt --overwrite && caddy run --watch"; }; - log.info("srv : root={s}", .{root_path}); + log.info("Serving root={s}", .{root_path}); try shell(io, command, .{ .cwd = .{ .dir = root_dir } }); } }; @@ -552,7 +574,7 @@ const Builder = struct { // check if we need to do any work if (try targetExists(io, gpa, self.target_dir, target_path, self.root_dir)) { - defer log.debug("{s}: done", .{self.source.path}); + defer log.debug("{s}: skipping", .{self.source.path}); return; // skip any further processing } @@ -672,35 +694,13 @@ const Builder = struct { return; } if (std.mem.eql(u8, ref_name, "builtin.backrefs")) { + log.debug("{s}: no backrefs yet", .{self.source.path}); try w.writeAll("{[builtin.backrefs]}"); // done in post processing return; } if (std.mem.eql(u8, ref_name, "builtin.index")) { - if (self.index == null) { - try w.writeAll("{[builtin.backrefs]}"); // done in post processing - return; - } - - std.debug.assert(self.index != null); - try w.writeAll( - \\<nav> - \\<ul> - \\ - ); - for (self.index.?.items) |e| { - try w.print( - \\<li><a href="{s}">{s}</a></li> - \\ - , .{ - try formatLink(gpa, std.fs.path.stem(e), self.options.link_prefix), - try formatName(gpa, std.fs.path.stem(e)), - }); - } - try w.writeAll( - \\</ul> - \\</nav> - \\ - ); + log.debug("{s}: no index yet", .{self.source.path}); + try w.writeAll("{[builtin.index]}"); // done in post processing return; } @@ -766,18 +766,14 @@ const Builder = struct { } } - const ref_name = try formatName(gpa, ref); - defer gpa.free(ref_name); - const ref_link = try formatLink(gpa, ref, self.options.link_prefix); - defer gpa.free(ref_link); - - try w.print( - \\<a href="{s}{s}">{s}</a> - , .{ - ref_link, + const ref_ = try formatRef( + gpa, + ref, + self.options.link_prefix, if (fragment) |i| ref_str[i..] else "", - ref_name, - }); + ); + defer gpa.free(ref_); + try w.writeAll(ref_); // TODO: $ and + refs should be handled too? if (track_refs) try self.refs.append(gpa, try gpa.dupe(u8, ref)); @@ -920,6 +916,16 @@ fn formatLink(gpa: Allocator, name: []const u8, prefix: []const u8) ![]u8 { return try std.fs.path.join(gpa, &.{ prefix, link_name }); } +fn formatRef(gpa: Allocator, name: []const u8, link_prefix: []const u8, fragment: []const u8) ![]u8 { + const link = try formatLink(gpa, name, link_prefix); + defer gpa.free(link); + const text = try formatName(gpa, name); + defer gpa.free(text); + return try std.fmt.allocPrint(gpa, + \\<a href="{s}{s}">{s}</a> + , .{ link, fragment, text }); +} + fn targetExists( io: Io, gpa: Allocator, |