From 9ffcffa27189dcc5fea1986cb9fdfc8ea396602c Mon Sep 17 00:00:00 2001 From: Robert Günzler Date: Thu, 24 Sep 2026 20:58:42 +0200 Subject: share logic between index and backrefs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Robert Günzler --- links/main.css | 6 --- src/main.zig | 142 ++++++++++++++++++++++++++++++--------------------------- 2 files changed, 74 insertions(+), 74 deletions(-) diff --git a/links/main.css b/links/main.css index 109d5b6..7467bf2 100644 --- a/links/main.css +++ b/links/main.css @@ -280,12 +280,6 @@ main .footnote-back { margin-left: 1ch; } -/* backrefs */ - -main section#backrefs ul { - list-style-type: none; -} - /* footer */ footer { 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 ""; try buf.writer.writeAll( - \\

incoming:

- \\ \\ ); 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 ""; + + try buf.writer.writeAll( + \\ + \\ + ); + 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( - \\ - \\ - ); + 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( - \\{s} - , .{ - 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, + \\{s} + , .{ link, fragment, text }); +} + fn targetExists( io: Io, gpa: Allocator, -- cgit 1.4.1