Module:Hex to HSV

local p = {} function p.main(frame) local hex = frame.args[1] --strip away # and spaces from our string, we don't want it   hex = string.gsub(hex, '#', '') hex = string.gsub(hex, ' ', '') --confirm that our input is a valid hex number 6 characters long. Return -1 if not if (#hex ~= 6 or tonumber(hex, 16) == nil) then return -1 end --Convert every 2 digits from hex to integer, then convert to percentage of the maximum amount (255) local red = tonumber(string.sub(hex, 1,2), 16)/255 local green = tonumber(string.sub(hex, 3,4), 16)/255 local blue = tonumber(string.sub(hex, 5,6), 16)/255 local H,S,V --Value is simply the maximum value of our colors V = math.max(red, green, blue) --The formula for Hue depends on which of our colors has the greatest value. Since we already calculated that as V, we can reuse the variable if V == math.min(red, green, blue) then -- if all colors are equal, we're just going to stick H at 0 to avoid a NaN H = 0 elseif V == red then H = (green - blue) / (red - math.min(green, blue)) elseif V == green then H = 2 + (blue - red) / (green - math.min(red, blue)) else H = 4 + (red - green) / (blue - math.min(red, green)) end --Convert Hue to a positive degree measurement on the color wheel H = H * 60 if H<0 then H = H + 360 end --We're reusing V as our maximum color value again for calculating saturation --Only do the formula if V is not equal to 0 to avoid a divide-by-zero error if V ~= 0 then S = (V - math.min(red, green, blue)) / V	else S = 0 end --We no longer need these as percentages, and they suit our final purposes better as integers S = S * 100 V = V * 100 --Concatenate HSV into a comma-separated string, with each segment being left-padded with 0s to have 3 digits and no decimals. --This allows it to be sorted as a number return string.format('%03.0f',H)..','..string.format('%03.0f',S)..','..string.format('%03.0f',V) end

return p