const std = @import("std"); const ziggy = @import("ziggy"); const Page = struct { title: ?[]const u8 = null, author: ?[]const u8 = null, date: ?[]const u8 = null, layout: ?[]const u8 = null, // draft: ?bool = null, // params: ?struct { // comments: bool, // } = null, }; pub fn main() !void { const a = std.heap.page_allocator; var args = std.process.args(); if (!args.skip()) @panic("errors kipping program name?"); const contentdirname = args.next() orelse return error.NoDir; const contentdir = try std.fs.cwd().openDir(contentdirname, .{ .iterate = true }); var walker = try contentdir.walk(a); while (try walker.next()) |we| { if (std.mem.endsWith(u8, we.basename, ".md")) { std.log.info("converting file {s}", .{we.basename}); const file = try we.dir.readFileAlloc(a, we.basename, 1_000_000); const start = (std.mem.indexOf(u8, file, "---\n") orelse return error.NoFrontmatter) + 4; const end = (std.mem.lastIndexOf(u8, file, "---\n") orelse return error.NoFrontMatter); var childproc = std.process.Child.init(&.{ "yq", "-o", "json" }, a); childproc.stdin_behavior = .Pipe; childproc.stdout_behavior = .Pipe; childproc.stderr_behavior = .Pipe; std.log.info("spawn", .{}); try childproc.spawn(); std.log.info("writeAll", .{}); try childproc.stdin.?.writeAll(file[start..end]); childproc.stdin.?.close(); childproc.stdin = null; var stdout = std.ArrayList(u8).init(a); var stderr = std.ArrayList(u8).init(a); std.log.info("collectOutput", .{}); try childproc.collectOutput(&stdout, &stderr, 1_000_000); std.log.info("got output {s}", .{stdout.items}); std.log.info("wait", .{}); const term = try childproc.wait(); if (term.Exited != 0) { return error.ProcessError; } const fm_json = try stdout.toOwnedSlice(); // Now parse it and add missing fields const fm_json_parsed_value = try std.json.parseFromSlice(Page, a, fm_json, .{ .ignore_unknown_fields = true, }); defer fm_json_parsed_value.deinit(); var fm_json_parsed = fm_json_parsed_value.value; fm_json_parsed.title = fm_json_parsed.title orelse ""; fm_json_parsed.author = fm_json_parsed.author orelse "Martin Ashby"; fm_json_parsed.date = fm_json_parsed.date orelse "1900-01-01T00:00:00Z"; fm_json_parsed.layout = fm_json_parsed.layout orelse "single.html"; var out = std.ArrayList(u8).init(a); defer out.deinit(); try ziggy.stringify(fm_json_parsed, .{.whitespace = .space_2}, out.writer()); const newfile = try std.mem.concat(a, u8, &.{ "---\n", out.items, "\n", file[end..] }); try we.dir.writeFile(we.basename, newfile); } } std.log.info("done!", .{}); }