Module:Iteration: Difference between revisions
From Neodyland Wiki
More actions
m odd number problem |
m Protected "Module:Iteration": Widely used Lua-module ([Edit=Allow only template editors and administrators] (indefinite) [Move=Allow only template editors and administrators] (indefinite)) |
||
| (114 intermediate revisions by 6 users not shown) | |||
| Line 1: | Line 1: | ||
-- | -- This module contains the functions for different templates, solving their iteration problems. | ||
local max = math.max | |||
local len = string.len | |||
local sub = string.sub | |||
local find = string.find | |||
local format = string.format | |||
local insert = table.insert | |||
local concat = table.concat | |||
local trim = mw.text.trim | |||
local split = mw.text.split | |||
local titleNew = mw.title.new | |||
local char = mw.ustring.char | |||
local NL = char(10) | |||
local lower = mw.ustring.lower | |||
local upper = mw.ustring.upper | |||
local gsub = mw.ustring.gsub | |||
local Usub = mw.ustring.sub | |||
local function Ucfirst(text) | |||
text = trim(text) | |||
return upper(Usub(text, 1, 1)) .. Usub(text, 2) | |||
end | |||
---------------------------------------------------------------------------------------------- | |||
-- Template expansion helpers for performance: | |||
-- Saves CPU and time resources on large iterations by minimizing repeated recursive calls to | |||
-- the parser, eliminating many table constructions/deletion/lookups in memory. Also allows | |||
-- reporting CPU/time usage for expansions of costly templates inside recursive calls | |||
-- (otherwise all CPU/time is counted inside Lua, those templates are not counted). | |||
local currentTitle = mw.title.getCurrentTitle() | |||
local currentNs = tonumber(currentTitle.namespace) | |||
local currentPage = currentTitle.text | |||
local | local frameCurrent = mw.getCurrentFrame() | ||
local expandTemplateCurrent = frameCurrent.expandTemplate | |||
local callParserFunctionCurrent = frameCurrent.callParserFunction | |||
local contentLanguage = mw.language.getContentLanguage() | |||
local langDefault = contentLanguage:getCode() | |||
local langUser = lower(trim(callParserFunctionCurrent(frameCurrent, 'Int', 'Lang'))) | |||
local transclude = {} | |||
function | local function expand(template, args) | ||
transclude.title = template | |||
local | transclude.args = args or {} | ||
return expandTemplateCurrent(frameCurrent, transclude) | |||
end | |||
local argsOne = {} | |||
local function expand1(title, arg1) | |||
argsOne[1] = arg1 | |||
return expand(title, argsOne) | |||
end | |||
local argsLangUser = { lang = langUser } | |||
local argsLangDefault = { lang = langDefault } | |||
local argsLangOther = {} | |||
local function expandWithLang(template, lang) | |||
if type(lang) == 'string' then | |||
lang = trim(lang) | |||
if lang == '' then | |||
lang = nil | |||
else | |||
lang = lower(lang) | |||
end | |||
else | |||
lang = nil | |||
end | |||
if not lang or lang == langUser then | |||
return expand(template, argsLangUser) | |||
elseif lang == langDefault then | |||
return expand(template, argsLangDefault) | |||
else | |||
argsLangOther.lang = lang | |||
return expand(template, argsLangOther) | |||
end | |||
end | |||
local Comma, ConjAnd | |||
local function commaAnd(isLast) | |||
if isLast then | |||
if not ConjAnd then | |||
ConjAnd = expand('Conj-and', argsLangUser) | |||
end | |||
return ConjAnd | |||
else | |||
if not Comma then | |||
Comma = expand('Comma', argsLangUser) | |||
end | |||
return Comma | |||
end | end | ||
end | end | ||
-- for Template: | ---------------------------------------------------------------------------------------------- | ||
local p = {} | |||
local | -- For Template:Ifim. | ||
local argsIfim1 = { -- Parameters for expanding 'Template:Ifim1'. | |||
'', -- [1] = v | |||
'', -- [2] = trim(ppar.p1 or ''), | |||
for _, v in ipairs( | '', -- [3] = trim(ppar.p2 or ''), | ||
'', -- [4] = trim(ppar.p3 or ''), | |||
'', -- [5] = trim(ppar.p4 or ''), | |||
'', -- [6] = trim(ppar.p5 or ''), | |||
n = '' -- ['n'] = trim(ppar.fn or ''), | |||
} | |||
function p.ifim1(frame) | |||
local ppar = frameCurrent:getParent().args | |||
argsIfim1[2] = trim(ppar.p1 or '') | |||
argsIfim1[3] = trim(ppar.p2 or '') | |||
argsIfim1[4] = trim(ppar.p3 or '') | |||
argsIfim1[5] = trim(ppar.p4 or '') | |||
argsIfim1[6] = trim(ppar.p5 or '') | |||
argsIfim1.n = trim(ppar.fn or '') | |||
local results = {} | |||
for _, v in ipairs(ppar) do | |||
argsIfim1[1] = v | |||
insert(results, expand('Ifim1', argsIfim1)) | |||
end | |||
return concat(results) | |||
end -- function ifim | |||
-- For Template:Ifimc. | |||
local argsIfim2 = { -- Parameters for expanding 'Template:Ifim2'. | |||
'', -- [1] = v1 | |||
'', -- [2] = trim(ppar.p1 or ''), | |||
'', -- [3] = trim(ppar.p2 or ''), | |||
'', -- [4] = trim(ppar.p3 or ''), | |||
'', -- [5] = trim(ppar.p4 or ''), | |||
'', -- [6] = v | |||
} | |||
function p.ifim2(frame) | |||
local ppar = frameCurrent:getParent().args | |||
argsIfim2[2] = trim(ppar.p1 or '') | |||
argsIfim2[3] = trim(ppar.p2 or '') | |||
argsIfim2[4] = trim(ppar.p3 or '') | |||
argsIfim2[5] = trim(ppar.p4 or '') | |||
local results = {} | |||
for _, v in ipairs(ppar) do | |||
argsIfim2[1] = v | |||
argsIfim2[6] = v | |||
insert(results, expand('Ifim2', argsIfim2)) | |||
end | end | ||
return | return concat(results) | ||
end | end -- function ifim2 | ||
-- | -- For Template:Ifimt (param pairs). | ||
function p.ifimt (frame) | function p.ifimt(frame) | ||
local | local ppar = frameCurrent:getParent().args | ||
argsIfim2[2] = trim(ppar.p1 or '') | |||
argsIfim2[3] = trim(ppar.p2 or '') | |||
argsIfim2[4] = trim(ppar.p3 or '') | |||
argsIfim2[5] = trim(ppar.p4 or '') | |||
local | local v1 = '' | ||
local | local results = {} | ||
for _, v in ipairs( | for _, v in ipairs(ppar) do | ||
if v1 == | if v1 == '' then | ||
v1 = | v1 = v | ||
else | else | ||
argsIfim2[1] = v1 | |||
v1 = | argsIfim2[6] = v | ||
insert(results, expand('Ifim2', argsIfim2)) | |||
v1 = '' | |||
end | end | ||
end | end | ||
return | if v1 ~= '' then | ||
end | argsIfim2[6] = '' | ||
insert(results, expand('Ifim2', argsIfim2)) -- Last item. | |||
end | |||
return concat(results) | |||
end -- function ifimt | |||
------------------------------------------------------- | ------------------------------------------------------- | ||
-- Helper function for: ownbased, and filelist | |||
local function samefile(filename, num, first) | |||
local filename = trim(filename or '') | |||
if sub(filename, 1, 1) == '.' then | |||
local part = 'Example' -- default filename | |||
if currentNs == 6 or currentNs == 7 then | |||
part = split(currentPage , '.', true) | |||
part = concat(part, '.', 1, math.max(#part - 1, 1)) | |||
end | |||
-- Supported short aliases: | |||
if filename == '.' then filename = part .. '.png' | |||
elseif filename == '.p' then filename = part .. '.png' | |||
elseif filename == '.g' then filename = part .. '.gif' | |||
elseif filename == '.j' then filename = part .. '.jpg' | |||
elseif filename == '.s' then filename = part .. '.svg' | |||
-- Exotics: | |||
elseif filename == '.m' then filename = part .. '.mid' | |||
elseif filename == '.o' then filename = part .. '.ogg' | |||
elseif filename == '.t' then filename = part .. '.tif' | |||
elseif filename == '.v' then filename = part .. '.wav' | |||
elseif filename == '.x' then filename = part .. '.xcf' | |||
-- Note: no "short alias" for '.pdf' ('.p' already used for '.png') | |||
-- Note: short aliases for a few longer extensions: | |||
elseif filename == '.d' then filename = part .. '.djvu' | |||
elseif filename == '.w' then filename = part .. '.webp' | |||
else filename = part .. filename | |||
end | |||
elseif filename == '' or filename == '*' then | |||
if tonumber(num) == 1 then | |||
filename = 'Example.svg' | |||
if currentNs == 6 or currentNs == 7 then | |||
filename = currentPage | |||
end | |||
else | |||
filename = trim(first) | |||
if filename == '' or filename == '*' or sub(filename, 1, 1) == '.' then | |||
filename = 'Example.svg' | |||
if currentNs == 6 or currentNs == 7 then | |||
filename = currentPage | |||
end | |||
end | |||
end | |||
end | |||
return filename | |||
end -- function samefile | |||
-- | ---++++++++++++++++++++++++++++++++++++++++++++++++++++ | ||
function p. | |||
local args = | -- Simple iterations - without many params. | ||
local | function p.iterate(frame) | ||
local gpar = frame.args -- global parms | |||
for _, v in ipairs( | local template = gpar[1] or '' -- template name | ||
local args = { -- Parameters for expanding the given template. | |||
'', -- [1] = v | |||
gpar[2] or '', | |||
gpar[3] or '', | |||
} | |||
local ppar = frameCurrent:getParent().args | |||
local results = {} | |||
for _, v in ipairs(ppar) do | |||
args[1] = v | |||
insert(results, expand(template, args)) | |||
end | end | ||
return | return concat(results) | ||
end | end -- function iterate | ||
-- for | -- More iterations - for params, param pairs, or n-tuples. | ||
function p. | function p.iteration(frame) | ||
local | local gpar = frame.args -- Global parms. | ||
local | local vmax = tonumber(gpar.n) or 2 -- Tuple number (default = 2). | ||
local vnum = vmax + 1 -- Additional not-changing params. | |||
local | local template = '' -- Template name. | ||
local | local args = {} -- Parameters for expanding the given template. | ||
local | for i, p in ipairs(gpar) do | ||
p = trim(p) | |||
if i == 1 then | |||
for i, | template = p | ||
else | |||
args[vnum] = p | |||
vnum = vnum + 1 | |||
end | |||
end | end | ||
for | vnum = 1 | ||
local ppar = frameCurrent:getParent().args | |||
local results = {} -- output | |||
if | for _, v in ipairs(ppar) do | ||
args[vnum] = trim(v) | |||
vnum = vnum + 1 | |||
if vnum > vmax then | |||
insert(results, expand(template, args)) | |||
vnum = 1 | |||
end | |||
end | |||
return concat(results) | |||
end -- function iteration | |||
-- For different templates, for general use, e.g. Emoji. | |||
function p.parlst(frame) | |||
local gpar = frame.args -- Global parameters. | |||
local template = trim(gpar.temp or '') | |||
local results = {} | |||
if template ~= '' then -- Slow expansion (e.g. for template = 'Emoji', which will recurse into iterations calling p.emodis) | |||
local ff = trim(gpar.ff or '') -- Inbetween? | |||
if ff ~= '' then | |||
ff = expand1(ff, trim(gpar.pf or '')) | |||
else | else | ||
ff = nil | |||
end | |||
local nocat = trim(gpar.nocat or '') | |||
local args = { -- Parameters for expanding the given template. | |||
nocat = nocat ~= '' and nocat or nil | |||
} | |||
for k, v in pairs(gpar) do | |||
v = trim(v) | |||
if v ~= '' then args[k] = v end | |||
end | end | ||
if | local count = tonumber(args[1] or '') or 0 | ||
for i = 1, (count or 1) do -- default: go 1× for nil | |||
if ff then insert(results, ff) end | |||
if count then args[1] = i - 1 end | |||
insert(results, expand(template, args)) | |||
end | |||
else -- Template expansion not needed (much faster, without recursed iterations calling p.emodis from a specified template). | |||
local count = tonumber(gpar[1] or '') or 0 | |||
local code = tonumber(gpar[2] or '', 16) or 0 | |||
local catlink = gpar.catlink or '' | |||
if catlink == '' then | |||
local args = { | |||
'<span title="U+', | |||
'', -- [2] = format('%04X', code + i - 1) | |||
'">', | |||
'', -- [4] = char(code + i - 1) | |||
'</span>', | |||
} | |||
for i = 1, count do | |||
args[2] = format('%04X', code + i - 1) | |||
args[4] = char(code + i - 1) | |||
insert(results, concat(args)) | |||
end | |||
elseif catlink == 'U' then | |||
local args = { | |||
'[[:Category:U+', | |||
'', -- [2] = format('%04X', code + i - 1) | |||
'|<span title="U+', | |||
'', -- [4] = format('%04X', code + i - 1) | |||
'">', | |||
'', -- [6] = char(code + i - 1) | |||
'</span>]]', | |||
} | |||
for i = 1, count do | |||
args[2] = format('%04X', code + i - 1) | |||
args[4] = args[2] | |||
args[6] = char(code + i - 1) | |||
insert(results, concat(args)) | |||
end | |||
else | |||
local args = { | |||
'[[:Category:', | |||
'', -- [2] = char(code + i - 1) | |||
'|<span title="U+', | |||
'', -- [4] = format('%04X', code + i - 1) | |||
'">', | |||
'', -- [6] = char(code + i - 1) | |||
'</span>]]', | |||
} | |||
for i = 1, count do | |||
args[2] = char(code + i - 1) | |||
args[4] = format('%04X', code + i - 1) | |||
args[6] = args[2] | |||
insert(results, concat(args)) | |||
end | |||
end | end | ||
end | end | ||
return concat(results) | |||
end -- function parlst | |||
-- Global function for one filename. | |||
function p.filename(frame) | |||
local gpar = frame.args -- Global parameters. | |||
return samefile(trim(gpar[1] or ''), 1) | |||
end -- function filename | |||
-- | -- For Template:Own based (one filename which is '.'). | ||
function p. | function p.ownbasby(frame) | ||
local args = | local gpar = frame.args -- Global parameters. | ||
local otab = {} | return expand('F', { | ||
local | samefile(gpar[1] or '.', 1), | ||
by = trim(gpar[2] or '') | |||
}) | |||
end -- function ownbasby | |||
-- For Template:Own based (horizontal - but vertical when "b1="). | |||
function p.ownbased(frame) | |||
local ppar = frameCurrent:getParent().args | |||
local by0 = trim(ppar.b or ppar.by or ppar.u or ppar.user or '') | |||
local dis = trim(ppar.d or ppar.dis or ppar.display or '') | |||
local hil = trim(ppar.h or ppar.hilite or '') | |||
local lng = trim(ppar.i or ppar.lang or '') | |||
local wik = trim(ppar.l or ppar.w or ppar.wiki or '') | |||
local nam = trim(ppar.n or ppar.name or '') | |||
local opt = trim(ppar.o or ppar.opt or ppar.option or '') | |||
local mod = trim(ppar.m or ppar.mod or '') | |||
local pr4 = trim(ppar.par4 or ppar.qpar or '') | |||
local pr5 = trim(ppar.par5 or ppar.rpar or '') | |||
local btab = {} | |||
local dtab = {} | |||
local htab = {} | |||
local itab = {} | |||
local ltab = {} | |||
local ntab = {} | |||
local otab = {} | |||
local qtab = {} | |||
local rtab = {} | local rtab = {} | ||
local | local ttab = {} | ||
local | local utab = {} | ||
local | local x = 0 -- running index, can be ~= i | ||
local fst = 0 -- first occurrence | |||
local cor = 0 | |||
local | local max = 0 | ||
local | local plus = '' | ||
local | for i, v in ipairs(ppar) do | ||
for | if v == '+' then | ||
plus = '+' | |||
-- | elseif v == '-' then | ||
-- | if plus == '' then plus = '-' end | ||
else | |||
x = x + 1 | |||
if fst == 0 then fst = x end | |||
local z = tostring(x) | |||
btab[x] = trim(ppar['b' .. z] or ppar['by' .. z] or ppar['u' .. z] or '-') | |||
dtab[x] = trim(ppar['d' .. z] or '-') | |||
htab[x] = trim(ppar['h' .. z] or '-') | |||
itab[x] = trim(ppar['i' .. z] or '-') | |||
ltab[x] = trim(ppar['l' .. z] or ppar['w' .. z] or '-') | |||
ntab[x] = trim(ppar['n' .. z] or '-') | |||
otab[x] = trim(ppar['o' .. z] or '-') | |||
qtab[x] = trim(ppar['q' .. z] or '-') | |||
rtab[x] = trim(ppar['r' .. z] or '-') | |||
ttab[x] = trim(ppar['t' .. z] or '-') | |||
utab[x] = trim(ppar['m' .. z] or '-') | |||
end | |||
max = x | |||
if v == 'x' or v == 'X' or v == '×' then | |||
cor = cor + 1 | |||
end | |||
end -- for | |||
x = 0 | |||
if fst > 0 then | |||
local mnm = trim(ppar[fst]) | |||
end | |||
local hls = { | |||
'<', | |||
'', -- [2] = hl | |||
'>', | |||
'', -- [4] = (nm ~= '') and nm or vv | |||
'</', | |||
'', -- [6] = hl | |||
'>', | |||
} | |||
local args = { -- Parameters for expanding 'Template:F'. | |||
'', -- [1] = vv, | |||
'', -- [2] = nm | |||
'', -- [3] = ds | |||
'', -- [4] = op | |||
'', -- [5] = p4 | |||
'', -- [6] = p5 | |||
plus, | |||
l = '', -- ['l'] = il | |||
lang = '', -- ['lang'] = lg | |||
p = '', -- ['p'] = px | |||
by = '', -- ['by'] = by | |||
u = '', -- ['u'] = um | |||
} | |||
local results = {} | |||
for _, v in ipairs(ppar) do | |||
if v ~= '+' and v ~= '-' then | |||
x = x + 1 | |||
local by = btab[x] ~= '-' and btab[x] or by0 | |||
local ds = dtab[x] ~= '-' and dtab[x] or dis | |||
local hl = htab[x] ~= '-' and htab[x] or hil | |||
local il = ltab[x] ~= '-' and ltab[x] or wik | |||
local lg = itab[x] ~= '-' and itab[x] or lng | |||
local op = otab[x] ~= '-' and otab[x] or opt | |||
local p4 = qtab[x] ~= '-' and qtab[x] or pr4 | |||
local p5 = rtab[x] ~= '-' and rtab[x] or pr5 | |||
local um = utab[x] ~= '-' and utab[x] or mod | |||
local nm = ntab[x] ~= '-' and ntab[x] or '' | |||
local tx = ttab[x] ~= '-' and ttab[x] or '' | |||
local vv = trim(v) | |||
if find(vv, '/') == nil then | |||
vv = samefile(vv, x, mnm) | |||
if x == 1 then mnm = vv end | |||
end | |||
if vv ~= '' and vv ~= '×' then | |||
local px = '' | |||
if ppar.b1 == nil then -- parameter missing | |||
if x == 1 then | |||
px = ' ' | |||
else | |||
insert(results, commaAnd(x == max)) | |||
end | |||
else -- ppar.b1 is defined (with value, or empty) | |||
px = '<br /> <span style=color:#69F>✦ </span>' -- "list" item | |||
end | |||
if sub(ds, -2) == 'px' then | |||
ds = sub(ds, 1, -3) | |||
end | |||
if nm == '' and x == 1 then | |||
nm = nam | |||
end | |||
if hl ~= '' then | |||
hls[2] = hl | |||
hls[4] = (nm ~= '') and nm or vv | |||
hls[6] = hl | |||
nm = concat(hls) | |||
end | |||
-- if il ~= '' then ds = '' end -- ? (discrepancy) | |||
if vv == 'x' then ds = '' end -- this should be the last "file" | |||
if by == '' then -- check for abbreviating '/' | |||
local sby = find(vv, '/') | |||
if sby ~= nil then | |||
by = sub(vv, sby + 1) | |||
vv = sub(vv, 1, sby - 1) | |||
vv = samefile(vv, x, mnm) | |||
if x == 1 then mnm = vv end | |||
end | |||
end | |||
args[1] = vv | |||
args[2] = nm | |||
args[3] = ds | |||
args[4] = op | |||
args[5] = p4 | |||
args[6] = p5 | |||
args.l = il | |||
args.lang = lg | |||
args.p = px | |||
args.by = by | |||
args.u = um | |||
insert(results, expand('F', args)) | |||
if tx ~= '' then | |||
insert(results, expand1('=', tx)) | |||
end | |||
end | |||
end | |||
end -- for | |||
if max - cor > 9 then | |||
insert(results, expand1('Igen/cat', 'Own-based with more than 9 files|' .. max)) | |||
end | |||
return concat(results) | |||
end -- function ownbased | |||
-- Horizontal file list for: Template:SVG lang, Template:Lang gallery, and others. | |||
function p.svglang(frame) | |||
local gpar = frame.args -- Global parameters. | |||
local template = gpar[1] or 'Source thumb' -- 'SVG lang', 'Lang gallery/thumb' | |||
local ppar = frameCurrent:getParent().args | |||
args = { -- Parameters to expand the given template. | |||
trim(ppar.file or ''), | |||
'', -- [2] = lang | |||
p = trim(ppar.p or ''), | |||
} | |||
local results = {} | |||
for _, v in ipairs(ppar) do | |||
local lang = trim(v) | |||
if lang > ' ' then | |||
args[2] = lang | |||
insert(results, trim(expand(template, args))) | |||
insert(results, NL) | |||
end | |||
end | end | ||
-- | return concat(results) | ||
if | end -- function svglang | ||
-- Elements count for: Template:SVG lang, Template:Lang gallery, and others. | |||
function p.elemct (frame) | |||
local ppar = frameCurrent:getParent().args | |||
local count = 0 | |||
for _, v in ipairs(ppar) do | |||
if trim(v) ~= '' then | |||
count = count + 1 | |||
end | |||
end | end | ||
-- | return count | ||
end -- function elemct | |||
-- Horizontal file list for: Template:Filelist, Template:File. | |||
-- Vertical file list for: Template:Other versions, Template:Derived from, Template:Derivative versions. | |||
function p.filelist(frame) | |||
local gpar = frame.args -- Global parameters. | |||
local ppar = frameCurrent:getParent().args | |||
local spa = trim(ppar.spa or ppar.s or '-') | |||
local pfx = trim(ppar.x or ppar.pfx or ppar.prefix or '') -- "List" item {{Comma}} | |||
local dir = gpar[1] or 'none' | |||
if dir == 'vert' and pfx == '' then | |||
pfx = '\n* ' -- "list" item | |||
end | |||
local nam = trim(ppar.n or ppar.name or '') | |||
local dis = trim(ppar.d or ppar.z or ppar.dis or ppar.display or '') | |||
if sub(dis, -2) == 'px' then dis = sub(dis, 1, -3) end | |||
local opt = trim(ppar.o or ppar.opt or ppar.option or '') | |||
local pr4 = trim(ppar.par4 or ppar.qpar or '') | |||
local pr5 = trim(ppar.par5 or ppar.rpar or '') | |||
local pr6 = trim(ppar.par6 or ppar.vpar or '') | |||
local wik = trim(ppar.w or ppar.k or ppar.wiki or ppar.sisterproject or '') | |||
local int = trim(ppar.i or ppar.int or ppar.ind or ppar.inter or '') | |||
local pre = trim(ppar.p or ppar.pre or ppar.pretext or '') | |||
local by0 = trim(ppar.user or ppar.by or '') | |||
local mod = trim(ppar.m or ppar.mod or '') | |||
local lnk = trim(ppar.l or ppar.lnk or ppar.link or '') | |||
local con = trim(ppar.conj or ppar.con or ppar.c or '') | |||
con = sub(con, 1, 1) | |||
if ppar.z then | |||
if con == '' then con = 'n' end | |||
if opt == '' then opt = 'Z' end | |||
if pre == '' then pre = ' ' end | |||
end | |||
local vary = trim(ppar.vary or ppar.v or '') -- Variable pattern | |||
local var1 = trim(ppar.var1 or ppar.v1 or '') -- Variable filling space before | |||
local var2 = trim(ppar.var2 or ppar.v2 or '') -- Variable filling space after | |||
local replacement = { | |||
(var1 == 'space') and ' ' or var1, | |||
'', -- [2] = (sp == '+' and ' ' or '') | |||
'', -- [3] = vv | |||
(var2 == 'space') and ' ' or var2, | |||
} | |||
local stab = {} | |||
local xtab = {} | |||
local ntab = {} | |||
local dtab = {} | |||
local otab = {} | |||
local qtab = {} | |||
local rtab = {} | |||
local vtab = {} | |||
local ktab = {} | |||
local itab = {} | |||
local ptab = {} | |||
local btab = {} | |||
local utab = {} | |||
local ltab = {} | |||
local ttab = {} | |||
local loop = {} | |||
local mnum = 0 -- maximum index reached in the previous tables of indexed parameters | |||
for i, v in ipairs(ppar) do | |||
local z = tostring(i) | |||
stab[i] = trim(ppar['s' .. z] or '~') | |||
xtab[i] = trim(ppar['x' .. z] or '-') | |||
ntab[i] = trim(ppar['n' .. z] or ppar['l' .. z] or '-') | |||
dtab[i] = trim(ppar['d' .. z] or '-') | |||
otab[i] = trim(ppar['o' .. z] or '-') | |||
qtab[i] = trim(ppar['q' .. z] or '-') | |||
rtab[i] = trim(ppar['r' .. z] or '-') | |||
vtab[i] = trim(ppar['v' .. z] or '-') | |||
ktab[i] = trim(ppar['k' .. z] or '-') | |||
itab[i] = trim(ppar['i' .. z] or '-') | |||
ptab[i] = trim(ppar['p' .. z] or '-') | |||
btab[i] = trim(ppar['b' .. z] or ppar['by' .. z] or '-') | |||
utab[i] = trim(ppar['m' .. z] or '-') | |||
ltab[i] = trim(ppar['l' .. z] or '-') | |||
ttab[i] = trim(ppar['t' .. z] or '-') | |||
mnum = i | |||
end | |||
local args = { -- Parameters for expanding 'Template:F'. | |||
'', -- [1] = vv | |||
'', -- [2] = nm | |||
'', -- [3] = ds | |||
'', -- [4] = op | |||
'', -- [5] = p4 | |||
'', -- [6] = p5 | |||
'', -- [7] = p6 | |||
l = '', -- ['l'] = pk | |||
lang = '', -- ['lang'] = pi | |||
p = '', -- ['p'] = pr | |||
by = '', -- ['by'] = by | |||
u = '', -- ['u'] = um | |||
link = '', -- ['link'] = (ln ~= '' and ln or nil) | |||
} | |||
local results = {} | |||
local lcnt = 0 -- Loop count. | |||
local i = 1 -- While index. | |||
while ppar[i] ~= nil do -- for i, v in ipairs(ppar) do | |||
local j = 1 | |||
local vv = trim(ppar[i]) | |||
if vary ~= '' and sub(vv, 1, 1) == '#' and sub(vv, -1) == '#' then -- Loop processing? | |||
loop = split(vv, '#', true--[[plain]]) | |||
local llow = tonumber(loop[2]) or -1 | |||
local lupp = tonumber(loop[3]) or -1 | |||
if llow >= 0 and lupp >= llow then | |||
llow = llow + lcnt | |||
vv = tostring(llow) | |||
lcnt = lcnt + 1 | |||
if llow < lupp then | |||
j = 0 -- Iterate this index. | |||
else | |||
lcnt = 0 -- Loop ended. | |||
end | |||
end | |||
end -- End loop processing. | |||
if sub(vv, 1, 1) == '"' and sub(vv, -1) == '"' then -- Text processing? | |||
insert(results, expand1('=', sub(vv, 2, -2))) | |||
elseif vary == '' or i > 1 then | |||
local sp = stab[i] ~= '~' and stab[i] or spa | |||
local px = xtab[i] ~= '-' and xtab[i] or pfx | |||
local nm = ntab[i] ~= '-' and ntab[i] or nam | |||
local ds = dtab[i] ~= '-' and dtab[i] or dis | |||
local op = otab[i] ~= '-' and otab[i] or opt | |||
local p4 = qtab[i] ~= '-' and qtab[i] or pr4 | |||
local p5 = rtab[i] ~= '-' and rtab[i] or pr5 | |||
local p6 = vtab[i] ~= '-' and vtab[i] or pr6 | |||
local pk = ktab[i] ~= '-' and ktab[i] or wik | |||
local pi = itab[i] ~= '-' and itab[i] or int | |||
local pr = ptab[i] ~= '-' and ptab[i] or pre | |||
local by = btab[i] ~= '-' and btab[i] or by0 | |||
local um = utab[i] ~= '-' and utab[i] or mod | |||
local ln = ltab[i] ~= '-' and ltab[i] or lnk | |||
local tx = ttab[i] ~= '-' and ttab[i] or '' | |||
if vary ~= '' then | |||
replacement[2] = (sp == '+' and ' ' or '') | |||
replacement[3] = vv | |||
vv = gsub(ppar[1], vary, concat(replacement)) | |||
else | |||
vv = samefile(vv, i, ppar[1]) | |||
end | |||
if vv ~= '' and vv ~= '×' then | |||
if dir == 'hori' and con ~= 'n' then -- Horizontal list. | |||
px = (i == 1) and ' ' or commaAnd(i == mnum) | |||
else -- elseif dir == 'vert' then -- Vertical list. | |||
px = (i == 1) and ' ' or px | |||
end | |||
if px ~= '' then insert(results, px) end | |||
if by == '' then -- Check for abbreviating '/'. | |||
local sby = find(vv, '/') | |||
if sby ~= nil then | |||
by = sub(vv, sby + 1) | |||
vv = sub(vv, 1, sby - 1) | |||
end | |||
end | |||
args[1] = vv | |||
args[2] = nm | |||
args[3] = ds | |||
args[4] = op | |||
args[5] = p4 | |||
args[6] = p5 | |||
args[7] = p6 | |||
args.l = pk | |||
args.lang = pi | |||
args.p = pr | |||
args.by = by | |||
args.u = um | |||
args.link = (ln ~= '' and ln or nil) | |||
insert(results, expand('F', args)) | |||
if tx ~= '' then insert(results, expand1('=', tx)) end | |||
end -- if vary | |||
end -- if vv | |||
i = i + j -- next in do loop | |||
end -- while | |||
return concat(results) | |||
end -- function filelist | |||
-- For Template:Attribs (param pairs; but also for single params). | |||
function p.attribs(frame) | |||
local ppar = frameCurrent:getParent().args | |||
local un = trim(ppar.by or ppar.U or ppar.u or '') | |||
local md = trim(ppar.m or ppar.mod or '') | |||
local tt = trim(ppar.t or ppar.to or '') -- "to" topic. | |||
local f = trim(ppar.f or ppar.from or tt) -- "from". | |||
local p = trim(ppar.p or ppar.part or '') | |||
local args = { -- Parameters for expandnig 'Template:Attrib'. | |||
'', -- [1] = vx | |||
'', -- [2] = ux | |||
'-', | |||
trim(ppar.type or 'SVG'), -- Needs check. | |||
'', | |||
ux, -- [6] = ux | |||
tt, | |||
'', -- [8] = (ftab[hnum] ~= '.') and ftab[hnum] or f | |||
'', -- [9] = (ptab[hnum] ~= '.') and ptab[hnum] or p | |||
m = '', -- ['m'] = (mtab[hnum] ~= '.') and mtab[hnum] or md | |||
s = trim(ppar.s or ppar.style or 's'), -- default | |||
} | |||
local ftab = {} -- "from" topic. | |||
local ptab = {} -- Parts. | |||
local mtab = {} -- Modification. | |||
local rtab = {} -- Working table. | |||
local fnum = 0 | |||
local rnum = 0 | |||
local hnum = 0 | |||
for i, v in ipairs(ppar) do | |||
fnum = fnum + 1 -- Input parm number. | |||
if fnum % 2 == 0 then -- Even: should be a username. | |||
local enam = trim(v) | |||
-- A rough check: is_extension? | |||
local snam = lower(sub(enam, -4)) | |||
if snam == '.png' | |||
or snam == '.gif' | |||
or snam == '.jpg' | |||
or snam == '.svg' | |||
-- Exotics: | |||
or snam == '.mid' | |||
or snam == '.ogg' | |||
or snam == '.tif' | |||
or snam == '.wav' | |||
or snam == '.xcf' | |||
or snam == '.pdf' -- Note: no "short alias" in samefile() | |||
-- Note: Longer extensions still not supported (need check): | |||
-- snam == '.djvu' | |||
-- snam == '.webp' | |||
then -- No - it's the next filename. | |||
insert(rtab, '') -- Empty username inbetween. | |||
rnum = rnum + 1 | |||
fnum = fnum + 1 -- Make it odd. | |||
end | |||
end | |||
if fnum % 2 == 1 then -- Odd (now): is a filename. | |||
hnum = (fnum + 1) / 2 | |||
local z = tostring(hnum) | |||
ftab[hnum] = ppar['f' .. z] or '.' | |||
ptab[hnum] = ppar['p' .. z] or '.' | |||
mtab[hnum] = ppar['m' .. z] or '.' | |||
end | |||
-- table.maxnum(ppar) does not work; therefore the "rtab" workaround. | |||
insert(rtab, ppar[i]) -- = enam | |||
rnum = rnum + 1 | |||
end | |||
if rnum % 2 == 1 then -- Plus one item when odd number. | |||
insert(rtab, '') -- Empty user name, to get a pair. | |||
end | |||
local results = {} -- Output. | |||
local vx = '' | |||
for i, v in ipairs(rtab) do | for i, v in ipairs(rtab) do | ||
if vx == | if i % 2 == 1 then -- odd: 1st value in pair is a filename | ||
vx = mw.text.trim( v ) | vx = trim(v) -- this 1st 'v' should not be empty | ||
else -- even: 2nd value in pair is a user name (possibly empty) | |||
local ux = trim(v) -- this 2nd 'v' can be empty | |||
if ux == '' then ux = un end -- Does not work otherwise? | |||
hnum = i / 2 | |||
args[1] = vx -- a filename | |||
args[2] = ux -- a username | |||
args[6] = ux -- a username | |||
args[8] = (ftab[hnum] ~= '.') and ftab[hnum] or f | |||
args[9] = (ptab[hnum] ~= '.') and ptab[hnum] or p | |||
args.m = (mtab[hnum] ~= '.') and mtab[hnum] or md | |||
insert(results, expand('Attrib', args)) | |||
vx = '' -- reset the filename for the next pairs | |||
end | |||
end | |||
return concat(results) | |||
end -- function attribs | |||
-- Get the user id: the (last) parameter which is prefixed by '/'. | |||
function p.byuser(frame) | |||
local ppar = frameCurrent:getParent().args | |||
local user = '' | |||
for _, value in pairs(ppar) do | |||
if value ~= nil and user == '' and sub(value, 1, 1) == '/' then | |||
user = sub(value, 2) -- remove the '/' | |||
end | |||
-- TODO: Test whether userID exists? | |||
end | |||
return user | |||
end -- function byuser, for template:F | |||
-- for Template:userlist (horizontal - but vertical when dir=I/O/U/D/V). | |||
function p.userlist(frame) | |||
local gpar = frame.args -- global parms (par/P, dir/V) | |||
local ppar = frameCurrent:getParent().args | |||
local mod = ppar.m or ppar.mod or ppar.user or ppar.u or ppar.page or ppar.p or '' | |||
local hil = ppar.h or ppar.hilite or '' | |||
local nam = ppar.n or ppar.name or '' | |||
local wik = ppar.w or ppar.wiki or ppar.lang or '' | |||
local opt = ppar.o or ppar.opt or ppar.option or '' | |||
local lnk = ppar.l or ppar.link or '' | |||
--@ local pr4 = ppar.q or ppar.qpar or ppar.par4 or '' | |||
--@ local pr5 = ppar.r or ppar.rpar or ppar.par5 or '' | |||
local cas = ppar.c or ppar.case or '' | |||
local trl = ppar.t or ppar.i18n or ppar.translate or '' | |||
-- If ever template expansion of prim, prfx, sufx, or pend is needed, | |||
-- this must be done once here (out of the loop below). | |||
local prim, prfx, sufx, pend = '', '', '', '' | |||
if gpar.dir == 'O' then -- Ordered/numbered vertical list. | |||
prim, prfx, sufx, pend = '<ol>', '<li>', '</li>', '</ol>' | |||
elseif gpar.dir == 'U' then -- Unordered/bulleted vertical list. | |||
prim, prfx, sufx, pend = '<ul>', '<li>', '</li>', '</ul>' | |||
elseif gpar.dir == 'D' then -- Simple definition/indented vertical list. | |||
prim, prfx, sufx, pend = '<dl>', '<dt>', '</dt>', '</dl>' | |||
elseif gpar.dir == 'V' then -- Custom vertical list of users. | |||
prim, prfx, sufx, pend = '<dl style="margin:.3em 0">', '<dt><span style="color:#69F">✦ </span>', '</dt>', '</dl>' | |||
else --'I': Inline horizontal list. | |||
-- prim, prfx, sufx, pend: not used; replaced by separators, expanded by commaAnd() | |||
end | |||
local mtab = {} -- u_mod c/t/w/wt (aka utab, mtab, ptab) | |||
local htab = {} -- hilite | |||
local ntab = {} -- 2 display name | |||
local wtab = {} -- 3 interwiki | |||
local otab = {} -- 4 +/- option | |||
local ltab = {} -- link option | |||
--@ local qtab = {} | |||
--@ local rtab = {} | |||
local ctab = {} -- case | |||
local ttab = {} -- translate i18n | |||
local xtab = {} -- postfix text | |||
local x = 0 -- running index, can be ~= i | |||
local y = 0 -- running index, can be ~= i | |||
local plus = '' -- opt | |||
local xmax = 0 | |||
for _, v in ipairs(ppar) do | |||
v = mw.text.trim ( v ) | |||
if v == '+' then | |||
plus = '+' | |||
elseif v == '-' then | |||
if plus == '' then | |||
plus = '-' | |||
end | |||
else | else | ||
y = y + 1 | |||
if | if gpar.par == 'P' --[[pairs of (user, name)]] and y % 2 == 0 --[[1=user, 0=name]] then | ||
x = x | |||
else | else | ||
x = x + 1 | |||
local z = tostring(x) | |||
mtab[x] = ppar['m' .. z] or ppar['u' .. z] or ppar['p' .. z] or '-' | |||
htab[x] = ppar['h' .. z] or '-' | |||
ntab[x] = ppar['n' .. z] or '-' | |||
wtab[x] = ppar['w' .. z] or '-' | |||
otab[x] = ppar['o' .. z] or '/' | |||
ltab[x] = ppar['l' .. z] or '-' | |||
--@ qtab[x] = ppar['q' .. z] or '-' | |||
--@ rtab[x] = ppar['r' .. z] or '-' | |||
ctab[x] = ppar['c' .. z] or '-' | |||
ttab[x] = ppar['t' .. z] or '-' | |||
xtab[x] = ppar['x' .. z] or '-' | |||
end | end | ||
end | end | ||
xmax = x | |||
end -- for | |||
if plus ~= '' and opt == '' then | |||
opt = plus --[[discrepancy? opt has priority]] | |||
end | end | ||
return | local odd = y % 2 --[[1 when last one not paired]] | ||
end | local p2s = { | ||
'~', | |||
'', -- [2] = (wk ~= '') and wk or 'commons' | |||
'wiki', | |||
} | |||
local hls = { | |||
'<', | |||
'', -- [2] = hl | |||
'>', | |||
'', -- [4] = (nm ~= '') and nm or vv | |||
'</', | |||
'', -- [6] = hl | |||
'>', | |||
} | |||
local args = { -- Parameters for expanding 'Tempplate:U/main'. | |||
'', -- [1] = vv, | |||
'', -- [2] = nm, | |||
'', -- [3] = wk, | |||
'', -- [4] = op, | |||
link = '', -- ['link'] = lk | |||
par1 = '', -- ['par1'] = p1 | |||
par2 = '', -- ['par2'] = p2 | |||
--@ par4 = '', -- ['par4'] = p4 | |||
--@ par5 = '', -- ['par5'] = p5 | |||
case = '', -- ['case'] = cs | |||
i18n = '', -- ['i18n'] = tr | |||
} | |||
local results = {} | |||
local out = 0 | |||
local vv = '' | |||
x = 0 | |||
y = 0 | |||
for _, v in ipairs(ppar) do | |||
v = trim(v) | |||
if v ~= '+' and v ~= '-' then | |||
y = y + 1 | |||
if gpar.par == 'P' --[[pairs of (user, name)]] and y % 2 == 1 --[[1=user, 0=name]] and odd == 0 then -- last one paired | |||
vv = v -- userid | |||
else | |||
x = x + 1 | |||
local md = (mtab[x] ~= '-') and mtab[x] or mod | |||
local hl = (htab[x] ~= '-') and htab[x] or hil | |||
local nm = (ntab[x] ~= '-') and ntab[x] or nam | |||
local wk = (wtab[x] ~= '-') and wtab[x] or wik | |||
local op = (otab[x] ~= '/') and otab[x] or opt | |||
local lk = (ltab[x] ~= '-') and ltab[x] or lnk | |||
--@ local p4 = (qtab[x] ~= '-') and qtab[x] or pr4 | |||
--@ local p5 = (rtab[x] ~= '-') and rtab[x] or pr5 | |||
local cs = (ctab[x] ~= '-') and ctab[x] or cas | |||
local tr = (ttab[x] ~= '-') and ttab[x] or trl | |||
local tx = (xtab[x] ~= '-') and xtab[x] or '' | |||
if gpar.par == 'P' then -- y%2 = 0 (name) | |||
if odd == 1 then --[[no: last user:]] | |||
vv = v --[[user]] | |||
else | |||
nm = v --[[name]] | |||
end | |||
else | |||
vv = v | |||
end | |||
if hl ~= '' then | |||
hls[2] = hl | |||
hls[4] = (nm ~= '') and nm or vv | |||
hls[6] = hl | |||
nm = concat(hls) | |||
end | |||
if md == 'n' or md == 'no' then | |||
lk = md -- no link | |||
end | |||
local p1 = '' -- prefix | |||
if md == 't' or md == 'wt' or md == 'tw' then | |||
p1 = ' talk' | |||
end | |||
local p2 = '' -- postfix | |||
if md == 'w' or md == 'wt' or md == 'tw' then | |||
p2s[2] = (wk ~= '') and wk or 'commons' | |||
p2 = concat(p2s) | |||
end | |||
if vv ~= '' and vv ~= '×' then | |||
if md == 'c' then vv = 'Special:Contributions/' .. vv end | |||
if gpar.dir == 'I' or gpar.dir == 'O' or gpar.dir == 'U' or gpar.dir == 'V' then | |||
-- Vertical list (uses: prim, prfx, sufx, pend). | |||
if out == 0 then | |||
insert(results, prim) -- expansion of prim not needed | |||
end | |||
insert(results, prfx) -- expansion of prefx not needed | |||
out = out + 1 | |||
else -- Horizontal inline list. | |||
if x ~= 1 then | |||
insert(results, commaAnd(x == xmax)) | |||
end | |||
end | |||
if sub(vv, 1, 2) == '{{' or sub(vv, 1, 2) == '[[' then | |||
insert(results, expand1('=', vv)) | |||
else | |||
args[1] = vv | |||
args[2] = nm | |||
args[3] = wk | |||
args[4] = op | |||
args.link = lk | |||
args.par1 = p1 | |||
args.par2 = p2 | |||
--@ args.par4 = p4 | |||
--@ args.par5 = p5 | |||
args.case = cs | |||
args.i18n = tr | |||
insert(results, expand('U/main', args)) | |||
end | |||
if tx ~= '' then | |||
insert(results, expand1('=', tx)) | |||
end | |||
if sufx ~= '' then | |||
insert(results, sufx) -- expansion of sufx not needed | |||
end | |||
end | |||
end | |||
end | |||
end -- for | |||
if out > 0 and pend ~= '' then | |||
insert(results, pend) -- expansion of pend not needed | |||
end | |||
return concat(results) | |||
end -- function userlist | |||
-- for | -- Table for templates: Legend; Legend-line, Legend2, Legend-small... (param pairs) | ||
function p.legendt (frame) | function p.legendt (frame) | ||
local | local ppar = frameCurrent:getParent().args | ||
local | local ttip = trim(ppar.tt or ppar.ttip or ppar.tooltipping or '') | ||
local | local frmp = frame.args | ||
local v1 = | local template = trim(frmp[1] or 'Legend') | ||
local args = { -- Parameters for expanding the given template. | |||
for _, v in ipairs( | '', -- [1] = v1 | ||
if v1 == | '', -- [2] = v | ||
v1 = | lang = trim(ppar.lang or ''), | ||
p = trim(frmp[2] or ''), | |||
size = trim(frmp[3] or ''), | |||
css = '', -- ['css'] = '" title="' .. upper(v1) | |||
} | |||
local results = {} | |||
local v1 = '' | |||
for _, v in ipairs(ppar) do | |||
if v1 == '' then | |||
v1 = v | |||
if ttip == 'yes' and v1 ~= '' then -- Tooltip the colors. | |||
-- HACK: terminates the style="..." attribute and opens another attribute | |||
args.css = '" title="' .. Ucfirst(v1) | |||
end | |||
else | else | ||
args[1] = v1 | |||
v1 = | args[2] = v | ||
end | insert(results, expand(template, args)) | ||
v1 = '' | |||
args.css = '' | |||
end | |||
end | end | ||
if v1 ~= | if v1 ~= '' then -- Last item: problem when not a last pair | ||
insert(results, expand(template, args)) | |||
end | end | ||
return | return concat(results) | ||
end | end -- function legendt | ||
-- | -- For Template:ColorString (Igen/cbox, param pairs). | ||
function p.colorbox (frame) | local argsColorbox = { -- Parameters for expanding 'Template:Igen/cbox'. | ||
local | '', -- [1] -- (striped; border) | ||
'', -- [2] -- color value | |||
local | '', -- [3] -- either code-2 ( BCDLMST-), or color value | ||
local v1 = | 0, -- [4] -- count of spaces | ||
'', -- [5] -- ? | |||
for i, v in ipairs( | '', -- [6] -- 'char' or 'file' | ||
if i <= 2 then | '', -- ['lang'] = ppar.lang or content language, | ||
} | |||
function p.colorbox(frame) | |||
local ppar = frameCurrent:getParent().args | |||
argsColorbox.lang = ppar.lang or mw.getContentLanguage():getCode() | |||
local results = {} | |||
local v1 = '' | |||
v1 = | for i, v in ipairs(ppar) do | ||
if i <= 2 then | |||
argsColorbox[3] = v -- either code-2 ( BCDLMST-), or color value | |||
elseif v1 == '' then | |||
v1 = v -- (striped; border) | |||
local ct = 0 -- count of spaces | |||
local bp = 0 -- position of first space | |||
for c = 1, len(v1) do | |||
if sub(v1, c, c) == ' ' then | |||
ct = ct + 1 -- space count | |||
if bp == 0 then bp = c end | |||
end | |||
end | |||
local bc = '' | |||
if ct >= 3 then -- 3 = border, 4 = line | |||
bc = sub(v1, bp + 1) | |||
v1 = sub(v1, 1, bp - 1) | |||
end | |||
local cf = '' | |||
if ct == 1 then -- 'char' or 'file' | |||
bc = sub(v1, bp + 1) | |||
v1 = sub(v1, 1, bp - 1) | |||
cf = (sub(bc, -4, -4 ) == '.') and 'file' or 'char' | |||
end | end | ||
argsColorbox[4] = ct -- count of spaces | |||
argsColorbox[5] = bc | |||
argsColorbox[6] = cf -- 'char' or 'file' | |||
else | |||
argsColorbox[1] = v1 | |||
argsColorbox[2] = v | |||
insert(results, expand('Igen/cbox', argsColorbox)) | |||
v1 = '' | |||
end | |||
end | |||
if v1 ~= '' then | |||
argsColorbox[1] = v1 | |||
argsColorbox[2] = '' | |||
insert(results, expand('Igen/cbox', argsColorbox)) -- last item | |||
end | |||
return concat(results) | |||
end -- function colorbox | |||
-------------------------------------------------------------------------------- | |||
-- Returns a parameter list: (replacement of «#» or «~» by «=»: not necessary). | |||
function p.plist(frame) | |||
local ppar = frameCurrent:getParent().args | |||
return concat(ppar, '|') -- return gsub(concat(ppar, '|'), '#', '='), not necessary | |||
end -- function plist | |||
-- Repeats a text string. | |||
function p.loop (frame) | |||
local ppar = frameCurrent:getParent().args | |||
return string.rep(ppar[2] or ' ', tonumber(ppar[1] or 1)) | |||
end -- function loop | |||
-- Increment a hex number by a ±decimal value | |||
function p.incrhx(frame) | |||
local gpar = frame.args -- global parms | |||
return format('%X', tonumber(gpar[1], 16) + gpar[2]) | |||
end -- function incrhx | |||
-- Display inline a range of characters with their Unicode code point in tool tip, such as emojis for Template:Emoji, with optional | |||
-- line breaks to limit lines to at most 16 characters (breaks after every code point which is the last one in a UCS column): | |||
-- {{#invoke:Iteration|parlst |temp=Emoji |1=(nb of characters) |2=(4- to 6-digits uppercase hexadecimal code point) | |||
-- |3=(border or 0) |4=(padding or 0) |5=(font size in px or -) | |||
-- |6=(styles or -) |(nocat=1) | |||
-- }} | |||
local argsEmodis = { | |||
-- WARNING: partial HTML (see the template using this function) | |||
-- This function can only be used after an UNTERMINATED opening HTML tag, | |||
-- whose LAST attribute MUST BE ' title=' not followed by quotes. | |||
-- This returned value closes the opening HTML tag of the template | |||
-- The calling template will then append itself the closing HTML tag. | |||
'"U+', | |||
'', -- [2] = format('%04X', code) | |||
'">', | |||
'', -- [4] = char(code) | |||
nil -- [5] = optional line break | |||
} | |||
function p.emodis(frame) | |||
local gpar = frame.args -- global parms | |||
local code = tonumber(gpar[1], 16) + gpar[2] | |||
argsEmodis[2] = format('%04X', code) | |||
argsEmodis[4] = char(code) | |||
argsEmodis[5] = gpar[3] == '16' and (code % 16 == 15 and '<br />') or nil | |||
return concat(argsEmodis) | |||
end -- function emodis | |||
-- For Template:Emoji table: {{#invoke:Iteration|emotab|prefix=1F250|par1=... | ... }} | |||
local argsEmotab = { -- Parameters for expanding 'Template:F'. | |||
'', -- [1] = file | |||
'', -- [2] = 'Z' | |||
'', -- [3] = '49' | |||
'', -- [4] = 'b' | |||
'', -- [5] = 'l' | |||
'', -- [6] = '' | |||
link = '*', | |||
} | |||
function p.emotab(frame) | |||
local gpar = frame.args -- global parms | |||
local codp | |||
codp = trim(gpar.par1 or '') --[['Z' ]] argsEmotab[2] = (codp ~= '') and codp or nil | |||
codp = trim(gpar.par2 or '') --[['49']] argsEmotab[3] = (codp ~= '') and codp or nil | |||
codp = trim(gpar.par3 or '') --[['b' ]] argsEmotab[4] = (codp ~= '') and codp or nil | |||
codp = trim(gpar.par4 or '') --[['l' ]] argsEmotab[5] = (codp ~= '') and codp or nil | |||
codp = trim(gpar.par5 or '') --[['' ]] argsEmotab[6] = (codp ~= '') and codp or nil | |||
codp = trim(gpar.codp or '') | |||
local parts = { | |||
'', -- [1] = v | |||
'', -- [2] = ((file == 'Emojio' or file == 'Fxemoj' or file == 'OpenMo') and upper or lower)(codp) | |||
'.svg', | |||
} | |||
local results = {} | |||
for _, v in ipairs(gpar) do | |||
local file = sub(v, 1, 6) | |||
parts[1] = v | |||
parts[2] = ((file == 'Emojio' or file == 'Fxemoj' or file == 'OpenMo') and upper or lower)(codp) | |||
file = concat(parts) | |||
if titleNew(file, 6).exists then | |||
argsEmotab[1] = file | |||
insert(results, expand('F', argsEmotab)) | |||
end | |||
end | |||
return concat(results) | |||
end -- function emotab | |||
-- For template: Navcat (via Navcattab). | |||
function p.navcat(frame) | |||
local gpar = frame.args -- global parms | |||
local cats = { -- Categories to generate. | |||
trim(gpar.c1 or ''), | |||
'', -- [2] = ctxt | |||
trim(gpar.c2 or ''), | |||
} | |||
local args = { -- Parameters for expanding 'Template:Navcat'. | |||
'', -- [1] = (ccod = vtab[2] --[[opt.]]) | |||
'', -- [2] = concat(cats) | |||
'', -- [3] = (dtxt = Ucfirst(ctxt)) | |||
'', -- [4] = (cnam = vtab[3] or ccod or ctxt) | |||
span = trim(gpar.span or ''), | |||
} | |||
local ppar = frameCurrent:getParent().args | |||
local results = {} | |||
for _, v in ipairs(ppar) do | |||
v = trim(v) | |||
if v == '' or v == 'nl' then | |||
insert(results, '<br /> ') | |||
else | |||
local vtab = split(v, '/') | |||
local ctxt = vtab[1] or ' ' --[[requ.]] | |||
local ccod = vtab[2] --[[opt.]] | |||
cats[2] = ctxt | |||
args[1] = ccod | |||
args[2] = concat(cats) | |||
args[3] = Ucfirst(ctxt) | |||
args[4] = vtab[3] or ccod or ctxt | |||
insert(results, expand('Navcat', args)) | |||
end | |||
end | |||
return concat(results) | |||
end -- function navcat | |||
-- For Template:Tle. | |||
function p.tleparm(frame) | |||
local ppar = frameCurrent:getParent().args | |||
local parnumber = trim(ppar.number or '') | |||
local parkbd = trim(ppar.kbd or '') | |||
if parkbd ~= '' then | |||
parkbd = { | |||
'<kbd>', | |||
'', -- [2] = par1 | |||
'</kbd>', | |||
} | |||
else | |||
parkbd = nil | |||
end | |||
local args = { -- Parameters for expanding 'Template:Tle/parm'. | |||
'', -- [1] = par1 | |||
'', -- [2] = v | |||
trim(ppar.f or ''), -- form feed | |||
trim(ppar.style or ''), -- style for parameter value | |||
trim(ppar.style2 or ''), -- style for parameter name | |||
} | |||
local results = {} | |||
for i, v in ipairs(ppar) do | |||
local z = tostring(i) | |||
local par1 = trim(ppar['p' .. z] or '') | |||
if par1 ~= '' and parkbd then | |||
parkbd[2] = par1 | |||
par1 = concat(parkbd) | |||
end | |||
if par1 == '' and parnumber ~= '' then | |||
par1 = z | |||
end | end | ||
if par1 ~= '' then -- keep parameter value as is if positional (and not parnumberd explicitly) | |||
v = trim(v) | |||
if v == '' then v = ' ' --[[Note: ' ' would change the semantics.]] end | |||
end | |||
args[1] = par1 | |||
args[2] = v | |||
insert(results, expand('Tle/parm', args)) | |||
end | end | ||
return concat(results) | |||
end -- function tleparm | |||
-- for Template:Variate. | |||
function p.variation(frame) | |||
local ppar = frameCurrent:getParent().args | |||
local sept = ppar.sept or '|' -- separator before | |||
local sample = trim(ppar[1] or '') -- sample string | |||
local pattern = ppar.pttn or '?' -- pattern | |||
local var1 = ppar.var1 or '' -- filling space before | |||
local var2 = ppar.var2 or '' -- filling space after | |||
local sep2 = ppar.sep2 or '' -- separator after | |||
local parts = { -- Replacement parts for gsub(). | |||
(var1 == 'space') and ' ' or var1, | |||
'', -- [2] = trim(v) | |||
(var2 == 'space') and ' ' or var2, | |||
} | |||
local results = {} | |||
for i, v in ipairs(ppar) do | |||
if i > 1 then | |||
insert(results, sept) | |||
parts[2] = trim(v) | |||
insert(results, gsub(sample, pattern, concat(parts))) | |||
insert(results, sep2) | |||
end | |||
end | end | ||
return | return concat(results) | ||
end | end | ||
return p | |||
return p | |||