diff options
Diffstat (limited to 'pkgs/simple/cgit-about-filter/cgit-about-filter.lua')
| -rw-r--r-- | pkgs/simple/cgit-about-filter/cgit-about-filter.lua | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/pkgs/simple/cgit-about-filter/cgit-about-filter.lua b/pkgs/simple/cgit-about-filter/cgit-about-filter.lua new file mode 100644 index 0000000..1b37643 --- /dev/null +++ b/pkgs/simple/cgit-about-filter/cgit-about-filter.lua @@ -0,0 +1,93 @@ +local function resolve(base, relative) + if relative:sub(1, 1) == "/" then + return relative + end + + local combined = base .. "/" .. relative + + local segments = {} + for segment in combined:gmatch("[^/]+") do + if segment == ".." then + if #segments > 0 and segments[#segments] ~= ".." then + table.remove(segments) + else + table.insert(segments, "..") + end + elseif segment ~= "." and segment ~= "" then + table.insert(segments, segment) + end + end + + local prefix = (base:sub(1, 1) == "/" or relative:sub(1, 1) == "/") and "/" or "" + return prefix .. table.concat(segments, "/") +end + +local buffer = "" +local should_render = true +local current_dir = "" -- Stores the directory prefix of the file being processed +local current_file = "" + +function filter_open(...) + local args = {...} + current_file = args[1] or "" + + if current_file == "" then + current_file = "README.md" + end + + -- Strict route enforcement: Allow README.md OR any file starting with docs/ and ending in .md + if current_file == "README.md" or (current_file:sub(1, 5) == "docs/" and current_file:sub(-3) == ".md") then + should_render = true + + -- Extract directory context (e.g., "docs/ops.md" -> "docs/") + -- If it's the root README.md, current_dir stays an empty string "" + if current_file ~= "README.md" then + current_dir = current_file:match("(.*/)") or "" + else + current_dir = "" + end + else + should_render = false + end + + buffer = "" +end + +function filter_write(str) + if should_render then + buffer = buffer .. str + end +end + +function filter_close() + if not should_render then + io.write("<p><em>Error: Access Denied. Only README.md and documentation markdown files are viewable here.</em></p>") + return + end + + local repo = os.getenv("CGIT_REPO_URL") or "" + + local processed = buffer:gsub("%[([^%]]+)%]%(([^:)]+)%)", function(text, path) + -- Ignore protocols (http, https, etc.), absolute paths (/), and anchors (#) + if path:sub(1, 1) == "/" or path:sub(1, 1) == "#" or path:match("^%w+:") then + return string.format("[%s](%s)", text, path) + end + + path = resolve(current_dir, path) + + if path:sub(-3) == ".md" then + return string.format("[%s](/%s/about/%s)", text, repo, path) + else + return string.format("[%s](/%s/tree/%s)", text, repo, path) + end + end) + + -- Pipe everything into md2html + local handle = io.popen("@md2html@ --github", "w") + if handle then + handle:write(processed) + handle:close() + else + io.write("<p>Error: Could not execute md2html.</p>") + end +end |
