olexsmir.xyz/lua/lego/html/init.lua(view raw)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 |
local a = require "lego.html.attribute"
local html = {}
---@alias lego.HtmlNode lego._HtmlNote|string
---@class lego._HtmlNote
---@field tag string
---@field attributes lego.HtmlAttribute[]
---@field children lego._HtmlNote[]
---@param tag string
---@param attributes lego.HtmlAttribute[]
---@param children lego.HtmlNode[]
---@return lego.HtmlNode
function html.el(tag, attributes, children)
local attrs = {}
for _, attr_table in ipairs(attributes or {}) do
for k, v in pairs(attr_table) do
attrs[k] = v
end
end
return {
tag = tag,
attributes = attrs,
children = children or {},
}
end
---@param text string
---@return lego.HtmlNode
function html.text(text)
return text
end
---@param html_str string
---@return lego.HtmlNode
function html.raw(html_str)
return html_str
end
---@param txts string[]
---@return string[]
function html.tt(txts)
local tt = vim
.iter(txts)
:map(function(txt)
return { txt, " " }
end)
:flatten()
:totable()
if tt[#tt] == " " then
table.remove(tt, #tt)
end
return tt
end
local _self_closing_tags = {
area = {},
base = {},
br = {},
col = {},
embed = {},
hr = {},
img = {},
input = {},
-- link = {}, -- ignored because it needed for rss
meta = {},
source = {},
track = {},
wbr = {},
}
---@param node lego.HtmlNode
---@return string
function html.render(node)
if type(node) == "string" then
return node
elseif type(node) == "table" and node.tag then
local attr_keys = {}
for k in pairs(node.attributes or {}) do
table.insert(attr_keys, k)
end
table.sort(attr_keys)
local attrs_str = ""
for _, v in pairs(attr_keys) do
attrs_str = attrs_str .. string.format(' %s="%s"', v, node.attributes[v])
end
if _self_closing_tags[node.tag] then
return string.format("<%s%s>", node.tag, attrs_str)
end
local children_str = ""
for _, child in ipairs(node.children or {}) do
children_str = children_str .. html.render(child)
end
return string.format("<%s%s>%s</%s>", node.tag, attrs_str, children_str, node.tag)
end
return ""
end
function html.render_page(node)
return "<!DOCTYPE html>" .. html.render(node)
end
-- --- COMMON ELEMENTS
-- stylua: ignore start
---@param attributes lego.HtmlAttribute[]
---@param children lego.HtmlNode[]
function html.div(attributes, children) return html.el("div", attributes, children) end
---@param attributes lego.HtmlAttribute[]
---@param children lego.HtmlNode[]
function html.main(attributes, children) return html.el("main", attributes, children) end
---@param attributes lego.HtmlAttribute[]
function html.meta(attributes) return html.el("meta", attributes, {}) end
---@param attributes lego.HtmlAttribute[]
---@param children lego.HtmlNode[]
function html.span(attributes, children) return html.el("span", attributes, children) end
---@param attributes lego.HtmlAttribute[]
---@param children lego.HtmlNode[]
function html.p(attributes, children) return html.el("p", attributes, children) end
---@param attributes lego.HtmlAttribute[]
---@param children lego.HtmlNode[]
function html.a(attributes, children) return html.el("a", attributes, children) end
---@param attributes lego.HtmlAttribute[]
---@param children lego.HtmlNode[]
function html.ul(attributes, children) return html.el("ul", attributes, children) end
---@param attributes lego.HtmlAttribute[]
---@param children lego.HtmlNode[]
function html.li(attributes, children) return html.el("li", attributes, children) end
---@param attributes lego.HtmlAttribute[]
---@param children lego.HtmlNode[]
function html.title(attributes, children) return html.el("title", attributes, children) end
---@param attributes lego.HtmlAttribute[]
function html.link(attributes) return html.el("link", attributes, {}) end
---@param attributes lego.HtmlAttribute[]
---@param children lego.HtmlNode[]
function html.h1(attributes, children) return html.el("h1", attributes, children) end
---@param attributes lego.HtmlAttribute[]
---@param children lego.HtmlNode[]
function html.h2(attributes, children) return html.el("h2", attributes, children) end
---@param attributes lego.HtmlAttribute[]
---@param children lego.HtmlNode[]
function html.nav(attributes, children) return html.el("nav", attributes, children) end
function html.br() return html.el("br", {}, {}) end
---@param datetime string
function html.time(datetime)
return html.el("time",
{ a.attr("datetime", datetime) },
{ html.text(datetime)})
end
-- stylua: ignore end
return html
|