src/web/html.lua

changeset 0
6279a7d40ae7
--- /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 = { ["'"] = "&apos;", ["\""] = "&quot;", ["<"] = "&lt;", [">"] = "&gt;", ["&"] = "&amp;" };
+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;
+};

mercurial