Permanently protected module
From Wikipedia, the free encyclopedia


	---                                        ---

	---     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 newtabkey = 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.pipen_forward ~= nil then

		nextfn = ctx.pipen_forward]:match'^%s*(.*%S)'

	end

	if nextfn == nil then

		error(ctx.luaname .. ': You must specify a function to call', 0)

	end

	if librarynextfn == 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 librarynextfn](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

			newargskey + shift = val

		end

	else

		if ctx.subset == -1 then

			for key, val in ipairs(ctx.params) do

				ctx.paramskey = nil

			end

		end

		for key, val in pairs(ctx.params) do

			if type(key) == 'number' then

				newargskey + shift = val

			else

				newargskey = val

			end

		end

	end

	for key, val in pairs(ctx.pipe) do newargskey = 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 tblkey = 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) == 'number' then

				nlen = nlen + 1

				numsnlen = key

			else

				wlen = wlen + 1

				wordswlen = key

			end



		end

		table.sort(nums)

		table.sort(words)

		for idx = 1, nlen do fn(numsidx], tblnumsidx]]) end

		for idx = 1, wlen do fn(wordsidx], tblwordsidx]]) end

		return

	end

	if ctx.subset ~= -1 then

		for key, val in ipairs(tbl) do

			fn(key, val)

			tblkey = 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

	local nptns = 0

	for _, val in ipairs(opts) do

		if state == 0 then

			nptns = nptns + 1

			ptnsnptns = { val, false }

			state = -1

		else

			keyw = val:match'^%s*(.*%S)'

			if keyw == nil or mkeywordskeyw == nil then break

			else

				state = mkeywordskeyw

				if state ~= 0 then ptnsnptns][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 opts1 ~= nil then

		cmd = opts1]: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

				ctxval = optsargc

				destkey = nil

			end

			argc = argc + 1

		else

			vname = memoryslotsstring.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 ctxval = optsargc end

	return context_iterate(ctx, argc + 1)

end





-- See iface.squeezing()

library.squeezing = function(ctx)

	local tbl = ctx.params

	local store = {}

	local indices = {}

	local newlen = 0

	for key, val in pairs(tbl) do

		if type(key) == 'number' then

			newlen = newlen + 1

			indicesnewlen = key

			storekey = val

			tblkey = nil

		end

	end

	table.sort(indices)

	for idx = 1, newlen do tblidx = storeindicesidx]] end

	return context_iterate(ctx, 1)

end





-- See iface.cutting()

library.cutting = function(ctx)

	local lcut = tonumber(ctx.pipe1])

	if lcut == nil then error(ctx.luaname .. ', ‘cutting’: Left cut must be a number', 0) end

	local rcut = tonumber(ctx.pipe2])

	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 tblkey = nil end

			tot = len

		else

			for idx = len - rcut + 1, len, 1 do tblidx = nil end

			for idx = 1, lcut, 1 do tblidx = nil end

		end

		for key, val in pairs(tbl) do

			if type(key) == 'number' and key > 0 then

				if key > len then

					cachekey - tot = val

				else

					cachekey - lcut = val

				end

				tblkey = nil

			end

		end

		for key, val in pairs(cache) do tblkey = 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, ptn1], 1, ptn2]) then

				nomatch = false

				break

			end

		end

		if nomatch then tblkey = 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, ptn1], 1, ptn2]) then

				yesmatch = false

				break

			end

		end

		if yesmatch then tblkey = 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, ptn1], 1, ptn2]) then

				nomatch = false

				break

			end

		end

		if nomatch then tblkey = 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, ptn1], 1, ptn2]) then

				yesmatch = false

				break

			end

		end

		if yesmatch then tblkey = 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 tblkey = 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 opts1 ~= nil then tname = opts1]: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(opts2])

	if tmp == nil then

		nargs = 1

	elseif tmp < 1 then

		nargs = 2

	else

		nargs = tmp + 2

		for idx = 3, nargs do margsidx = optsidx end

	end

	local model = { title = tname, args = margs }

	local tbl = ctx.params

	if ctx.subset == 1 then

		for key, val in ipairs(tbl) do

			margs1 = key

			margs2 = val

			tblkey = ctx.frame:expandTemplate(model)

		end

	elseif ctx.subset == -1 then

		tmp = {}

		for key, val in pairs(tbl) do tmpkey = true end

		for key, val in ipairs(tmp) do tmpkey = nil end

		for key in pairs(tmp) do

			margs1 = key

			margs2 = tblkey

			tblkey = ctx.frame:expandTemplate(model)

		end

	else

		for key, val in pairs(tbl) do

			margs1 = key

			margs2 = val

			tblkey = 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 opts1 ~= nil then mname = opts1]:match'^%s*(.*%S)' end

	if mname == nil then error(ctx.luaname .. ', ‘mapping_values_by_invoking’: No module name was provided', 0) end

	if opts2 ~= nil then fname = opts2]: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(opts3])

	if tmp == nil then

		nargs = 2

	elseif tmp < 1 then

		nargs = 3

	else

		nargs = tmp + 3

		for idx = 4, nargs do margsidx - 1 = optsidx 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

			margs1 = key

			margs2 = val

			tblkey = mfunc(ctx.frame:newChild(model))

		end

	elseif ctx.subset == -1 then

		tmp = {}

		for key, val in pairs(tbl) do tmpkey = true end

		for key, val in ipairs(tmp) do tmpkey = nil end

		for key in pairs(tmp) do

			margs1 = key

			margs2 = tblkey

			tblkey = mfunc(ctx.frame:newChild(model))

		end

	else

		for key, val in pairs(tbl) do

			margs1 = key

			margs2 = val

			tblkey = 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 opts1 ~= nil then tname = opts1]: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(opts2])

	if tmp == nil then

		nargs = 1

	elseif tmp < 1 then

		nargs = 2

	else

		nargs = tmp + 2

		for idx = 3, nargs do margsidx - 1 = optsidx end

	end

	local model = { title = tname, args = margs }

	local tbl = ctx.params

	if ctx.subset == 1 then

		for key, val in ipairs(tbl) do

			margs1 = val

			tblkey = ctx.frame:expandTemplate(model)

		end

	elseif ctx.subset == -1 then

		tmp = {}

		for key, val in pairs(tbl) do tmpkey = true end

		for key, val in ipairs(tmp) do tmpkey = nil end

		for key in pairs(tmp) do

			margs1 = tblkey

			tblkey = ctx.frame:expandTemplate(model)

		end

	else

		for key, val in pairs(tbl) do

			margs1 = val

			tblkey = 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 opts1 ~= nil then mname = opts1]:match'^%s*(.*%S)' end

	if mname == nil then error(ctx.luaname .. ', ‘mapping_values_blindly_by_invoking’: No module name was provided', 0) end

	if opts2 ~= nil then fname = opts2]: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(opts3])

	if tmp == nil then

		nargs = 2

	elseif tmp < 1 then

		nargs = 3

	else

		nargs = tmp + 3

		for idx = 4, nargs do margsidx - 2 = optsidx 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

			margs1 = val

			tblkey = mfunc(ctx.frame:newChild(model))

		end

	elseif ctx.subset == -1 then

		tmp = {}

		for key, val in pairs(tbl) do tmpkey = true end

		for key, val in ipairs(tmp) do tmpkey = nil end

		for key in pairs(tmp) do

			margs1 = tblkey

			tblkey = mfunc(ctx.frame:newChild(model))

		end

	else

		for key, val in pairs(tbl) do

			margs1 = val

			tblkey = 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 opts1 ~= nil then tname = opts1]: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 opts1 ~= nil then mname = opts1]:match'^%s*(.*%S)' end

	if mname == nil then error(ctx.luaname .. ', ‘concat_and_invoke’: No module name was provided', 0) end

	if opts2 ~= nil then fname = opts2]: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 opts1 ~= nil then magic = opts1]: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 opts1 ~= nil then keystr = opts1]:match'^%s*(.*%S)' end

	if keystr == nil then error(ctx.luaname .. ', ‘value_of’: No parameter name was provided', 0) end

	local keynum = tonumber(keystr)

	local len = #ctx.params

	if (

		ctx.subset == -1 and keynum ~= nil and len >= keynum

	) or (

		ctx.subset == 1 and (keynum == nil or len < keynum)

	) then return (ctx.ifngiven or '') end

	local val = ctx.paramskeynum 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)

			retnss + 1 = pps

			retnss + 2 = key

			retnss + 3 = kvs

			retnss + 4 = val

			nss = nss + 4

		end

	)

	if nss > 0 then

		if nss > 4 and ctx.lastsep ~= nil then

			retnss - 3 = ctx.lastsep

		end

		ret1 = ctx.header or ''

		if ctx.footer ~= nil then retnss + 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)

			retnss + 1 = pps

			retnss + 2 = val

			nss = nss + 2

		end

	)

	if nss > 0 then

		if nss > 2 and ctx.lastsep ~= nil then

			retnss - 1 = ctx.lastsep

		end

		ret1 = ctx.header or ''

		if ctx.footer ~= nil then retnss + 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.pipe1 or ''

	local pps = ctx.itersep or ''

	local ret = {}

	local nss = 0

	flush_params(

		ctx,

		function(key, val)

			retnss + 1 = pps

			retnss + 2 = txt:gsub('%$#', key):gsub('%$@', val)

			nss = nss + 2

		end

	)

	if nss > 0 then

		if nss > 2 and ctx.lastsep ~= nil then

			retnss - 1 = ctx.lastsep

		end

		ret1 = ctx.header or ''

		if ctx.footer ~= nil then retnss + 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 opts1 ~= nil then tname = opts1]: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)

			opts1 = key

			opts2 = val

			retnss + 1 = ccs

			retnss + 2 = ctx.frame:expandTemplate(model)

			nss = nss + 2

		end

	)

	if nss > 0 then

		if nss > 2 and ctx.lastsep ~= nil then

			retnss - 1 = ctx.lastsep

		end

		ret1 = ctx.header or ''

		if ctx.footer ~= nil then retnss + 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 opts1 ~= nil then mname = opts1]:match'^%s*(.*%S)' end

	if mname == nil then error(ctx.luaname .. ', ‘invoke_for_each’: No module name was provided', 0) end

	if opts2 ~= nil then fname = opts2]: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)

			opts1 = key

			opts2 = val

			retnss + 1 = ccs

			retnss + 2 = mfunc(ctx.frame:newChild(model))

			nss = nss + 2

		end

	)

	if nss > 0 then

		if nss > 2 and ctx.lastsep ~= nil then

			retnss - 1 = ctx.lastsep

		end

		ret1 = ctx.header or ''

		if ctx.footer ~= nil then retnss + 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 opts1 ~= nil then magic = opts1]: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)

			opts1 = key

			opts2 = val

			retnss + 1 = ccs

			retnss + 2 = ctx.frame:callParserFunction(magic,

				opts)

			nss = nss + 2

		end

	)

	if nss > 0 then

		if nss > 2 and ctx.lastsep ~= nil then

			retnss - 1 = ctx.lastsep

		end

		ret1 = ctx.header or ''

		if ctx.footer ~= nil then retnss + 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 opts1 ~= nil then tname = opts1]: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)

			opts1 = val

			retnss + 1 = ccs

			retnss + 2 = ctx.frame:expandTemplate(model)

			nss = nss + 2

		end

	)

	if nss > 0 then

		if nss > 2 and ctx.lastsep ~= nil then

			retnss - 1 = ctx.lastsep

		end

		ret1 = ctx.header or ''

		if ctx.footer ~= nil then retnss + 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 opts1 ~= nil then mname = opts1]:match'^%s*(.*%S)' end

	if mname == nil then error(ctx.luaname .. ', ‘invoke_for_each_value’: No module name was provided', 0) end

	if opts2 ~= nil then fname = opts2]: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)

			opts1 = val

			retnss + 1 = ccs

			retnss + 2 = mfunc(ctx.frame:newChild(model))

			nss = nss + 2

		end

	)

	if nss > 0 then

		if nss > 2 and ctx.lastsep ~= nil then

			retnss - 1 = ctx.lastsep

		end

		ret1 = ctx.header or ''

		if ctx.footer ~= nil then retnss + 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 opts1 ~= nil then magic = opts1]: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)

			opts1 = val

			retnss + 1 = ccs

			retnss + 2 = ctx.frame:callParserFunction(magic,

				opts)

			nss = nss + 2

		end

	)

	if nss > 0 then

		if nss > 2 and ctx.lastsep ~= nil then

			retnss - 1 = ctx.lastsep

		end

		ret1 = ctx.header or ''

		if ctx.footer ~= nil then retnss + 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
Permanently protected module
From Wikipedia, the free encyclopedia


	---                                        ---

	---     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 newtabkey = 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.pipen_forward ~= nil then

		nextfn = ctx.pipen_forward]:match'^%s*(.*%S)'

	end

	if nextfn == nil then

		error(ctx.luaname .. ': You must specify a function to call', 0)

	end

	if librarynextfn == 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 librarynextfn](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

			newargskey + shift = val

		end

	else

		if ctx.subset == -1 then

			for key, val in ipairs(ctx.params) do

				ctx.paramskey = nil

			end

		end

		for key, val in pairs(ctx.params) do

			if type(key) == 'number' then

				newargskey + shift = val

			else

				newargskey = val

			end

		end

	end

	for key, val in pairs(ctx.pipe) do newargskey = 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 tblkey = 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) == 'number' then

				nlen = nlen + 1

				numsnlen = key

			else

				wlen = wlen + 1

				wordswlen = key

			end



		end

		table.sort(nums)

		table.sort(words)

		for idx = 1, nlen do fn(numsidx], tblnumsidx]]) end

		for idx = 1, wlen do fn(wordsidx], tblwordsidx]]) end

		return

	end

	if ctx.subset ~= -1 then

		for key, val in ipairs(tbl) do

			fn(key, val)

			tblkey = 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

	local nptns = 0

	for _, val in ipairs(opts) do

		if state == 0 then

			nptns = nptns + 1

			ptnsnptns = { val, false }

			state = -1

		else

			keyw = val:match'^%s*(.*%S)'

			if keyw == nil or mkeywordskeyw == nil then break

			else

				state = mkeywordskeyw

				if state ~= 0 then ptnsnptns][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 opts1 ~= nil then

		cmd = opts1]: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

				ctxval = optsargc

				destkey = nil

			end

			argc = argc + 1

		else

			vname = memoryslotsstring.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 ctxval = optsargc end

	return context_iterate(ctx, argc + 1)

end





-- See iface.squeezing()

library.squeezing = function(ctx)

	local tbl = ctx.params

	local store = {}

	local indices = {}

	local newlen = 0

	for key, val in pairs(tbl) do

		if type(key) == 'number' then

			newlen = newlen + 1

			indicesnewlen = key

			storekey = val

			tblkey = nil

		end

	end

	table.sort(indices)

	for idx = 1, newlen do tblidx = storeindicesidx]] end

	return context_iterate(ctx, 1)

end





-- See iface.cutting()

library.cutting = function(ctx)

	local lcut = tonumber(ctx.pipe1])

	if lcut == nil then error(ctx.luaname .. ', ‘cutting’: Left cut must be a number', 0) end

	local rcut = tonumber(ctx.pipe2])

	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 tblkey = nil end

			tot = len

		else

			for idx = len - rcut + 1, len, 1 do tblidx = nil end

			for idx = 1, lcut, 1 do tblidx = nil end

		end

		for key, val in pairs(tbl) do

			if type(key) == 'number' and key > 0 then

				if key > len then

					cachekey - tot = val

				else

					cachekey - lcut = val

				end

				tblkey = nil

			end

		end

		for key, val in pairs(cache) do tblkey = 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, ptn1], 1, ptn2]) then

				nomatch = false

				break

			end

		end

		if nomatch then tblkey = 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, ptn1], 1, ptn2]) then

				yesmatch = false

				break

			end

		end

		if yesmatch then tblkey = 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, ptn1], 1, ptn2]) then

				nomatch = false

				break

			end

		end

		if nomatch then tblkey = 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, ptn1], 1, ptn2]) then

				yesmatch = false

				break

			end

		end

		if yesmatch then tblkey = 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 tblkey = 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 opts1 ~= nil then tname = opts1]: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(opts2])

	if tmp == nil then

		nargs = 1

	elseif tmp < 1 then

		nargs = 2

	else

		nargs = tmp + 2

		for idx = 3, nargs do margsidx = optsidx end

	end

	local model = { title = tname, args = margs }

	local tbl = ctx.params

	if ctx.subset == 1 then

		for key, val in ipairs(tbl) do

			margs1 = key

			margs2 = val

			tblkey = ctx.frame:expandTemplate(model)

		end

	elseif ctx.subset == -1 then

		tmp = {}

		for key, val in pairs(tbl) do tmpkey = true end

		for key, val in ipairs(tmp) do tmpkey = nil end

		for key in pairs(tmp) do

			margs1 = key

			margs2 = tblkey

			tblkey = ctx.frame:expandTemplate(model)

		end

	else

		for key, val in pairs(tbl) do

			margs1 = key

			margs2 = val

			tblkey = 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 opts1 ~= nil then mname = opts1]:match'^%s*(.*%S)' end

	if mname == nil then error(ctx.luaname .. ', ‘mapping_values_by_invoking’: No module name was provided', 0) end

	if opts2 ~= nil then fname = opts2]: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(opts3])

	if tmp == nil then

		nargs = 2

	elseif tmp < 1 then

		nargs = 3

	else

		nargs = tmp + 3

		for idx = 4, nargs do margsidx - 1 = optsidx 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

			margs1 = key

			margs2 = val

			tblkey = mfunc(ctx.frame:newChild(model))

		end

	elseif ctx.subset == -1 then

		tmp = {}

		for key, val in pairs(tbl) do tmpkey = true end

		for key, val in ipairs(tmp) do tmpkey = nil end

		for key in pairs(tmp) do

			margs1 = key

			margs2 = tblkey

			tblkey = mfunc(ctx.frame:newChild(model))

		end

	else

		for key, val in pairs(tbl) do

			margs1 = key

			margs2 = val

			tblkey = 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 opts1 ~= nil then tname = opts1]: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(opts2])

	if tmp == nil then

		nargs = 1

	elseif tmp < 1 then

		nargs = 2

	else

		nargs = tmp + 2

		for idx = 3, nargs do margsidx - 1 = optsidx end

	end

	local model = { title = tname, args = margs }

	local tbl = ctx.params

	if ctx.subset == 1 then

		for key, val in ipairs(tbl) do

			margs1 = val

			tblkey = ctx.frame:expandTemplate(model)

		end

	elseif ctx.subset == -1 then

		tmp = {}

		for key, val in pairs(tbl) do tmpkey = true end

		for key, val in ipairs(tmp) do tmpkey = nil end

		for key in pairs(tmp) do

			margs1 = tblkey

			tblkey = ctx.frame:expandTemplate(model)

		end

	else

		for key, val in pairs(tbl) do

			margs1 = val

			tblkey = 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 opts1 ~= nil then mname = opts1]:match'^%s*(.*%S)' end

	if mname == nil then error(ctx.luaname .. ', ‘mapping_values_blindly_by_invoking’: No module name was provided', 0) end

	if opts2 ~= nil then fname = opts2]: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(opts3])

	if tmp == nil then

		nargs = 2

	elseif tmp < 1 then

		nargs = 3

	else

		nargs = tmp + 3

		for idx = 4, nargs do margsidx - 2 = optsidx 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

			margs1 = val

			tblkey = mfunc(ctx.frame:newChild(model))

		end

	elseif ctx.subset == -1 then

		tmp = {}

		for key, val in pairs(tbl) do tmpkey = true end

		for key, val in ipairs(tmp) do tmpkey = nil end

		for key in pairs(tmp) do

			margs1 = tblkey

			tblkey = mfunc(ctx.frame:newChild(model))

		end

	else

		for key, val in pairs(tbl) do

			margs1 = val

			tblkey = 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 opts1 ~= nil then tname = opts1]: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 opts1 ~= nil then mname = opts1]:match'^%s*(.*%S)' end

	if mname == nil then error(ctx.luaname .. ', ‘concat_and_invoke’: No module name was provided', 0) end

	if opts2 ~= nil then fname = opts2]: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 opts1 ~= nil then magic = opts1]: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 opts1 ~= nil then keystr = opts1]:match'^%s*(.*%S)' end

	if keystr == nil then error(ctx.luaname .. ', ‘value_of’: No parameter name was provided', 0) end

	local keynum = tonumber(keystr)

	local len = #ctx.params

	if (

		ctx.subset == -1 and keynum ~= nil and len >= keynum

	) or (

		ctx.subset == 1 and (keynum == nil or len < keynum)

	) then return (ctx.ifngiven or '') end

	local val = ctx.paramskeynum 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)

			retnss + 1 = pps

			retnss + 2 = key

			retnss + 3 = kvs

			retnss + 4 = val

			nss = nss + 4

		end

	)

	if nss > 0 then

		if nss > 4 and ctx.lastsep ~= nil then

			retnss - 3 = ctx.lastsep

		end

		ret1 = ctx.header or ''

		if ctx.footer ~= nil then retnss + 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)

			retnss + 1 = pps

			retnss + 2 = val

			nss = nss + 2

		end

	)

	if nss > 0 then

		if nss > 2 and ctx.lastsep ~= nil then

			retnss - 1 = ctx.lastsep

		end

		ret1 = ctx.header or ''

		if ctx.footer ~= nil then retnss + 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.pipe1 or ''

	local pps = ctx.itersep or ''

	local ret = {}

	local nss = 0

	flush_params(

		ctx,

		function(key, val)

			retnss + 1 = pps

			retnss + 2 = txt:gsub('%$#', key):gsub('%$@', val)

			nss = nss + 2

		end

	)

	if nss > 0 then

		if nss > 2 and ctx.lastsep ~= nil then

			retnss - 1 = ctx.lastsep

		end

		ret1 = ctx.header or ''

		if ctx.footer ~= nil then retnss + 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 opts1 ~= nil then tname = opts1]: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)

			opts1 = key

			opts2 = val

			retnss + 1 = ccs

			retnss + 2 = ctx.frame:expandTemplate(model)

			nss = nss + 2

		end

	)

	if nss > 0 then

		if nss > 2 and ctx.lastsep ~= nil then

			retnss - 1 = ctx.lastsep

		end

		ret1 = ctx.header or ''

		if ctx.footer ~= nil then retnss + 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 opts1 ~= nil then mname = opts1]:match'^%s*(.*%S)' end

	if mname == nil then error(ctx.luaname .. ', ‘invoke_for_each’: No module name was provided', 0) end

	if opts2 ~= nil then fname = opts2]: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)

			opts1 = key

			opts2 = val

			retnss + 1 = ccs

			retnss + 2 = mfunc(ctx.frame:newChild(model))

			nss = nss + 2

		end

	)

	if nss > 0 then

		if nss > 2 and ctx.lastsep ~= nil then

			retnss - 1 = ctx.lastsep

		end

		ret1 = ctx.header or ''

		if ctx.footer ~= nil then retnss + 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 opts1 ~= nil then magic = opts1]: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)

			opts1 = key

			opts2 = val

			retnss + 1 = ccs

			retnss + 2 = ctx.frame:callParserFunction(magic,

				opts)

			nss = nss + 2

		end

	)

	if nss > 0 then

		if nss > 2 and ctx.lastsep ~= nil then

			retnss - 1 = ctx.lastsep

		end

		ret1 = ctx.header or ''

		if ctx.footer ~= nil then retnss + 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 opts1 ~= nil then tname = opts1]: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)

			opts1 = val

			retnss + 1 = ccs

			retnss + 2 = ctx.frame:expandTemplate(model)

			nss = nss + 2

		end

	)

	if nss > 0 then

		if nss > 2 and ctx.lastsep ~= nil then

			retnss - 1 = ctx.lastsep

		end

		ret1 = ctx.header or ''

		if ctx.footer ~= nil then retnss + 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 opts1 ~= nil then mname = opts1]:match'^%s*(.*%S)' end

	if mname == nil then error(ctx.luaname .. ', ‘invoke_for_each_value’: No module name was provided', 0) end

	if opts2 ~= nil then fname = opts2]: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)

			opts1 = val

			retnss + 1 = ccs

			retnss + 2 = mfunc(ctx.frame:newChild(model))

			nss = nss + 2

		end

	)

	if nss > 0 then

		if nss > 2 and ctx.lastsep ~= nil then

			retnss - 1 = ctx.lastsep

		end

		ret1 = ctx.header or ''

		if ctx.footer ~= nil then retnss + 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 opts1 ~= nil then magic = opts1]: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)

			opts1 = val

			retnss + 1 = ccs

			retnss + 2 = ctx.frame:callParserFunction(magic,

				opts)

			nss = nss + 2

		end

	)

	if nss > 0 then

		if nss > 2 and ctx.lastsep ~= nil then

			retnss - 1 = ctx.lastsep

		end

		ret1 = ctx.header or ''

		if ctx.footer ~= nil then retnss + 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

Videos

Youtube | Vimeo | Bing

Websites

Google | Yahoo | Bing

Encyclopedia

Google | Yahoo | Bing

Facebook