<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://linguifex.com/w/index.php?action=history&amp;feed=atom&amp;title=Module%3Astring%2Ftemplates</id>
	<title>Module:string/templates - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://linguifex.com/w/index.php?action=history&amp;feed=atom&amp;title=Module%3Astring%2Ftemplates"/>
	<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=Module:string/templates&amp;action=history"/>
	<updated>2026-06-22T08:13:17Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.6</generator>
	<entry>
		<id>https://linguifex.com/w/index.php?title=Module:string/templates&amp;diff=512876&amp;oldid=prev</id>
		<title>Sware: Created page with &quot;local export = {}  local parameters_module = &quot;Module:parameters&quot; local string_pattern_escape_module = &quot;Module:string/patternEscape&quot; local string_replacement_escape_module = &quot;Module:string/replacementEscape&quot; local string_utilities_module = &quot;Module:string utilities&quot;  local abs = math.abs local find = string.find local format = string.format local floor = math.floor local lower = string.lower local match = string.match local rep = string.rep local require = require local to...&quot;</title>
		<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=Module:string/templates&amp;diff=512876&amp;oldid=prev"/>
		<updated>2026-05-07T14:48:27Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;local export = {}  local parameters_module = &amp;quot;Module:parameters&amp;quot; local string_pattern_escape_module = &amp;quot;Module:string/patternEscape&amp;quot; local string_replacement_escape_module = &amp;quot;Module:string/replacementEscape&amp;quot; local string_utilities_module = &amp;quot;Module:string utilities&amp;quot;  local abs = math.abs local find = string.find local format = string.format local floor = math.floor local lower = string.lower local match = string.match local rep = string.rep local require = require local to...&amp;quot;&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 parameters_module = &amp;quot;Module:parameters&amp;quot;&lt;br /&gt;
local string_pattern_escape_module = &amp;quot;Module:string/patternEscape&amp;quot;&lt;br /&gt;
local string_replacement_escape_module = &amp;quot;Module:string/replacementEscape&amp;quot;&lt;br /&gt;
local string_utilities_module = &amp;quot;Module:string utilities&amp;quot;&lt;br /&gt;
&lt;br /&gt;
local abs = math.abs&lt;br /&gt;
local find = string.find&lt;br /&gt;
local format = string.format&lt;br /&gt;
local floor = math.floor&lt;br /&gt;
local lower = string.lower&lt;br /&gt;
local match = string.match&lt;br /&gt;
local rep = string.rep&lt;br /&gt;
local require = require&lt;br /&gt;
local tonumber = tonumber&lt;br /&gt;
local type = type&lt;br /&gt;
local unpack = unpack or table.unpack -- Lua 5.2 compatibility&lt;br /&gt;
local dump = mw.dumpObject&lt;br /&gt;
&lt;br /&gt;
local function decode_uri(...)&lt;br /&gt;
	decode_uri = require(string_utilities_module).decode_uri&lt;br /&gt;
	return decode_uri(...)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function pattern_escape(...)&lt;br /&gt;
	pattern_escape = require(string_pattern_escape_module)&lt;br /&gt;
	return pattern_escape(...)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function process_params(...)&lt;br /&gt;
	process_params = require(parameters_module).process&lt;br /&gt;
	return process_params(...)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function replacement_escape(...)&lt;br /&gt;
	replacement_escape = require(string_replacement_escape_module)&lt;br /&gt;
	return replacement_escape(...)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function ufind(...)&lt;br /&gt;
	ufind = require(string_utilities_module).find&lt;br /&gt;
	return ufind(...)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function ugmatch(...)&lt;br /&gt;
	ugmatch = require(string_utilities_module).gmatch&lt;br /&gt;
	return ugmatch(...)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function ugsub(...)&lt;br /&gt;
	ugsub = require(string_utilities_module).gsub&lt;br /&gt;
	return ugsub(...)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function ulen(...)&lt;br /&gt;
	ulen = require(string_utilities_module).len&lt;br /&gt;
	return ulen(...)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function ulower(...)&lt;br /&gt;
	ulower = require(string_utilities_module).lower&lt;br /&gt;
	return ulower(...)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function umatch(...)&lt;br /&gt;
	umatch = require(string_utilities_module).match&lt;br /&gt;
	return umatch(...)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function usub(...)&lt;br /&gt;
	usub = require(string_utilities_module).sub&lt;br /&gt;
	return usub(...)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function track(page)&lt;br /&gt;
	return require(&amp;quot;Module:debug/track&amp;quot;)(&amp;quot;string/templates/&amp;quot; .. page)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Helper function that populates the argument list given that user may need to use a mix of&lt;br /&gt;
named and unnamed parameters.  This is relevant because named parameters are not&lt;br /&gt;
identical to unnamed parameters due to string trimming, and when dealing with strings&lt;br /&gt;
we sometimes want to either preserve or remove that whitespace depending on the application.&lt;br /&gt;
]]&lt;br /&gt;
local function _getParameters(frame_args, arg_list)&lt;br /&gt;
	local new_args, i, value = {}, 1&lt;br /&gt;
	&lt;br /&gt;
	for _, arg in ipairs(arg_list) do&lt;br /&gt;
		value = frame_args[arg]&lt;br /&gt;
		if value == nil then&lt;br /&gt;
			value = frame_args[i]&lt;br /&gt;
			i = i + 1&lt;br /&gt;
		end&lt;br /&gt;
		new_args[arg] = value&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return new_args&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
len&lt;br /&gt;
&lt;br /&gt;
This function returns the length of the target string.&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
{{#invoke:string/templates|len|target_string|}}&lt;br /&gt;
OR&lt;br /&gt;
{{#invoke:string/templates|len|s=target_string}}&lt;br /&gt;
&lt;br /&gt;
Parameters&lt;br /&gt;
    s: The string whose length to report&lt;br /&gt;
&lt;br /&gt;
If invoked using named parameters, Mediawiki will automatically remove any leading or&lt;br /&gt;
trailing whitespace from the target string.&lt;br /&gt;
]]&lt;br /&gt;
function export.len(frame)&lt;br /&gt;
	return ulen(_getParameters(frame.args, {&amp;quot;s&amp;quot;}).s or &amp;quot;&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
len_visible&lt;br /&gt;
&lt;br /&gt;
This function returns the length of the target string, excluding the text encompassed in &amp;lt; ... &amp;gt;&lt;br /&gt;
&lt;br /&gt;
Usage: exactly as len, above.&lt;br /&gt;
]]&lt;br /&gt;
function export.len_visible(frame)&lt;br /&gt;
	return ulen(ugsub(_getParameters(frame.args, {&amp;quot;s&amp;quot;}).s or &amp;quot;&amp;quot;, &amp;quot;&amp;lt;[^&amp;lt;&amp;gt;]+&amp;gt;&amp;quot;, &amp;quot;&amp;quot;))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
sub&lt;br /&gt;
&lt;br /&gt;
This function returns a substring of the target string at specified indices.&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
{{#invoke:string/templates|sub|target_string|start_index|end_index}}&lt;br /&gt;
OR&lt;br /&gt;
{{#invoke:string/templates|sub|s=target_string|i=start_index|j=end_index}}&lt;br /&gt;
&lt;br /&gt;
Parameters&lt;br /&gt;
    s: The string to return a subset of&lt;br /&gt;
    i: The first index of the substring to return, defaults to 1.&lt;br /&gt;
    j: The last index of the string to return, defaults to the last character.&lt;br /&gt;
    &lt;br /&gt;
The first character of the string is assigned an index of 1.  If either i or j&lt;br /&gt;
is a negative value, it is interpreted the same as selecting a character by&lt;br /&gt;
counting from the end of the string.  Hence, a value of -1 is the same as&lt;br /&gt;
selecting the last character of the string.&lt;br /&gt;
&lt;br /&gt;
If the requested indices are out of range for the given string, an error is&lt;br /&gt;
reported.&lt;br /&gt;
]]&lt;br /&gt;
function export.sub(frame)&lt;br /&gt;
	local new_args = _getParameters(frame.args, {&amp;quot;s&amp;quot;, &amp;quot;i&amp;quot;, &amp;quot;j&amp;quot;})&lt;br /&gt;
	local s = new_args[&amp;quot;s&amp;quot;] or &amp;quot;&amp;quot;&lt;br /&gt;
	local i, j = new_args[&amp;quot;i&amp;quot;], new_args[&amp;quot;j&amp;quot;]&lt;br /&gt;
	if i then&lt;br /&gt;
		i = tonumber(i)&lt;br /&gt;
	end&lt;br /&gt;
	if j then&lt;br /&gt;
		j = tonumber(j)&lt;br /&gt;
	end&lt;br /&gt;
	return usub(s, i, j)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
This function implements that features of {{str sub old}} and is kept in order&lt;br /&gt;
to maintain these older templates.&lt;br /&gt;
]]&lt;br /&gt;
function export.sublength(frame)&lt;br /&gt;
	local i = tonumber(frame.args.i) or 0&lt;br /&gt;
	local len = tonumber(frame.args.len)&lt;br /&gt;
	return usub(frame.args.s, i + 1, len and (i + len))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
match&lt;br /&gt;
&lt;br /&gt;
This function returns a substring from the source string that matches a&lt;br /&gt;
specified pattern.&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
{{#invoke:string/templates|match|source_string|pattern_string|start_index|match_number|plain_flag|nomatch_output}}&lt;br /&gt;
OR&lt;br /&gt;
{{#invoke:string/templates|pos|s=source_string|pattern=pattern_string|start=start_index&lt;br /&gt;
    |match=match_number|plain=plain_flag|nomatch=nomatch_output}}&lt;br /&gt;
&lt;br /&gt;
Parameters&lt;br /&gt;
    s: The string to search&lt;br /&gt;
    pattern: The pattern or string to find within the string&lt;br /&gt;
    start: The index within the source string to start the search.  The first&lt;br /&gt;
        character of the string has index 1.  Defaults to 1.&lt;br /&gt;
    match: In some cases it may be possible to make multiple matches on a single&lt;br /&gt;
        string.  This specifies which match to return, where the first match is&lt;br /&gt;
        match= 1.  If a negative number is specified then a match is returned&lt;br /&gt;
        counting from the last match.  Hence match = -1 is the same as requesting&lt;br /&gt;
        the last match.  Defaults to 1.&lt;br /&gt;
    plain: A flag indicating that the pattern should be understood as plain&lt;br /&gt;
        text.  Defaults to false.&lt;br /&gt;
    nomatch: If no match is found, output the &amp;quot;nomatch&amp;quot; value rather than an error.&lt;br /&gt;
&lt;br /&gt;
If invoked using named parameters, Mediawiki will automatically remove any leading or&lt;br /&gt;
trailing whitespace from each string.  In some circumstances this is desirable, in&lt;br /&gt;
other cases one may want to preserve the whitespace.&lt;br /&gt;
&lt;br /&gt;
If the match_number or start_index are out of range for the string being queried, then&lt;br /&gt;
this function generates an error.  An error is also generated if no match is found.&lt;br /&gt;
If one adds the parameter ignore_errors=true, then the error will be suppressed and&lt;br /&gt;
an empty string will be returned on any failure.&lt;br /&gt;
&lt;br /&gt;
For information on constructing Lua patterns, a form of [regular expression], see:&lt;br /&gt;
&lt;br /&gt;
* http://www.lua.org/manual/5.1/manual.html#5.4.1&lt;br /&gt;
* http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Patterns&lt;br /&gt;
* http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Ustring_patterns&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
function export.match(frame)&lt;br /&gt;
	local new_args = _getParameters(frame.args, { &amp;#039;s&amp;#039;, &amp;#039;pattern&amp;#039;, &amp;#039;start&amp;#039;, &amp;#039;match&amp;#039;, &amp;#039;plain&amp;#039;, &amp;#039;nomatch&amp;#039; })&lt;br /&gt;
	local s = new_args[&amp;#039;s&amp;#039;] or &amp;#039;&amp;#039;&lt;br /&gt;
	local start = tonumber(new_args[&amp;#039;start&amp;#039;]) or 1&lt;br /&gt;
	local plain_flag = export._getBoolean(new_args[&amp;#039;plain&amp;#039;] or false)&lt;br /&gt;
	local pattern = new_args[&amp;#039;pattern&amp;#039;] or &amp;#039;&amp;#039;&lt;br /&gt;
	local match_index = floor(tonumber(new_args[&amp;#039;match&amp;#039;]) or 1)&lt;br /&gt;
	local nomatch = new_args[&amp;#039;nomatch&amp;#039;]&lt;br /&gt;
	&lt;br /&gt;
	if pattern == &amp;quot;&amp;quot; then&lt;br /&gt;
		return export._error(&amp;#039;Pattern string is empty&amp;#039;)&lt;br /&gt;
	elseif match_index == 0 or abs(start) &amp;gt; ulen(s) then&lt;br /&gt;
		return nomatch or &amp;quot;&amp;quot;&lt;br /&gt;
	elseif plain_flag then&lt;br /&gt;
		pattern = pattern_escape(pattern)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local result&lt;br /&gt;
	if match_index == 1 then&lt;br /&gt;
		-- Find first match is simple case&lt;br /&gt;
		result = umatch(s, pattern, start)&lt;br /&gt;
	else&lt;br /&gt;
		if start &amp;gt; 1 then&lt;br /&gt;
			s = usub(s, start)&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		local iterator = ugmatch(s, pattern)&lt;br /&gt;
		if match_index &amp;gt; 0 then&lt;br /&gt;
			-- Forward search&lt;br /&gt;
			for w in iterator do&lt;br /&gt;
				match_index = match_index - 1&lt;br /&gt;
				if match_index == 0 then&lt;br /&gt;
					result = w&lt;br /&gt;
					break&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		else&lt;br /&gt;
			-- Reverse search&lt;br /&gt;
			local result_table, i = {}, 0&lt;br /&gt;
			for w in iterator do&lt;br /&gt;
				i = i + 1&lt;br /&gt;
				result_table[i] = w&lt;br /&gt;
			end&lt;br /&gt;
			&lt;br /&gt;
			result = result_table[i + match_index]&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return result or nomatch or &amp;quot;&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
pos&lt;br /&gt;
&lt;br /&gt;
This function returns a single character from the target string at position pos.&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
{{#invoke:string/templates|pos|target_string|index_value}}&lt;br /&gt;
OR&lt;br /&gt;
{{#invoke:string/templates|pos|target=target_string|pos=index_value}}&lt;br /&gt;
&lt;br /&gt;
Parameters&lt;br /&gt;
    target: The string to search&lt;br /&gt;
    pos: The index for the character to return&lt;br /&gt;
&lt;br /&gt;
If invoked using named parameters, Mediawiki will automatically remove any leading or&lt;br /&gt;
trailing whitespace from the target string.  In some circumstances this is desirable, in&lt;br /&gt;
other cases one may want to preserve the whitespace.&lt;br /&gt;
&lt;br /&gt;
The first character has an index value of 1.&lt;br /&gt;
&lt;br /&gt;
If one requests a negative value, this function will select a character by counting backwards&lt;br /&gt;
from the end of the string.  In other words pos = -1 is the same as asking for the last character.&lt;br /&gt;
&lt;br /&gt;
A requested value of zero, or a value greater than the length of the string returns an error.&lt;br /&gt;
]]&lt;br /&gt;
function export.pos(frame)&lt;br /&gt;
	local new_args = _getParameters(frame.args, { &amp;#039;target&amp;#039;, &amp;#039;pos&amp;#039; })&lt;br /&gt;
	local target_str = new_args[&amp;#039;target&amp;#039;] or &amp;#039;&amp;#039;&lt;br /&gt;
	local pos = tonumber(new_args[&amp;#039;pos&amp;#039;]) or 0&lt;br /&gt;
	&lt;br /&gt;
	if pos == 0 or abs(pos) &amp;gt; ulen(target_str) then&lt;br /&gt;
		mw.log((&amp;quot;String index %s from original %s out of range: should be in range [1,%s]&amp;quot;):format(&lt;br /&gt;
			dump(pos), dump(new_args[&amp;#039;pos&amp;#039;]), dump(ulen(target_str))))&lt;br /&gt;
		track(&amp;quot;string-index-out-of-range&amp;quot;)&lt;br /&gt;
		-- return export._error(&amp;#039;String index out of range&amp;#039;)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return usub(target_str, pos, pos)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
str_find&lt;br /&gt;
&lt;br /&gt;
This function duplicates the behavior of {{str_find}}, including all of its quirks.&lt;br /&gt;
This is provided in order to support existing templates, but is NOT RECOMMENDED for&lt;br /&gt;
new code and templates.  New code is recommended to use the &amp;quot;find&amp;quot; function instead.&lt;br /&gt;
&lt;br /&gt;
Returns the first index in &amp;quot;source&amp;quot; that is a match to &amp;quot;target&amp;quot;.  Indexing is 1-based,&lt;br /&gt;
and the function returns -1 if the &amp;quot;target&amp;quot; string is not present in &amp;quot;source&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Important Note: If the &amp;quot;target&amp;quot; string is empty / missing, this function returns a&lt;br /&gt;
value of &amp;quot;1&amp;quot;, which is generally unexpected behavior, and must be accounted for&lt;br /&gt;
separately.&lt;br /&gt;
]]&lt;br /&gt;
function export.str_find(frame)&lt;br /&gt;
	local new_args = _getParameters(frame.args, { &amp;#039;source&amp;#039;, &amp;#039;target&amp;#039; })&lt;br /&gt;
	local source_str = new_args[&amp;#039;source&amp;#039;] or &amp;#039;&amp;#039;&lt;br /&gt;
	local target_str = new_args[&amp;#039;target&amp;#039;] or &amp;#039;&amp;#039;&lt;br /&gt;
	&lt;br /&gt;
	if target_str == &amp;#039;&amp;#039; then&lt;br /&gt;
		return 1&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local start = ufind(source_str, target_str, 1, true)&lt;br /&gt;
	if start == nil then&lt;br /&gt;
		start = -1&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return start&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[==[&lt;br /&gt;
This function allows one to search for a target string or pattern within another string.&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
`{{#invoke:string/templates|find|source_string|target_string|start_index|plain_flag|return_end_flag}}`&lt;br /&gt;
OR&lt;br /&gt;
`{{#invoke:string/templates|find|source=string|target=string|start=start_index|plain=boolean|return_end=boolean}}`&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
; {{para|source}} or {{para|1}}&lt;br /&gt;
: The string to search.&lt;br /&gt;
; {{para|target}} or {{para|2}}&lt;br /&gt;
: The string or pattern to find within source.&lt;br /&gt;
; {{para|start}} or {{para|3}}&lt;br /&gt;
: The index within the source string to start the search, defaults to 1.&lt;br /&gt;
; {{para|plain}} or {{para|4}}&lt;br /&gt;
: Boolean flag indicating that target should be understood as plain text and not as a Lua style regular expression.&lt;br /&gt;
  Defaults to false.&lt;br /&gt;
; {{para|return_end}} or {{para|5}}&lt;br /&gt;
: Boolean flag indicating that index in {{para|source}} of the last character of {{para|target}} that is found should be&lt;br /&gt;
  returned. By default, the index in {{para|source}} of the first character in {{para|target}} is returned.&lt;br /&gt;
&lt;br /&gt;
If invoked using named parameters, Mediawiki will automatically remove any leading or trailing whitespace from the&lt;br /&gt;
parameter; otherwise, it will be preserved. In some circumstances this is desirable, in other cases one may want to&lt;br /&gt;
preserve the whitespace.&lt;br /&gt;
&lt;br /&gt;
This function normally returns the first index &amp;gt;= {{para|start}} where the beginning of {{para|target}} can be found&lt;br /&gt;
within {{para|source}}. Indices are 1-based. If {{para|target}} is not found, then this function returns an empty&lt;br /&gt;
string. If either {{para|source}} or {{para|target}} are missing / empty, this function also returns an empty string. If&lt;br /&gt;
the parameter {{para|return_end}} or {{para|5}} is true, the index returned is that of the end of {{para|target}} rather&lt;br /&gt;
than the beginning. For example,&lt;br /&gt;
* `{{#invoke:string/templates|find|apples|[pl]+}}` = 2&lt;br /&gt;
* `{{#invoke:string/templates|find|apples|[pl]+|return_end=1}}` = 4&lt;br /&gt;
&lt;br /&gt;
This function is safe for UTF-8 strings.&lt;br /&gt;
]==]&lt;br /&gt;
function export.find(frame)&lt;br /&gt;
	local main_param = {required = true, allow_empty = true, no_trim = true}&lt;br /&gt;
	local args = process_params(frame.args, {&lt;br /&gt;
		[1] = main_param,&lt;br /&gt;
		source = {alias_of = 1},&lt;br /&gt;
		[2] = main_param,&lt;br /&gt;
		target = {alias_of = 2},&lt;br /&gt;
		[3] = {type = &amp;quot;number&amp;quot;},&lt;br /&gt;
		start = {alias_of = 3},&lt;br /&gt;
		[4] = {type = &amp;quot;boolean&amp;quot;},&lt;br /&gt;
		plain = {alias_of = 4},&lt;br /&gt;
		[5] = {type = &amp;quot;boolean&amp;quot;},&lt;br /&gt;
		return_end = {alias_of = 5},&lt;br /&gt;
	})&lt;br /&gt;
	local start, end_ = ufind(args[1], args[2], args[3], args[4])&lt;br /&gt;
	if args[5] then&lt;br /&gt;
		return end_ and tostring(end_) or &amp;quot;&amp;quot;&lt;br /&gt;
	else&lt;br /&gt;
		return start and tostring(start) or &amp;quot;&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
replace&lt;br /&gt;
&lt;br /&gt;
This function allows one to replace a target string or pattern within another&lt;br /&gt;
string.&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
{{#invoke:string/templates|replace|source_str|pattern_string|replace_string|replacement_count|plain_flag}}&lt;br /&gt;
OR&lt;br /&gt;
{{#invoke:string/templates|replace|source=source_string|pattern=pattern_string|replace=replace_string|&lt;br /&gt;
   count=replacement_count|plain=plain_flag}}&lt;br /&gt;
&lt;br /&gt;
Parameters&lt;br /&gt;
    source: The string to search&lt;br /&gt;
    pattern: The string or pattern to find within source&lt;br /&gt;
    replace: The replacement text&lt;br /&gt;
    count: The number of occurences to replace, defaults to all.&lt;br /&gt;
    plain: Boolean flag indicating that pattern should be understood as plain&lt;br /&gt;
        text and not as a Lua style regular expression, defaults to true&lt;br /&gt;
]]&lt;br /&gt;
function export.replace(frame)&lt;br /&gt;
	local new_args = _getParameters(frame.args, { &amp;#039;source&amp;#039;, &amp;#039;pattern&amp;#039;, &amp;#039;replace&amp;#039;, &amp;#039;count&amp;#039;, &amp;#039;plain&amp;#039; })&lt;br /&gt;
	local source_str = new_args[&amp;#039;source&amp;#039;] or &amp;#039;&amp;#039;&lt;br /&gt;
	local pattern = new_args[&amp;#039;pattern&amp;#039;] or &amp;#039;&amp;#039;&lt;br /&gt;
	local replace = new_args[&amp;#039;replace&amp;#039;] or &amp;#039;&amp;#039;&lt;br /&gt;
	local count = tonumber(new_args[&amp;#039;count&amp;#039;])&lt;br /&gt;
	local plain = new_args[&amp;#039;plain&amp;#039;] or true&lt;br /&gt;
	&lt;br /&gt;
	if source_str == &amp;#039;&amp;#039; or pattern == &amp;#039;&amp;#039; then&lt;br /&gt;
		return source_str&lt;br /&gt;
	end&lt;br /&gt;
	plain = export._getBoolean(plain)&lt;br /&gt;
	&lt;br /&gt;
	if plain then&lt;br /&gt;
		pattern = pattern_escape(pattern)&lt;br /&gt;
		replace = replacement_escape(replace)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return (ugsub(source_str, pattern, replace, count))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function export.gsub(frame)&lt;br /&gt;
	local main_param = {required = true, allow_empty = true, no_trim = true}&lt;br /&gt;
	return (ugsub(unpack(process_params(frame.args, {&lt;br /&gt;
		[1] = main_param,&lt;br /&gt;
		[2] = main_param,&lt;br /&gt;
		[3] = main_param,&lt;br /&gt;
		[4] = {type = &amp;quot;number&amp;quot;},&lt;br /&gt;
	}))))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
    simple function to pipe string.rep to templates.&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
function export.rep(frame)&lt;br /&gt;
	local repetitions = tonumber(frame.args[2])&lt;br /&gt;
	if not repetitions then&lt;br /&gt;
		return export._error(&amp;#039;function rep expects a number as second parameter, received &amp;quot;&amp;#039; .. (frame.args[2] or &amp;#039;&amp;#039;) .. &amp;#039;&amp;quot;&amp;#039;)&lt;br /&gt;
	end&lt;br /&gt;
	return rep(frame.args[1] or &amp;#039;&amp;#039;, repetitions)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function export.lower(frame)&lt;br /&gt;
	return ulower(frame.args[1] or &amp;quot;&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
export.lc = export.lower&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
format&lt;br /&gt;
&lt;br /&gt;
This function allows one to format strings according to a template. This is a direct interface onto&lt;br /&gt;
export.format() in Lua, and works like the C printf() function.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
{{#invoke:string/templates|format|page_%04d.html|65}}&lt;br /&gt;
will produce the result&lt;br /&gt;
page_0065.html&lt;br /&gt;
&lt;br /&gt;
Parameters&lt;br /&gt;
    1: The format template. See https://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#string.format&lt;br /&gt;
    2, 3, ...: Arguments to be inserted into the template.&lt;br /&gt;
&lt;br /&gt;
Note that leading and trailing whitespace is not removed from the arguments.&lt;br /&gt;
]]&lt;br /&gt;
function export.format(frame)&lt;br /&gt;
	local fmt = frame.args[1]&lt;br /&gt;
	-- You can&amp;#039;t call unpack() directly on frame.args because it isn&amp;#039;t really a&lt;br /&gt;
	-- table, and doesn&amp;#039;t support the # operator.&lt;br /&gt;
	local args = {}&lt;br /&gt;
	local i = 2&lt;br /&gt;
	while true do&lt;br /&gt;
		local val = frame.args[i]&lt;br /&gt;
		if not val then&lt;br /&gt;
			break&lt;br /&gt;
		end&lt;br /&gt;
		table.insert(args, val)&lt;br /&gt;
		i = i + 1&lt;br /&gt;
	end&lt;br /&gt;
	return format(fmt, unpack(args))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Helper function to handle error messages.&lt;br /&gt;
]]&lt;br /&gt;
function export._error(error_str)&lt;br /&gt;
	local frame = mw.getCurrentFrame()&lt;br /&gt;
	local ignore_errors = frame.args.ignore_errors or false&lt;br /&gt;
	&lt;br /&gt;
	if export._getBoolean(ignore_errors) then&lt;br /&gt;
		return &amp;#039;&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	error(error_str)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Helper Function to interpret boolean strings&lt;br /&gt;
]]&lt;br /&gt;
function export._getBoolean(boolean_str)&lt;br /&gt;
	local boolean_str_type = type(boolean_str)&lt;br /&gt;
	if boolean_str_type == &amp;#039;boolean&amp;#039; then&lt;br /&gt;
		return boolean_str&lt;br /&gt;
	elseif boolean_str_type ~= &amp;quot;string&amp;quot; then&lt;br /&gt;
		error(&amp;#039;No boolean value found&amp;#039;)&lt;br /&gt;
	end&lt;br /&gt;
	boolean_str = lower(boolean_str)&lt;br /&gt;
	return not (&lt;br /&gt;
		boolean_str == &amp;#039;false&amp;#039; or&lt;br /&gt;
		boolean_str == &amp;#039;no&amp;#039; or&lt;br /&gt;
		boolean_str == &amp;#039;0&amp;#039; or&lt;br /&gt;
		boolean_str == &amp;#039;&amp;#039;&lt;br /&gt;
	)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function export.matchToArray(text, pattern)&lt;br /&gt;
	local invoked = false&lt;br /&gt;
	&lt;br /&gt;
	if type(text) == &amp;quot;table&amp;quot; then&lt;br /&gt;
		invoked = true&lt;br /&gt;
		&lt;br /&gt;
		if text.args then&lt;br /&gt;
			local frame = text&lt;br /&gt;
			&lt;br /&gt;
			local params = {&lt;br /&gt;
				[1] = { required = true },&lt;br /&gt;
				[2] = { required = true },&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			local args = process_params(frame.args, params)&lt;br /&gt;
			&lt;br /&gt;
			text = args[1]&lt;br /&gt;
			pattern = args[2]&lt;br /&gt;
		else&lt;br /&gt;
			error(&amp;quot;If the first argument to matchToArray is a table, it should be a frame object.&amp;quot;)&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		if not (type(pattern) == &amp;quot;string&amp;quot; or type(pattern) == &amp;quot;number&amp;quot;) then&lt;br /&gt;
			error(&amp;quot;The second argument to matchToArray should be a string or a number.&amp;quot;)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local matches = {}&lt;br /&gt;
	local i = 0&lt;br /&gt;
	for match in ugmatch(text, pattern) do&lt;br /&gt;
		i = i + 1&lt;br /&gt;
		matches[i] = match&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if i &amp;gt; 0 then&lt;br /&gt;
		if invoked then&lt;br /&gt;
			return table.concat(matches, &amp;quot;, &amp;quot;)&lt;br /&gt;
		else&lt;br /&gt;
			return matches&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		if invoked then&lt;br /&gt;
			return &amp;quot;&amp;quot;&lt;br /&gt;
		else&lt;br /&gt;
			return nil&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[=[&lt;br /&gt;
	Similar to gmatch, but it returns the count of the match in addition to the&lt;br /&gt;
	list of captures, something like ipairs().&lt;br /&gt;
	&lt;br /&gt;
	If the pattern doesn&amp;#039;t contain any captures, the whole match is returned.&lt;br /&gt;
	&lt;br /&gt;
	Invoke thus:&lt;br /&gt;
	&lt;br /&gt;
		for i, whole_match in require(&amp;quot;Module:string/templates&amp;quot;).imatch(text, pattern) do&lt;br /&gt;
			[ do something with i and whole_match ]&lt;br /&gt;
		end&lt;br /&gt;
	&lt;br /&gt;
	or&lt;br /&gt;
	&lt;br /&gt;
		for i, capture1[, capture2[, capture3[, ...]]] in require(&amp;quot;Module:string/templates&amp;quot;).imatch(text, pattern) do&lt;br /&gt;
			[ do something with i and capture1 ]&lt;br /&gt;
		end&lt;br /&gt;
	&lt;br /&gt;
	For example, this code&lt;br /&gt;
		for i, whole_match in require(&amp;quot;Module:string/templates&amp;quot;).imatch(&amp;quot;a b c&amp;quot;, &amp;quot;[a-z]&amp;quot;) do&lt;br /&gt;
			mw.log(i, whole_match)&lt;br /&gt;
		end&lt;br /&gt;
	will log&lt;br /&gt;
		1	a&lt;br /&gt;
		2	b&lt;br /&gt;
		3	c&lt;br /&gt;
]=]&lt;br /&gt;
function export.imatch(text, pattern, pos, plain, use_basic_Lua_function)&lt;br /&gt;
	local i = 0&lt;br /&gt;
	pos = pos or 0&lt;br /&gt;
	if not match(pattern, &amp;quot;%b()&amp;quot;) then&lt;br /&gt;
		pattern = &amp;quot;(&amp;quot; .. pattern .. &amp;quot;)&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	local _find = use_basic_Lua_function and find or ufind&lt;br /&gt;
	return function()&lt;br /&gt;
		i = i + 1&lt;br /&gt;
		local return_values = { _find(text, pattern, pos, plain) }&lt;br /&gt;
		local j = return_values[2]&lt;br /&gt;
		&lt;br /&gt;
		if return_values[3] then&lt;br /&gt;
			pos = j + 1&lt;br /&gt;
			-- Skip the first two returned values, which are the indices of the&lt;br /&gt;
			-- whole match.&lt;br /&gt;
			return i, unpack(return_values, 3)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function export.URIdecode(frame)&lt;br /&gt;
	return decode_uri(frame.args[1], frame.args[2] or &amp;quot;PATH&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return export&lt;/div&gt;</summary>
		<author><name>Sware</name></author>
	</entry>
</feed>