<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://test.st34an.tech/index.php?action=history&amp;feed=atom&amp;title=Module%3AParameters</id>
	<title>Module:Parameters - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://test.st34an.tech/index.php?action=history&amp;feed=atom&amp;title=Module%3AParameters"/>
	<link rel="alternate" type="text/html" href="https://test.st34an.tech/index.php?title=Module:Parameters&amp;action=history"/>
	<updated>2026-04-10T19:16:35Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.45.3</generator>
	<entry>
		<id>https://test.st34an.tech/index.php?title=Module:Parameters&amp;diff=19&amp;oldid=prev</id>
		<title>Jsrs701: 1 revision imported</title>
		<link rel="alternate" type="text/html" href="https://test.st34an.tech/index.php?title=Module:Parameters&amp;diff=19&amp;oldid=prev"/>
		<updated>2026-04-10T07:25:46Z</updated>

		<summary type="html">&lt;p&gt;1 revision imported&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 07:25, 10 April 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;4&quot; class=&quot;diff-notice&quot; lang=&quot;en&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(No difference)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;!-- diff cache key mediawikidb:diff:1.41:old-18:rev-19 --&gt;
&lt;/table&gt;</summary>
		<author><name>Jsrs701</name></author>
	</entry>
	<entry>
		<id>https://test.st34an.tech/index.php?title=Module:Parameters&amp;diff=18&amp;oldid=prev</id>
		<title>bob&gt;Djpwikiadmin at 00:09, 8 September 2023</title>
		<link rel="alternate" type="text/html" href="https://test.st34an.tech/index.php?title=Module:Parameters&amp;diff=18&amp;oldid=prev"/>
		<updated>2023-09-08T00:09:15Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;local export = {}&lt;br /&gt;
&lt;br /&gt;
local function track(page, calling_module, calling_function, param_name)&lt;br /&gt;
	local track = require(&amp;quot;Module:debug/track&amp;quot;)&lt;br /&gt;
	local tracking_page = &amp;quot;parameters/&amp;quot; .. page&lt;br /&gt;
	-- Cascades down in specificity, as each level is a prerequisite for the next.&lt;br /&gt;
	track(tracking_page)&lt;br /&gt;
	if calling_module then&lt;br /&gt;
		track(tracking_page .. &amp;quot;/&amp;quot; .. calling_module)&lt;br /&gt;
		if calling_function then&lt;br /&gt;
			track(tracking_page .. &amp;quot;/&amp;quot; .. calling_module .. &amp;quot;/&amp;quot; .. calling_function)&lt;br /&gt;
			if param_name then&lt;br /&gt;
				track(tracking_page .. &amp;quot;/&amp;quot; .. calling_module .. &amp;quot;/&amp;quot; .. calling_function .. &amp;quot;/&amp;quot; .. param_name)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function export.process(args, params, return_unknown, calling_module, calling_function)&lt;br /&gt;
	local args_new = {}&lt;br /&gt;
	&lt;br /&gt;
	if not calling_module then&lt;br /&gt;
		track(&amp;quot;no calling module&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
	if not calling_function then&lt;br /&gt;
		track(&amp;quot;no calling function&amp;quot;, calling_module)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Process parameters for specific properties&lt;br /&gt;
	local required = {}&lt;br /&gt;
	local patterns = {}&lt;br /&gt;
	local names_with_equal_sign = {}&lt;br /&gt;
	local list_from_index = nil&lt;br /&gt;
	&lt;br /&gt;
	for name, param in pairs(params) do&lt;br /&gt;
		if param.required then&lt;br /&gt;
			if param.alias_of then&lt;br /&gt;
				track(&amp;quot;required alias&amp;quot;, calling_module, calling_function, name)&lt;br /&gt;
			end&lt;br /&gt;
			required[name] = true&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		if name == 1 and param.no_lang_code then&lt;br /&gt;
			if not params[&amp;quot;notlangcode&amp;quot;] then&lt;br /&gt;
				error(&amp;quot;The parameter \&amp;quot;notlangcode\&amp;quot; must be enabled for this template.&amp;quot;, 2)&lt;br /&gt;
			elseif not args[&amp;quot;notlangcode&amp;quot;] and require(&amp;quot;Module:languages&amp;quot;).getByCode(args[name]) then&lt;br /&gt;
				error(&amp;quot;The parameter \&amp;quot;&amp;quot; .. name .. &amp;quot;\&amp;quot; should not be a language code.&amp;quot;, 2)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		if param.list then&lt;br /&gt;
			-- A helper function to escape magic characters in a string&lt;br /&gt;
			-- Magic characters: ^$()%.[]*+-?&lt;br /&gt;
			local plain = require(&amp;quot;Module:string/pattern_escape&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
			local key = name&lt;br /&gt;
			if type(name) == &amp;quot;string&amp;quot; then&lt;br /&gt;
				key = string.gsub(name, &amp;quot;=&amp;quot;, &amp;quot;&amp;quot;)&lt;br /&gt;
			end&lt;br /&gt;
			if param.default ~= nil then&lt;br /&gt;
				args_new[key] = {param.default, maxindex = 1}&lt;br /&gt;
			else&lt;br /&gt;
				args_new[key] = {maxindex = 0}&lt;br /&gt;
			end&lt;br /&gt;
			&lt;br /&gt;
			if type(param.list) == &amp;quot;string&amp;quot; then&lt;br /&gt;
				-- If the list property is a string, then it represents the name&lt;br /&gt;
				-- to be used as the prefix for list items. This is for use with lists&lt;br /&gt;
				-- where the first item is a numbered parameter and the&lt;br /&gt;
				-- subsequent ones are named, such as 1, pl2, pl3.&lt;br /&gt;
				if string.find(param.list, &amp;quot;=&amp;quot;) then&lt;br /&gt;
					patterns[&amp;quot;^&amp;quot; .. string.gsub(plain(param.list), &amp;quot;=&amp;quot;, &amp;quot;(%%d+)&amp;quot;) .. &amp;quot;$&amp;quot;] = name&lt;br /&gt;
				else&lt;br /&gt;
					patterns[&amp;quot;^&amp;quot; .. plain(param.list) .. &amp;quot;(%d+)$&amp;quot;] = name&lt;br /&gt;
				end&lt;br /&gt;
			elseif type(name) == &amp;quot;number&amp;quot; then&lt;br /&gt;
				-- If the name is a number, then all indexed parameters from&lt;br /&gt;
				-- this number onwards go in the list.&lt;br /&gt;
				list_from_index = name&lt;br /&gt;
			else&lt;br /&gt;
				if string.find(name, &amp;quot;=&amp;quot;) then&lt;br /&gt;
					patterns[&amp;quot;^&amp;quot; .. string.gsub(plain(name), &amp;quot;=&amp;quot;, &amp;quot;(%%d+)&amp;quot;) .. &amp;quot;$&amp;quot;] = string.gsub(name, &amp;quot;=&amp;quot;, &amp;quot;&amp;quot;)&lt;br /&gt;
				else&lt;br /&gt;
					patterns[&amp;quot;^&amp;quot; .. plain(name) .. &amp;quot;(%d+)$&amp;quot;] = name&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
			&lt;br /&gt;
			if string.find(name, &amp;quot;=&amp;quot;) then&lt;br /&gt;
				-- DO NOT SIDE-EFFECT A TABLE WHILE ITERATING OVER IT.&lt;br /&gt;
				-- Some elements may be skipped or processed twice if you do.&lt;br /&gt;
				-- Instead, track the changes we want to make to `params`, and&lt;br /&gt;
				-- do them after the iteration over `params` is done.&lt;br /&gt;
				table.insert(names_with_equal_sign, name)&lt;br /&gt;
			end&lt;br /&gt;
		elseif param.default ~= nil then&lt;br /&gt;
			args_new[name] = param.default&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	--Process required changes to `params`.&lt;br /&gt;
	if #names_with_equal_sign &amp;gt; 0 then&lt;br /&gt;
		local m_params_data = calling_module and mw.loadData(&amp;quot;Module:parameters/data&amp;quot;)[calling_module]&lt;br /&gt;
		-- If there is a ready-made version in the data module, use that.&lt;br /&gt;
		if m_params_data and m_params_data[calling_function .. &amp;quot;_no_equals&amp;quot;] then&lt;br /&gt;
			params = m_params_data[calling_function .. &amp;quot;_no_equals&amp;quot;]&lt;br /&gt;
		-- Otherwise, shallow copy the params table and substitute the keys.&lt;br /&gt;
		else&lt;br /&gt;
			params = require(&amp;quot;Module:table&amp;quot;).shallowcopy(params)&lt;br /&gt;
			for _, name in ipairs(names_with_equal_sign) do&lt;br /&gt;
				track(&amp;quot;name with equals&amp;quot;, calling_module, calling_function, name)&lt;br /&gt;
				params[string.gsub(name, &amp;quot;=&amp;quot;, &amp;quot;&amp;quot;)] = params[name]&lt;br /&gt;
				params[name] = nil&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Process the arguments&lt;br /&gt;
	local args_unknown = {}&lt;br /&gt;
	local max_index&lt;br /&gt;
	&lt;br /&gt;
	for name, val in pairs(args) do&lt;br /&gt;
		local index = nil&lt;br /&gt;
		&lt;br /&gt;
		if type(name) == &amp;quot;number&amp;quot; then&lt;br /&gt;
			if list_from_index ~= nil and name &amp;gt;= list_from_index then&lt;br /&gt;
				index = name - list_from_index + 1&lt;br /&gt;
				name = list_from_index&lt;br /&gt;
			end&lt;br /&gt;
		else&lt;br /&gt;
			-- Does this argument name match a pattern?&lt;br /&gt;
			for pattern, pname in pairs(patterns) do&lt;br /&gt;
				index = mw.ustring.match(name, pattern)&lt;br /&gt;
				&lt;br /&gt;
				-- It matches, so store the parameter name and the&lt;br /&gt;
				-- numeric index extracted from the argument name.&lt;br /&gt;
				if index then&lt;br /&gt;
					index = tonumber(index)&lt;br /&gt;
					name = pname&lt;br /&gt;
					break&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		local param = params[name]&lt;br /&gt;
		&lt;br /&gt;
		-- If a parameter without the trailing index was found, and&lt;br /&gt;
		-- require_index is set on the param, set the param to nil to treat it&lt;br /&gt;
		-- as if it isn&amp;#039;t recognized.&lt;br /&gt;
		if not index and param and param.require_index then&lt;br /&gt;
			param = nil&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		-- If no index was found, use 1 as the default index.&lt;br /&gt;
		-- This makes list parameters like g, g2, g3 put g at index 1.&lt;br /&gt;
		-- If `separate_no_index` is set, then use 0 as the default instead.&lt;br /&gt;
		index = index or (param and param.separate_no_index and 0) or 1&lt;br /&gt;
		&lt;br /&gt;
		-- If the argument is not in the list of parameters, trigger an error.&lt;br /&gt;
		-- return_unknown suppresses the error, and stores it in a separate list instead.&lt;br /&gt;
		if not param then&lt;br /&gt;
			if return_unknown then&lt;br /&gt;
				args_unknown[name] = val&lt;br /&gt;
			else&lt;br /&gt;
				error(&amp;quot;The parameter \&amp;quot;&amp;quot; .. name .. &amp;quot;\&amp;quot; is not used by this template.&amp;quot;, 2)&lt;br /&gt;
			end&lt;br /&gt;
		else&lt;br /&gt;
			-- Remove leading and trailing whitespace unless allow_whitespace is true.&lt;br /&gt;
			if not param.allow_whitespace then&lt;br /&gt;
				val = mw.text.trim(val)&lt;br /&gt;
			end&lt;br /&gt;
			&lt;br /&gt;
			-- Empty string is equivalent to nil unless allow_empty is true.&lt;br /&gt;
			if val == &amp;quot;&amp;quot; and not param.allow_empty then&lt;br /&gt;
				val = nil&lt;br /&gt;
				-- Track empty parameters, unless (1) allow_empty is set or (2) they&amp;#039;re numbered parameters where a higher numbered parameter is also in use (e.g. track {{l|en|term|}}, but not {{l|en||term}}).&lt;br /&gt;
				if type(name) == &amp;quot;number&amp;quot; and not max_index then&lt;br /&gt;
					-- Find the highest numbered parameter that&amp;#039;s in use/an empty string, as we don&amp;#039;t want parameters like 500= to mean we can&amp;#039;t track any empty parameters with a lower index than 500.&lt;br /&gt;
					local max_contiguous_index = 0&lt;br /&gt;
					while args[max_contiguous_index + 1] do&lt;br /&gt;
						max_contiguous_index = max_contiguous_index + 1&lt;br /&gt;
					end&lt;br /&gt;
					if max_contiguous_index &amp;gt; 0 then&lt;br /&gt;
						for name, val in pairs(args) do&lt;br /&gt;
							if type(name) == &amp;quot;number&amp;quot; and name &amp;gt; 0 and name &amp;lt;= max_contiguous_index and ((not max_index) or name &amp;gt; max_index) and val ~= &amp;quot;&amp;quot; then&lt;br /&gt;
								max_index = name&lt;br /&gt;
							end&lt;br /&gt;
						end&lt;br /&gt;
					end&lt;br /&gt;
					max_index = max_index or 0&lt;br /&gt;
				end&lt;br /&gt;
				if type(name) ~= &amp;quot;number&amp;quot; or name &amp;gt; max_index then&lt;br /&gt;
					track(&amp;quot;empty parameter&amp;quot;, calling_module, calling_function, name)&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
			&lt;br /&gt;
			-- Convert to proper type if necessary.&lt;br /&gt;
			if param.type == &amp;quot;boolean&amp;quot; then&lt;br /&gt;
				val = require(&amp;quot;Module:yesno&amp;quot;)(val, true)&lt;br /&gt;
			elseif param.type == &amp;quot;number&amp;quot; then&lt;br /&gt;
				val = tonumber(val)&lt;br /&gt;
			elseif param.type then&lt;br /&gt;
				track(&amp;quot;unrecognized type&amp;quot;, calling_module, calling_function, name)&lt;br /&gt;
				track(&amp;quot;unrecognized type/&amp;quot; .. tostring(param.type), calling_module, calling_function, name)&lt;br /&gt;
			end&lt;br /&gt;
			&lt;br /&gt;
			-- Can&amp;#039;t use &amp;quot;if val&amp;quot; alone, because val may be a boolean false.&lt;br /&gt;
			if val ~= nil then&lt;br /&gt;
				-- Mark it as no longer required, as it is present.&lt;br /&gt;
				required[param.alias_of or name] = nil&lt;br /&gt;
				&lt;br /&gt;
				-- Store the argument value.&lt;br /&gt;
				if param.list then&lt;br /&gt;
					-- If the parameter is an alias of another, store it as the original,&lt;br /&gt;
					-- but avoid overwriting it; the original takes precedence.&lt;br /&gt;
					if not param.alias_of then&lt;br /&gt;
						args_new[name][index] = val&lt;br /&gt;
						&lt;br /&gt;
						-- Store the highest index we find.&lt;br /&gt;
						args_new[name].maxindex = math.max(index, args_new[name].maxindex)&lt;br /&gt;
						if args_new[name][0] then&lt;br /&gt;
							args_new[name].default = args_new[name][0]&lt;br /&gt;
							args_new[name][0] = nil&lt;br /&gt;
						end&lt;br /&gt;
					elseif args[param.alias_of] == nil then&lt;br /&gt;
						if params[param.alias_of] and params[param.alias_of].list then&lt;br /&gt;
							args_new[param.alias_of][index] = val&lt;br /&gt;
							&lt;br /&gt;
							-- Store the highest index we find.&lt;br /&gt;
							args_new[param.alias_of].maxindex = math.max(index, args_new[param.alias_of].maxindex)&lt;br /&gt;
						else&lt;br /&gt;
							args_new[param.alias_of] = val&lt;br /&gt;
						end&lt;br /&gt;
					end&lt;br /&gt;
				else&lt;br /&gt;
					-- If the parameter is an alias of another, store it as the original,&lt;br /&gt;
					-- but avoid overwriting it; the original takes precedence.&lt;br /&gt;
					if not param.alias_of then&lt;br /&gt;
						args_new[name] = val&lt;br /&gt;
					elseif args[param.alias_of] == nil then&lt;br /&gt;
						if params[param.alias_of] and params[param.alias_of].list then&lt;br /&gt;
							args_new[param.alias_of][1] = val&lt;br /&gt;
							&lt;br /&gt;
							-- Store the highest index we find.&lt;br /&gt;
							args_new[param.alias_of].maxindex = math.max(1, args_new[param.alias_of].maxindex)&lt;br /&gt;
						else&lt;br /&gt;
							args_new[param.alias_of] = val&lt;br /&gt;
						end&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- The required table should now be empty.&lt;br /&gt;
	-- If any entry remains, trigger an error, unless we&amp;#039;re in the template namespace.&lt;br /&gt;
	if mw.title.getCurrentTitle().namespace ~= 10 then&lt;br /&gt;
		local list = {}&lt;br /&gt;
		for name, param in pairs(required) do&lt;br /&gt;
			table.insert(list, name)&lt;br /&gt;
		end&lt;br /&gt;
		if #list &amp;gt; 0 then&lt;br /&gt;
			error(&amp;#039;The parameters &amp;quot;&amp;#039; .. mw.text.listToText(list, &amp;#039;&amp;quot;, &amp;quot;&amp;#039;, &amp;#039;&amp;quot; and &amp;quot;&amp;#039;) .. &amp;#039;&amp;quot; are required.&amp;#039;, 2)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Remove holes in any list parameters if needed.&lt;br /&gt;
	for name, val in pairs(args_new) do&lt;br /&gt;
		if type(val) == &amp;quot;table&amp;quot; and not params[name].allow_holes then&lt;br /&gt;
			args_new[name] = require(&amp;quot;Module:parameters/remove_holes&amp;quot;)(val)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if return_unknown then&lt;br /&gt;
		return args_new, args_unknown&lt;br /&gt;
	else&lt;br /&gt;
		return args_new&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return export&lt;/div&gt;</summary>
		<author><name>bob&gt;Djpwikiadmin</name></author>
	</entry>
</feed>