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
|
-- Hex to 256 color conversion utilities
local M = {}
-- Convert hex color to RGB values
local function hex_to_rgb(hex)
hex = hex:gsub("#", "")
return {
r = tonumber(hex:sub(1, 2), 16),
g = tonumber(hex:sub(3, 4), 16),
b = tonumber(hex:sub(5, 6), 16),
}
end
-- Convert RGB to nearest 256 color index
local function rgb_to_256(r, g, b)
-- Build full 256 color palette and find nearest
local palette = {}
-- Gray ramp (232-255)
for i = 0, 23 do
local gray = 8 + i * 10
palette[#palette + 1] = { r = gray, g = gray, b = gray, idx = 232 + i }
end
-- 6x6x6 color cube (16-231)
local values = {0, 95, 135, 175, 215, 255}
for ri = 0, 5 do
for gi = 0, 5 do
for bi = 0, 5 do
local idx = 16 + ri * 36 + gi * 6 + bi
palette[#palette + 1] = {
r = values[ri + 1],
g = values[gi + 1],
b = values[bi + 1],
idx = idx
}
end
end
end
-- Find nearest color (minimum Manhattan distance)
local min_dist = 100000
local nearest_idx = 15
for _, color in ipairs(palette) do
local dist = math.abs(r - color.r) + math.abs(g - color.g) + math.abs(b - color.b)
if dist < min_dist then
min_dist = dist
nearest_idx = color.idx
end
end
return nearest_idx
end
-- Convert hex color string to 256 color index
function M.hex_to_256(hex)
if not hex or hex == "" or hex == "NONE" then
return nil
end
if type(hex) == "number" then
return hex -- Already a cterm color
end
local rgb = hex_to_rgb(hex)
return rgb_to_256(rgb.r, rgb.g, rgb.b)
end
-- Create highlight table with cterm colors from fg and bg hex colors
function M.convert_theme_theme(theme)
local cterm_theme = {}
for group, hl in pairs(theme) do
local cterm = {}
if hl.fg then
cterm.fg = M.hex_to_256(hl.fg)
end
-- Include background colors
if hl.bg then
cterm.bg = M.hex_to_256(hl.bg)
end
if hl.sp then
cterm.sp = M.hex_to_256(hl.sp)
end
if hl.bold then
cterm.bold = true
end
if hl.underline then
cterm.underline = true
end
if hl.undercurl then
cterm.undercurl = true
end
if hl.italic then
cterm.italic = true
end
if hl.reverse then
cterm.reverse = true
end
if hl.standout then
cterm.standout = true
end
cterm_theme[group] = cterm
end
return cterm_theme
end
return M
|