มอดูล:Params
หน้าตา
This module is rated as beta, and is ready for widespread use. It is still new and should be used with some caution to ensure the results are as expected. |
เอกสารประกอบแม่แบบนี้ ขาดหายไป ไม่เพียงพอ หรืออธิบายฟังก์ชันการทำงานและ/หรือพารามิเตอร์ในโค้ดไม่ถูกต้อง โปรดช่วยขยายความและปรับปรุง |
คู่มือการใช้งานที่ปรากฏด้านบนนี้ดึงมาจาก มอดูล:Params/doc (แก้ | ประวัติ) ผู้เขียนสามารถทำการทดลองได้ที่กระบะทราย (สร้าง | คัดลอก) และชุดทดสอบ (สร้าง) ของมอดูลนี้ หน้าย่อยของมอดูลนี้ |
--- ---
--- LOCAL ENVIRONMENT ---
--- ________________________________ ---
--- ---
-- Special user-given keywords (functions and modifiers MUST avoid these names)
local mkeywords = {
-- ['pattern'] = false,
['plain'] = true,
['or'] = 0
}
-- Set directives
local memoryslots = {
i = 'itersep',
l = 'lastsep',
p = 'pairsep',
h = 'header',
f = 'footer',
n = 'ifngiven'
}
-- The private table of functions
local library = {}
-- Return a copy or a reference to a table
local function copy_or_ref_table(src, refonly)
if refonly then return src end
newtab = {}
for key, val in pairs(src) do newtab[key] = val end
return newtab
end
-- Prepare the context
local function context_init(frame, funcname, refpipe, refparams)
local ctx = {}
ctx.luaname = 'Module:Params' --[[ or `frame:getTitle()` ]]--
ctx.iterfunc = pairs
ctx.pipe = copy_or_ref_table(frame.args, refpipe)
ctx.frame = frame:getParent()
ctx.params = copy_or_ref_table(ctx.frame.args, refparams)
return funcname(ctx)
end
-- Move to the next action within the user-given list
local function context_iterate(ctx, n_forward)
local nextfn
if ctx.pipe[n_forward] ~= nil then
nextfn = ctx.pipe[n_forward]:match'^%s*(.*%S)'
end
if nextfn == nil then
error(ctx.luaname .. ': You must specify a function to call', 0)
end
if library[nextfn] == nil then
error(ctx.luaname .. ': The function ‘' .. nextfn .. '’ does not exist', 0)
end
for idx = n_forward, 1, -1 do table.remove(ctx.pipe, idx) end
return library[nextfn](ctx)
end
-- Concatenate the numerical keys from the table of parameters to the numerical
-- keys from the table of options; non-numerical keys from the table of options
-- will prevail over colliding non-numerical keys from the table of parameters
local function concat_params(ctx)
local shift = table.maxn(ctx.pipe)
local newargs = {}
if ctx.subset == 1 then
-- We need only the sequence
for key, val in ipairs(ctx.params) do
newargs[key + shift] = val
end
else
if ctx.subset == -1 then
for key, val in ipairs(ctx.params) do
ctx.params[key] = nil
end
end
for key, val in pairs(ctx.params) do
if type(key) == 'number' then
newargs[key + shift] = val
else
newargs[key] = val
end
end
end
for key, val in pairs(ctx.pipe) do newargs[key] = val end
return newargs
end
local function flush_params(ctx, fn)
local tbl = ctx.params
if ctx.subset == 1 then
for key, val in ipairs(tbl) do fn(key, val) end
return
end
if ctx.subset == -1 then
for key, val in ipairs(tbl) do tbl[key] = nil end
end
if ctx.dosort then
local nums = {}
local words = {}
for key, val in pairs(tbl) do
if type(key) == 'number' then
nums[#nums + 1] = key
else
words[#words + 1] = key
end
end
table.sort(nums)
table.sort(words)
for idx = 1, #nums do fn(nums[idx], tbl[nums[idx]]) end
for idx = 1, #words do fn(words[idx], tbl[words[idx]]) end
return
end
if ctx.subset ~= -1 then
for key, val in ipairs(tbl) do
fn(key, val)
tbl[key] = nil
end
end
for key, val in pairs(tbl) do fn(key, val) end
end
-- Parse the arguments of the `with_*_matching` class of modifiers
local function parse_match_args(opts, ptns, fname)
local state = 0
local cnt = 1
local keyw
for _, val in ipairs(opts) do
if state == 0 then
ptns[#ptns + 1] = { val, false }
state = -1
else
keyw = val:match'^%s*(.*%S)'
if keyw == nil or mkeywords[keyw] == nil then break
else
state = mkeywords[keyw]
if state ~= 0 then ptns[#ptns][2] = state end
end
end
cnt = cnt + 1
end
if state == 0 then error(ctx.luaname .. ', ‘' .. fname .. '’: No pattern was given', 0) end
return cnt
end
--[[ Library's modifiers ]]--
--------------------------------
-- See iface.sequential()
library.sequential = function(ctx)
if ctx.subset == -1 then error(ctx.luaname .. ': The two directives ‘non-sequential’ and ‘sequential’ are in contradiction with each other', 0) end
if ctx.dosort then error(ctx.luaname .. ': The ‘all_sorted’ directive is redundant when followed by ‘sequential’', 0) end
ctx.iterfunc = ipairs
ctx.subset = 1
return context_iterate(ctx, 1)
end
-- See iface['non-sequential']()
library['non-sequential'] = function(ctx)
if ctx.subset == 1 then error(ctx.luaname .. ': The two directives ‘sequential’ and ‘non-sequential’ are in contradiction with each other', 0) end
ctx.iterfunc = pairs
ctx.subset = -1
return context_iterate(ctx, 1)
end
-- See iface.all_sorted()
library.all_sorted = function(ctx)
if ctx.subset == 1 then error(ctx.luaname .. ': The ‘all_sorted’ directive is redundant after ‘sequential’', 0) end
ctx.dosort = true
return context_iterate(ctx, 1)
end
-- See iface.setting()
library.setting = function(ctx)
local opts = ctx.pipe
local cmd
if opts[1] ~= nil then
cmd = opts[1]:gsub('%s+', ''):gsub('/+', '/'):match'^/*(.*[^/])'
end
if cmd == nil then error(ctx.luaname .. ', ‘setting’: No directive was given', 0) end
local sep = string.byte('/')
local argc = 2
local dest = {}
local vname
local chr
for idx = 1, #cmd do
chr = cmd:byte(idx)
if chr == sep then
for key, val in ipairs(dest) do
ctx[val] = opts[argc]
dest[key] = nil
end
argc = argc + 1
else
vname = memoryslots[string.char(chr)]
if vname == nil then error(ctx.luaname .. ', ‘setting’: Unknown slot "' ..
string.char(chr) .. '"', 0) end
table.insert(dest, vname)
end
end
for key, val in ipairs(dest) do ctx[val] = opts[argc] end
return context_iterate(ctx, argc + 1)
end
-- See iface.squeezing()
library.squeezing = function(ctx)
local tbl = ctx.params
local store = {}
local indices = {}
for key, val in pairs(tbl) do
if type(key) == 'number' then
indices[#indices + 1] = key
store[key] = val
tbl[key] = nil
end
end
table.sort(indices)
for idx = 1, #indices do tbl[idx] = store[indices[idx]] end
return context_iterate(ctx, 1)
end
-- See iface.cutting()
library.cutting = function(ctx)
local lcut = tonumber(ctx.pipe[1])
if lcut == nil then error(ctx.luaname .. ', ‘cutting’: Left cut must be a number', 0) end
local rcut = tonumber(ctx.pipe[2])
if rcut == nil then error(ctx.luaname .. ', ‘cutting’: Right cut must be a number', 0) end
local tbl = ctx.params
local len = #tbl
if lcut < 0 then lcut = len + lcut end
if rcut < 0 then rcut = len + rcut end
local tot = lcut + rcut
if tot > 0 then
local cache = {}
if tot >= len then
for key, val in ipairs(tbl) do tbl[key] = nil end
tot = len
else
for idx = len - rcut + 1, len, 1 do tbl[idx] = nil end
for idx = 1, lcut, 1 do tbl[idx] = nil end
end
for key, val in pairs(tbl) do
if type(key) == 'number' and key > 0 then
if key > len then
cache[key - tot] = val
else
cache[key - lcut] = val
end
tbl[key] = nil
end
end
for key, val in pairs(cache) do tbl[key] = val end
end
return context_iterate(ctx, 3)
end
-- See iface.with_name_matching()
library.with_name_matching = function(ctx)
local tbl = ctx.params
local patterns = {}
local argc = parse_match_args(ctx.pipe, patterns, 'with_name_matching')
local nomatch
for key in pairs(tbl) do
nomatch = true
for _, ptn in ipairs(patterns) do
if string.find(key, ptn[1], 1, ptn[2]) then
nomatch = false
break
end
end
if nomatch then tbl[key] = nil end
end
return context_iterate(ctx, argc)
end
-- See iface.with_name_not_matching()
library.with_name_not_matching = function(ctx)
local tbl = ctx.params
local patterns = {}
local argc = parse_match_args(ctx.pipe, patterns,
'with_name_not_matching')
local yesmatch
for key in pairs(tbl) do
yesmatch = true
for _, ptn in ipairs(patterns) do
if not string.find(key, ptn[1], 1, ptn[2]) then
yesmatch = false
break
end
end
if yesmatch then tbl[key] = nil end
end
return context_iterate(ctx, argc)
end
-- See iface.with_value_matching()
library.with_value_matching = function(ctx)
local tbl = ctx.params
local patterns = {}
local argc = parse_match_args(ctx.pipe, patterns,
'with_value_matching')
local nomatch
for key, val in pairs(tbl) do
nomatch = true
for _, ptn in ipairs(patterns) do
if string.find(val, ptn[1], 1, ptn[2]) then
nomatch = false
break
end
end
if nomatch then tbl[key] = nil end
end
return context_iterate(ctx, argc)
end
-- See iface.with_value_not_matching()
library.with_value_not_matching = function(ctx)
local tbl = ctx.params
local patterns = {}
local argc = parse_match_args(ctx.pipe, patterns,
'with_value_not_matching')
local yesmatch
for key, val in pairs(tbl) do
yesmatch = true
for _, ptn in ipairs(patterns) do
if not string.find(val, ptn[1], 1, ptn[2]) then
yesmatch = false
break
end
end
if yesmatch then tbl[key] = nil end
end
return context_iterate(ctx, argc)
end
-- See iface.trimming_values()
library.trimming_values = function(ctx)
local tbl = ctx.params
for key, val in pairs(tbl) do tbl[key] = val:match'^%s*(.-)%s*$' end
return context_iterate(ctx, 1)
end
-- See iface.mapping_values_by_calling()
library.mapping_values_by_calling = function(ctx)
local opts = ctx.pipe
local tname
if opts[1] ~= nil then tname = opts[1]:match'^%s*(.*%S)' end
if tname == nil then error(ctx.luaname .. ', ‘mapping_values_by_calling’: No template name was provided', 0) end
local nargs
local margs = {}
local tmp = tonumber(opts[2])
if tmp == nil then
nargs = 1
elseif tmp < 1 then
nargs = 2
else
nargs = tmp + 2
for idx = 3, nargs do margs[idx] = opts[idx] end
end
local model = { title = tname, args = margs }
local tbl = ctx.params
if ctx.subset == 1 then
for key, val in ipairs(tbl) do
margs[1] = key
margs[2] = val
tbl[key] = ctx.frame:expandTemplate(model)
end
elseif ctx.subset == -1 then
tmp = {}
for key, val in pairs(tbl) do tmp[key] = true end
for key, val in ipairs(tmp) do tmp[key] = nil end
for key in pairs(tmp) do
margs[1] = key
margs[2] = tbl[key]
tbl[key] = ctx.frame:expandTemplate(model)
end
else
for key, val in pairs(tbl) do
margs[1] = key
margs[2] = val
tbl[key] = ctx.frame:expandTemplate(model)
end
end
return context_iterate(ctx, nargs + 1)
end
-- See iface.mapping_values_by_invoking()
library.mapping_values_by_invoking = function(ctx)
local opts = ctx.pipe
local mname
local fname
if opts[1] ~= nil then mname = opts[1]:match'^%s*(.*%S)' end
if mname == nil then error(ctx.luaname .. ', ‘mapping_values_by_invoking’: No module name was provided', 0) end
if opts[2] ~= nil then fname = opts[2]:match'^%s*(.*%S)' end
if fname == nil then error(ctx.luaname .. ', ‘mapping_values_by_invoking’: No function name was provided', 0) end
local nargs
local margs = {}
local tmp = tonumber(opts[3])
if tmp == nil then
nargs = 2
elseif tmp < 1 then
nargs = 3
else
nargs = tmp + 3
for idx = 4, nargs do margs[idx - 1] = opts[idx] end
end
local model = { title = 'Module:' .. mname, args = margs }
local mfunc = require(model.title)[fname]
local tbl = ctx.params
if ctx.subset == 1 then
for key, val in ipairs(tbl) do
margs[1] = key
margs[2] = val
tbl[key] = mfunc(ctx.frame:newChild(model))
end
elseif ctx.subset == -1 then
tmp = {}
for key, val in pairs(tbl) do tmp[key] = true end
for key, val in ipairs(tmp) do tmp[key] = nil end
for key in pairs(tmp) do
margs[1] = key
margs[2] = tbl[key]
tbl[key] = mfunc(ctx.frame:newChild(model))
end
else
for key, val in pairs(tbl) do
margs[1] = key
margs[2] = val
tbl[key] = mfunc(ctx.frame:newChild(model))
end
end
return context_iterate(ctx, nargs + 1)
end
-- See iface.mapping_values_blindly_by_calling()
library.mapping_values_blindly_by_calling = function(ctx)
local opts = ctx.pipe
local tname
if opts[1] ~= nil then tname = opts[1]:match'^%s*(.*%S)' end
if tname == nil then error(ctx.luaname .. ', ‘mapping_values_blindly_by_calling’: No template name was provided', 0) end
local nargs
local margs = {}
local tmp = tonumber(opts[2])
if tmp == nil then
nargs = 1
elseif tmp < 1 then
nargs = 2
else
nargs = tmp + 2
for idx = 3, nargs do margs[idx - 1] = opts[idx] end
end
local model = { title = tname, args = margs }
local tbl = ctx.params
if ctx.subset == 1 then
for key, val in ipairs(tbl) do
margs[1] = val
tbl[key] = ctx.frame:expandTemplate(model)
end
elseif ctx.subset == -1 then
tmp = {}
for key, val in pairs(tbl) do tmp[key] = true end
for key, val in ipairs(tmp) do tmp[key] = nil end
for key in pairs(tmp) do
margs[1] = tbl[key]
tbl[key] = ctx.frame:expandTemplate(model)
end
else
for key, val in pairs(tbl) do
margs[1] = val
tbl[key] = ctx.frame:expandTemplate(model)
end
end
return context_iterate(ctx, nargs + 1)
end
-- See iface.mapping_values_blindly_by_invoking()
library.mapping_values_blindly_by_invoking = function(ctx)
local opts = ctx.pipe
local mname
local fname
if opts[1] ~= nil then mname = opts[1]:match'^%s*(.*%S)' end
if mname == nil then error(ctx.luaname .. ', ‘mapping_values_blindly_by_invoking’: No module name was provided', 0) end
if opts[2] ~= nil then fname = opts[2]:match'^%s*(.*%S)' end
if fname == nil then error(ctx.luaname .. ', ‘mapping_values_blindly_by_invoking’: No function name was provided', 0) end
local nargs
local margs = {}
local tmp = tonumber(opts[3])
if tmp == nil then
nargs = 2
elseif tmp < 1 then
nargs = 3
else
nargs = tmp + 3
for idx = 4, nargs do margs[idx - 2] = opts[idx] end
end
local model = { title = 'Module:' .. mname, args = margs }
local mfunc = require(model.title)[fname]
local tbl = ctx.params
if ctx.subset == 1 then
for key, val in ipairs(tbl) do
margs[1] = val
tbl[key] = mfunc(ctx.frame:newChild(model))
end
elseif ctx.subset == -1 then
tmp = {}
for key, val in pairs(tbl) do tmp[key] = true end
for key, val in ipairs(tmp) do tmp[key] = nil end
for key in pairs(tmp) do
margs[1] = tbl[key]
tbl[key] = mfunc(ctx.frame:newChild(model))
end
else
for key, val in pairs(tbl) do
margs[1] = val
tbl[key] = mfunc(ctx.frame:newChild(model))
end
end
return context_iterate(ctx, nargs + 1)
end
--[[ Library's functions ]]--
------------------------------------
-- See iface.count()
library.count = function(ctx)
local count = 0
for _ in ctx.iterfunc(ctx.params) do count = count + 1 end
if ctx.subset == -1 then count = count - #ctx.params end
return count
end
-- See iface.concat_and_call()
library.concat_and_call = function(ctx)
local opts = ctx.pipe
local tname
if opts[1] ~= nil then tname = opts[1]:match'^%s*(.*%S)' end
if tname == nil then error(ctx.luaname .. ', ‘concat_and_call’: No template name was provided', 0) end
table.remove(opts, 1)
return ctx.frame:expandTemplate{
title = tname,
args = concat_params(ctx)
}
end
-- See iface.concat_and_invoke()
library.concat_and_invoke = function(ctx)
local opts = ctx.pipe
local mname
local fname
if opts[1] ~= nil then mname = opts[1]:match'^%s*(.*%S)' end
if mname == nil then error(ctx.luaname .. ', ‘concat_and_invoke’: No module name was provided', 0) end
if opts[2] ~= nil then fname = opts[2]:match'^%s*(.*%S)' end
if fname == nil then error(ctx.luaname .. ', ‘concat_and_invoke’: No function name was provided', 0) end
table.remove(opts, 2)
table.remove(opts, 1)
return require('Module:' .. mname)[fname](ctx.frame:newChild{
title = 'Module:' .. fname,
args = concat_params(ctx)
})
end
-- See iface.concat_and_magic()
library.concat_and_magic = function(ctx)
local opts = ctx.pipe
local magic
if opts[1] ~= nil then magic = opts[1]:match'^%s*(.*%S)' end
if magic == nil then error(ctx.luaname .. ', ‘concat_and_magic’: No parser function was provided', 0) end
table.remove(opts, 1)
return ctx.frame:callParserFunction(magic, concat_params(ctx))
end
-- See iface.value_of()
library.value_of = function(ctx)
local opts = ctx.pipe
local keystr
if opts[1] ~= nil then keystr = opts[1]:match'^%s*(.*%S)' end
if keystr == nil then error(ctx.luaname .. ', ‘value_of’: No parameter name was provided', 0) end
local keynum = tonumber(keystr)
if (
ctx.subset == -1 and keynum ~= nil and #ctx.params >= keynum
) or (
ctx.subset == 1 and (keynum == nil or #ctx.params < keynum)
) then return (ctx.ifngiven or '') end
local val = ctx.params[keynum or keystr]
if val == nil then return (ctx.ifngiven or '') end
return (ctx.header or '') .. val .. (ctx.footer or '')
end
-- See iface.list()
library.list = function(ctx)
local kvs = ctx.pairsep or ''
local pps = ctx.itersep or ''
local ret = {}
local nss = 0
flush_params(
ctx,
function(key, val)
ret[nss + 1] = pps
ret[nss + 2] = key
ret[nss + 3] = kvs
ret[nss + 4] = val
nss = nss + 4
end
)
if nss > 0 then
if nss > 4 and ctx.lastsep ~= nil then
ret[nss - 3] = ctx.lastsep
end
ret[1] = ctx.header or ''
if ctx.footer ~= nil then ret[nss + 1] = ctx.footer end
return table.concat(ret)
end
return ctx.ifngiven or ''
end
-- See iface.list_values()
library.list_values = function(ctx)
local pps = ctx.itersep or ''
local ret = {}
local nss = 0
flush_params(
ctx,
function(key, val)
ret[nss + 1] = pps
ret[nss + 2] = val
nss = nss + 2
end
)
if nss > 0 then
if nss > 2 and ctx.lastsep ~= nil then
ret[nss - 1] = ctx.lastsep
end
ret[1] = ctx.header or ''
if ctx.footer ~= nil then ret[nss + 1] = ctx.footer end
return table.concat(ret)
end
return ctx.ifngiven or ''
end
-- See iface.for_each()
library.for_each = function(ctx)
local txt = ctx.pipe[1] or ''
local pps = ctx.itersep or ''
local ret = {}
local nss = 0
flush_params(
ctx,
function(key, val)
ret[nss + 1] = pps
ret[nss + 2] = txt:gsub('%$#', key):gsub('%$@', val)
nss = nss + 2
end
)
if nss > 0 then
if nss > 2 and ctx.lastsep ~= nil then
ret[nss - 1] = ctx.lastsep
end
ret[1] = ctx.header or ''
if ctx.footer ~= nil then ret[nss + 1] = ctx.footer end
return table.concat(ret)
end
return ctx.ifngiven or ''
end
-- See iface.call_for_each()
library.call_for_each = function(ctx)
local opts = ctx.pipe
local tname
if opts[1] ~= nil then tname = opts[1]:match'^%s*(.*%S)' end
if tname == nil then error(ctx.luaname .. ', ‘call_for_each’: No template name was provided', 0) end
local model = { title = tname, args = opts }
local ccs = ctx.itersep or ''
local ret = {}
local nss = 0
table.insert(opts, 1, true)
flush_params(
ctx,
function(key, val)
opts[1] = key
opts[2] = val
ret[nss + 1] = ccs
ret[nss + 2] = ctx.frame:expandTemplate(model)
nss = nss + 2
end
)
if nss > 0 then
if nss > 2 and ctx.lastsep ~= nil then
ret[nss - 1] = ctx.lastsep
end
ret[1] = ctx.header or ''
if ctx.footer ~= nil then ret[nss + 1] = ctx.footer end
return table.concat(ret)
end
return ctx.ifngiven or ''
end
-- See iface.invoke_for_each()
library.invoke_for_each = function(ctx)
local opts = ctx.pipe
local mname
local fname
if opts[1] ~= nil then mname = opts[1]:match'^%s*(.*%S)' end
if mname == nil then error(ctx.luaname .. ', ‘invoke_for_each’: No module name was provided', 0) end
if opts[2] ~= nil then fname = opts[2]:match'^%s*(.*%S)' end
if fname == nil then error(ctx.luaname .. ', ‘invoke_for_each’: No function name was provided', 0) end
local model = { title = 'Module:' .. mname, args = opts }
local mfunc = require(model.title)[fname]
local ccs = ctx.itersep or ''
local ret = {}
local nss = 0
flush_params(
ctx,
function(key, val)
opts[1] = key
opts[2] = val
ret[nss + 1] = ccs
ret[nss + 2] = mfunc(ctx.frame:newChild(model))
nss = nss + 2
end
)
if nss > 0 then
if nss > 2 and ctx.lastsep ~= nil then
ret[nss - 1] = ctx.lastsep
end
ret[1] = ctx.header or ''
if ctx.footer ~= nil then ret[nss + 1] = ctx.footer end
return table.concat(ret)
end
return ctx.ifngiven or ''
end
-- See iface.magic_for_each()
library.magic_for_each = function(ctx)
local opts = ctx.pipe
local magic
if opts[1] ~= nil then magic = opts[1]:match'^%s*(.*%S)' end
if magic == nil then error(ctx.luaname .. ', ‘magic_for_each’: No parser function was provided', 0) end
local ccs = ctx.itersep or ''
local ret = {}
local nss = 0
table.insert(opts, 1, true)
flush_params(
ctx,
function(key, val)
opts[1] = key
opts[2] = val
ret[nss + 1] = ccs
ret[nss + 2] = ctx.frame:callParserFunction(magic,
opts)
nss = nss + 2
end
)
if nss > 0 then
if nss > 2 and ctx.lastsep ~= nil then
ret[nss - 1] = ctx.lastsep
end
ret[1] = ctx.header or ''
if ctx.footer ~= nil then ret[nss + 1] = ctx.footer end
return table.concat(ret)
end
return ctx.ifngiven or ''
end
-- See iface.call_for_each_value()
library.call_for_each_value = function(ctx)
local opts = ctx.pipe
local tname
if opts[1] ~= nil then tname = opts[1]:match'^%s*(.*%S)' end
if tname == nil then error(ctx.luaname .. ', ‘call_for_each_value’: No template name was provided', 0) end
local model = { title = tname, args = opts }
local ccs = ctx.itersep or ''
local ret = {}
local nss = 0
flush_params(
ctx,
function(key, val)
opts[1] = val
ret[nss + 1] = ccs
ret[nss + 2] = ctx.frame:expandTemplate(model)
nss = nss + 2
end
)
if nss > 0 then
if nss > 2 and ctx.lastsep ~= nil then
ret[nss - 1] = ctx.lastsep
end
ret[1] = ctx.header or ''
if ctx.footer ~= nil then ret[nss + 1] = ctx.footer end
return table.concat(ret)
end
return ctx.ifngiven or ''
end
-- See iface.invoke_for_each_value()
library.invoke_for_each_value = function(ctx)
local opts = ctx.pipe
local mname
local fname
if opts[1] ~= nil then mname = opts[1]:match'^%s*(.*%S)' end
if mname == nil then error(ctx.luaname .. ', ‘invoke_for_each_value’: No module name was provided', 0) end
if opts[2] ~= nil then fname = opts[2]:match'^%s*(.*%S)' end
if fname == nil then error(ctx.luaname .. ', ‘invoke_for_each_value’: No function name was provided', 0) end
local model = { title = 'Module:' .. mname, args = opts }
local mfunc = require(model.title)[fname]
local ccs = ctx.itersep or ''
local ret = {}
local nss = 0
table.remove(opts, 1)
flush_params(
ctx,
function(key, val)
opts[1] = val
ret[nss + 1] = ccs
ret[nss + 2] = mfunc(ctx.frame:newChild(model))
nss = nss + 2
end
)
if nss > 0 then
if nss > 2 and ctx.lastsep ~= nil then
ret[nss - 1] = ctx.lastsep
end
ret[1] = ctx.header or ''
if ctx.footer ~= nil then ret[nss + 1] = ctx.footer end
return table.concat(ret)
end
return ctx.ifngiven or ''
end
-- See iface.magic_for_each_value()
library.magic_for_each_value = function(ctx)
local opts = ctx.pipe
local magic
if opts[1] ~= nil then magic = opts[1]:match'^%s*(.*%S)' end
if magic == nil then error(ctx.luaname .. ', ‘magic_for_each_value’: No parser function was provided', 0) end
local ccs = ctx.itersep or ''
local ret = {}
local nss = 0
flush_params(
ctx,
function(key, val)
opts[1] = val
ret[nss + 1] = ccs
ret[nss + 2] = ctx.frame:callParserFunction(magic,
opts)
nss = nss + 2
end
)
if nss > 0 then
if nss > 2 and ctx.lastsep ~= nil then
ret[nss - 1] = ctx.lastsep
end
ret[1] = ctx.header or ''
if ctx.footer ~= nil then ret[nss + 1] = ctx.footer end
return table.concat(ret)
end
return ctx.ifngiven or ''
end
-- See iface.self()
library.self = function(ctx)
return ctx.frame:getTitle()
end
--- ---
--- PUBLIC ENVIRONMENT ---
--- ________________________________ ---
--- ---
-- The public table of functions
local iface = {}
--[[ Modifiers ]]--
------------------------------------
-- Syntax: #invoke:params|sequential|function name
iface.sequential = function(frame)
return context_init(frame, library.sequential, false, false)
end
-- Syntax: #invoke:params|non-sequential|function name
iface['non-sequential'] = function(frame)
return context_init(frame, library['non-sequential'], false, false)
end
-- Syntax: #invoke:params|sort|function name
iface.all_sorted = function(frame)
return context_init(frame, library.all_sorted, false, false)
end
-- Syntax: #invoke:params|setting|directives|...|function name
iface.setting = function(frame)
return context_init(frame, library.setting, false, false)
end
-- Syntax: #invoke:params|squeezing|function name
iface.squeezing = function(frame)
return context_init(frame, library.squeezing, false, false)
end
-- Syntax: #invoke:params|cutting|left cut|right cut|function name
iface.cutting = function(frame)
return context_init(frame, library.cutting, false, false)
end
-- Syntax: #invoke:params|with_name_matching|pattern 1|[plain flag 1]|[or]
-- |[pattern 2]|[plain flag 2]|[or]|[...]|[pattern N]|[plain flag
-- N]|function name
iface.with_name_matching = function(frame)
return context_init(frame, library.with_name_matching, false, false)
end
-- Syntax: #invoke:params|with_name_not_matching|pattern 1|[plain flag 1]
-- |[and]|[pattern 2]|[plain flag 2]|[and]|[...]|[pattern N]|[plain
-- flag N]|function name
iface.with_name_not_matching = function(frame)
return context_init(frame, library.with_name_not_matching, false,
false)
end
-- Syntax: #invoke:params|with_value_matching|pattern 1|[plain flag 1]|[or]
-- |[pattern 2]|[plain flag 2]|[or]|[...]|[pattern N]|[plain flag
-- N]|function name
iface.with_value_matching = function(frame)
return context_init(frame, library.with_value_matching, false, false)
end
-- Syntax: #invoke:params|with_value_not_matching|pattern 1|[plain flag 1]
-- |[and]|[pattern 2]|[plain flag 2]|[and]|[...]|[pattern N]|[plain
-- flag N]|function name
iface.with_value_not_matching = function(frame)
return context_init(frame, library.with_value_not_matching, false,
false)
end
-- Syntax: #invoke:params|trimming_values|function name
iface.trimming_values = function(frame)
return context_init(frame, library.trimming_values, false, false)
end
-- Syntax: #invoke:params|mapping_values_by_calling|template name|[number of additional
-- arguments]|[argument 1]|[argument 2]|[...]|[argument N]|function
-- name
iface.mapping_values_by_calling = function(frame)
return context_init(frame, library.mapping_values_by_calling, false, false)
end
-- Syntax: #invoke:params|mapping_values_by_invoking|module name|function name|[number of
-- additional arguments]|[argument 1]|[argument 2]|[...]|[argument
-- N]|function name
iface.mapping_values_by_invoking = function(frame)
return context_init(frame, library.mapping_values_by_invoking, false, false)
end
-- Syntax: #invoke:params|mapping_values_blindly_by_calling|template name|[number of
-- additional arguments]|[argument 1]|[argument 2]|[...]|[argument
-- N]|function name
iface.mapping_values_blindly_by_calling = function(frame)
return context_init(frame, library.mapping_values_blindly_by_calling, false,
false)
end
-- Syntax: #invoke:params|mapping_values_blindly_by_invoking|module name|function name
-- |[number of additional arguments]|[argument 1]|[argument 2]|[...]
-- |[argument N]|function name
iface.mapping_values_blindly_by_invoking = function(frame)
return context_init(frame, library.mapping_values_blindly_by_invoking, false,
false)
end
--[[ Functions ]]--
----------------------------------------
-- Syntax: #invoke:params|count
iface.count = function(frame)
return context_init(frame, library.count, true, true)
end
-- Syntax: #invoke:args|concat_and_call|template name|[prepend 1]|[prepend 2]
-- |[...]|[item n]|[named item 1=value 1]|[...]|[named item n=value
-- n]|[...]
iface.concat_and_call = function(frame)
return context_init(frame, library.concat_and_call, false, true)
end
-- Syntax: #invoke:args|concat_and_invoke|module name|function name|[prepend
-- 1]|[prepend 2]|[...]|[item n]|[named item 1=value 1]|[...]|[named
-- item n=value n]|[...]
iface.concat_and_invoke = function(frame)
return context_init(frame, library.concat_and_invoke, false, true)
end
-- Syntax: #invoke:args|concat_and_magic|parser function|[prepend 1]|[prepend
-- 2]|[...]|[item n]|[named item 1=value 1]|[...]|[named item n=
-- value n]|[...]
iface.concat_and_magic = function(frame)
return context_init(frame, library.concat_and_magic, false, true)
end
-- Syntax: #invoke:params|value_of|parameter name
iface.value_of = function(frame)
return context_init(frame, library.value_of, true, true)
end
-- Syntax: #invoke:params|list
iface.list = function(frame)
return context_init(frame, library.list, true, false)
end
-- Syntax: #invoke:params|list_values
iface.list_values = function(frame)
return context_init(frame, library.list_values, true, false)
end
-- Syntax: #invoke:params|for_each|wikitext
iface.for_each = function(frame)
return context_init(frame, library.for_each, true, false)
end
-- Syntax: #invoke:params|call_for_each|template name|[append 1]|[append 2]
-- |[...]|[append n]|[named param 1=value 1]|[...]|[named param
-- n=value n]|[...]
iface.call_for_each = function(frame)
return context_init(frame, library.call_for_each, false, false)
end
-- Syntax: #invoke:params|invoke_for_each|module name|module function|[append
-- 1]|[append 2]|[...]|[append n]|[named param 1=value 1]|[...]
-- |[named param n=value n]|[...]
iface.invoke_for_each = function(frame)
return context_init(frame, library.invoke_for_each, false, false)
end
-- Syntax: #invoke:params|magic_for_each|parser function|[append 1]|[append 2]
-- |[...]|[append n]|[named param 1=value 1]|[...]|[named param
-- n=value n]|[...]
iface.magic_for_each = function(frame)
return context_init(frame, library.magic_for_each, false, false)
end
-- Syntax: #invoke:params|call_for_each_value|template name|[append 1]|[append
-- 2]|[...]|[append n]|[named param 1=value 1]|[...]|[named param
-- n=value n]|[...]
iface.call_for_each_value = function(frame)
return context_init(frame, library.call_for_each_value, false, false)
end
-- Syntax: #invoke:params|invoke_for_each_value|module name|[append 1]|[append
-- 2]|[...]|[append n]|[named param 1=value 1]|[...]|[named param
-- n=value n]|[...]
iface.invoke_for_each_value = function(frame)
return context_init(frame, library.invoke_for_each_value, false, false)
end
-- Syntax: #invoke:params|magic_for_each_value|parser function|[append 1]
-- |[append 2]|[...]|[append n]|[named param 1=value 1]|[...]|[named
-- param n=value n]|[...]
iface.magic_for_each_value = function(frame)
return context_init(frame, library.magic_for_each_value, false, false)
end
-- Syntax: #invoke:params|self
iface.self = function(frame)
return frame:getParent():getTitle()
end
return iface