all repos

olexsmir.xyz @ 620792cf2ab97761a56488444d1732ee99e76f22

my site, yes, i like lua

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