Module:LightDarkColor
Appearance
| This module is rated as beta. It is considered ready for widespread use, but as it is still relatively new, it should be applied with some caution to ensure results are as expected. |
| This module depends on the following other modules: |
| Description | Given a color given in light or dark mode, provide CSS that makes it dark mode compatible. |
|---|---|
| Author(s) | Awesome Aasim |
| Code source | LightDarkColor |
| Status | Beta |
| Dependencies |
Given a color given in light or dark mode, provide CSS that makes it dark mode compatible.
Documentation
Package items
lightdarkcolor.invertRGB(rgb)(function)- Inverts RGB
- Parameter:
rgbrgb table (table) - Returns: Inverted RGB table
lightdarkcolor._RGB(rgb)(function)- Converts from (R, G, B) to (r, g, b, a) while preserving actual color in light mode
- Parameter:
rgbrgb table (table) - Returns: Appropriate RGBA
lightdarkcolor.RGB(frame)(function)- Entrypoint for RGB related functions
- Parameter:
frameinvocation frame (table) - Returns: Wikitext output
lightdarkcolor.Hex(frame)(function)- Converts from #RRGGBB to #rrggbbaa while preserving actual color
- Parameter:
frameinvocation frame (table) - Returns: Wikitext output
lightdarkcolor.HSL(frame)(function)- Converts from HSL to hsla while preserving actual color
- Parameter:
frameinvocation frame (table) - Returns: Wikitext output
- TODO: fill in function
lightdarkcolor.main(frame)(function)- Entrypoint for module
- Parameter:
frameinvocation frame (table) - Returns: Wikitext output
Other items
getHue(rgb)(function)- Get original hue for any color
- Parameter:
rgbrgb table (table) - Returns: Appropriate RGB for pigment
--- Given a color given in light or dark mode, provide CSS that makes it dark
-- mode compatible.
--
-- @module lightdarkcolor
-- @alias p
-- @release beta
-- @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 padZero(x, length)
while #x < length do
x = '0' .. x
end
return x
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 (maxPRGB == minPRGB) or (maxPRGB == 255 and minPRGB == 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 / (maxPRGB - minPRGB)
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
p._getHue = getHue
--- 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}
local avgColor = (bg[1] + bg[2] + bg[3]) / 3
-- extract original hue
local hrgb = getHue(rgb)
if hrgb[1] == hrgb[2] and hrgb[2] == hrgb[3] then
hrgb[1] = hrgb[1] < avgColor and 0 or (hrgb[1] > avgColor and 1 or avgColor)
hrgb[2] = hrgb[1]
hrgb[3] = hrgb[1]
end
local alpha = 0
local alphaCount = 0
for k,v in pairs(rgb) do
if hrgb[k] ~= bg[k] then
alpha = alpha + math.abs(rgb[k] - bg[k]) / math.abs(hrgb[k] - bg[k])
alphaCount = alphaCount + 1
end
end
if alphaCount == 0 then
alpha = 0
else
alpha = alpha / alphaCount
end
if alpha >= 1 then
rgb[4] = 1
return rgb
elseif alpha <= 0 then
alpha = 0
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(rgba[1])
gH = dec2hex(rgba[2])
bH = dec2hex(rgba[3])
aH = dec2hex(round(rgba[4] * 255))
return padZero(rH, 2) .. padZero(gH, 2) .. padZero(bH, 2) .. padZero(aH, 2)
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