Module:Tincture

From DoveArchives
Jump to navigation Jump to search

Documentation for this module may be created at Module:Tincture/doc

local getArgs = require( 'Module:Arguments' ).getArgs
--cal convdec = require( 'Module:Color2dec' ).convert

local p = {}  -- Tincture

--------------
local function hexdec ( arg )
	local dig  =  ( string.upper ( string.char ( arg ) ) );
	local dec  =  0;
	if     dig == 'F' then  dec = 0xF
	elseif dig == 'E' then  dec = 0xE
	elseif dig == 'D' then  dec = 0xD
	elseif dig == 'C' then  dec = 0xC
	elseif dig == 'B' then  dec = 0xB
	elseif dig == 'A' then  dec = 0xA
	else   dec = tonumber (dig)
	end
	return dec;
end 

--
local function dezhex ( arg )
	local hex = ''
	if arg > 15 then 
		error ('value "' .. arg .. '" is > 15')
	end
	if     arg == 15 then hex = 'F'
	elseif arg == 14 then hex = 'E'
	elseif arg == 13 then hex = 'D' 
	elseif arg == 12 then hex = 'C' 
	elseif arg == 11 then hex = 'B'
	elseif arg == 10 then hex = 'A'
	else hex = tostring (arg)
	end
	return hex;
end

-- local/global function
local function convdec ( color )
--	local gpar = frame.args
--	local hex = ''
--	if  gpar then
--		hex   =  gpar[1] or 'glo'
--	elseif  frame then
--		hex  =  frame   or 'loc'
--	else hex  = '#0F0'   --  parameter missing
--	end

	local hex  =  color or '#010';
    if  mw.ustring.sub ( hex, 1,  1) ~= '#' then 
        error ('value "' .. hex .. '" cannot be converted to decimal')
	end  
	local dec  =  {};
	if #hex == 7 then
		dec [1] = hexdec ( string.byte (hex, 2)) * 16 + hexdec (string.byte (hex, 3))
		dec [2] = hexdec ( string.byte (hex, 4)) * 16 + hexdec (string.byte (hex, 5))
		dec [3] = hexdec ( string.byte (hex, 6)) * 16 + hexdec (string.byte (hex, 7))
	else
		dec [1] = hexdec ( string.byte (hex, 2)) * 16 + hexdec (string.byte (hex, 2))
		dec [2] = hexdec ( string.byte (hex, 3)) * 16 + hexdec (string.byte (hex, 3))
		dec [3] = hexdec ( string.byte (hex, 4)) * 16 + hexdec (string.byte (hex, 4))
	end
	dec [4] = '000'
	if dec [1] * 3 + dec [2] * 10 < 1568 then 
		dec [4] = 'FFF'   -- this calculation is nonsense - not useful !
	end
	return dec;
end
--
local function draw(color, ss, tc, pf, gt)
	return mw.getCurrentFrame():expandTemplate{ title = 'Tincture/draw' .. ss, args = { color, gt, tc = tc, pf = pf } }
end
--
local function category(colors, ss, tc, cat, no_error_cat)
	return mw.getCurrentFrame():expandTemplate{ title = 'Tincture/cat' .. ss, args = { table.concat(colors, '/'), tc = tc, cat = cat, ['no error cat'] = no_error_cat and '1' or nil } }
end

-- function returns contrast color
function p.titcolor ( frame )
	local gpar = frame.args
	decval =  convdec ( gpar[1] );
	return decval[4] 
end -- function titcolor 

-- function converts '#rrggbb' or '#rgb' and returns 'ddd ddd ddd'
function p.convhd (parm)
	local gpar = parm.args
	decval =  convdec ( gpar[1] );
	return decval[1]..' '..decval[2]..' '..decval[3]
end -- function convhd

-- function converts  'ddd ddd ddd and returns ''#rrggbb' (or '#rgb')
function p.convdh (parm)
	local gpar = parm.args -- separated by either pipe, space or comma 
	local dect = parm.args
	local hext = {}
	local numb = {}
	local same = true
	if gpar [2] == nil then 
		gpar[1] = mw.ustring.gsub (gpar[1], '-', '/', 3) -- split-pattern: REGEXP won't work
		gpar[1] = mw.ustring.gsub (gpar[1], ',', '/', 3)
		gpar[1] = mw.ustring.gsub (gpar[1], ' ', '/', 3)
		dect = mw.text.split(gpar[1] or '0 0 0', '/')
	end
	for i = 1, 3 do
		numb[i] = tonumber( dect[i] )
		if numb[i] == nil or numb[i] > 255 then
			error ('value "' .. dect[i] .. '" cannot be converted to hexadecimal')
--				..dect[1]..','..dect[2]..','..dect[3]..'.'..i)
		end
		hext[i] = dezhex (math.floor (numb[i] / 16) ) .. dezhex (math.floor (numb[i] % 16) )
		if string.byte ( hext [i], 1 )  ~= string.byte ( hext[i], 2 )  then
			same = false
		end
	end
	if same then 
		hext[1] = mw.ustring.sub (hext[1], 2)
		hext[2] = mw.ustring.sub (hext[2], 2)
		hext[3] = mw.ustring.sub (hext[3], 2)
	end
	return ' #'..hext[1]..hext[2]..hext[3]
end -- function convdh

-- function converts '#rrggbb' or '#rgb' to 'ddd ddd ddd'
function p.tinctgpl (parm)
	local gpar = parm.args
	decval =  convdec ( gpar[1] );
	local r = tostring (decval [1])
	local g = tostring (decval [2])
	local b = tostring (decval [3])
	local l = '' -- '{{#tag:span|&nbsp;&nbsp;&nbsp;&nbsp;|style="width:2en;background:'..gpar[1]..'"}}'
	local f = ''
	local x = ' '
    if decval[1] < 100 then 
    	r = "&nbsp;" .. r
    	if decval[1] < 10 then 
    		r = "&nbsp;" .. r
    	end
	end
    if decval[2] < 100 then 
    	g = "&nbsp;" .. g
    	if decval[2] < 10 then 
    		g = "&nbsp;" .. g
     	end
	end
      if decval[3] < 100 then 
    	b = "&nbsp;" .. b
    	if decval[3] < 10 then 
    		b = "&nbsp;" .. b
    	end
      end
--  checks the contrast color (000 or FFF) when any     
	if gpar[2] ~= nil and gpar[2] ~= decval[4] then f = '⋅' end
	if #gpar[1] == 4 then x = '&nbsp; &nbsp; ' end
	return ' '..r..' &nbsp;'..g..' &nbsp;'..b .. '&nbsp; &nbsp;'..l..gpar[1]..x..gpar[3]..f   
end -- function tinctgpl 



--  ============================================================================
--  main function tincture
function p.main (frame)
	local getArgs = require( 'Module:Arguments' ).getArgs
	local args = getArgs(frame)
	local ss = args.ss  or '0'
	if ss == '≈' then ss = '0' end
	local tc = args.tc
	local pf = args.pf
	local gt = args.gpltab or ""
	local align = 'tincturebox-left'
	local error_cat = true
	local InFi = (args['+'] == '+')
	local cols = args
	local colors = {}
	local box = {}
	local tab = {}
	local out = {}
	if gt == "" then 
		if mw.title.getCurrentTitle().namespace == 4 then gt = '3' 
		else gt = '1'
		end
	end
	if gt == "2" or gt == "3" then
		InFi = true
		error_cat = false
	end

	ss = mw.ustring.upper( ss )
	if type(args[1]) == 'string' and args[1]:sub(1, 6) == '<table' then
		return args[1]
	end

	if args[2] == nil  then
		cols = mw.text.split(args[1] or '', '%s*/%s*')
	end
	for _, v in ipairs(cols) do
		if not v or v == '' then
			break
		elseif v == '-' then
			error_cat = false
		elseif v == '+' then
			InFi = true
		else  --if mw.ustring.sub( v, 1, 3 ) ~= 'ss=' then
			table.insert(colors, v)
		end
	end
	
--  0) headline
	if gt == "2" or gt =="3" then
		table.insert(out, frame:expandTemplate{title='=', args={'<h4>GPLtab '..draw('gpltabnam',ss,'','','tab')..'</h4>'}})
	end

	for i, v in ipairs(colors) do
		box[i] = draw(v, ss, tc, pf, 'box')
	end

-- 1) cat
	if error_cat == true then
		table.insert(box, category(colors, ss, tc, args.cat, no_error_cat))
	end
	
-- 2) box
	if gt == "1" or gt =="3" then
		if args.align == 'right' or args.align == 'center' then
			align = 'tincturebox-' .. align
		end
		local frame = mw.getCurrentFrame()
		text = frame:extensionTag('templatestyles', '', { src = 'Tincture/styles.css' }) ..
			'<div class="tincturebox ' .. align .. '">' .. table.concat(box) .. '</div>'
		if InFi then
			local name = mw.getContentLanguage():ucfirst(frame:expandTemplate{ title = 'I18n/COA', args = { 'tincture' } })
			local link = ' ([[Template:Tincture/draw'..ss..'|'..ss..']])'
			if ss ~= '' and ss ~= '0' then name = name .. link end 
			table.insert(out, frame:expandTemplate{ title = 'InFi', args = { name, text } })
		else
			table.insert(out, text )
		end
	end
	
-- 3) tab
	if gt == "2" or gt =="3" then
		table.insert(out, frame:expandTemplate{ title = '=', args = { "&#35;<br>" } })
		for i, v in ipairs(colors) do
			table.insert(out, draw( v, ss, tc, pf, 'tab') )
		end
		table.insert(out, frame:expandTemplate{ title = '=', args = { "<br><br>" } })
	end
	return table.concat(out)
end -- function main / tincture 

return p;