Edge Rewrite
// HTMLRewriter · presentation

This page was redesigned at the edge.

Cloudflare fetched the original article and streamed it through HTMLRewriter to apply an entirely new visual system without rebuilding the source page.

Jump to content

Module:Module:LuminanceChroma to sRGB

From Wikipedia, the free encyclopedia
-- Module:LuminanceChroma to sRGB
-- Converts:
--   Luminance (%) 
--   Chroma angle (degrees)
--   Chroma (%)
-- to sRGB hex
-- Preserves luminance
-- Output:
--   hex (default)
--   swatch

local p = {}

------------------------------------------------
-- Clamp helper
------------------------------------------------
local function clamp(x, min, max)
    if x < min then return min end
    if x > max then return max end
    return x
end

------------------------------------------------
-- Convert sRGB (0-1) to hex
------------------------------------------------
local function rgbToHex(r, g, b)
    r = clamp(math.floor(r * 255 + 0.5), 0, 255)
    g = clamp(math.floor(g * 255 + 0.5), 0, 255)
    b = clamp(math.floor(b * 255 + 0.5), 0, 255)
    return string.format("#%02X%02X%02X", r, g, b)
end

------------------------------------------------
-- HSL → sRGB conversion
-- L = luminance (0–1)
-- C = chroma (0–1)
-- H = hue angle (degrees)
------------------------------------------------
local function hslToRgb(L, C, H)

    H = H % 360
    local Hp = H / 60

    local X = C * (1 - math.abs((Hp % 2) - 1))

    local r1, g1, b1 = 0, 0, 0

    if Hp >= 0 and Hp < 1 then
        r1, g1, b1 = C, X, 0
    elseif Hp < 2 then
        r1, g1, b1 = X, C, 0
    elseif Hp < 3 then
        r1, g1, b1 = 0, C, X
    elseif Hp < 4 then
        r1, g1, b1 = 0, X, C
    elseif Hp < 5 then
        r1, g1, b1 = X, 0, C
    else
        r1, g1, b1 = C, 0, X
    end

    local m = L - C/2

    return r1 + m, g1 + m, b1 + m
end

------------------------------------------------
-- Main entry
------------------------------------------------
function p.convert(frame)

    local args = frame.args

    local L = tonumber(args.L)
    local H = tonumber(args.H)
    local C = tonumber(args.C)

    local format = args.format or "hex"

    if not L or not H or not C then
        return "Error: L, H, and C must be numeric."
    end

    ------------------------------------------------
    -- Normalize input
    ------------------------------------------------

    L = clamp(L, 0, 100) / 100
    C = clamp(C, 0, 100) / 100
    H = H % 360

    ------------------------------------------------
    -- Convert
    ------------------------------------------------

    local R, G, B = hslToRgb(L, C, H)

    -- Final clamp
    R = clamp(R, 0, 1)
    G = clamp(G, 0, 1)
    B = clamp(B, 0, 1)

    local hex = rgbToHex(R, G, B)

    if format == "swatch" then
        return string.format(
            '<span style="display:inline-block;width:1.5em;height:1.5em;border:1px solid #000;background-color:%s;vertical-align:middle;margin-right:0.4em;"></span><code>%s</code>',
            hex,
            hex
        )
    end

    return "&#35;" .. string.sub(hex, 2)
end

return p