about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRobert Günzler <r@gnzler.io>2024-10-15 15:53:51 +0200
committerRobert Günzler <r@gnzler.io>2024-10-16 15:40:15 +0200
commita502a7c15af80cd9e37d85ff6c0bccae62ca3e1e (patch)
tree50fceca3b06284ba98972f9dce8cb85bac360576
parent2922f3b859d4f3585460da2463b8f60c64fb3401 (diff)
downloadsite-a502a7c15af80cd9e37d85ff6c0bccae62ca3e1e.tar.gz
add support for tilde meta pages
Signed-off-by: Robert Günzler <r@gnzler.io>
-rw-r--r--src/main.zig119
1 files changed, 97 insertions, 22 deletions
diff --git a/src/main.zig b/src/main.zig
index 56dc7a1..b5a6967 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -7,6 +7,7 @@ const c = @cImport({
 });
 
 const PAGE_PATH = "src/inc";
+const SITE_ROOT = ".";
 const SITE_PATH = "site";
 
 const DOMAIN_URL = "https://example.com";
@@ -16,6 +17,14 @@ const SOURCE_URL = "https://example.com/source";
 
 const BuildErrors = (std.fs.File.OpenError || std.fs.File.WriteError || std.mem.Allocator.Error);
 
+const Context = struct {
+    allocator: std.mem.Allocator,
+    pages: [][]const u8,
+    generated: usize = 0,
+    meta: usize = 0,
+    tilde: usize = 0,
+};
+
 // also trims off base paths
 fn stripExt(path: []const u8) ![]const u8 {
     const basename = std.fs.path.basename(path);
@@ -215,28 +224,86 @@ fn build(allocator: std.mem.Allocator, f: std.fs.File, page_name: []const u8, sr
     });
 }
 
-fn generate(allocator: std.mem.Allocator, pages: [][]const u8) !void {
-    for (pages) |p| {
-        const dstname = try stripExt(p);
-        const srcpath = try joinIn(allocator, &.{PAGE_PATH}, &.{ dstname, ".htm" });
-        defer allocator.free(srcpath);
-        const dstpath = try joinIn(allocator, &.{SITE_PATH}, &.{ dstname, ".html" });
-        defer allocator.free(dstpath);
+fn meta(ctx: *Context, p: []const u8) !void {
+    ctx.meta += 1;
+
+    if (std.mem.startsWith(u8, p, "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 joinIn(ctx.allocator, &.{PAGE_PATH}, &.{p});
+        defer ctx.allocator.free(srcpath);
+        const dstpath = try joinIn(ctx.allocator, &.{SITE_ROOT}, &.{ "~", dstname });
+        defer ctx.allocator.free(dstpath);
+
+        const link = blk: {
+            const f = try std.fs.cwd().openFile(srcpath, .{ .mode = .read_only });
+            defer f.close();
+            const content = try f.readToEndAlloc(ctx.allocator, std.os.linux.PATH_MAX);
+            defer ctx.allocator.free(content);
+            const trimmed = std.mem.trim(u8, content, " \n\t\r");
+            break :blk try ctx.allocator.dupe(u8, trimmed);
+        };
+        defer ctx.allocator.free(link);
 
         const f = try std.fs.cwd().createFile(dstpath, .{});
+        defer f.close();
 
-        const page_name = try std.mem.replaceOwned(u8, allocator, dstname, "_", " ");
-        defer allocator.free(page_name);
+        try f.writer().print(
+            \\<!DOCTYPE html>
+            \\<html lang="en">
+            \\<head>
+            \\<meta charset="utf-8">
+            \\<meta http-equiv="refresh" content="0; url={[LINK]s}">
+            \\<link rel="stylesheet" type="text/css" href="links/main.css">
+            \\</head>
+            \\<body>
+            \\<noscript>Continue to <a href="{[LINK]s}">{[LINK]s}</a>.</noscript>
+            \\<script>
+            \\'use strict'
+            \\window.location.replace("{[LINK]s}")
+            \\</script>
+            \\</body>
+            \\</html>
+            \\
+        , .{
+            .LINK = link,
+        });
 
-        try build(allocator, f, page_name, srcpath);
+        ctx.tilde += 1;
+        return;
     }
 
-    std.log.info("Generated {d} files.", .{pages.len});
+    return error.unknownMeta;
 }
 
-fn genindex(allocator: std.mem.Allocator, pages: [][]const u8) !void {
-    const srcpathIndex = try joinIn(allocator, &.{PAGE_PATH}, &.{"index.htm"});
-    defer allocator.free(srcpathIndex);
+fn generate(ctx: *Context) !void {
+    for (ctx.pages) |p| {
+        if (std.mem.startsWith(u8, p, "meta.")) {
+            try meta(ctx, p);
+            continue;
+        }
+
+        const dstname = try stripExt(p);
+        const srcpath = try joinIn(ctx.allocator, &.{PAGE_PATH}, &.{ dstname, ".htm" });
+        defer ctx.allocator.free(srcpath);
+        const dstpath = try joinIn(ctx.allocator, &.{SITE_PATH}, &.{ dstname, ".html" });
+        defer ctx.allocator.free(dstpath);
+
+        const f = try std.fs.cwd().createFile(dstpath, .{});
+
+        const page_name = try std.mem.replaceOwned(u8, ctx.allocator, dstname, "_", " ");
+        defer ctx.allocator.free(page_name);
+
+        try build(ctx.allocator, f, page_name, srcpath);
+        ctx.generated += 1;
+    }
+}
+
+fn genindex(ctx: *Context) !void {
+    const srcpathIndex = try joinIn(ctx.allocator, &.{PAGE_PATH}, &.{"index.htm"});
+    defer ctx.allocator.free(srcpathIndex);
 
     const f = try std.fs.cwd().createFile(srcpathIndex, .{});
     defer f.close();
@@ -249,7 +316,7 @@ fn genindex(allocator: std.mem.Allocator, pages: [][]const u8) !void {
     // alphanum ascii sort
     std.mem.sort(
         []const u8,
-        pages,
+        ctx.pages,
         {},
         struct {
             fn lessthan(_: void, a: []const u8, b: []const u8) bool {
@@ -258,12 +325,12 @@ fn genindex(allocator: std.mem.Allocator, pages: [][]const u8) !void {
         }.lessthan,
     );
 
-    for (pages) |p| {
+    for (ctx.pages) |p| {
         if (std.mem.startsWith(u8, p, "meta.")) continue;
 
         const dstname = try stripExt(p);
-        const dstpath = try joinIn(allocator, &.{SITE_PATH}, &.{ dstname, ".html" });
-        defer allocator.free(dstpath);
+        const dstpath = try joinIn(ctx.allocator, &.{SITE_PATH}, &.{ dstname, ".html" });
+        defer ctx.allocator.free(dstpath);
 
         try f.writer().print(
             \\<li><a href="/{[HREF]s}">{[LINK]s}</a></li>
@@ -278,8 +345,6 @@ fn genindex(allocator: std.mem.Allocator, pages: [][]const u8) !void {
         \\</ul>
         \\
     );
-
-    std.log.info("Generated index.", .{});
 }
 
 fn index(allocator: std.mem.Allocator, path: []const u8) ![][]const u8 {
@@ -318,6 +383,16 @@ pub fn main() !void {
         allocator.free(pages);
     }
 
-    try genindex(allocator, pages);
-    try generate(allocator, pages);
+    std.log.info("Generated index.", .{});
+
+    var ctx = Context{
+        .allocator = allocator,
+        .pages = pages,
+    };
+
+    try genindex(&ctx);
+    try generate(&ctx);
+
+    std.log.info("Generated {d} files.", .{ctx.generated});
+    std.log.info("Generated {d} tildes.", .{ctx.tilde});
 }