ravenous.dev/listing.lua

local lfs = require "lfs"

local files_dir, output_dir, file = ...

l '<style>html {overflow: hidden;}</style>'

local function show_dir(file)
	l '<ul class="dir-list">'
	local files = {}
	local directories = {}
	for name in lfs.dir(files_dir.."/"..file) do
		local attr = assert(lfs.attributes(files_dir.."/"..file.."/"..name))
		if attr.mode ~= "directory" then
			table.insert(files, name)
		else
			table.insert(directories, name)
		end
	end
	table.sort(files)
	table.sort(directories)
	for _, name in ipairs(directories) do
		local path = "/"..output_dir.."/"..file.."/"..name
		if not name:match "^%." then
			w '<li>'
			l '<details>'

			w '<summary>'
			w '<a href="'
			t(path)
			w '">'
			t(name.."/")
			w '</a>'
			l '</summary>'

			show_dir(file.."/"..name)

			l '</details>'
			l '</li>'
		end
	end
	for _, name in ipairs(files) do
		w '<li>'
		local path = "/"..output_dir.."/"..file.."/"..name..".htm"
		w '<a href="'
		t(path)
		w '">'
		t(name)
		w '</a>'
		w '</li>'
	end
	l '</ul>'
end

local function show_file(file)
	local attr = assert(lfs.attributes(files_dir.."/"..file))
	w '<main class="file"><pre class="hl listing">'
	if attr.mode == "file" then
		local ok = os.execute(
			("highlight -u utf-8 -fO html %q"):format(files_dir.."/"..file))
		if not ok then
			local f = io.open(files_dir.."/"..file, "r")
			t(f:read "a")
			f:close()
		end
	else
		assert(os.execute(
			("stat -c '%%A %%Hr %%s %%N' %q"):format(files_dir.."/"..file)))
	end
	l '</pre></main>'
end

local function heading(file)
	local attr = assert(lfs.attributes(files_dir.."/"..file))

	w '<h1 class="filepath">'
	local components = {}
	for component in file:gmatch "[^/]+" do
		table.insert(components, component)
	end
	for i, component in ipairs(components) do
		if i ~= #components then
			w '<a href="'
			if attr.mode ~= "directory" then
				t(("../"):rep(#components - i - 1)..".")
			else
				t(("../"):rep(#components - i))
			end
			w '">'
			t(component)
			w '</a>'
			t "/"
		else
			t(component)
			if attr.mode == "directory" then
				t "/"
			end
		end
	end
	l '</h1>'
end

local attr = assert(lfs.attributes(files_dir.."/"..file))

w [[
<link rel="stylesheet" type="text/css" href="/highlight.css" />
]]

w "<title>"
t(file)
l "</title>"

if attr.mode ~= "directory" then
	l '<div class="file-view">'

	l "<main>"
	heading(file)
	show_file(file)
	l "</main>"

	l '<div class="file-view-dir">'
	show_dir(file:match "(.*)/[^/]+/*$", file)
	l '</div>'
else
	l "<main>"
	heading(file)
	show_dir(file)
	l "</main>"
end