about summary refs log tree commit diff
path: root/src/main.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.zig')
-rw-r--r--src/main.zig104
1 files changed, 73 insertions, 31 deletions
diff --git a/src/main.zig b/src/main.zig
index 8e515ee..a32d968 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -7,6 +7,7 @@
 
 const std = @import("std");
 const gen = @import("gen.zig");
+const exe = @import("exe.zig");
 
 const log = std.log.scoped(.root);
 
@@ -17,8 +18,11 @@ pub const std_options = std.Options{
 
 pub const Context = struct {
     arena: std.heap.ArenaAllocator,
+    progress_nodes: std.ArrayList(std.Progress.Node),
+
+    pages: std.ArrayListUnmanaged([]const u8),
+    markdown: std.ArrayListUnmanaged([]const u8),
 
-    pages: [][]const u8 = undefined,
     generated: usize = 0,
     meta: usize = 0,
     tilde: usize = 0,
@@ -37,15 +41,24 @@ pub const Context = struct {
         pub const PUBLIC_INBOX = "~robertgzr/public-inbox@lists.sr.ht";
     };
 
-    fn new(parent_alloc: std.mem.Allocator) *Context {
-        const ctx = parent_alloc.create(Context) catch |err| @panic(@errorName(err));
-        ctx.* = .{
+    fn create(parent_alloc: std.mem.Allocator) !*Context {
+        const self = try parent_alloc.create(Context);
+        self.* = .{
             .arena = std.heap.ArenaAllocator.init(parent_alloc),
+            .progress_nodes = try .initCapacity(self.allocator(), 10),
+            .pages = .{},
+            .markdown = .{},
         };
-        return ctx;
+        // create root progress node
+        self.progress_nodes.appendAssumeCapacity(
+            std.Progress.start(.{ .root_name = "" }),
+        );
+        return self;
     }
 
-    fn deinit(self: *Context) void {
+    fn destroy(self: *Context) void {
+        self.progress_end();
+        self.progress_nodes.deinit();
         self.arena.deinit();
         self.arena.child_allocator.destroy(self);
     }
@@ -53,9 +66,22 @@ pub const Context = struct {
     pub fn allocator(self: *Context) std.mem.Allocator {
         return self.arena.allocator();
     }
+
+    // progress handling
+    pub fn progress_start(self: *Context, name: []const u8) void {
+        const new = self.progress_nodes.getLast().start(name, 0);
+        self.progress_nodes.appendAssumeCapacity(new);
+    }
+    pub fn progress_end(self: *Context) void {
+        const current = self.progress_nodes.pop() orelse return;
+        current.end();
+    }
 };
 
 fn index(ctx: *Context) !void {
+    ctx.progress_start("index");
+    defer ctx.progress_end();
+
     var root = std.fs.cwd().openDir(Context.params.PAGE_PATH, .{ .iterate = true }) catch |err| switch (err) {
         error.FileNotFound => {
             std.log.err("Missing {s} folder.", .{Context.params.PAGE_PATH});
@@ -65,47 +91,34 @@ fn index(ctx: *Context) !void {
     };
     defer root.close();
 
-    var pages = std.ArrayList([]const u8).init(ctx.allocator());
-    defer pages.deinit();
-
     var walk = try root.walk(ctx.allocator());
     defer walk.deinit();
 
     while (try walk.next()) |e| {
         switch (e.kind) {
             .file => {
+                ctx.progress_start(e.basename);
+                defer ctx.progress_end();
+
                 if (std.mem.endsWith(u8, e.basename, ".htm")) {
                     std.log.debug("Indexing {s}", .{e.path});
-                    try pages.append(try ctx.allocator().dupe(u8, e.path));
+                    try ctx.pages.append(ctx.allocator(), try ctx.allocator().dupe(u8, e.path));
+                }
+                if (std.mem.endsWith(u8, e.basename, ".md")) {
+                    std.log.debug("Indexing {s}", .{e.path});
+                    try ctx.markdown.append(ctx.allocator(), try ctx.allocator().dupe(u8, e.path));
                 }
             },
             else => {},
         }
     }
 
-    ctx.pages = try pages.toOwnedSlice();
+    log.info("Indexed {d} pages.", .{ctx.pages.items.len});
+    log.info("Indexed {d} markdown files.", .{ctx.markdown.items.len});
 
     return;
 }
 
-pub fn main() !void {
-    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
-    const allocator = gpa.allocator();
-    defer _ = gpa.deinit();
-
-    var ctx = Context.new(allocator);
-    defer ctx.deinit();
-
-    index(ctx) catch {
-        log.err("Failed to index pages.", .{});
-        std.os.linux.exit(1);
-    };
-
-    log.info("Indexed {d} pages.", .{ctx.pages.len});
-
-    Cli.parse()(ctx);
-}
-
 const RunFn = fn (*Context) void;
 
 const Cli = struct {
@@ -119,20 +132,49 @@ const Cli = struct {
 
         if (std.mem.eql(u8, next_arg, "gen")) {
             return &Cli.gen_cmd;
+        } else if (std.mem.eql(u8, next_arg, "md")) {
+            return &Cli.gen_md_cmd;
         } else {
             return &Cli.help_cmd;
         }
     }
 
     fn help_cmd(_: *Context) void {
-        std.debug.print("usage: rbl [gen]\n", .{});
-        std.os.linux.exit(0);
+        std.debug.print("usage: rbl [gen|md]\n\n", .{});
     }
 
     fn gen_cmd(ctx: *Context) void {
+        index(ctx) catch {
+            log.err("Failed to index pages.", .{});
+            std.os.linux.exit(1);
+        };
+
         gen.generate(ctx) catch {
             log.err("Failed to generate site.", .{});
             std.os.linux.exit(1);
         };
     }
+
+    fn gen_md_cmd(ctx: *Context) void {
+        index(ctx) catch {
+            log.err("Failed to index pages.", .{});
+            std.os.linux.exit(1);
+        };
+
+        exe.run_pandoc(ctx) catch {
+            log.err("Failed to process markdown files.", .{});
+            std.os.linux.exit(1);
+        };
+    }
 };
+
+pub fn main() !void {
+    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
+    const allocator = gpa.allocator();
+    defer _ = gpa.deinit();
+
+    var ctx = try Context.create(allocator);
+    defer ctx.destroy();
+
+    Cli.parse()(ctx);
+}