Created
November 30, 2023 22:30
-
-
Save rfl890/26e369bb8e5ffdf774dea37f1563f28e to your computer and use it in GitHub Desktop.
Lua color library
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local lib_color = {} | |
-- Constants | |
lib_color.color_type = { TYPE_8 = 39710315, TYPE_256 = 34942623, TYPE_RGB = 29505187 } | |
local FOREGROUND = 1 | |
local BACKGROUND = 2 | |
local ESCAPE = "\x1b[" | |
local RESET = "\x1b[0m" | |
lib_color.modifiers = { | |
BOLD = "1", | |
DIM = "2", | |
ITALIC = "3", | |
UNDERLINE = "4", | |
BLINKING = "5", | |
INVERSE = "7", | |
INVISIBLE = "8", | |
STRIKETHROUGH = "9" | |
} | |
lib_color.colors = { | |
BLACK = { "30", "40" }, | |
RED = { "31", "41" }, | |
GREEN = { "32", "42" }, | |
YELLOW = { "33", "43" }, | |
BLUE = { "34", "44" }, | |
MAGENTA = { "35", "45" }, | |
CYAN = { "36", "46" }, | |
WHITE = { "37", "47" }, | |
DEFAULT = { "39", "39" } | |
} | |
-- Utility functions | |
local function assert_conditionally(condition, value, error) if condition then assert(value, error) end end | |
local function checkIfExistsInTable(item, table, checkIdx, idx) | |
checkIdx = checkIdx or false | |
for _, member in pairs(table) do | |
if checkIdx then | |
if item == member[idx] then | |
return true | |
end | |
else | |
if item == member then | |
return true | |
end | |
end | |
end | |
return false | |
end | |
local function checkIndexesInTable(item, table) | |
for _, member in ipairs(item) do | |
if not checkIfExistsInTable(member, table) then return false end | |
end | |
return true | |
end | |
local function validateRGB(rgb) | |
if type(rgb) ~= "table" then return false end | |
if #rgb < 3 then return false end | |
for i = 1, 3 do | |
local n = tonumber(rgb[i]) | |
if (n == nil) or (not (n >= 0 and n <= 255)) then return false end | |
end | |
return true | |
end | |
-- Library functions | |
lib_color.format = function(color_type, modifiers, color, background, text) | |
-- Validate color_type and modifiers | |
assert(checkIfExistsInTable(color_type, lib_color.color_type), "Argument 'color_type' must be one of: TYPE_8, TYPE_256 or TYPE_RGB.") | |
assert(type(modifiers) == "table", "Argument 'modifiers' must be a table.") | |
assert(checkIndexesInTable(modifiers, lib_color.modifiers), "Argument 'modifiers' contains an invalid modifier.") | |
-- Validate color and background | |
assert_conditionally(color_type == lib_color.color_type.TYPE_RGB, validateRGB(color), "Argument 'color' must be a table with 3 numbers >= 0 and <= 255 when using RGB.") | |
assert_conditionally((color_type == lib_color.color_type.TYPE_RGB) and background, validateRGB(background), "Argument 'background' must be a table with 3 numbers >= 0 and <= 255 when using RGB.") | |
assert_conditionally(color_type == lib_color.color_type.TYPE_8, checkIfExistsInTable((type(color) == "table" and color or {})[FOREGROUND], lib_color.colors, true, FOREGROUND), "Argument 'color' must be a valid color when using 8 colors.") | |
assert_conditionally((color_type == lib_color.color_type.TYPE_8) and background, checkIfExistsInTable((type(background) == "table" and background or {})[BACKGROUND], lib_color.colors, true, BACKGROUND), "Argument 'background' must be a valid color when using 8 colors.") | |
assert_conditionally(color_type == lib_color.color_type.TYPE_256, tonumber(color) and (tonumber(color) >= 0 and tonumber(color) <= 255), "Argument 'color' must be a number >= 0 and <= 255 when using 256 colors.") | |
assert_conditionally((color_type == lib_color.color_type.TYPE_256) and background, tonumber(background) and (tonumber(background) >= 0 and tonumber(background) <= 255), "Argument 'background' must be a number >= 0 and <= 255 when using 256 colors.") | |
local fmttdString = ESCAPE | |
local modifiersAlreadySeen = {} | |
if color_type == lib_color.color_type.TYPE_8 then | |
for _, modifier in pairs(modifiers) do | |
if not checkIfExistsInTable(modifier, modifiersAlreadySeen) then | |
fmttdString = fmttdString .. modifier .. ";" | |
table.insert(modifiersAlreadySeen, modifier) | |
end | |
end | |
if background then | |
fmttdString = string.format("%s%s;%sm%s%s", fmttdString, color[FOREGROUND], background[BACKGROUND], text, RESET) | |
else | |
fmttdString = string.format("%s%sm%s%s", fmttdString, color[FOREGROUND], text, RESET) | |
end | |
elseif color_type == lib_color.color_type.TYPE_256 then | |
for _, modifier in pairs(modifiers) do | |
if not checkIfExistsInTable(modifier, modifiersAlreadySeen) then | |
fmttdString = fmttdString .. modifier .. ";" | |
table.insert(modifiersAlreadySeen, modifier) | |
end | |
end | |
if background then | |
fmttdString = string.format("%s38;5;%s;48;5;%sm%s%s", fmttdString, tostring(color), tostring(background), text, RESET) | |
else | |
fmttdString = string.format("%s38;5;%sm%s%s", fmttdString, tostring(color), text, RESET) | |
end | |
else | |
for _, modifier in pairs(modifiers) do | |
if not checkIfExistsInTable(modifier, modifiersAlreadySeen) then | |
fmttdString = fmttdString .. modifier .. ";" | |
table.insert(modifiersAlreadySeen, modifier) | |
end | |
end | |
if background then | |
fmttdString = string.format("%s38;2;%s;48;2;%sm%s%s", fmttdString, table.concat(color, ";"), table.concat(background, ";"), text, RESET) | |
else | |
fmttdString = string.format("%s38;2;%sm%s%s", fmttdString, table.concat(color, ";"), text, RESET) | |
end | |
end | |
return fmttdString | |
end | |
return lib_color |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment