Module:Sandbox/Sameboat/m2

From WikiProjectMed
Jump to navigation Jump to search
local getArgs = require('Module:Arguments').getArgs
 
local p = {}

local function makeInvokeFunction(funcName)
	return function (frame)
		local args = getArgs(frame, {parentOnly = true})
		return p[funcName](args)
	end
end

p.spectrum = makeInvokeFunction('_spectrum')
function p._spectrum(args)
	local list = mw.text.split(args[1], '\n')
	local width = tonumber(args[2]) or tonumber(args.width) or 768
	local pos,length,rgb,red,green,blue,gray,neargray,title
	local result = '<div style="padding:15px 15px 25px 15px;border:1px solid #999;position:relative;line-height:92%;width:' .. width .. 'px">'
	for i1, v1 in ipairs(list) do
		for i2, v2 in ipairs(mw.text.split(v1, '\\')) do -- i.1:Name; i.2:RGB
			if (i2 % 2 == 1) then
				title = v2
				result = result .. '<div>&nbsp;'
			elseif (i2 % 2 == 0) then
				if not (string.len(v2) == 6 or string.len(v2) == 3) then
					result = '<div style="position:relative;color:red;font-weight:bold">Invalid RGB value. Please use "RRGGBB" or "RGB" formats and all numbers must be converted to hexadecimal.</div>'
				else
					if string.len(v2) == 6 then
						red, green, blue = v2:match("(..)(..)(..)")
					else
						red, green, blue = v2:match("(.)(.)(.)")
						red = red .. red
						green = green .. green
						blue = blue .. blue
					end
					red = tonumber(red, 16)
					green = tonumber(green, 16)
					blue = tonumber(blue, 16)
					rgb = v2
					if red == green and red == blue then -- grayscale
						gray = true
						pos = 0
						result = result .. '<div style="position:relative;height:13px">'
					else
						if red > green and red > blue then -- red
							if blue > green then pos = width - (width / 6) * (blue - green) / (red - green) -- magenta to red
							elseif green > blue then pos = (width / 6) * (green - blue) / (red - blue) -- red to yellow
							else pos = 0
							end
						elseif green > red and green > blue then -- green
							if red > blue then pos = width / 3 - (width / 6) * (red - blue) / (green - blue) -- yellow to green
							elseif blue > red then pos = width / 3 + (width / 6) * (blue - red) / (green - red) -- green to cyan
							else pos = width / 3
							end
						elseif blue > red and blue > green then -- blue
							if green > red then pos = width * 2 / 3 - (width / 6) * (green - red) / (blue - red) -- cyan to blue
							elseif red > green then pos = width * 2 / 3 + (width / 6) * (red - green) / (blue - green) -- blue to magenta
							else pos = width * 2 / 3
							end
						elseif red == green then -- yellow
							pos = width / 6
						elseif green == blue then -- cyan
							pos = width / 2
						elseif blue == red then -- magenta
							pos = width * 5 / 6
						end
						if (math.abs(red - blue) < 20) and (math.abs(red - green) < 20) and (math.abs(green - blue) < 20) then -- near grayscale
							neargray = true
						end
						pos = math.ceil(pos) - 5
						if pos <= 0 then
						else
							result = result .. '<div style="position:relative;top:4px;border-bottom:2px solid #' .. rgb .. ';width:' .. pos .. 'px"></div>'
						end
						result = result .. '<div style="position:relative;left:' .. pos .. 'px">[[File:Black Arrow Down.svg|10px|link=|alt=]]<div style="position:absolute;left:4px;border:1px solid #'
						if neargray == true then
							result = result .. '000;opacity:0.05'
						else
							result = result .. rgb
						end
						result = result .. ';height:' .. (table.maxn(list) - i1) * 32 + 21 .. 'px"></div>'
					end
					if pos < 0 then pos = 5 else pos = '-' .. pos end
					result = result .. '<div style="position:absolute;top:-12px;left:' .. pos .. 'px"><span style="background:#' .. rgb .. '">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background:#fff">&nbsp;<span style="font-weight:bold">' .. title .. ': </span>' .. string.upper(rgb) .. '&nbsp;'
					if gray == true then result = result .. '<span style="font-size:70%">(grayscale)</span>&nbsp;'
					elseif neargray == true then result = result .. '<span style="font-size:70%">(near grayscale)</span>&nbsp;'
					end
					gray = false
					neargray = false
					result = result .. '</span></div></div></div>'
				end
			end
		end
	end
	result = result .. '<div style="width:' .. width .. 'px;height:20px;background:linear-gradient(to right, #f00, #ff0, #0f0, #0ff, #00f, #f0f, #f00);">&nbsp;</div><div style="position:relative;left:-5px;top:3px;font-size:11px"><div style="position:absolute;background:#fff;height:22px;border-bottom:1px solid #aaa;width:' .. width + 10 .. 'px">'
	local colori = {'red', 'orange', 'yellow', 'lime', 'green', 'teal', 'cyan', 'azure', 'blue', 'violet', 'magenta', 'purple'}
	for i, v in ipairs(colori) do
		local colorin = '<div style="position:absolute;left:' .. (i - 1) * width / 12 .. 'px">[[File:Black Arrow Up.svg|10px|link=|alt=]] ' .. v .. '</div>'
		if width < 768 then
			if (i % 2) == 1 then
				result = result .. colorin
			else
			end
		else
			result = result .. colorin
		end
	end
	return result .. '</div></div></div></div>'
end

return p