From 664f471c774d6182efb0f9c4d4c9af9857b1bf52 Mon Sep 17 00:00:00 2001 From: ubq323 Date: Thu, 31 Oct 2024 04:02:07 +0000 Subject: initial commit --- html.lua | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 html.lua (limited to 'html.lua') diff --git a/html.lua b/html.lua new file mode 100644 index 0000000..87ecc53 --- /dev/null +++ b/html.lua @@ -0,0 +1,87 @@ +local function fmt_attrs(attrs) + local function fmt_attr(k,v) + if v == true then + return k + else + if type(v) == "table" then v = table.concat(v," ") end + return ('%s="%s"'):format(k,v) + end + end + + local o = "" + for k,v in pairs(attrs) do + o = o .. " " .. fmt_attr(k,v) + end + return o +end + +local html +local function fmt_tag(tag) + local attrs = tag.attrs and fmt_attrs(tag.attrs) or "" + local selfclosing = (tag.body == "") + local sameline = type(tag.body) == "string" or (type(tag.body) == "table" and tag.body.tag) + local maybenl = sameline and "" or "\n" + if selfclosing then + return ("<%s%s/>"):format(tag.tname,attrs) + else + return ("<%s%s>%s%s"):format(tag.tname,attrs,maybenl,html(tag.body),tag.tname) + end +end + +local function tag(tname, a1, a2) + -- tag(tname,body) or tag(tname,attrs,body) + local body, attrs + if a2 then attrs=a1 body=a2 else attrs=nil body=a1 end + return setmetatable({tag=true,tname=tname,attrs=attrs,body=body},{__tostring=fmt_tag}) +end + +-- instead of tag('ul', {x, y, z}) +-- you can do T.ul{ x, y, z} +local T = setmetatable({}, {__index=function(_,tname) + return function (...) + return tag(tname, ...) + end +end}) + +local function safe(s) + -- marks s as safe, doesn't escape it + assert(type(s) == "string","can only mark string as safe") + return setmetatable({safe=true,s=s},{__tostring=function(x)return x.s end}) +end + +local function escape(s) + s=s:gsub("&","&") + s=s:gsub("<","<") + s=s:gsub(">",">") + s=s:gsub('"',""") + return safe(s) +end + + +html = function (x) + if type(x) == "string" then + return escape(x) + elseif type(x) == "table" then + if x.safe then + -- safestr. already escaped + return x + elseif x.tag then + -- it's a tag + return safe( tostring(x) ) + else + -- just a regular list + local o = "" + for _,item in ipairs(x) do + o = o .. tostring(html(item)) .. "\n" + end + return safe(o) + end + end +end + +return { + html = html, + tag = tag, + safe = safe, + T = T, +} -- cgit v1.2.3