all repos

olexsmir.xyz @ 620792cf2ab97761a56488444d1732ee99e76f22

my site, yes, i like lua

olexsmir.xyz/lua/lego/css.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
local css = {}

---@param str string
---@return string
local function to_kebab_case(str)
  str = str:gsub("_", "-")
  str = str:gsub("([a-z])([A-Z])", "%1-%2"):lower() -- Convert camelCase to kebab-case
  return str
end

---@param value string|number
---@return string
local function value_to_css(value)
  if type(value) == "number" then
    return tostring(value)
  end
  return string.format("%s", value)
end

local function render_properties(properties)
  local parts = {}
  local keys = {}
  for key in pairs(properties) do
    table.insert(keys, key)
  end
  table.sort(keys)

  for _, key in ipairs(keys) do
    local value = properties[key]
    table.insert(parts, string.format("%s:%s", to_kebab_case(key), value_to_css(value)))
  end

  return table.concat(parts, ";")
end

local function flatten_css_rules(rules)
  local all_rules = {}

  local function process_rule(sel, props, prefix)
    local full_sel
    if sel:find "^&" then
      full_sel = prefix .. sel:gsub("^&", "")
    else
      full_sel = prefix and (prefix .. " " .. sel) or sel
    end
    local flat_props = {}
    for k, v in pairs(props) do
      if type(v) == "table" then
        process_rule(k, v, full_sel)
      else
        flat_props[k] = v
      end
    end
    if next(flat_props) then
      all_rules[full_sel] = flat_props
    end
  end

  for sel, props in pairs(rules) do
    process_rule(sel, props, nil)
  end

  return all_rules
end

---@param rules table
---@return string
function css.style(rules)
  local all_rules = flatten_css_rules(rules)

  local selectors = {}
  for s in pairs(all_rules) do
    table.insert(selectors, s)
  end
  table.sort(selectors)

  local rule_parts = {}
  for _, sel in ipairs(selectors) do
    local props = all_rules[sel]
    local props_str = render_properties(props) .. ";"
    table.insert(rule_parts, string.format("%s{%s}", sel, props_str))
  end

  return table.concat(rule_parts, "")
end

return css