Module:Params: Difference between revisions
From All Skies Encyclopaedia
imported>Grufo m Internal nomenclature (no changes) |
imported>Grufo New functions `magic_for_each` and `magic_for_each_value`; new `setting` modifier; structural changes in all iterating functions; general code review |
||
| Line 5: | Line 5: | ||
-- | -- Set directives | ||
local | local slots = { | ||
i = 'itersep', | |||
p = 'pairsep', | |||
h = 'header', | |||
f = 'footer', | |||
n = 'ifngiven' | |||
} | |||
| Line 39: | Line 41: | ||
-- Move to the next action within the user-given list | -- Move to the next action within the user-given list | ||
local function context_iterate(ctx, n_forward) | local function context_iterate(ctx, n_forward) | ||
local nextfn = ctx.pipe[n_forward]:match'^%s*(.*%S)' | local nextfn | ||
if ctx.pipe[n_forward] ~= nil then | |||
nextfn = ctx.pipe[n_forward]:match'^%s*(.*%S)' | |||
end | |||
if nextfn == nil then | if nextfn == nil then | ||
error(' | error('End of arguments reached without a function call', 0) | ||
end | end | ||
if library[nextfn] == nil then | if library[nextfn] == nil then | ||
| Line 92: | Line 97: | ||
-- See iface | -- See iface['non-sequential']() | ||
library['non-sequential'] = function(ctx) | library['non-sequential'] = function(ctx) | ||
if ctx.subset == 1 then | if ctx.subset == 1 then | ||
| Line 101: | Line 106: | ||
for key, val in ipairs(ctx.params) do ctx.params[key] = nil end | for key, val in ipairs(ctx.params) do ctx.params[key] = nil end | ||
return context_iterate(ctx, 1) | return context_iterate(ctx, 1) | ||
end | |||
-- See iface.setting() | |||
library.setting = function(ctx) | |||
local opts = ctx.pipe | |||
local cmd = (opts[1] or | |||
''):gsub('%s+', ''):gsub('/+', '/'):match'^/*(.*[^/])' | |||
if cmd == nil then | |||
error('No directive was given about what variables to set', 0) | |||
end | |||
local target = string.byte('/') | |||
local arglen = 2 | |||
local aggregate = {} | |||
local varname | |||
local chr | |||
for idx = 1, #cmd do | |||
chr = cmd:byte(idx) | |||
if chr == target then | |||
for key, val in ipairs(aggregate) do | |||
ctx[val] = opts[arglen] | |||
aggregate[key] = nil | |||
end | |||
arglen = arglen + 1 | |||
else | |||
varname = slots[string.char(chr)] | |||
if varname == nil then error('Unknown slot "' .. | |||
string.char(chr) .. '"', 0) end | |||
table.insert(aggregate, varname) | |||
end | |||
end | |||
for key, val in ipairs(aggregate) do ctx[val] = opts[arglen] end | |||
return context_iterate(ctx, arglen + 1) | |||
end | end | ||
| Line 182: | Line 228: | ||
for _ in ctx.iterfunc(ctx.params) do count = count + 1 end | for _ in ctx.iterfunc(ctx.params) do count = count + 1 end | ||
return count | return count | ||
end | |||
-- See iface.concat_and_call() | |||
library.concat_and_call = function(ctx) | |||
local opts = ctx.pipe | |||
local tname = opts[1] | |||
if tname == nil then error('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 = opts[1] | |||
if mname == nil then error('No module name was provided', 0) end | |||
if opts[2] == nil then error('No function name was provided', 0) end | |||
local fname = opts[2]:match'^%s*(.*%S)' | |||
table.remove(opts, 2) | |||
table.remove(opts, 1) | |||
return require('Module:' .. mname)[fname](ctx.frame:newChild{ | |||
title = 'Module:' .. fname, | |||
args = concat_params(ctx) | |||
}) | |||
end | end | ||
| Line 191: | Line 277: | ||
if keystr == '' then error('No parameter name was provided', 0) end | if keystr == '' then error('No parameter name was provided', 0) end | ||
local val = ctx.params[tonumber(keystr) or keystr] | local val = ctx.params[tonumber(keystr) or keystr] | ||
if val == nil then return '' end | if val == nil then return (ctx.ifngiven or '') end | ||
return ( | return (ctx.header or '') .. val .. (ctx.footer or '') | ||
end | end | ||
| Line 200: | Line 285: | ||
library.list = function(ctx) | library.list = function(ctx) | ||
local | local pps = ctx.itersep or '' | ||
local kvs = ctx.pairsep or '' | |||
local kvs | local sep = ctx.header or '' | ||
local las = ctx.footer or '' | |||
local foo = ctx.ifngiven or '' | |||
local | |||
local ret = '' | local ret = '' | ||
if ctx.subset ~= -1 then | if ctx.subset ~= -1 then | ||
for key, val in ipairs(ctx.params) do | for key, val in ipairs(ctx.params) do | ||
ret = ret | ret = ret .. sep .. key .. kvs .. val | ||
sep = | sep = pps | ||
foo = las | foo = las | ||
ctx.params[key] = nil | ctx.params[key] = nil | ||
| Line 227: | Line 303: | ||
if ctx.subset ~= 1 then | if ctx.subset ~= 1 then | ||
for key, val in pairs(ctx.params) do | for key, val in pairs(ctx.params) do | ||
ret = ret | ret = ret .. sep .. key .. kvs .. val | ||
sep = | sep = pps | ||
foo = las | foo = las | ||
end | end | ||
| Line 242: | Line 317: | ||
library.list_values = function(ctx) | library.list_values = function(ctx) | ||
local | local pps = ctx.itersep or '' | ||
local sep = ctx.header or '' | |||
local las = ctx.footer or '' | |||
local foo = ctx.ifngiven or '' | |||
local sep = '' | |||
local | |||
local ret = '' | local ret = '' | ||
if ctx.subset ~= -1 then | if ctx.subset ~= -1 then | ||
for key, val in ipairs(ctx.params) do | for key, val in ipairs(ctx.params) do | ||
ret = ret | ret = ret .. sep .. val | ||
sep = | sep = pps | ||
foo = las | foo = las | ||
ctx.params[key] = nil | ctx.params[key] = nil | ||
| Line 267: | Line 334: | ||
if ctx.subset ~= 1 then | if ctx.subset ~= 1 then | ||
for key, val in pairs(ctx.params) do | for key, val in pairs(ctx.params) do | ||
ret = ret | ret = ret .. sep .. val | ||
sep = | sep = pps | ||
foo = las | foo = las | ||
end | end | ||
| Line 282: | Line 348: | ||
library.for_each = function(ctx) | library.for_each = function(ctx) | ||
local las | local pps = ctx.itersep or '' | ||
local | local las = ctx.footer or '' | ||
local sep = ctx.header or '' | |||
local foo = ctx.ifngiven or '' | |||
local txt = ctx.pipe[1] | local txt = ctx.pipe[1] | ||
local ret = '' | local ret = '' | ||
if ctx.subset ~= -1 then | if ctx.subset ~= -1 then | ||
for key, val in ipairs(ctx.params) do | for key, val in ipairs(ctx.params) do | ||
ret = ret .. | ret = ret .. sep .. string.gsub( | ||
string.gsub(txt, '%$#', key), | string.gsub(txt, '%$#', key), | ||
'%$@', | '%$@', | ||
val | val | ||
) | ) | ||
sep = pps | |||
foo = las | foo = las | ||
ctx.params[key] = nil | ctx.params[key] = nil | ||
| Line 308: | Line 370: | ||
if ctx.subset ~= 1 then | if ctx.subset ~= 1 then | ||
for key, val in pairs(ctx.params) do | for key, val in pairs(ctx.params) do | ||
ret = ret .. | ret = ret .. sep .. string.gsub( | ||
string.gsub(txt, '%$#', key), | string.gsub(txt, '%$#', key), | ||
'%$@', | '%$@', | ||
val | val | ||
) | ) | ||
sep = pps | |||
foo = las | foo = las | ||
end | end | ||
| Line 323: | Line 385: | ||
-- See iface. | -- See iface.call_for_each() | ||
library. | library.call_for_each = function(ctx) | ||
local opts = ctx.pipe | local opts = ctx.pipe | ||
if | if opts[1] == nil then error('No template name was provided', 0) end | ||
local ccs = ctx.itersep or '' | |||
local sep = ctx.header or '' | |||
local las = ctx.footer or '' | |||
local foo = ctx.ifngiven or '' | |||
local ret = '' | |||
local model = { title = opts[1]:match'^%s*(.*%S)', args = opts } | |||
table.insert(opts, 1, true) | |||
if ctx.subset ~= -1 then | |||
for key, val in ipairs(ctx.params) do | |||
opts[1] = key | |||
opts[2] = val | |||
ret = ret .. sep .. ctx.frame:expandTemplate(model) | |||
sep = ccs | |||
foo = las | |||
ctx.params[key] = nil | |||
end | |||
end | |||
if ctx.subset ~= 1 then | |||
for key, val in pairs(ctx.params) do | |||
opts[1] = key | |||
opts[2] = val | |||
ret = ret .. sep .. ctx.frame:expandTemplate(model) | |||
sep = ccs | |||
foo = las | |||
end | |||
end | |||
return ret .. foo | |||
return | |||
end | end | ||
-- See iface. | -- See iface.invoke_for_each() | ||
library. | library.invoke_for_each = function(ctx) | ||
local opts = ctx.pipe | local opts = ctx.pipe | ||
if opts[1] == nil then error('No | if opts[1] == nil then error('No module name was provided', 0) end | ||
if opts[2] == nil then error('No function name was provided', 0) end | |||
local ccs = ctx.itersep or '' | |||
local sep = ctx.header or '' | |||
local las = ctx.footer or '' | |||
local foo = ctx.ifngiven or '' | |||
local ret = '' | local ret = '' | ||
local model = { title = 'Module:' .. opts[1]:match'^%s*(.*%S)', args = opts } | |||
local mfunc = require(model.title)[opts[2]:match'^%s*(.*%S)'] | |||
if ctx.subset ~= -1 then | if ctx.subset ~= -1 then | ||
| Line 379: | Line 449: | ||
opts[1] = key | opts[1] = key | ||
opts[2] = val | opts[2] = val | ||
ret = ret .. ctx.frame: | ret = ret .. sep .. mfunc(ctx.frame:newChild(model)) | ||
sep = ccs | |||
foo = las | |||
ctx.params[key] = nil | ctx.params[key] = nil | ||
end | end | ||
| Line 388: | Line 460: | ||
opts[1] = key | opts[1] = key | ||
opts[2] = val | opts[2] = val | ||
ret = ret .. ctx.frame: | ret = ret .. sep .. mfunc(ctx.frame:newChild(model)) | ||
sep = ccs | |||
foo = las | |||
end | end | ||
end | end | ||
return ret | return ret .. foo | ||
end | end | ||
-- See iface. | -- See iface.magic_for_each() | ||
library. | library.magic_for_each = function(ctx) | ||
local opts = ctx.pipe | local opts = ctx.pipe | ||
if opts[1] == nil then error('No | if opts[1] == nil then error('No template name was provided', 0) end | ||
local ccs = ctx.itersep or '' | |||
local sep = ctx.header or '' | |||
local las = ctx.footer or '' | |||
local foo = ctx.ifngiven or '' | |||
local magic = opts[1]:match'^%s*(.*%S)' | |||
local ret = '' | local ret = '' | ||
table.insert(opts, 1, true) | |||
if ctx.subset ~= -1 then | if ctx.subset ~= -1 then | ||
| Line 413: | Line 491: | ||
opts[1] = key | opts[1] = key | ||
opts[2] = val | opts[2] = val | ||
ret = ret .. | ret = ret .. sep .. ctx.frame:callParserFunction(magic, opts) | ||
sep = ccs | |||
foo = las | |||
ctx.params[key] = nil | ctx.params[key] = nil | ||
end | end | ||
| Line 422: | Line 502: | ||
opts[1] = key | opts[1] = key | ||
opts[2] = val | opts[2] = val | ||
ret = ret .. | ret = ret .. sep .. ctx.frame:callParserFunction(magic, opts) | ||
sep = ccs | |||
foo = las | |||
end | end | ||
end | end | ||
return ret | return ret .. foo | ||
end | end | ||
| Line 438: | Line 520: | ||
if opts[1] == nil then error('No template name was provided', 0) end | if opts[1] == nil then error('No template name was provided', 0) end | ||
local ccs = ctx.itersep or '' | |||
local sep = ctx.header or '' | |||
local las = ctx.footer or '' | |||
local foo = ctx.ifngiven or '' | |||
local ret = '' | local ret = '' | ||
local model = { title = opts[1], args = opts } | |||
local model = { title = opts[1]:match'^%s*(.*%S)', args = opts } | |||
if ctx.subset ~= -1 then | if ctx.subset ~= -1 then | ||
for key, val in ipairs(ctx.params) do | for key, val in ipairs(ctx.params) do | ||
opts[1] = val | opts[1] = val | ||
ret = ret .. ctx.frame:expandTemplate(model) | ret = ret .. sep .. ctx.frame:expandTemplate(model) | ||
sep = ccs | |||
foo = las | |||
ctx.params[key] = nil | ctx.params[key] = nil | ||
end | end | ||
| Line 452: | Line 541: | ||
for key, val in pairs(ctx.params) do | for key, val in pairs(ctx.params) do | ||
opts[1] = val | opts[1] = val | ||
ret = ret .. ctx.frame:expandTemplate(model) | ret = ret .. sep .. ctx.frame:expandTemplate(model) | ||
sep = ccs | |||
foo = las | |||
end | end | ||
end | end | ||
return ret | return ret .. foo | ||
end | end | ||
| Line 469: | Line 560: | ||
if opts[2] == nil then error('No function name was provided', 0) end | if opts[2] == nil then error('No function name was provided', 0) end | ||
local ccs = ctx.itersep or '' | |||
local sep = ctx.header or '' | |||
local las = ctx.footer or '' | |||
local foo = ctx.ifngiven or '' | |||
local ret = '' | local ret = '' | ||
local model = { title = 'Module:' .. opts[1], args = opts } | |||
local model = { title = 'Module:' .. opts[1]:match'^%s*(.*%S)', args = opts } | |||
local mfunc = require(model.title)[opts[2]:match'^%s*(.*%S)'] | local mfunc = require(model.title)[opts[2]:match'^%s*(.*%S)'] | ||
| Line 478: | Line 574: | ||
for key, val in ipairs(ctx.params) do | for key, val in ipairs(ctx.params) do | ||
opts[1] = val | opts[1] = val | ||
ret = ret .. mfunc(ctx.frame:newChild(model)) | ret = ret .. sep .. mfunc(ctx.frame:newChild(model)) | ||
sep = ccs | |||
foo = las | |||
ctx.params[key] = nil | |||
end | |||
end | |||
if ctx.subset ~= 1 then | |||
for key, val in pairs(ctx.params) do | |||
opts[1] = val | |||
ret = ret .. sep .. mfunc(ctx.frame:newChild(model)) | |||
sep = ccs | |||
foo = las | |||
end | |||
end | |||
return ret .. foo | |||
end | |||
-- See iface.magic_for_each_value() | |||
library.magic_for_each_value = function(ctx) | |||
local opts = ctx.pipe | |||
if opts[1] == nil then error('No template name was provided', 0) end | |||
local ccs = ctx.itersep or '' | |||
local sep = ctx.header or '' | |||
local las = ctx.footer or '' | |||
local foo = ctx.ifngiven or '' | |||
local magic = opts[1]:match'^%s*(.*%S)' | |||
local ret = '' | |||
if ctx.subset ~= -1 then | |||
for key, val in ipairs(ctx.params) do | |||
opts[1] = val | |||
ret = ret .. sep .. ctx.frame:callParserFunction(magic, opts) | |||
sep = ccs | |||
foo = las | |||
ctx.params[key] = nil | ctx.params[key] = nil | ||
end | end | ||
| Line 486: | Line 622: | ||
for key, val in pairs(ctx.params) do | for key, val in pairs(ctx.params) do | ||
opts[1] = val | opts[1] = val | ||
ret = ret .. | ret = ret .. sep .. ctx.frame:callParserFunction(magic, opts) | ||
sep = ccs | |||
foo = las | |||
end | end | ||
end | end | ||
return ret | return ret .. foo | ||
end | end | ||
| Line 520: | Line 658: | ||
iface['non-sequential'] = function(frame) | iface['non-sequential'] = function(frame) | ||
return context_init(frame, library['non-sequential'], false, false) | return context_init(frame, library['non-sequential'], false, false) | ||
end | |||
-- Syntax: #invoke:params|setting|directives|...|function name | |||
iface.setting = function(frame) | |||
return context_init(frame, library.setting, false, false) | |||
end | end | ||
| Line 564: | Line 708: | ||
-- Syntax: #invoke: | -- 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:params|value_of|parameter name | |||
iface.value_of = function(frame) | iface.value_of = function(frame) | ||
return context_init(frame, library.value_of, true, true) | return context_init(frame, library.value_of, true, true) | ||
| Line 570: | Line 730: | ||
-- Syntax: #invoke:params|list | -- Syntax: #invoke:params|list | ||
iface.list = function(frame) | iface.list = function(frame) | ||
return context_init(frame, library.list, true, false) | return context_init(frame, library.list, true, false) | ||
| Line 577: | Line 736: | ||
-- Syntax: #invoke:params|list_values | -- Syntax: #invoke:params|list_values | ||
iface.list_values = function(frame) | iface.list_values = function(frame) | ||
return context_init(frame, library.list_values, true, false) | return context_init(frame, library.list_values, true, false) | ||
| Line 583: | Line 742: | ||
-- Syntax: #invoke:params|for_each|wikitext | -- Syntax: #invoke:params|for_each|wikitext | ||
iface.for_each = function(frame) | iface.for_each = function(frame) | ||
return context_init(frame, library.for_each, true, false) | return context_init(frame, library.for_each, true, false) | ||
end | end | ||
| Line 621: | Line 764: | ||
-- Syntax: #invoke:params|call_for_each_value|template name|[append 1] | -- 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) | iface.call_for_each_value = function(frame) | ||
return context_init(frame, library.call_for_each_value, false, false) | return context_init(frame, library.call_for_each_value, false, false) | ||
| Line 629: | Line 780: | ||
-- Syntax: #invoke:params|invoke_for_each_value|module name | -- 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) | iface.invoke_for_each_value = function(frame) | ||
return context_init(frame, library.invoke_for_each_value, false, false) | 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 | end | ||
return iface | return iface | ||
Revision as of 07:19, 12 July 2023
Documentation for this module may be created at Module:Params/doc
--- ---
--- LOCAL ENVIRONMENT ---
--- ________________________________ ---
--- ---
-- Set directives
local slots = {
i = 'itersep',
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.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('End of arguments reached without a function call', 0)
end
if library[nextfn] == nil then
error('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
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
--[[ Piping piped functions ]]--
--------------------------------
-- See iface.sequential()
library.sequential = function(ctx)
if ctx.subset == -1 then
error('The two directives `non-sequential` and `sequential` are in contradiction with each other', 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('The two directives `sequential` and `non-sequential` are in contradiction with each other', 0)
end
ctx.iterfunc = pairs
ctx.subset = -1
for key, val in ipairs(ctx.params) do ctx.params[key] = nil end
return context_iterate(ctx, 1)
end
-- See iface.setting()
library.setting = function(ctx)
local opts = ctx.pipe
local cmd = (opts[1] or
''):gsub('%s+', ''):gsub('/+', '/'):match'^/*(.*[^/])'
if cmd == nil then
error('No directive was given about what variables to set', 0)
end
local target = string.byte('/')
local arglen = 2
local aggregate = {}
local varname
local chr
for idx = 1, #cmd do
chr = cmd:byte(idx)
if chr == target then
for key, val in ipairs(aggregate) do
ctx[val] = opts[arglen]
aggregate[key] = nil
end
arglen = arglen + 1
else
varname = slots[string.char(chr)]
if varname == nil then error('Unknown slot "' ..
string.char(chr) .. '"', 0) end
table.insert(aggregate, varname)
end
end
for key, val in ipairs(aggregate) do ctx[val] = opts[arglen] end
return context_iterate(ctx, arglen + 1)
end
-- See iface.cutting()
library.cutting = function(ctx)
local lcut = tonumber(ctx.pipe[1])
if lcut == nil then error('Left trim must be a number', 0) end
local rcut = tonumber(ctx.pipe[2])
if rcut == nil then error('Right trim must be a number', 0) end
if ctx.subset == -1 then return context_iterate(ctx, 3) end
local tbl = ctx.params
local tlen = #tbl
if lcut < 0 then lcut = tlen + lcut end
if rcut < 0 then rcut = tlen + rcut end
if lcut + rcut > 0 then
if lcut + rcut >= tlen then
for key, val in ipairs(tbl) do tbl[key] = nil end
else
local last = tlen - rcut + 1
for idx = tlen, last, -1 do tbl[idx] = nil end
for _ = 1, lcut, 1 do table.remove(tbl, 1) end
end
end
return context_iterate(ctx, 3)
end
-- See iface.with_name_matching()
library.with_name_matching = function(ctx)
for key, val in ctx.iterfunc(ctx.params) do
if not string.find(key, ctx.pipe[1], 1, false) then
ctx.params[key] = nil
end
end
return context_iterate(ctx, 2)
end
-- See iface.with_name_not_matching()
library.with_name_not_matching = function(ctx)
for key, val in ctx.iterfunc(ctx.params) do
if string.find(key, ctx.pipe[1], 1, false) then
ctx.params[key] = nil
end
end
return context_iterate(ctx, 2)
end
-- See iface.with_value_matching()
library.with_value_matching = function(ctx)
for key, val in ctx.iterfunc(ctx.params) do
if not string.find(val, ctx.pipe[1], 1, false) then
ctx.params[key] = nil
end
end
return context_iterate(ctx, 2)
end
-- See iface.with_value_not_matching()
library.with_value_not_matching = function(ctx)
for key, val in ctx.iterfunc(ctx.params) do
if string.find(val, ctx.pipe[1], 1, false) then
ctx.params[key] = nil
end
end
return context_iterate(ctx, 2)
end
--[[ Non-piping piped functions ]]--
------------------------------------
-- See iface.count()
library.count = function(ctx)
local count = 0
for _ in ctx.iterfunc(ctx.params) do count = count + 1 end
return count
end
-- See iface.concat_and_call()
library.concat_and_call = function(ctx)
local opts = ctx.pipe
local tname = opts[1]
if tname == nil then error('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 = opts[1]
if mname == nil then error('No module name was provided', 0) end
if opts[2] == nil then error('No function name was provided', 0) end
local fname = opts[2]:match'^%s*(.*%S)'
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.value_of()
library.value_of = function(ctx)
local opts = ctx.pipe
local keystr = (opts[1] or ''):match'^%s*(.*%S)'
if keystr == '' then error('No parameter name was provided', 0) end
local val = ctx.params[tonumber(keystr) 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 pps = ctx.itersep or ''
local kvs = ctx.pairsep or ''
local sep = ctx.header or ''
local las = ctx.footer or ''
local foo = ctx.ifngiven or ''
local ret = ''
if ctx.subset ~= -1 then
for key, val in ipairs(ctx.params) do
ret = ret .. sep .. key .. kvs .. val
sep = pps
foo = las
ctx.params[key] = nil
end
end
if ctx.subset ~= 1 then
for key, val in pairs(ctx.params) do
ret = ret .. sep .. key .. kvs .. val
sep = pps
foo = las
end
end
return ret .. foo
end
-- See iface.list_values()
library.list_values = function(ctx)
local pps = ctx.itersep or ''
local sep = ctx.header or ''
local las = ctx.footer or ''
local foo = ctx.ifngiven or ''
local ret = ''
if ctx.subset ~= -1 then
for key, val in ipairs(ctx.params) do
ret = ret .. sep .. val
sep = pps
foo = las
ctx.params[key] = nil
end
end
if ctx.subset ~= 1 then
for key, val in pairs(ctx.params) do
ret = ret .. sep .. val
sep = pps
foo = las
end
end
return ret .. foo
end
-- See iface.for_each()
library.for_each = function(ctx)
local pps = ctx.itersep or ''
local las = ctx.footer or ''
local sep = ctx.header or ''
local foo = ctx.ifngiven or ''
local txt = ctx.pipe[1]
local ret = ''
if ctx.subset ~= -1 then
for key, val in ipairs(ctx.params) do
ret = ret .. sep .. string.gsub(
string.gsub(txt, '%$#', key),
'%$@',
val
)
sep = pps
foo = las
ctx.params[key] = nil
end
end
if ctx.subset ~= 1 then
for key, val in pairs(ctx.params) do
ret = ret .. sep .. string.gsub(
string.gsub(txt, '%$#', key),
'%$@',
val
)
sep = pps
foo = las
end
end
return ret .. foo
end
-- See iface.call_for_each()
library.call_for_each = function(ctx)
local opts = ctx.pipe
if opts[1] == nil then error('No template name was provided', 0) end
local ccs = ctx.itersep or ''
local sep = ctx.header or ''
local las = ctx.footer or ''
local foo = ctx.ifngiven or ''
local ret = ''
local model = { title = opts[1]:match'^%s*(.*%S)', args = opts }
table.insert(opts, 1, true)
if ctx.subset ~= -1 then
for key, val in ipairs(ctx.params) do
opts[1] = key
opts[2] = val
ret = ret .. sep .. ctx.frame:expandTemplate(model)
sep = ccs
foo = las
ctx.params[key] = nil
end
end
if ctx.subset ~= 1 then
for key, val in pairs(ctx.params) do
opts[1] = key
opts[2] = val
ret = ret .. sep .. ctx.frame:expandTemplate(model)
sep = ccs
foo = las
end
end
return ret .. foo
end
-- See iface.invoke_for_each()
library.invoke_for_each = function(ctx)
local opts = ctx.pipe
if opts[1] == nil then error('No module name was provided', 0) end
if opts[2] == nil then error('No function name was provided', 0) end
local ccs = ctx.itersep or ''
local sep = ctx.header or ''
local las = ctx.footer or ''
local foo = ctx.ifngiven or ''
local ret = ''
local model = { title = 'Module:' .. opts[1]:match'^%s*(.*%S)', args = opts }
local mfunc = require(model.title)[opts[2]:match'^%s*(.*%S)']
if ctx.subset ~= -1 then
for key, val in ipairs(ctx.params) do
opts[1] = key
opts[2] = val
ret = ret .. sep .. mfunc(ctx.frame:newChild(model))
sep = ccs
foo = las
ctx.params[key] = nil
end
end
if ctx.subset ~= 1 then
for key, val in pairs(ctx.params) do
opts[1] = key
opts[2] = val
ret = ret .. sep .. mfunc(ctx.frame:newChild(model))
sep = ccs
foo = las
end
end
return ret .. foo
end
-- See iface.magic_for_each()
library.magic_for_each = function(ctx)
local opts = ctx.pipe
if opts[1] == nil then error('No template name was provided', 0) end
local ccs = ctx.itersep or ''
local sep = ctx.header or ''
local las = ctx.footer or ''
local foo = ctx.ifngiven or ''
local magic = opts[1]:match'^%s*(.*%S)'
local ret = ''
table.insert(opts, 1, true)
if ctx.subset ~= -1 then
for key, val in ipairs(ctx.params) do
opts[1] = key
opts[2] = val
ret = ret .. sep .. ctx.frame:callParserFunction(magic, opts)
sep = ccs
foo = las
ctx.params[key] = nil
end
end
if ctx.subset ~= 1 then
for key, val in pairs(ctx.params) do
opts[1] = key
opts[2] = val
ret = ret .. sep .. ctx.frame:callParserFunction(magic, opts)
sep = ccs
foo = las
end
end
return ret .. foo
end
-- See iface.call_for_each_value()
library.call_for_each_value = function(ctx)
local opts = ctx.pipe
if opts[1] == nil then error('No template name was provided', 0) end
local ccs = ctx.itersep or ''
local sep = ctx.header or ''
local las = ctx.footer or ''
local foo = ctx.ifngiven or ''
local ret = ''
local model = { title = opts[1]:match'^%s*(.*%S)', args = opts }
if ctx.subset ~= -1 then
for key, val in ipairs(ctx.params) do
opts[1] = val
ret = ret .. sep .. ctx.frame:expandTemplate(model)
sep = ccs
foo = las
ctx.params[key] = nil
end
end
if ctx.subset ~= 1 then
for key, val in pairs(ctx.params) do
opts[1] = val
ret = ret .. sep .. ctx.frame:expandTemplate(model)
sep = ccs
foo = las
end
end
return ret .. foo
end
-- See iface.invoke_for_each_value()
library.invoke_for_each_value = function(ctx)
local opts = ctx.pipe
if opts[1] == nil then error('No module name was provided', 0) end
if opts[2] == nil then error('No function name was provided', 0) end
local ccs = ctx.itersep or ''
local sep = ctx.header or ''
local las = ctx.footer or ''
local foo = ctx.ifngiven or ''
local ret = ''
local model = { title = 'Module:' .. opts[1]:match'^%s*(.*%S)', args = opts }
local mfunc = require(model.title)[opts[2]:match'^%s*(.*%S)']
table.remove(opts, 1)
if ctx.subset ~= -1 then
for key, val in ipairs(ctx.params) do
opts[1] = val
ret = ret .. sep .. mfunc(ctx.frame:newChild(model))
sep = ccs
foo = las
ctx.params[key] = nil
end
end
if ctx.subset ~= 1 then
for key, val in pairs(ctx.params) do
opts[1] = val
ret = ret .. sep .. mfunc(ctx.frame:newChild(model))
sep = ccs
foo = las
end
end
return ret .. foo
end
-- See iface.magic_for_each_value()
library.magic_for_each_value = function(ctx)
local opts = ctx.pipe
if opts[1] == nil then error('No template name was provided', 0) end
local ccs = ctx.itersep or ''
local sep = ctx.header or ''
local las = ctx.footer or ''
local foo = ctx.ifngiven or ''
local magic = opts[1]:match'^%s*(.*%S)'
local ret = ''
if ctx.subset ~= -1 then
for key, val in ipairs(ctx.params) do
opts[1] = val
ret = ret .. sep .. ctx.frame:callParserFunction(magic, opts)
sep = ccs
foo = las
ctx.params[key] = nil
end
end
if ctx.subset ~= 1 then
for key, val in pairs(ctx.params) do
opts[1] = val
ret = ret .. sep .. ctx.frame:callParserFunction(magic, opts)
sep = ccs
foo = las
end
end
return ret .. foo
end
--- ---
--- PUBLIC ENVIRONMENT ---
--- ________________________________ ---
--- ---
-- The public table of functions
local iface = {}
--[[ Piping interface functions ]]--
------------------------------------
-- 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|setting|directives|...|function name
iface.setting = function(frame)
return context_init(frame, library.setting, false, false)
end
-- Syntax: #invoke:params|cutting|left trim|right trim|function name
iface.cutting = function(frame)
return context_init(frame, library.cutting, false, false)
end
-- Syntax: #invoke:params|with_name_matching|pattern|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|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|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|function name
iface.with_value_not_matching = function(frame)
return context_init(frame, library.with_value_not_matching, false, false)
end
--[[ Non-piping interface 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: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
return iface






