--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/web/html.lua Tue Mar 09 12:16:56 2021 +0000 @@ -0,0 +1,54 @@ + +local s_gsub = string.gsub; + +local html_escape_table = { ["'"] = "'", ["\""] = """, ["<"] = "<", [">"] = ">", ["&"] = "&" }; +local function html_escape(str) return (s_gsub(str, "['&<>\"]", html_escape_table)); end + +local html_unescape_table = {}; for k,v in pairs(html_escape_table) do html_unescape_table[v] = k; end +local function html_unescape(str) return (s_gsub(str, "&%a+;", html_unescape_table)); end + +local tags = { + em = "/"; strong = "*"; small = ""; s = ""; cite = ""; + q = "\""; dfn = ""; code = "`"; var = "`"; samp = "`"; kbd = "`"; + sub = "~"; sup = "^"; i = "/"; b = "*"; u = "_"; mark = ""; +}; + +local function formatted(text) + return html_escape(text):gsub(html_escape("<(%a+)([^>]*)>(.-)</%1>"), function (tag, attrs, content) + tag = tag:lower(); + if tags[tag] then + return ("<%s>%s</%s>"):format(tag, content, tag); + end + end); +end + +local function html2md(text) + return text:gsub("<(%a+)([^>]*)>(.-)</%1>", function (tag, attrs, content) + tag = tags[tag]; + if tag then + return tag .. content .. tag; + end + end); +end + +local par = { ["("] = ")", ["<"] = ">", ["["] = "]", ["{"] = "}", [";"] = "&", }; + +local function linkify(text) + return text:gsub("(%S?)(https?://%S+)", function (p, url) + local extra = ""; + -- Attempt to get rid of trailing parenthesis from found URLs + if par[p] and url:find(par[p], 1, true) then + extra = url:sub(url:find(par[p], 1, true), -1); + url = url:sub(1, url:find(par[p], 1, true) - 1); + end + return ("%s<a rel=\"nofollow\" href=\"%s\">%s</a>%s"):format(p, url, url, extra); + end); +end + +return { + escape = html_escape; + html2md = html2md; + formatted = formatted; + linkify = linkify; + unescape = html_unescape; +};