about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main.zig119
1 files changed, 91 insertions, 28 deletions
diff --git a/src/main.zig b/src/main.zig
index 0fb913a..53048df 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -32,6 +32,9 @@ const Cli = struct {
             \\  build [-f, --force] SOURCE-FILE TARGET-DIR
             \\    builds while resolving references
             \\
+            \\  mdn SOURCE-FILE TARGET-DIR
+            \\    build markdown files (using pandoc)
+            \\
             \\  gen ROOT-DIR TARGET-DIR
             \\    runs build for relevant files
             \\
@@ -54,6 +57,7 @@ const Cli = struct {
             if (std.mem.eql(u8, o, "-h")) return Cli.usage();
             if (std.mem.eql(u8, o, "build")) return Cli.build(io, gpa, &opts);
             if (std.mem.eql(u8, o, "gen")) return Cli.gen(io, gpa, &opts);
+            if (std.mem.eql(u8, o, "mdn")) return Cli.markdown(io, gpa, &opts);
         }
         return Cli.usage();
     }
@@ -127,11 +131,17 @@ const Cli = struct {
         var work: std.ArrayList([]const u8) = .empty;
         defer work.deinit(gpa);
 
+        var mdn = std.BufSet.init(gpa);
+        defer mdn.deinit();
+
         var iter = root_dir.iterate();
         while (try iter.next(io)) |child| {
             if (child.kind != .file) continue;
 
-            if (std.mem.endsWith(u8, child.name, ".md")) continue;
+            if (std.mem.endsWith(u8, child.name, ".md")) {
+                try mdn.insert(child.name);
+                continue;
+            }
             if (std.mem.endsWith(u8, child.name, "meta.baseof.htm")) continue;
             if (std.mem.endsWith(u8, child.name, "meta.nav.htm")) continue;
             try work.append(gpa, child.name);
@@ -140,10 +150,27 @@ const Cli = struct {
         var progress = if (!DEBUG) std.Progress.start(io, .{});
         defer if (!DEBUG) progress.end();
 
+        var mdnProgress = if (!DEBUG) progress.start("Generating markdown", mdn.count());
+        defer if (!DEBUG) mdnProgress.end();
+
         var htmProgress = if (!DEBUG) progress.start("Generating html", work.items.len);
         defer if (!DEBUG) htmProgress.end();
 
         for (work.items) |path| {
+            const md_name = try std.fmt.allocPrint(gpa, "{s}.md", .{std.fs.path.stem(path)});
+            defer gpa.free(md_name);
+            const md_path = try std.fs.path.join(gpa, &.{ root_path, md_name });
+            defer gpa.free(md_path);
+            const full_path = try std.fs.path.join(gpa, &.{ root_path, path });
+            defer gpa.free(full_path);
+
+            if (mdn.contains(md_name)) {
+                const mdnNode = if (!DEBUG) mdnProgress.start(md_name, 0);
+                defer if (!DEBUG) mdnNode.end();
+
+                try pandoc(io, gpa, Io.Dir.cwd(), md_path, full_path);
+            }
+
             const htmNode = if (!DEBUG) htmProgress.start(path, 0);
             defer if (!DEBUG) htmNode.end();
 
@@ -155,6 +182,40 @@ const Cli = struct {
             try b.build(io, gpa);
         }
     }
+
+    fn markdown(io: Io, gpa: Allocator, opts: *std.process.Args.Iterator) !void {
+        var args: std.ArrayList([]const u8) = .empty;
+        defer args.deinit(gpa);
+
+        while (opts.next()) |o| {
+            if (std.mem.eql(u8, o, "help")) return Cli.usage();
+            if (std.mem.eql(u8, o, "--help")) return Cli.usage();
+            if (std.mem.eql(u8, o, "-h")) return Cli.usage();
+            // if (std.mem.eql(u8, o, "--force")) FORCE = true and continue;
+            // if (std.mem.eql(u8, o, "-f")) FORCE = true and continue;
+            try args.append(gpa, o);
+        }
+
+        if (args.items.len < 2) return Cli.usage();
+
+        const source_path = args.items[0];
+        const target_path = args.items[1];
+
+        log.info("mdn : target={s} source={s}", .{ target_path, source_path });
+
+        try pandoc(io, gpa, Io.Dir.cwd(), source_path, target_path);
+    }
+
+    // TODO: integrate into builder?
+    fn pandoc(io: Io, gpa: Allocator, root_dir: Io.Dir, source: []const u8, target: []const u8) !void {
+        const pandoc_command = try std.fmt.allocPrint(gpa,
+            \\pandoc --from=markdown+wikilinks_title_after_pipe+autolink_bare_uris --to=html5 --lua-filter=preproc.lua --strip-comments --output={s} {s}
+        , .{ target, source });
+        defer gpa.free(pandoc_command);
+
+        try root_dir.access(io, "preproc.lua", .{}); // check preproc script
+        try shell(io, pandoc_command, .{ .cwd = .{ .dir = root_dir } });
+    }
 };
 
 const File = struct {
@@ -646,35 +707,37 @@ fn getXattrSourceComponents(gpa: Allocator, fd: Io.File) ![][]const u8 {
     return try parts.toOwnedSlice(gpa);
 }
 
+// shell
+
+pub fn shell(
+    io: std.Io,
+    command: []const u8,
+    opts: struct {
+        cwd: std.process.Child.Cwd = .inherit,
+        environ_map: ?*const std.process.Environ.Map = null,
+        progress_node: std.Progress.Node = std.Progress.Node.none,
+    },
+) !void {
+    log.debug("Running Shell <<< {s}", .{command});
+
+    var p = try std.process.spawn(io, .{
+        .argv = &.{ "sh", "-c", command },
+        .cwd = opts.cwd,
+        .stdin = .ignore,
+        .stderr = .inherit,
+        .stdout = .inherit,
+        .environ_map = opts.environ_map,
+        .progress_node = opts.progress_node,
+    });
+
+    const result = try p.wait(io);
+    if (result.exited != 0) return error.NonZeroExitCode;
+}
+
 // tests
 
 pub const Testing = if (@import("builtin").is_test)
     struct {
-        pub fn shell(
-            io: std.Io,
-            command: []const u8,
-            opts: struct {
-                cwd: std.process.Child.Cwd = .inherit,
-                environ_map: ?*const std.process.Environ.Map = null,
-                progress_node: std.Progress.Node = std.Progress.Node.none,
-            },
-        ) !void {
-            log.debug("Running Shell <<< {s}", .{command});
-
-            var p = try std.process.spawn(io, .{
-                .argv = &.{ "sh", "-c", command },
-                .cwd = opts.cwd,
-                .stdin = .ignore,
-                .stderr = .inherit,
-                .stdout = .inherit,
-                .environ_map = opts.environ_map,
-                .progress_node = opts.progress_node,
-            });
-
-            const result = try p.wait(io);
-            if (result.exited != 0) return error.NonZeroExitCode;
-        }
-
         pub fn parse_hash(comptime str: []const u8) !Digest {
             var buffer: [BUFFER_SIZE]u8 = undefined;
             var out = try std.fmt.hexToBytes(&buffer, str);
@@ -808,10 +871,10 @@ test "e2e" {
                 return error.TestExpectedEqual;
             }
 
-            try Testing.shell(io, "tree", .{ .cwd = .{ .dir = dest } });
+            try shell(io, "tree", .{ .cwd = .{ .dir = dest } });
             const cmd = try std.fmt.allocPrint(gpa, "cat {s}", .{tc.expect_path});
             defer gpa.free(cmd);
-            try Testing.shell(io, cmd, .{ .cwd = .{ .dir = dest } });
+            try shell(io, cmd, .{ .cwd = .{ .dir = dest } });
         }
     };