Jump to content

Module:LightDarkColor

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Awesome Aasim (talk | contribs) at 17:09, 20 June 2025. The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

--- Given a color given in light or dark mode, provide CSS that makes it dark
--  mode compatible.
--
-- @module		lightdarkcolor
-- @alias		p
-- @release		alpha
-- @author		Awesome Aasim
-- @require		Module:Arguments
-- @require		Module:Entrypoint

local p = {}
local getArgs = require("Module:Arguments").getArgs

--- Converts hex to dec
-- @function		hex2dec
-- @param	{string}	hex		hex to convert
-- @return						Decimal value
local function hex2dec(hex)
	return tonumber('0x' .. hex)
end

function round(x)
	local q,r = math.modf(x)
	if math.abs(r) < 0.5 or (math.abs(r) <= 0.5 and x < 0) then
		return q
	else
		return q + 1
	end
end

--- Converts dec to hex
-- @function		dec2hex
-- @param	{string}	dec		dec to convert
-- @return						Hexadecimal value
local function dec2hex(dec)
	return mw.ustring.format("%x", dec)
end

--- Inverts RGB
-- @function		p.invertRGB
-- @param	{table}		rgb		rgb table
-- @return						Inverted RGB table
function p._invertRGB(rgb)
	rgb[1] = 255 - rgb[1]
	rgb[2] = 255 - rgb[2]
	rgb[3] = 255 - rgb[3]
	return rgb
end

--- Get original hue for any color
-- @function			getHue
-- @param	{table}		rgb		rgb table
-- @return						Appropriate RGB for pigment
function getHue(rgb)
	local prgb = {
		rgb[1],
		rgb[2],
		rgb[3]
	}
	local maxPRGB = math.max(prgb[1], prgb[2], prgb[3])
	local minPRGB = math.min(prgb[1], prgb[2], prgb[3])
	if (maxRGB == minRGB) or (maxRGB == 255 and minRGB == 0) or (prgb[1] == prgb[2] and prgb[2] == prgb[3]) then
		return prgb
	end
	prgb[1] = prgb[1] - minPRGB
	prgb[2] = prgb[2] - minPRGB
	prgb[3] = prgb[3] - minPRGB
	local prgbFraction = 255 / maxRGB
	prgb[1] = prgb[1] * prgbFraction
	prgb[2] = prgb[2] * prgbFraction
	prgb[3] = prgb[3] * prgbFraction
	prgb[1] = round(prgb[1])
	prgb[2] = round(prgb[2])
	prgb[3] = round(prgb[3])
	return prgb
end

--- Converts from (R, G, B) to (r, g, b, a) while preserving actual color in light mode
-- @function			p._RGB
-- @param	{table}		rgb		rgb table
-- @return						Appropriate RGBA
function p._RGB(rgb, bg)
	bg = bg or {255, 255, 255}
	-- extract original hue
	local hrgb = getHue(rgb)
	local alpha = 0
	local alphaCount = 0
	for k,v in pairs(rgb) do
		if rgb[k] ~= bg[k] then
			alpha = alpha + math.abs(hrgb[k] - bg[k]) / math.abs(rgb[k] - bg[k])
		end
	end
	if alphaCount == 0 then
		alpha = 1
	else
		alpha = alpha / alphaCount
	end
	hrgb[4] = alpha
	return hrgb
end

--- Entrypoint for RGB related functions
-- @function			p.RGB
-- @param	{table} 	frame		invocation frame
-- @return							Wikitext output
function p.RGB(frame)
	local args = getArgs(frame)
	local rgbStr = args[1] or error("RGB not specified", 1)
	rgbStr = mw.text.trim(rgbStr)
	local rgb = mw.text.split(rgbStr, ",")
	rgb[1] = tonumber(rgb[1])
	if not rgb[2] and not rgb[3] then
		rgb[2] = rgb[1]
		rgb[3] = rgb[1]
	end
	rgb[2] = tonumber(rgb[2])
	rgb[3] = tonumber(rgb[3])
	local rgba = p._RGB(rgb)
	return table.concat(rgba, ',')
end


--- Converts from #RRGGBB to #rrggbbaa while preserving actual color
-- @function			p.Hex
-- @param	{table}		frame	invocation frame
-- @return						Wikitext output
function p.Hex(frame)
	local args = getArgs(frame)
	local hexStr = args[1] or error("Hex not specified", 1)
	hexStr = mw.text.trim(hexStr)
	local hexChars = mw.text.split(hexStr, '')
	local rgb = {}
	local rH = hexChars[1] .. hexChars[2]
	local gH = (hexChars[3] or '') .. (hexChars[4] or '')
	local bH = (hexChars[5] or '') .. (hexChars[6] or '')
	local aH = ''
	rgb[1] = hex2dec(rH)
	if gH == '' and bH == '' then
		rgb[2] = rgb[1]
		rgb[3] = rgb[1]
	end
	rgb[2] = hex2dec(gH)
	rgb[3] = hex2dec(bH)
	local rgba = p._RGB(rgb)
	rH = dec2hex(rgb[1])
	gH = dec2hex(rgb[2])
	bH = dec2hex(rgb[3])
	aH = dec2hex(rgb[4] * 255)
	return rH .. gH .. bH .. aH
end

--- Converts from HSL to hsla while preserving actual color
-- @function			p.HSL
-- @param	{table}		frame	invocation frame
-- @return						Wikitext output
-- @todo fill in function
function p.HSL(frame, dark)
	
end

--- Entrypoint for module
-- @function			p.main
-- @param	{table}		frame	invocation frame
-- @return						Wikitext output
p.main = require("Module:Entrypoint")(p)

return p