Module:Iteration



From Wikimedia Commons, the free media repository



Jump to navigation  Jump to search  

Lua

CodeDiscussionEditHistoryLinksLink count Subpages:DocumentationTestsResultsSandboxLive code All modules

0 The module uses frequently the template {{=}} for title = "=" 0

This module contains the functions for different templates, solving their iteration problem

The MediaWiki template coding does not support the repetitive processing of a parameter set, which leads often to a very primitive and long chain of parameter checks in the kind of:

{{#if:{{{1|}}} | perform an action with parameter 1 }}
{{#if:{{{2|}}} | perform an action with parameter 2 }}
{{#if:{{{3|}}} | perform an action with parameter 3 }}
{{#if:{{{4|}}} | perform an action with parameter 4 }}
•••
•••
{{#if:{{{33|}}} perform an action with parameter 33 }}

with the disadvantage that such a construct will fail as soon as there comes a 34nd parm. I always thought that with Lua and its for loops this iterations should be possible, somehow. After long searching without any success and without an idea how to perform it, I asked at several forums and got finally from User:Trappist the monk the helping hint to solve it with a control structure like:

 local out = {}
 for i, v in ipairs (args) do
  table.insert (out, frame:expandTemplate{ title = title, args = v })
 end
 return table.concat (out)

The functions contained therein are from very simple, just one parameter to pass, to more complicated ones, where e.g. a pair of parameters needs kind of a flip-flop switch when always a tuple of e.g. an item and its correlated text needs to be passed.

When there are tuples, triples etc., the table.insert occurs, when the last element is processed; this performs problems when the last group is incomplete – it should be finished with empty values to trigger the table.insert. The check with table.maxn seems not to work correctly?

This problem is solved differently, for the function attribs with a primitive workaround.

Namespace lists

[edit]

There are special lists for some namespaces:

Filelist

[edit]

File list templates

[edit]

The three templates {{Ifim}}, {{Ifim1}} and {{Ifimt}} avoid to display the file itself as an |other version=.

There are currently five templates creating file lists with the function:filelist

  1. {{Other versions}} a vertical list (without initial)
  2. {{Filelist}} a horizontal list (without initial)
  3. {{Derivative versions}} a vertical list
  4. {{Derived from}} a vertical list
  5. {{File}} a horizontal list

All these templates are autoreferencing, and the support also the |gallery= option.

Other file lists

[edit]

The function:svglang creates a list of just file_names and language_codes, for:

  1. {{Svg lang}}
  2. {{Lang gallery}}
  3. {{Multilingual SVG diagrams}}

Much more is created by the function:ownbased for the template:

  1. {{Own based}}

which will handle in the majority of cases just one file, but can serve an unlimited number.

This list can be controlled by the user to be displayed either horizontally or vertically.

  1. {{Attribs}}

The template works, whether there is a user assigned for a file, or one filename follows another.

  1. {{Emoji}}

The template displays a line of SVG emojis; Unicode characters/emojis can be displayed with the function emodisoremotab.

Variable iterations

[edit]

A very simple iteration, usable for everything, is performed by function:iterate

used by e.g. {{Image extracted}}, {{Image translated}},

More usable is the function:iteration for transclusions of a template with:

See template {{Iterate}}. The function:loop is used by {{Repeat}}.

samefile function

[edit]

When the name of one of the files is the same as the first one, it is enough to reference it with its extension after a dot, e.g. just ".jpeg". The most standard extensions can be abbreviated, e.g. ".j" will be sufficient for ".jpg" (only for lower case!).

The function incrhx increments a hexadecimal number (parm 1) by a decimal number (parm 2).

Valid numbers are assumed, no checking occurs!

When parameter 2 is preceded by a minus, the first number is decremented by the second one.

Userlist

[edit]
[edit]

Templist

[edit]

Other iterations

[edit]
The function emodis displays Unicode characters / emojis; it can care for newlines, while
The function emotab displays a table of files / emojis.

Code

-- 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 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 = {}
local function expand(template, args)
 transclude.title = template
    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

----------------------------------------------------------------------------------------------

local p = {}

-- For Template:Ifim.
local argsIfim1 = { -- Parameters for expanding 'Template:Ifim1'.
 '', -- [1] = v
 '', -- [2] = trim(ppar.p1 or ''),
 '', -- [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
 return concat(results)
end -- function ifim2

-- For Template:Ifimt (param pairs).
function p.ifimt(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 v1 = ''
 local results = {}
 for _, v in ipairs(ppar) do
  if v1 == '' then
   v1 = v
  else
   argsIfim2[1] = v1
   argsIfim2[6] = v
   insert(results, expand('Ifim2', argsIfim2))
   v1 = ''
  end
 end
 if v1 ~= '' then
  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

---++++++++++++++++++++++++++++++++++++++++++++++++++++

-- Simple iterations - without many params.
function p.iterate(frame)
 local gpar = frame.args -- global parms
 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
 return concat(results)
end -- function iterate

-- More iterations - for params, param pairs, or n-tuples.
function p.iteration(frame)
 local gpar = frame.args -- Global parms.
 local vmax = tonumber(gpar.n) or 2 -- Tuple number (default = 2).
 local vnum = vmax + 1 -- Additional not-changing params.
 local template = '' -- Template name.
 local args = {} -- Parameters for expanding the given template.
 for i, p in ipairs(gpar) do
  p = trim(p)
  if i == 1 then
   template = p
  else
   args[vnum] = p
   vnum = vnum + 1
  end
 end
 vnum = 1
 local ppar = frameCurrent:getParent().args
 local results = {} -- output
 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
   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
  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
 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.ownbasby(frame)
 local gpar = frame.args -- Global parameters.
 return expand('F', {
  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 ttab = {}
 local utab = {}
 local x = 0 -- running index, can be ~= i
 local fst = 0 -- first occurrence
 local cor = 0
 local max = 0
 local plus = ''
 for i, v in ipairs(ppar) do
  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 = '&#32;'
     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
 return concat(results)
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
 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 = '&#32;' 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 '&#32;' 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 '&#32;' 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 '&#32;' or commaAnd(i == mnum)
    else -- elseif dir == 'vert' then -- Vertical list.
     px = (i == 1) and '&#32;' 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
  if i % 2 == 1 then -- odd: 1st value in pair is a filename
   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
   y = y + 1
   if gpar.par == 'P' --[[pairs of (user, name)]] and y % 2 == 0 --[[1=user, 0=name]] then
    x = x
   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
  xmax = x
 end -- for
 if plus ~= '' and opt == '' then
  opt = plus --[[discrepancy? opt has priority]]
 end
 local odd = y % 2 --[[1 when last one not paired]]
 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 = '&#32;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

-- Table for templates: Legend; Legend-line, Legend2, Legend-small... (param pairs)
function p.legendt (frame)
 local ppar = frameCurrent:getParent().args
 local ttip = trim(ppar.tt or ppar.ttip or ppar.tooltipping or '')
 local frmp = frame.args
 local template = trim(frmp[1] or 'Legend')
 local args = { -- Parameters for expanding the given template.
  '', -- [1] = v1
  '', -- [2] = v
  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
   args[1] = v1
   args[2] = v
   insert(results, expand(template, args))
   v1 = ''
   args.css = ''
  end
 end
 if v1 ~= '' then -- Last item: problem when not a last pair
  insert(results, expand(template, args))
 end
 return concat(results)
end -- function legendt

-- For Template:ColorString (Igen/cbox, param pairs).
local argsColorbox = { -- Parameters for expanding 'Template:Igen/cbox'.
 '', -- [1] -- (striped; border)
 '', -- [2] -- color value
 '', -- [3] -- either code-2 ( BCDLMST-), or color value
 0, -- [4] -- count of spaces
 '', -- [5] -- ?
 '', -- [6] -- 'char' or 'file'
 '', -- ['lang'] = ppar.lang or '{{PAGELANGUAGE}}',
}
function p.colorbox(frame)
 local ppar = frameCurrent:getParent().args
 argsColorbox.lang = ppar.lang or '{{PAGELANGUAGE}}'
 local results = {}
 local 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
   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 '&nbsp', 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 '&nbsp;' --[[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
  if par1 ~= '' then -- keep parameter value as is if positional (and not parnumberd explicitly)
   v = trim(v)
   if v == '' then v = '&thinsp;' --[[Note: '&thinsp;' would change the semantics.]] end
  end
  args[1] = par1
  args[2] = v
  insert(results, expand('Tle/parm', args))
 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
 return concat(results)
end

return p

Retrieved from "https://commons.wikimedia.org/w/index.php?title=Module:Iteration&oldid=901019908"

Categories: 
Modules for general use
Modules subject to page protection
Heavily used modules
 


Navigation menu


Personal tools  




English
Not logged in
Talk
Contributions
Create account
Log in
 


Namespaces  




Module
Discussion