Module:EGAColor

From Wiki of ZZT
Jump to navigation Jump to search

Documentation for this module may be created at Module:EGAColor/doc

-- Module for working with EGA colors

--
-- Lookup tables
--

local hex_codes = {
	"#000",
	"#00a",
	"#0a0",
	"#0aa",
	"#a00",
	"#a0a",
	"#a50",
	"#aaa",
	"#555",
	"#55f",
	"#5f5",
	"#5ff",
	"#f55",
	"#f5f",
	"#ff5",
	"#fff"
}

local color_names = {
	"black",
	"dark blue",
	"dark green",
	"dark cyan",
	"dark red",
	"dark purple",
	"dark brown",
	"light gray",
	"dark gray",
	"blue",
	"green",
	"cyan",
	"red",
	"purple",
	"yellow",
	"white"
}

-- Compute a lookup table of names to indexes, and include a few synonyms as well
local inv_color_names = {}
for i, name in ipairs(color_names) do
	inv_color_names[name] = i
end
local color_synonyms = {
	brown = "dark brown",
	["dark yellow"] = "dark brown",
	["light brown"] = "yellow",
	gray = "light gray"
}
for synonym, name in pairs(color_synonyms) do
	local i = inv_color_names[name]
	inv_color_names[synonym] = i
end

--
-- Package functions
--

local p = {}

function p.to_name(val)
	i = p.to_index(val)
	return color_names[i + 1]
end

function p.to_hex_color(val)
	i = p.to_index(val)
	return hex_codes[i + 1]
end

function p.to_index(val)
	-- Handle decimal numbers, hex numbers starting with "0x"
	local number = tonumber(val)
	if number ~= nil then
		if number ~= math.floor(number) or number < 0 or number > 15 then
			error("color index " .. number .. " not an integer 0-15")
		end
		return number
	end

	-- Handle color names
	local name = string.lower(val)
	name = string.gsub(name, "grey", "gray")
	if inv_color_names[name] == nil then
		name = string.gsub(name, "^light ", "")
	end
	if inv_color_names[name] == nil then
		error("color name not recognized: " .. val)
	end
	return inv_color_names[name] - 1
end

return p