FANDOM


-- <nowiki>
--------------------------------------------------------------------------------
-- General-purpose color module.
--------------------------------------------------------------------------------
local p = {}
 
local checkType = require("libraryUtil").checkType
local math = require("Dev:Sandbox/DarthKitty/Math")
local namedColors = mw.loadData("Dev:Sandbox/DarthKitty/Color/names")
 
--[=[
-- Converts an HSL color value to RGB. Conversion formula
-- adapted from http://en.wikipedia.org/wiki/HSL_color_space.
-- Assumes h, s, and l are contained in the set [0, 1] and
-- returns r, g, and b in the set [0, 255].
--
-- @param   Number  h       The hue
-- @param   Number  s       The saturation
-- @param   Number  l       The lightness
-- @return  Array           The RGB representation
--
-- Ported to Lua by [[User:DarthKitty]].
--
-- Original code can be found at:
-- <http://axonflux.com/handy-rgb-to-hsl-and-rgb-to-hsv-color-model-c>
--]=]
local function hslToRgb(h, s, l)
    local r, g, b
 
    if s == 0 then
        r, g, b = l, l, l -- achromatic
    else
        local function hue2rgb(p, q, t)
            if t < 0 then t = t + 1 end
            if t > 1 then t = t - 1 end
            if t < 1/6 then return p + (q - p) * 6 * t end
            if t < 1/2 then return q end
            if t < 2/3 then return p + (q - p) * (2/3 - t) * 6 end
            return p
        end
 
        local q = l < 0.5 and l * (1 + s) or l + s - l * s
        local p = 2 * l - q
        r = hue2rgb(p, q, h + 1/3)
        g = hue2rgb(p, q, h)
        b = hue2rgb(p, q, h - 1/3)
    end
 
    return r * 255, g * 255, b * 255
end
 
--------------------------------------------------------------------------------
-- @TODO
--------------------------------------------------------------------------------
function p.new(tbl)
    return "Sorry, nothing here yet! :("
end
 
--------------------------------------------------------------------------------
-- Parses all colors defined in the CSS Color Module Level 3 specification,
-- except for dynamic values like the `currentColor` keyword.
--
-- NOTE:
-- Stay away from the CSS Color Module Level 4 specification for now, since it's
-- still a draft and can change at any moment. This means no `rebeccapurple`,
-- sadly. :(
--
-- @see <https://developer.mozilla.org/en-US/docs/Web/CSS/color_value>
-- @see <https://drafts.csswg.org/css-color-3/>
--------------------------------------------------------------------------------
function p.parseCSS(str)
    checkType("Dev:Color", 1, str, "string")
 
    local value = mw.text.trim(str):lower()
    local formats = {
        -- 3-digit hex
        ["^#([0-9a-f])([0-9a-f])([0-9a-f])$"] =
        function (r, g, b)
            return {
                red = tonumber(r:rep(2), 16),
                green = tonumber(g:rep(2), 16),
                blue = tonumber(b:rep(2), 16),
                alpha = 1
            }
        end,
 
        -- 6-digit hex
        ["^#([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])$"] =
        function (r, g, b)
            return {
                red = tonumber(r, 16),
                green = tonumber(g, 16),
                blue = tonumber(b, 16),
                alpha = 1
            }
        end,
 
        -- integer rgb()
        ["^rgb%(%s*(%-?%d-)%s*,%s*(%-?%d-)%s*,%s*(%-?%d-)%s*%)$"] =
        function (r, g, b)
            return {
                red = math.clamp(r, 0, 255),
                green = math.clamp(g, 0, 255),
                blue = math.clamp(b, 0, 255),
                alpha = 1
            }
        end,
 
        -- percentage rgb()
        ["^rgb%(%s*(%-?%d-%.?%d-)%%%s*,%s*(%-?%d-%.?%d-)%%%s*,%s*(%-?%d-%.?%d-)%%%s*%)$"] =
        function (r, g, b)
            return {
                red = math.remap(r, 0, 100, 0, 255),
                green = math.remap(g, 0, 100, 0, 255),
                blue = math.remap(b, 0, 100, 0, 255),
                alpha = 1
            }
        end,
 
        -- integer rgba()
        ["^rgba%(%s*(%-?%d-)%s*,%s*(%-?%d-)%s*,%s*(%-?%d-)%s*,%s*(%d-%.?%d-)%s*%)$"] =
        function (r, g, b, a)
            return {
                red = math.clamp(r, 0, 255),
                green = math.clamp(g, 0, 255),
                blue = math.clamp(b, 0, 255),
                alpha = math.min(a, 1)
            }
        end,
 
        -- percentage rgba()
        ["^rgb%(%s*(%-?%d-%.?%d-)%%%s*,%s*(%-?%d-%.?%d-)%%%s*,%s*(%-?%d-%.?%d-)%%%s*,%s*(%d-%.?%d-)%s*%)$"] =
        function (r, g, b)
            return {
                red = math.remap(r, 0, 100, 0, 255),
                green = math.remap(g, 0, 100, 0, 255),
                blue = math.remap(b, 0, 100, 0, 255),
                alpha = math.min(a, 1)
            }
        end,
 
        -- hsl()
        ["^hsl%(%s*(%-?%d-%.?%d-)%s*,%s*(%-?%d-%.?%d-)%%%s*,%s*(%-?%d-%.?%d-)%%%s*%)$"] =
        function (h, s, l)
            local r, g, b = hslToRgb(
                math.remap(h, 0, 360, 0, 1),
                math.remap(s, 0, 100, 0, 1),
                math.remap(l, 0, 100, 0, 1)
            )
 
            return {
                red = r,
                green = g,
                blue = b,
                alpha = 1
            }
        end,
 
        -- hsla()
        ["^hsla%(%s*(%-?%d-%.?%d-)%s*,%s*(%-?%d-%.?%d-)%%%s*,%s*(%-?%d-%.?%d-)%%%s*,%s*(%d-%.?%d-)%s*%)$"] =
        function (h, s, l, a)
            local r, g, b = hslToRgb(
                math.remap(h, 0, 360, 0, 1),
                math.remap(s, 0, 100, 0, 1),
                math.remap(l, 0, 100, 0, 1)
            )
 
            return {
                red = r,
                green = g,
                blue = b,
                alpha = math.min(a, 1)
            }
        end
    }
 
    if namedColors[value] then
        -- don't expose `mw.loadData()`s metatable
        return {
            red = namedColors[value].red,
            green = namedColors[value].green,
            blue = namedColors[value].blue,
            alpha = namedColors[value].alpha
        }
    end
 
    for pattern, callback in pairs(formats) do
        if value:find(pattern) then
            return callback(value:match(pattern))
        end
    end
 
    error("invalid color value according to the 'CSS Color Module Level 3' specification")
end
 
return p
-- </nowiki>

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.