Difference between revisions of "Module:Tincture"
Jump to navigation
Jump to search
Mediawiki>Sarang m (+parm) |
m (1 revision imported) |
Latest revision as of 07:59, 24 January 2022
Documentation for this module may be created at Module:Tincture/doc
local p = {} -- Tincture
-------------- locals
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 draw
--
local function sortc ( itab, otab, ccode )
for i, v in ipairs(itab) do
if v == ccode then
table.insert(otab, v)
return true
end
end
return false
end -- local function sortc
--
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 -- local function category
-- local function: converts 'ddd ddd ddd' to '#rrggbb' (or '#rgb')
local function convdh ( p1, p2, p3 )
local lpar = {}; -- separated by either pipe, slash, minus, comma or space
local dect = {}
local hext = {}
local numb = {}
local same = true
lpar [1] = mw.text.trim ( p1 );
if p3 == nil then -- split-pattern: REGEXP won't work
if p2 ~= nil then
lpar[1] = lpar[1] .. '-' .. mw.text.trim(p2)
end
lpar[1] = mw.ustring.gsub (lpar[1], '-', '/', 3)
lpar[1] = mw.ustring.gsub (lpar[1], ',', '/', 3)
lpar[1] = mw.ustring.gsub (lpar[1], ' ', '/', 3)
dect = mw.text.split(lpar[1] or '1/2/3', '/');
else
lpar [2] = mw.text.trim ( p2 );
lpar [3] = mw.text.trim ( p3 );
dect = lpar;
end
for i = 1, 3 do
numb[i] = tonumber( dect[i] )
if numb[i] == nil or numb[i] > 255 then
error (i .. 'value "' .. dect[i] or '?' .. '" cannot be converted to hexadecimal')
-- ..dect[1]..','..dect[2]..','..dect[3]..'.'..i)
end
hext [i] = mw.ustring.format ( "%X", numb[i] )
if numb[i] < 16 then hext[i] = '0' .. hext[i] end;
if mw.ustring.byte ( hext [i], 1 ) ~= mw.ustring.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 -- local function convdh
-------------------- local / global ----------``-------------------------------
-- local / global function: converts h → d: #rrggbb or #rgb to table {rr, gg, bb}
function p.convht ( frame )
local gpar = {};
local hexv = nil;
local hexi = '000';
local hwxt = '0';
local gpar = frame.args;
if gpar then
hexv = tostring (gpar[1]); -- global
else
hexv = tostring ( frame ); -- local
end
hexv = mw.text.trim( hexv )
if mw.ustring.sub ( hexv, 1, 1 ) == '#' then
hexi = mw.ustring.sub (hexv, 2)
hext = '1'
elseif mw.ustring.sub ( hexv, 1, 3) == '\\35' then
hexi = mw.ustring.sub (hexv, 4)
hext = '2'
elseif mw.ustring.sub ( hexv, 1, 5) == '#' then
hexi = mw.ustring.sub (hexv, 6)
hext = '3'
elseif mw.ustring.sub ( hexv, 1, 6) == '#' then
hexi = mw.ustring.sub (hexv, 7)
hext = '4'
elseif mw.ustring.sub ( hexv, 1, 6) == '#' then
hexi = mw.ustring.sub (hexv, 7, #hexv)
hext = '5'
elseif mw.ustring.sub ( hexv, 1, 7) == '#' then
hexi = mw.ustring.sub (hexv, 8, #hexv)
hext = '6'
else
hext = '9'
error ('value "' .. hexv .. '" cannot be converted to decimal ' .. #hexv )
end
if #hexi ~= 3 and #hexi ~= 6 then
error ('value "' .. hexi .. '" with length ' .. #hexi .. ' are invalid' )
end
-- error ('value "' .. hexv .. '" type ' .. hext .. ' = ' .. hexi)
local dec = {};
for i = 1, 3 do
if #hexi == 3 then
dec [i] = tonumber ( mw.ustring.sub (hexi, i, i)..mw.ustring.sub (hexi, i, i), 16 )
else
dec [i] = tonumber ( mw.ustring.sub (hexi, 2*i - 1, 2*i), 16 )
end
end
return dec;
end -- function convht
-- local / global function: converts h ← d '#rrggbb' or '#rgb' and returns 'ddd ddd ddd'
function p.convhd ( frame )
local gpar = frame.args;
if gpar then decval = p.convht (gpar[1]); -- global
else decval = p.convht ( frame ); -- local
end
return decval[1]..' '..decval[2]..' '..decval[3]
end -- function convhd
-- local / global function: converts h → d'#rrggbb' or '#rgb' and returns 'ddd ddd ddd' formatted
function p.convhdf ( frame )
local gpar = frame.args;
if gpar then dtab = p.convht (gpar[1]); -- global
else dtab = p.convht ( frame ); -- local
end
local dtxt = ' '
for i = 1, 3 do
if dtab[i] < 100 then
if dtab[i] < 10 then
dtxt = dtxt .. ' '
end
dtxt = dtxt .. ' '
end
dtxt = dtxt .. ' ' .. tostring ( dtab [i] )
end
local contrast = '0';
if dtab [1] + dtab [2] + dtab [3] < 400 then
contrast = 'F';
end
-- TEST ----------
-- local contval = dtab [1] + dtab [2] + dtab [3]
-- contrast = contrast .. ' - ';
-- if contval < 100 then
-- if contval < 10 then
-- contrast = contrast .. ' '
-- end
-- contrast = contrast .. ' '
-- end
-- contrast = contrast .. tostring ( contval );
-- TEST ----------
dtxt = contrast .. dtxt;
return dtxt
end -- function convhdf
-- function returns contrast color
function p.titcolor ( frame )
local gpar = frame.args
local decval = p.convhdf ( gpar[1] );
if mw.ustring.sub ( decval, 1, 1 ) == 'F'
then return 'FFF'
else return '000'
end
end -- function titcolor
-- global function tbcbox: returns a Tbc box
function p.tbcbox ( frame )
local gpar = frame.args
local hstr = convdh ( gpar[1], gpar[2], gpar[3] )
return frame:expandTemplate { title = 'colorbox', args = { hstr, title = '"' .. hstr ..'"' } }
end -- function tbxbox
-- global function convgpl: gets #rgb, contrast, name; returns line formatted
function p.convgpl ( frame )
local gpar = frame.args;
local line = p.convhdf ( gpar [1] ); -- convert #rgb
local expl = mw.ustring.sub ( line, 2) .. ' ' .. gpar [1]; -- d d d #rgb
if #gpar[1] == 4 then
expl = expl .. ' '
end
local contrast = gpar [2] or '#001'
-- expl = expl .. ' ' .. contrast; -- contrast -test
if mw.ustring.sub ( contrast, 2, 2) == mw.ustring.sub ( line, 1, 1)
then expl = expl .. '<tt> </tt>'
else expl = expl .. '<tt>·</tt>'
end
expl = expl .. gpar [3]; -- name
return expl
end -- function convgpl
-- global function convert: gets 3 num, returns hex and dec formatted
function p.convert ( frame )
local gpar = frame.args;
local hcod = convdh ( gpar[1], gpar[2], gpar[3] );
local fnum = p.convhdf (hcod)
return '#' .. mw.ustring.sub ( hcod, 2 ) .. mw.ustring.sub ( fnum, 2);
end -- function convert
-- ============================================================================
-- 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 top = ''
if args.s == 'f' then top = 'flag ' 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 = {}
local ordtab = { }
local insert = false
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
if cols.ss then
ss = mw.ustring.upper( cols.ss )
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
elseif mw.ustring.sub( v, 1, 3 ) == 'ss=' then -- any case when ss=
ss = mw.ustring.upper( mw.ustring.sub( v, 4 ) )
elseif mw.ustring.len( v ) == 2
and v == mw.ustring.upper( v ) then -- belongs to character class %u
ss = v
else
table.insert(colors, v)
end
end
-- 0) headline and boxes
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: sorted table
if error_cat == true then
insort = sortc (colors, ordtab, 'a' )
insort = sortc (colors, ordtab, 'A' )
insort = sortc (colors, ordtab, 'o' )
insort = sortc (colors, ordtab, 'b' )
insort = sortc (colors, ordtab, 'B' )
insort = sortc (colors, ordtab, 'c' )
insort = sortc (colors, ordtab, 'C' )
insort = sortc (colors, ordtab, 'g' )
insort = sortc (colors, ordtab, 'n' )
insort = sortc (colors, ordtab, 'p' )
insort = sortc (colors, ordtab, 's' )
insort = sortc (colors, ordtab, 't' )
insort = sortc (colors, ordtab, 'v' )
insort = sortc (colors, ordtab, 'x' )
table.insert(box, category(ordtab, 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 = { top .. 'tincture' } })
local link = ' <small>([[Template:Tincture/draw'..ss..'|'..ss..']])</small>'
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 = { "#<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;