-- SPDX-License-Identifier: AGPL-3.0-only
local function html_escape(s)
expect(1, s, "string")
s = string.gsub(s, "&", "&")
s = string.gsub(s, "<", "<")
s = string.gsub(s, ">", ">")
s = string.gsub(s, "'", "'")
s = string.gsub(s, "\"", """)
return s
end
local function html(el, tbl)
expect(1, el, "string")
expect(2, tbl, "table")
local innerHtml = ""
local attributes = ""
for k, v in pairs(tbl) do
if type(k) == "string" then
expect.field(tbl, k, "string")
attributes = attributes .. " " .. k .. "='" .. html_escape(v) .. "'"
end
end
for k, v in ipairs(tbl) do
expect.field(tbl, k, "string", "table")
if type(v) == "table" then v = html_escape(v[1]) end
innerHtml = innerHtml .. v
end
return string.format("<%s%s>%s</%s>", el, attributes, innerHtml, el)
end
local function root(tbl)
return "<!DOCTYPE html>\n" .. html("html", tbl)
end
return setmetatable(
{},
{ __call = html,
__index = function (_, idx)
if idx == "root" then
return root
else
return function(tbl) return html(idx, tbl) end
end
end })