--- --- --- LOCAL ENVIRONMENT --- --- ________________________________ --- --- ---
--Abstract utilities -- ----------------------------
-- Helper function for `string.gsub` (for managing zero-padded numbers)function zero_padded(str) return ("%03d%s"):format(#str, str)end
-- Helper function for `table.sort` (for natural sorting)function natural_sort(var1, var2) return tostring(var1):gsub("%d+", zero_padded) < tostring(var2):gsub("%d+", zero_padded)end
-- Return a copy or a reference to a tablelocal 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 newtabend
-- Remove numerical elements from a table, shifting everything to the leftfunction remove_numerical_keys(tbl, idx, len) local cache = local tmp = idx + len - 1 for key, val in pairs(tbl) do if type(key)
-- Make a reduced copy of a table (shifting in both directions if necessary)function copy_table_reduced(tbl, idx, len) local ret = local tmp = idx + len - 1 if idx > 0 then for key, val in pairs(tbl) do if type(key) ~= 'number' or key < idx then ret[key] = val elseif key > tmp then ret[key - len] = val end end elseif tmp > 0 then local nshift = 1 - idx for key, val in pairs(tbl) do if type(key) ~= 'number' then ret[key] = val elseif key > tmp then ret[key - tmp] = val elseif key < idx then ret[key + nshift] = val end end else for key, val in pairs(tbl) do if type(key) ~= 'number' or key > tmp then ret[key] = val elseif key < idx then ret[key + len] = val end end end return retend
-- Make an expanded copy of a table (shifting in both directions if necessary)function copy_table_expanded(tbl, idx, len) local ret = local tmp = idx + len - 1 if idx > 0 then for key, val in pairs(tbl) do if type(key) ~= 'number' or key < idx then ret[key] = val else ret[key + len] = val end end elseif tmp > 0 then local nshift = idx - 1 for key, val in pairs(tbl) do if type(key) ~= 'number' then ret[key] = val elseif key > 0 then ret[key + tmp] = val elseif key < 1 then ret[key + nshift] = val end end else for key, val in pairs(tbl) do if type(key) ~= 'number' or key > tmp then ret[key] = val else ret[key - len] = val end end end return retend
-- Move a key from a table to another, but only if under a different name and-- always parsing numerical strings as numbersfunction steal_if_renamed(val, src, skey, dest, dkey) local realkey = tonumber(dkey) or dkey:match'^%s*(.-)%s*$' if skey ~= realkey then dest[realkey] = val src[skey] = nil endend
--Public strings -- ------------------------
-- Special match keywords (functions and modifiers MUST avoid these names)local mkeywords =
-- Sort functions (functions and modifiers MUST avoid these names)local sortfunctions =
-- Callback styles for the `mapping_*` and `renaming_*` class of modifiers-- (functions and modifiers MUST avoid these names)----local mapping_styles =
-- Memory slots (functions and modifiers MUST avoid these names)local memoryslots =
-- Functions and modifiers MUST avoid these names too: `let`
--Module's private environment -- --------------------------------------
-- Maximum number of numerical parameters that can be filled, if missing (we-- chose an arbitrary number for this constant; you can discuss about its-- optimal value at Module talk:Params)local maxfill = 1024
-- The private table of functionslocal library =
-- Functions that can only be invoked in first positionlocal static_iface =
-- Create a new contextlocal function context_new local ctx = ctx.luaname = 'Module:Params' ---- ctx.iterfunc = pairs ctx.firstposonly = static_iface ctx.n_available = maxfill return ctxend
-- Move to the next action within the user-given listlocal 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 if ctx.firstposonly[nextfn]
-- Main looplocal function main_loop(ctx, start_with) local fn = start_with repeat fn = fn(ctx) until not fnend
-- Parse the arguments of the `mapping_*` and `renaming_*` class of modifiersfunction parse_child_args(dest, src, n_skip, default_style) local style local shf local tmp = src[n_skip + 1] if tmp ~= nil then style = mapping_styles[tmp:match'^%s*(.-)%s*$'] end if style
nil then karg = tmp:match'^%s*(.-)%s*$' else n_exist = math.max(n_exist, karg) end end tmp = style[7] if tmp > -1 then tmp = src[tmp + shf] varg = tonumber(tmp) if varg
nil or not src[pin]:match'^%s*let%s*$' end tmp = tonumber(src[pin]) if tmp ~= nil then if tmp < 0 then tmp = -1 end shf = n_exist - pin for idx = pin + 1, pin + tmp do dest[idx + shf] = src[idx] end nargs = pin + tmp + 1 else nargs = pin end if names ~= nil then for key, val in pairs(names) do dest[key] = val end end tmp = style[1] if (tmp
2) and dest[karg] ~= nil then tmp = tmp - 2 end if (tmp
1) and dest[varg] ~= nil then tmp = tmp - 1 end return nargs, tmp, karg, vargend
-- Parse the arguments of the `with_*_matching` class of modifierslocal function parse_pattern_args(ctx, ptns, fname) local state = 0 local cnt = 1 local keyw local nptns = 0 for _, val in ipairs(ctx.pipe) do if state
nil or mkeywords[keyw]
3 then ptns[nptns][3] = true end end end cnt = cnt + 1 end if state
-- Map parameters' values using a custom callback and a referenced tablefunction map_values(tbl, margs, karg, varg, looptype, fn) if looptype
3 then for key, val in pairs(tbl) do margs[karg] = key margs[varg] = val tbl[key] = fn end elseif looptype
0 then for key in pairs(tbl) do tbl[key] = fn end endend
-- Map parameters' names using a custom callback and a referenced tablefunction map_names(tbl, rargs, karg, varg, looptype, fn) local cache = if looptype
3 then for key, val in pairs(tbl) do rargs[karg] = key rargs[varg] = val steal_if_renamed(val, tbl, key, cache, fn) end elseif looptype
0 then for key, val in pairs(tbl) do steal_if_renamed(val, tbl, key, cache, fn) end end for key, val in pairs(cache) do tbl[key] = val endend
-- 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 parameterslocal function concat_params(ctx) local tbl = ctx.params local size = table.maxn(ctx.pipe) local retval = if ctx.subset
-1 then for key, val in ipairs(tbl) do tbl[key] = nil end end for key, val in pairs(tbl) do if type(key)
-- Flush the parameters by calling a custom function for each value (after this-- function has been invoked `ctx.params` will be no longer usable)local function flush_params(ctx, fn) local tbl = ctx.params 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 = local nlen = 0 local wlen = 0 for key, val in pairs(tbl) do if type(key)
--Modifiers -- -----------------------------
-- Syntax: #invoke:params|sequential|pipe tolibrary.sequential = function(ctx) if ctx.subset
-- Syntax: #invoke:params|non-sequential|pipe tolibrary['non-sequential'] = function(ctx) if ctx.subset
-- Syntax: #invoke:params|sort|pipe tolibrary.all_sorted = function(ctx) if ctx.subset
-- Syntax: #invoke:params|setting|directives|...|pipe tolibrary.setting = function(ctx) local opts = ctx.pipe local cmd = opts[1] if cmd ~= nil then cmd = cmd:gsub('%s+', ):gsub('/+', '/'):match'^/*(.*[^/])' end if cmd
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
-- Syntax: #invoke:params|squeezing|pipe tolibrary.squeezing = function(ctx) local tbl = ctx.params local store = local indices = local newlen = 0 for key, val in pairs(tbl) do if type(key)
-- Syntax: #invoke:params|filling_the_gaps|pipe tolibrary.filling_the_gaps = function(ctx) local tbl = ctx.params local nmin = 1 local nmax = nil local nnums = -1 local tmp = for key, val in pairs(tbl) do if type(key)
nil then if key < nmin then nmin = key end nmax = key elseif key > nmax then nmax = key elseif key < nmin then nmin = key end nnums = nnums + 1 tmp[key] = val end end if nmax ~= nil and nmax - nmin > nnums then ctx.n_available = ctx.n_available + nmin + nnums - nmax if ctx.n_available < 0 then error(ctx.luaname .. ', ‘filling_the_gaps’: It is possible to fill at most ' .. tostring(maxfill) .. ' parameters', 0) end for idx = nmin, nmax, 1 do tbl[idx] = end for key, val in pairs(tmp) do tbl[key] = val end end return context_iterate(ctx, 1)end
-- Syntax: #invoke:params|clearing|pipe tolibrary.clearing = function(ctx) local tbl = ctx.params local numericals = for key, val in pairs(tbl) do if type(key)
-- Syntax: #invoke:params|cutting|left cut|right cut|pipe tolibrary.cutting = function(ctx) local lcut = tonumber(ctx.pipe[1]) if lcut
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 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)
-- Syntax: #invoke:params|cropping|left crop|right crop|pipe tolibrary.cropping = function(ctx) local lcut = tonumber(ctx.pipe[1]) if lcut
nil then error(ctx.luaname .. ', ‘cropping’: Right crop must be a number', 0) end local tbl = ctx.params local nmin local nmax for key in pairs(tbl) do if type(key)
nil then nmin = key nmax = key elseif key > nmax then nmax = key elseif key < nmin then nmin = key end end end if nmin ~= nil then local len = nmax - nmin + 1 if lcut < 0 then lcut = len + lcut end if rcut < 0 then rcut = len + rcut end if lcut + rcut - len > -1 then for key in pairs(tbl) do if type(key)
-- Syntax: #invoke:params|purging|start offset|length|pipe tolibrary.purging = function(ctx) local idx = tonumber(ctx.pipe[1]) if idx
nil then error(ctx.luaname .. ', ‘purging’: Length must be a number', 0) end local tbl = ctx.params if len < 1 then len = len + table.maxn(tbl) if idx > len then return context_iterate(ctx, 3) end len = len - idx + 1 end ctx.params = copy_table_reduced(tbl, idx, len) return context_iterate(ctx, 3)end
-- Syntax: #invoke:params|backpurging|start offset|length|pipe tolibrary.backpurging = function(ctx) local last = tonumber(ctx.pipe[1]) if last
nil then error(ctx.luaname .. ', ‘backpurging’: Length must be a number', 0) end local idx local tbl = ctx.params if len > 0 then idx = last - len + 1 else for key in pairs(tbl) do if type(key)
nil or key < idx) then idx = key end end if idx
-- Syntax: #invoke:params|rotating|pipe tolibrary.rotating = function(ctx) local tbl = ctx.params local numericals = local nmax = 0 for key, val in pairs(tbl) do if type(key)
-- Syntax: #invoke:params|pivoting|pipe to--library.pivoting = function(ctx) local tbl = ctx.params local shift = #tbl + 1 if shift < 2 then return library.rotating(ctx) end local numericals = for key, val in pairs(tbl) do if type(key)
-- Syntax: #invoke:params|mirroring|pipe to--library.mirroring = function(ctx) local tbl = ctx.params local numericals = local nmax local nmin for key, val in pairs(tbl) do if type(key)
nil then nmax = key nmin = key elseif key > nmax then nmax = key elseif key < nmin then nmin = key end end end for key, val in pairs(numericals) do tbl[nmax + nmin - key] = val end return context_iterate(ctx, 1)end
---- Syntax: #invoke:params|swapping|pipe to--library.swapping = function(ctx) local tbl = ctx.params local cache = local nsize = 0 local tmp for key in pairs(tbl) do if type(key)
-- Syntax: #invoke:params|sorting_sequential_values|[criterion]|pipe tolibrary.sorting_sequential_values = function(ctx) local sortfn if ctx.pipe[1] ~= nil then sortfn = sortfunctions[ctx.pipe[1]] end if sortfn then table.sort(ctx.params, sortfn) else table.sort(ctx.params) end -- i.e. either `false` or `nil` if sortfn
-- Syntax: #invoke:params|inserting|position|how many|...|pipe to----
-- Syntax: #invoke:params|imposing|name|value|pipe tolibrary.imposing = function(ctx) if ctx.pipe[1]
-- Syntax: #invoke:params|discarding|name|[how many]|pipe tolibrary.discarding = function(ctx) if ctx.pipe[1]
nil then ctx.params[tonumber(key) or key:match'^%s*(.-)%s*$'] = nil return context_iterate(ctx, 2) end key = tonumber(key) if key
-- Syntax: #invoke:params|with_name_matching|pattern 1|[plain flag 1]|[or]-- |[pattern 2]|[plain flag 2]|[or]|[...]|[pattern N]|[plain flag -- N]|pipe tolibrary.with_name_matching = function(ctx) local tbl = ctx.params local patterns = local argc = parse_pattern_args(ctx, patterns, 'with_name_matching') local nomatch for key in pairs(tbl) do nomatch = true for _, ptn in ipairs(patterns) do if not ptn[3] then if string.find(key, ptn[1], 1, ptn[2]) then nomatch = false break end elseif key
-- Syntax: #invoke:params|with_name_not_matching|pattern 1|[plain flag 1]-- |[and]|[pattern 2]|[plain flag 2]|[and]|[...]|[pattern N]|[plain -- flag N]|pipe tolibrary.with_name_not_matching = function(ctx) local tbl = ctx.params local patterns = local argc = parse_pattern_args(ctx, patterns, 'with_name_not_matching') local yesmatch for key in pairs(tbl) do yesmatch = true for _, ptn in ipairs(patterns) do if ptn[3] then if key ~= ptn[1] then yesmatch = false break end elseif 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
-- Syntax: #invoke:params|with_value_matching|pattern 1|[plain flag 1]|[or]-- |[pattern 2]|[plain flag 2]|[or]|[...]|[pattern N]|[plain flag -- N]|pipe tolibrary.with_value_matching = function(ctx) local tbl = ctx.params local patterns = local argc = parse_pattern_args(ctx, patterns, 'with_value_matching') local nomatch for key, val in pairs(tbl) do nomatch = true for _, ptn in ipairs(patterns) do if ptn[3] then if val
-- Syntax: #invoke:params|with_value_not_matching|pattern 1|[plain flag 1]-- |[and]|[pattern 2]|[plain flag 2]|[and]|[...]|[pattern N]|[plain -- flag N]|pipe tolibrary.with_value_not_matching = function(ctx) local tbl = ctx.params local patterns = local argc = parse_pattern_args(ctx, patterns, 'with_value_not_matching') local yesmatch for key, val in pairs(tbl) do yesmatch = true for _, ptn in ipairs(patterns) do if ptn[3] then if val ~= ptn[1] then yesmatch = false break end elseif 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
-- Syntax: #invoke:params|trimming_values|pipe tolibrary.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
-- Syntax: #invoke:params|mapping_by_calling|template name|[call -- style]|[let]|[...][number of additional parameters]|[parameter -- 1]|[parameter 2]|[...]|[parameter N]|pipe tolibrary.mapping_by_calling = function(ctx) local opts = ctx.pipe local tname if opts[1] ~= nil then tname = opts[1]:match'^%s*(.*%S)' end if tname
-- Syntax: #invoke:params|mapping_by_invoking|module name|function-- name|[call style]|[let]|[...]|[number of additional -- arguments]|[argument 1]|[argument 2]|[...]|[argument N]|pipe tolibrary.mapping_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_by_invoking’: No function name was provided', 0) end local margs = local argc, looptype, karg, varg = parse_child_args(margs, opts, 2, mapping_styles.values_only) local model = local mfunc = require(model.title)[fname] if mfunc
-- Syntax: #invoke:params|mapping_by_magic|parser function|[call -- style]|[let]|[...][number of additional arguments]|[argument -- 1]|[argument 2]|[...]|[argument N]|pipe tolibrary.mapping_by_magic = function(ctx) local opts = ctx.pipe local magic if opts[1] ~= nil then magic = opts[1]:match'^%s*(.*%S)' end if magic
-- Syntax: #invoke:params|renaming_by_calling|template name|[call -- style]|[let]|[...][number of additional parameters]|[parameter -- 1]|[parameter 2]|[...]|[parameter N]|pipe tolibrary.renaming_by_calling = function(ctx) local opts = ctx.pipe local tname if opts[1] ~= nil then tname = opts[1]:match'^%s*(.*%S)' end if tname
-- Syntax: #invoke:params|renaming_by_invoking|module name|function-- name|[call style]|[let]|[...]|[number of additional -- arguments]|[argument 1]|[argument 2]|[...]|[argument N]|pipe tolibrary.renaming_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 .. ', ‘renaming_by_invoking’: No function name was provided', 0) end local rargs = local argc, looptype, karg, varg = parse_child_args(rargs, opts, 2, mapping_styles.names_only) local model = local mfunc = require(model.title)[fname] if mfunc
-- Syntax: #invoke:params|renaming_by_magic|parser function|[call -- style]|[let]|[...][number of additional arguments]|[argument -- 1]|[argument 2]|[...]|[argument N]|pipe tolibrary.renaming_by_magic = function(ctx) local opts = ctx.pipe local magic if opts[1] ~= nil then magic = opts[1]:match'^%s*(.*%S)' end if magic
--Functions -- -----------------------------
-- Syntax: #invoke:params|countlibrary.count = function(ctx) -- NOTE: `ctx.pipe` and `ctx.params` might be the original metatables! local retval = 0 for _ in ctx.iterfunc(ctx.params) do retval = retval + 1 end if ctx.subset
-- Syntax: #invoke:args|concat_and_call|template name|[prepend 1]|[prepend 2]-- |[...]|[item n]|[named item 1=value 1]|[...]|[named item n=value -- n]|[...]library.concat_and_call = function(ctx) -- NOTE: `ctx.params` might be the original metatable! local opts = ctx.pipe local tname if opts[1] ~= nil then tname = opts[1]:match'^%s*(.*%S)' end if tname
-- 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]|[...]library.concat_and_invoke = function(ctx) -- NOTE: `ctx.params` might be the original metatable! 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 function name was provided', 0) end remove_numerical_keys(opts, 1, 2) local mfunc = require('Module:' .. mname)[fname] if mfunc
-- Syntax: #invoke:args|concat_and_magic|parser function|[prepend 1]|[prepend -- 2]|[...]|[item n]|[named item 1=value 1]|[...]|[named item n= -- value n]|[...]library.concat_and_magic = function(ctx) -- NOTE: `ctx.params` might be the original metatable! local opts = ctx.pipe local magic if opts[1] ~= nil then magic = opts[1]:match'^%s*(.*%S)' end if magic
-- Syntax: #invoke:params|value_of|parameter namelibrary.value_of = function(ctx) -- NOTE: `ctx.pipe` and `ctx.params` might be the original metatables! local opts = ctx.pipe local kstr if opts[1] ~= nil then kstr = opts[1]:match'^%s*(.*%S)' end if kstr
nil or knum > len or knum < 1 ) and (ctx.subset ~= 1 or (knum ~= nil and knum <= len and knum > 0) ) then ctx.text = (ctx.header or ) .. val .. (ctx.footer or ) return false end ctx.text = ctx.ifngiven or return falseend
-- Syntax: #invoke:params|listlibrary.list = function(ctx) -- NOTE: `ctx.pipe` might be the original metatable! 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 ctx.text = table.concat(ret) return false end ctx.text = ctx.ifngiven or return falseend
-- Syntax: #invoke:params|list_valueslibrary.list_values = function(ctx) -- NOTE: `ctx.pipe` might be the original metatable! 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 ctx.text = table.concat(ret) return false end ctx.text = ctx.ifngiven or return falseend
-- Syntax: #invoke:params|for_each|wikitextlibrary.for_each = function(ctx) -- NOTE: `ctx.pipe` might be the original metatable! 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 ctx.text = table.concat(ret) return false end ctx.text = ctx.ifngiven or return falseend
-- Syntax: #invoke:params|call_for_each|template name|[append 1]|[append 2]-- |[...]|[append n]|[named param 1=value 1]|[...]|[named param -- n=value n]|[...]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
-- 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]|[...]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 function name was provided', 0) end local model = 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 ctx.text = table.concat(ret) return false end ctx.text = ctx.ifngiven or return falseend
-- Syntax: #invoke:params|magic_for_each|parser function|[append 1]|[append 2]-- |[...]|[append n]|[named param 1=value 1]|[...]|[named param -- n=value n]|[...]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
-- 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]|[...]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
-- 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]|[...]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 function name was provided', 0) end local model = local mfunc = require(model.title)[fname] local ccs = ctx.itersep or local ret = local nss = 0 remove_numerical_keys(opts, 1, 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 ctx.text = table.concat(ret) return false end ctx.text = ctx.ifngiven or return falseend
-- 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]|[...]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
-- Syntax: #invoke:params|call_for_each_group|template name|[append 1]|[append -- 2]|[...]|[append n]|[named param 1=value 1]|[...]|[named param -- n=value n]|[...]library.call_for_each_group = function(ctx) -- NOTE: `ctx.pipe` and `ctx.params` might be the original metatables! local opts = ctx.pipe local tmp if opts[1] ~= nil then tmp = opts[1]:match'^%s*(.*%S)' end if tmp
'number' then opts[key - 1] = val else opts[key] = val end end ctx.pipe = opts for key, val in pairs(ctx.params) do prefix, gid = tostring(key):match'^%s*(.-)%s*(%-?%d*)%s*$' gid = tonumber(gid) or if groups[gid]
--- --- --- PUBLIC ENVIRONMENT --- --- ________________________________ --- --- ---
--First-position-only modifiers -- ---------------------------------------
-- Syntax: #invoke:params|new|pipe to----
--First-position-only functions -- ---------------------------------------
-- Syntax: #invoke:params|selfstatic_iface.self = function(frame) return frame:getParent:getTitleend
--Public metatable of functions -- ---------------------------------------
return setmetatable(static_iface,)