Module:ArrayParameter: Difference between revisions

From Puella Magi Wiki
Jump to navigation Jump to search
Use table.insert instead
Automatically surround the arguments with spaces in list mode
Tag: Reverted
Line 36: Line 36:
local listFrame = {}
local listFrame = {}
for i = first, last do
for i = first, last do
table.insert(listFrame, result[i])
local this = ' ' .. result[i]
if i < last then this = this .. ' ' end
table.insert(listFrame, this)
end
end
return list[frame.separator](listFrame)
return list[frame.separator](listFrame)

Revision as of 21:53, 3 January 2026

Module Documentation    [edit]

This module enables a template to handle multiple "array-like" parameters. It defines an "array-like" as any set of parameters that consist of a common prefix followed by a number. The numbers must be sequential, or the module will raise an error.

The module takes every matching parameter, substitutes its value into a template, and concatenates the result together.

Usage: {{#invoke:ArrayParameter|main|name=...|...}}

The following parameters are supported:

  • name – The name of the array-like parameter. If name=char, then the module looks for template parameters called char_n where n is any positive integer. Defaults to arg if not specified.
  • separator – A string used as a separator when concatenating. Defaults to an empty string if not specified.
  • aslist – Format with Module:List instead of a simple concatenation. In this case, separator must be either and or or.
  • first, last – If specified, the transformation is limited to the subsequence of parameters with the indicated indices. A negative index counts from the end. For example, if you pass name=value, first=3, and last=-2, and there are 10 parameters passed to the template, then only the parameters from value_3 to value_9 are formatted and concatenated.
  • template or unnamed parameter – The template to substitute the values into. The string %s will be replaced with the values of the parameters.

You can also count the number of parameters as follows:

{{#invoke:ArrayParameter|length|name=...}}

The name parameter is just as above. No other parameters are used in this form.


local p = {}
local list = require('Module:List')

local function get_args(frame)
	local arg_name = frame.args.name or ''
	local template = frame.args.template or frame.args[1] or ''
	local parent_frame = frame:getParent()
	local result = {}
	for arg, val in pairs(parent_frame.args) do
		if type(arg) ~= 'number' then
			local m
			if arg_name == '' then
				m = arg:match('^(%d+)$')
			else
				m = arg:match('^' .. arg_name .. '_(%d+)$')
			end
			if m then
				local i = tonumber(m)
				result[i] = template:gsub('%%s', val)
			end
		end
	end
	local first, last = frame.first or 1, frame.last or -1
	local size = table.maxn(result)
	if first < 0 then first = first + size + 1 end
	if last < 0 then last = last + size + 1 end
	if first > last then first,last = last,first end
	return result, first, last
end

function p.main(frame)
	local sep = frame.args.separator or ''
	local result, first, last = get_args(frame)
	if first == last then return result[first] end
	if frame.aslist and (frame.separator == 'and' or frame.separator == 'or') then
		local listFrame = {}
		for i = first, last do
			local this = ' ' .. result[i]
			if i < last then this = this .. ' ' end
			table.insert(listFrame, this)
		end
		return list[frame.separator](listFrame)
	else
		return table.concat(result, sep, first, last)
	end
end

function p.length(frame)
	local result, first, last = get_args(frame)
	return last - first + 1
end

return p