diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.zig | 29 | ||||
| -rw-r--r-- | src/preproc.lua | 60 |
2 files changed, 86 insertions, 3 deletions
diff --git a/src/main.zig b/src/main.zig index 7b53295..c5956fc 100644 --- a/src/main.zig +++ b/src/main.zig @@ -785,6 +785,8 @@ const Builder = struct { log.debug("{s}: done", .{self.source.path}); } + const prepocLua = @embedFile("preproc.lua"); + fn markdown(self: *Builder, io: Io, gpa: Allocator) !void { log.info("mdn : {s}", .{self.source.path}); @@ -800,12 +802,14 @@ const Builder = struct { }); defer target_fd.close(io); + // embedded preproc.lua -> fd + // which we pass to the pandoc subshell + const fd = try memfd("preproc.lua", prepocLua); 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_path, self.source.path }); + \\pandoc --from=markdown+wikilinks_title_after_pipe+autolink_bare_uris --to=html5 --lua-filter=/dev/fd/{d} --strip-comments --output={s} {s} + , .{ fd, target_path, self.source.path }); defer gpa.free(pandoc_command); - try self.root_dir.access(io, "../../preproc.lua", .{}); // check preproc script try shell(io, pandoc_command, .{ .cwd = .{ .dir = self.root_dir } }); // track source @@ -952,6 +956,25 @@ fn getXattrSourceComponents(gpa: Allocator, fd: Io.File) !?[][]const u8 { // shell +pub fn memfd(name: [*:0]const u8, data: []const u8) !usize { + const fd = linux.memfd_create(name, 0); + if (linux.errno(fd) != .SUCCESS) return error.MemfdCreate; + const rc = linux.ftruncate(@intCast(fd), @intCast(data.len)); + if (linux.errno(rc) != .SUCCESS) return error.Ftruncate; + const page = linux.mmap( + null, + data.len, + .{ .READ = true, .WRITE = true }, + .{ .TYPE = .SHARED }, + @intCast(fd), + 0, + ); + if (linux.errno(page) != .SUCCESS) return error.Mmap; + const ptr: [*]volatile u8 = @ptrFromInt(page); + @memcpy(ptr, data); + return fd; +} + pub fn shell( io: std.Io, command: []const u8, diff --git a/src/preproc.lua b/src/preproc.lua new file mode 100644 index 0000000..76f0678 --- /dev/null +++ b/src/preproc.lua @@ -0,0 +1,60 @@ +---@diagnostic disable: undefined-global +-- see https://pandoc.org/lua-filters.html +return { + Link = function(link) + -- set target="_blank" for outgoing links (open them in new tab) + if string.match(link.target, "gzr.im") == nil then + table.insert(link.attributes, { "target", "_blank" }) + end + return link + end, + Pandoc = function(doc) + local front = {} + + -- add a comment + table.insert( + front, + pandoc.RawBlock( + "html5", + "<!-- Generated file, you may edit and discard " + .. pandoc.path.filename(PANDOC_STATE.input_files[1]) + .. " :) -->" + ) + ) + + local toc = pandoc.structure.table_of_contents(doc) + if doc.meta.toc and toc then + table.insert(front, pandoc.RawBlock("html5", '<nav class="table-of-contents capital">')) + table.insert(front, pandoc.RawBlock("html5", "<ol>")) + -- insert jump to top + table.insert(front, pandoc.RawBlock("html5", "<li>")) + table.insert(front, pandoc.Link("back to top", "#top")) + table.insert(front, pandoc.RawBlock("html5", "</li>")) + -- create custom toc + toc:walk({ + Link = function(e) + table.insert(front, pandoc.RawBlock("html5", "<li>")) + table.insert(front, e) + table.insert(front, pandoc.RawBlock("html5", "</li>")) + end, + }) + table.insert(front, pandoc.RawBlock("html5", "</ol>")) + table.insert(front, pandoc.RawBlock("html5", "</nav>")) + end + + -- insert date blocks + if doc.meta.date then + table.insert(front, pandoc.RawBlock("html5", '<span class="date">')) + table.insert(front, doc.meta.date) + table.insert(front, pandoc.RawBlock("html5", "</span>")) + end + + -- prepend front stuffs + for i = #front, 1, -1 do + table.insert(doc.blocks, 1, front[i]) + end + + -- return finished ast + return doc + end, +} |