diff options
| author | Robert Günzler <r@gnzler.io> | 2026-09-23 13:23:25 +0200 |
|---|---|---|
| committer | Robert Günzler <r@gnzler.io> | 2026-09-23 13:23:25 +0200 |
| commit | 225e0075d85bb807d24cb7e7e0e5eb5b3db69f2e (patch) | |
| tree | dd5b6a592ac3b518bf746e6ecbea08271844bcb2 | |
| parent | 6697b9fc8b082f2e7e89b9cd2ca6f8fa309e151f (diff) | |
| download | site-225e0075d85bb807d24cb7e7e0e5eb5b3db69f2e.tar.gz | |
implement mdn subcommand
Signed-off-by: Robert Günzler <r@gnzler.io>
Diffstat (limited to '')
| -rw-r--r-- | src/main.zig | 119 |
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 } }); } }; |