local M = {} function M.element(tag, attrs, content) local out = { "<", tag } if attrs then for k, v in pairs(attrs) do if v ~= false and v ~= nil then if v == true then out[#out + 1] = " " .. k else out[#out + 1] = " " .. k .. "=\"" .. tostring(v) .. "\"" end end end end if content == nil then out[#out + 1] = " />" return table.concat(out) end out[#out + 1] = ">" out[#out + 1] = tostring(content) out[#out + 1] = "" return table.concat(out) end function M.a(link, str) link = link or "https://example.com" str = str or link return M.element("a", { href = link }, str) end function M.ha(link, str) link = link or "https://example.com" str = str or link return M.element("a", { href = link, class = "hidden" }, str) end function M.external(link, str) return M.element("a", { href = link, target = "_blank" }, str) end function M.note(str) return M.element("div", { class = "note" }, str) end function M.muted(str) return M.element("div", { class = "muted" }, str) end function M.callout(str) return M.element("div", { class = "callout" }, str) end function M.h1(str) return M.element("h1", nil, str or "") end function M.h2(str) return M.element("h2", nil, str or "") end function M.h3(str) return M.element("h3", nil, str or "") end function M.h4(str) return M.element("h4", nil, str or "") end function M.h5(str) return M.element("h5", nil, str or "") end function M.h6(str) return M.element("h6", nil, str or "") end function M.p(str) return M.element("p", nil, str or "") end function M.pre(str) return M.element("pre", nil, str or "") end function M.code(str) return M.element("pre", nil, M.element("code", nil, str or "")) end function M.ul(items) items = items or {} local out = {} for _, item in ipairs(items) do out[#out + 1] = M.element("li", nil, item) end return M.element("ul", nil, table.concat(out)) end function M.ol(items) items = items or {} local out = {} for _, item in ipairs(items) do out[#out + 1] = M.element("li", nil, item) end return M.element("ol", nil, table.concat(out)) end function M.tl(items) items = items or {} local out = {} for _, item in ipairs(items) do out[#out + 1] = M.element("li", nil, item) end return M.element("ul", { class = "tl" }, table.concat(out)) end function M.blockquote(str) return M.element("blockquote", nil, str or "") end function M.hr() return M.element("hr") end function M.img(src, alt) return M.element("img", { src = src or "", alt = alt or "" }) end function M.strong(str) return M.element("strong", nil, str or "") end function M.em(str) return M.element("em", nil, str or "") end function M.br() return M.element("br") end function M.div(content, class) return M.element("div", class and { class = class } or nil, content or "") end function M.span(content, class) return M.element("span", class and { class = class } or nil, content or "") end function M.escape(str) str = tostring(str or "") str = str:gsub("&", "&") str = str:gsub("<", "<") str = str:gsub(">", ">") str = str:gsub('"', """) str = str:gsub("'", "'") return str end function M.highlight(str) return M.element("span", { class = "highlight" }, str or "") end function M.banner(str) return M.element("div", { class = "banner" }, str or "") end function M.center(str) return M.element("div", { class = "center" }, str or "") end function M.nav(link, str) link = link or "example.com" str = str or link return M.element("a", { href = link, class = "nav" }, str) end function M.rl(r, l) return M.element("span", { class = "left" }, r or "") .. M.element("span", { class = "right" }, l or "") end return M