Module:Tincture/sandbox
Jump to navigation
Jump to search
Lua
CodeDiscussionEditHistoryLinksLink count Subpages:DocumentationTestsResultsSandboxLive code All modules
Code
local p = {} -- Tincture
-------------- locals
local function draw(color, ss, tc, pf, gt)
if mw.title.new('Tincture/draw' .. ss,10).exists then
return mw.getCurrentFrame():expandTemplate{ title = 'Tincture/draw' .. ss, args = { color, gt, tc = tc, pf = pf } }
else
return '<strong><span style="color: red; text-decoration: inherit;">Bad color definition in [[Template:Tincture]]: '.. ss ..'</span></strong>'
end
end -- local function draw
--
local function sortc ( itab, otab, ccode )
local tinct = ccode;
if tinct == 'A' then tinct = 'a'; end -- in categories treat argent-dark like argent (2023-05-10)
if tinct == 'l'
and ss == 'CH' then tinct = 'b'; end --
for i, v in ipairs(itab) do
if v == ccode then
table.insert(otab, tinct)
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 paletcat(ss, cat)
return mw.getCurrentFrame():expandTemplate{ title = 'Tincture/catP', args = { ss, cat = cat } }
end -- local function p-category
--
local function pnotspec()
local exp = '';
if mw.ustring.lower(mw.ustring.sub(mw.title.getCurrentTitle().text,-4)) ~= '.svg' then
exp = '_(nonSVG)';
end
return mw.getCurrentFrame():expandTemplate{ title = 'Igen/cat', args = {'Tincture palette not specified'..exp } }
end -- local function pnotspec
--
local function defnonsvg()
return mw.getCurrentFrame():expandTemplate{ title = 'Igen/cat', args = {'Tinctures (Defined nonSVG)' } }
end -- local function defnonsvg
--
local function tnotspec()
local exp = '';
if mw.ustring.lower(mw.ustring.sub(mw.title.getCurrentTitle().text,-4)) ~= '.svg' then
exp = '_(nonSVG)';
end
-- return mw.getCurrentFrame():expandTemplate{ title = 'Igen/cat', args = {'Tinctures not specified'..exp } }
return mw.getCurrentFrame():expandTemplate{ title = 'Igen/cat', args = {'No tincture specified'..exp } }
end -- local function tnotspec
--
local function tsuppress()
local exp = '';
-- if mw.ustring.lower(mw.ustring.sub(mw.title.getCurrentTitle().text,-4)) ~= '.svg' then
-- exp = '_(nonSVG)';
-- end
return mw.getCurrentFrame():expandTemplate{ title = 'Igen/cat', args = {'Tincture categorizing suppressed'..exp } }
end -- local function t-suppress
--
local function tinc_cat(colors)
return mw.getCurrentFrame():expandTemplate{ title = 'Tincture/cat0', args = { table.concat(colors, '/') } }
end -- local function t-category
--
local function unab_cat(colors) -- colors for catsort ?
return mw.getCurrentFrame():expandTemplate{ title = 'Igen/cat', args = {'Tinctures uncategorizeable' } }
end -- local function unable to categorize
-- 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 function cats ( titl, outs, tinc )
if mw.ustring.find (titl, tinc .. ',')
or mw.ustring.find (titl, tinc .. ' ') then
outs = outs .. ', ' .. tinc;
end
return outs;
end -- local function cats
-------------------- 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
-- global 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 - does not work perfectly
-- 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 .. ' ' -- '{{mono|1= }}'
-- else expl = expl .. '·' -- '{{mono|1=·}}''
-- 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)
ss = args.ss or '0'
if ss == '≈' then ss = '0' end
local top = ''
if args.s == 'f' then top = 'flag ' end
local cm = args.cm or ' ';
local tc = args.tc
local pf = args.pf
local gt = args.gpltab or ""
local align = 'tincturebox-left'
local InFi = (args['+'] == '+')
local cols = args
local tincunt = 0;
local colors = {}
local box = {}
local tab = {}
local out = {}
local ordtab = { }
-- local ssytab = { ' ', } -- table of all palettes: catyes
-- local ssntab = { '0', } -- table of all palettes: catnot
local gpltab = false
local insert = false
local gennot = false -- generell = don't t-cat
local genyes = true -- generell = force t-cat
local catnot = false -- indiv. '-' = don't t-cat
local catyes = false -- indiv. '*' = force t-cat
local catimp = false -- indiv. '?' = not t-categorizeable
local nopcat = false -- indiv. '-' = don't p-cat
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
gpltab = true
end
if cols.ss then
ss = cols.ss
end
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 -- empty par
elseif v == '-' then
v = '0' -- t-cat suppression
catnot = true
elseif v == '~' then
v = '0' -- p-cat suppression
nopcat = true
elseif v == '*' then
v = '0' -- t-cat forcing
catyes = true
elseif v == '?' then
v = '0' -- not t-catable
catimp = true
elseif v == '+' then
InFi = true
elseif mw.ustring.sub( v, 1, 3 ) == 'ss=' then -- any case when ss=
ss = 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 -- tincture palette
else
table.insert(colors, v) -- it's a tincture
tincunt = tincunt + 1
end
end
ss = mw.ustring.upper( ss ) -- final formatting
---- general yes/not depending on ss
-- for i = 1, #ssytab do -- force the specified palette ?
-- if ss == ssytab [i] then genyes = true; end
-- end
-- for i = 1, #ssntab do -- exclude the specified palette ?
-- if ss == ssntab [i] then gennot = true; end
-- end
if args.el == "y" then gennot = true; end -- exclude coa elements
-- indiv. precedes gener.
if catnot == false then
if catyes == false then -- expl. indiv. "yes" ?
catnot = gennot
end
end
if catyes == false then
catyes = genyes
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) categories: p_cat, t_cat
if gpltab == false -- either palette or tincture
and args.ns == "6" then
if nopcat ~= true then -- when not suppressed:
if ss ~= '0' then -- Palette def (^GN)
table.insert(box, paletcat( ss, args.cat ))
if mw.ustring.lower(mw.ustring.sub(mw.title.getCurrentTitle().text,-4)) ~= '.svg' then
table.insert(box, defnonsvg() )
end
else -- Palette not specified
if args.el ~= "y"
and catimp == false
and tincunt ~= 0 then
table.insert(box, pnotspec() )
end
end
end
-- Tincture categorizaton
if catnot == true then -- suppressed ?
if args.el ~= "y" then -- when not an element
table.insert(box, tsuppress() ) -- categorization suppressed
end
else
if catimp == true then -- cat impossible ?
table.insert(box, unab_cat() ) -- categorizationt unable
elseif tincunt > 0 then -- sorted table
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, 'l' ) -- l-azure (CH)
insort = sortc (colors, ordtab, 'c' )
insort = sortc (colors, ordtab, 'C' )
insort = sortc (colors, ordtab, 'e' ) -- (h)ermine
insort = sortc (colors, ordtab, 'g' )
insort = sortc (colors, ordtab, 'm' ) -- multicolor
insort = sortc (colors, ordtab, 'n' )
insort = sortc (colors, ordtab, 'p' )
insort = sortc (colors, ordtab, 's' )
insort = sortc (colors, ordtab, 't' )
insort = sortc (colors, ordtab, 'T' )
insort = sortc (colors, ordtab, 'v' )
insort = sortc (colors, ordtab, 'V' ) -- vair, fur
insort = sortc (colors, ordtab, 'x' )
table.insert(box, tinc_cat(ordtab)) -- std tincture cat
else -- tincunt = zero:
table.insert(box, tnotspec() )
end -- catimp false & tincunt > 0
end -- catnot false
end -- gpltab false
-- 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) .. cm .. '</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
-- main function: create sorted tincture categories
function p.cstc (frame)
local titl = mw.ustring.lower( mw.title.getCurrentTitle().text )
local outs = ''
outs = cats (titl, outs, 'argent' )
outs = cats (titl, outs, 'argent-dark' )
outs = cats (titl, outs, 'or' )
outs = cats (titl, outs, 'azure' )
outs = cats (titl, outs, 'brunâtre' ) -- +
outs = cats (titl, outs, 'céleste' )
outs = cats (titl, outs, 'carnation' )
outs = cats (titl, outs, 'cendrée' )
outs = cats (titl, outs, 'ermine' )
outs = cats (titl, outs, 'gules' )
-- outs = cats (titl, outs, 'multiple' )
outs = cats (titl, outs, 'murrey' ) -- +
outs = cats (titl, outs, 'naranja' )
outs = cats (titl, outs, 'orange_t' ) -- + +
outs = cats (titl, outs, 'purpure' )
outs = cats (titl, outs, 'sable' )
outs = cats (titl, outs, 'sanguine' ) -- +
-- outs = cats (titl, outs, 'tawny' ) -- +?
outs = cats (titl, outs, 'tenné' )
outs = cats (titl, outs, 'vert' )
outs = cats (titl, outs, 'vair' )
outs = cats (titl, outs, 'invisible' )
outs = mw.ustring.upper( mw.ustring.sub( outs, 3, 3 ) ) .. mw.ustring.sub( outs, 4 ) .. ' in heraldry'
if mw.ustring.gsub( outs, ', ', '? ' ) == mw.ustring.gsub( outs, ', ', '? ', 1 ) then
outs = mw.ustring.gsub( outs, ', ', ' and ' ); -- "and" when only two colors
end
return outs
end -- cstc
return p;