<?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%3AScribunto</id>
	<title>Module:Scribunto - 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%3AScribunto"/>
	<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=Module:Scribunto&amp;action=history"/>
	<updated>2026-04-06T02:57:32Z</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:Scribunto&amp;diff=474923&amp;oldid=prev</id>
		<title>Sware: 1 revision imported</title>
		<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=Module:Scribunto&amp;diff=474923&amp;oldid=prev"/>
		<updated>2025-11-04T17:47:20Z</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;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 17:47, 4 November 2025&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&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;/table&gt;</summary>
		<author><name>Sware</name></author>
	</entry>
	<entry>
		<id>https://linguifex.com/w/index.php?title=Module:Scribunto&amp;diff=461109&amp;oldid=prev</id>
		<title>Sware: Created page with &quot;local export = {}  local math_module = &quot;Module:math&quot;  local dump = mw.dumpObject local format = string.format local gsub = string.gsub local match = string.match local php_trim -- defined below local sub = string.sub local tonumber = tonumber local tostring = tostring local type = type  do 	local php_htmlspecialchars_data 	local function get_php_htmlspecialchars_data() 		php_htmlspecialchars_data, get_php_htmlspecialchars_data = { 			[&quot;\&quot;&quot;] = &quot;&amp;quot;&quot;, 			[&quot;&amp;&quot;] = &quot;&amp;amp;&quot;...&quot;</title>
		<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=Module:Scribunto&amp;diff=461109&amp;oldid=prev"/>
		<updated>2025-07-01T23:13:55Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;local export = {}  local math_module = &amp;quot;Module:math&amp;quot;  local dump = mw.dumpObject local format = string.format local gsub = string.gsub local match = string.match local php_trim -- defined below local sub = string.sub local tonumber = tonumber local tostring = tostring local type = type  do 	local php_htmlspecialchars_data 	local function get_php_htmlspecialchars_data() 		php_htmlspecialchars_data, get_php_htmlspecialchars_data = { 			[&amp;quot;\&amp;quot;&amp;quot;] = &amp;quot;&amp;quot;&amp;quot;, 			[&amp;quot;&amp;amp;&amp;quot;] = &amp;quot;&amp;amp;&amp;quot;...&amp;quot;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 23:13, 1 July 2025&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&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;/table&gt;</summary>
		<author><name>Sware</name></author>
	</entry>
	<entry>
		<id>https://linguifex.com/w/index.php?title=Module:Scribunto&amp;diff=474922&amp;oldid=prev</id>
		<title>wikt&gt;Theknightwho at 03:21, 23 May 2025</title>
		<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=Module:Scribunto&amp;diff=474922&amp;oldid=prev"/>
		<updated>2025-05-23T03:21:05Z</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 math_module = &amp;quot;Module:math&amp;quot;&lt;br /&gt;
&lt;br /&gt;
local dump = mw.dumpObject&lt;br /&gt;
local format = string.format&lt;br /&gt;
local gsub = string.gsub&lt;br /&gt;
local match = string.match&lt;br /&gt;
local php_trim -- defined below&lt;br /&gt;
local sub = string.sub&lt;br /&gt;
local tonumber = tonumber&lt;br /&gt;
local tostring = tostring&lt;br /&gt;
local type = type&lt;br /&gt;
&lt;br /&gt;
do&lt;br /&gt;
	local php_htmlspecialchars_data&lt;br /&gt;
	local function get_php_htmlspecialchars_data()&lt;br /&gt;
		php_htmlspecialchars_data, get_php_htmlspecialchars_data = {&lt;br /&gt;
			[&amp;quot;\&amp;quot;&amp;quot;] = &amp;quot;&amp;amp;quot;&amp;quot;,&lt;br /&gt;
			[&amp;quot;&amp;amp;&amp;quot;] = &amp;quot;&amp;amp;amp;&amp;quot;,&lt;br /&gt;
			[&amp;quot;&amp;#039;&amp;quot;] = &amp;quot;&amp;amp;#039;&amp;quot;,&lt;br /&gt;
			[&amp;quot;&amp;lt;&amp;quot;] = &amp;quot;&amp;amp;lt;&amp;quot;,&lt;br /&gt;
			[&amp;quot;&amp;gt;&amp;quot;] = &amp;quot;&amp;amp;gt;&amp;quot;,&lt;br /&gt;
		}, nil&lt;br /&gt;
		return php_htmlspecialchars_data&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	--[==[Lua equivalent of PHP&amp;#039;s {{code|php|htmlspecialchars($string)}}, which converts the characters `&amp;amp;&amp;quot;&amp;#039;&amp;lt;&amp;gt;` to HTML entities.&lt;br /&gt;
&lt;br /&gt;
	If the `quotes` flag is set to {&amp;quot;compat&amp;quot;}, then `&amp;#039;` will not be converted, and if it is set to {&amp;quot;noquotes&amp;quot;}, then neither `&amp;quot;` nor `&amp;#039;` will be converted.]==]&lt;br /&gt;
	function export.php_htmlspecialchars(str, quotes)&lt;br /&gt;
		if quotes == nil or quotes == &amp;quot;quotes&amp;quot; then&lt;br /&gt;
			quotes = &amp;quot;&amp;#039;\&amp;quot;&amp;quot;&lt;br /&gt;
		elseif quotes == &amp;quot;compat&amp;quot; then&lt;br /&gt;
			quotes = &amp;quot;\&amp;quot;&amp;quot;&lt;br /&gt;
		elseif quotes == &amp;quot;noquotes&amp;quot; then&lt;br /&gt;
			quotes = &amp;quot;&amp;quot;&lt;br /&gt;
		else&lt;br /&gt;
			local quotes_type = type(quotes)&lt;br /&gt;
			error(&amp;#039;`quotes` must be &amp;quot;quotes&amp;quot;, &amp;quot;compat&amp;quot;, &amp;quot;noquotes&amp;quot; or nil; received &amp;#039; ..&lt;br /&gt;
				(quotes_type == &amp;quot;string&amp;quot; and dump(quotes) or &amp;quot;a &amp;quot; .. quotes_type))&lt;br /&gt;
		end&lt;br /&gt;
		return (gsub(str, &amp;quot;[&amp;amp;&amp;lt;&amp;gt;&amp;quot; .. quotes .. &amp;quot;]&amp;quot;, php_htmlspecialchars_data or get_php_htmlspecialchars_data()))&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
do&lt;br /&gt;
	local function tonumber_extended(...)&lt;br /&gt;
		tonumber_extended = require(math_module).tonumber_extended&lt;br /&gt;
		return tonumber_extended(...)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Normalizes a string for use in comparisons which emulate PHP&amp;#039;s equals&lt;br /&gt;
	-- operator, which coerces certain strings to numbers: those within the&lt;br /&gt;
	-- range -2^63 to 2^63 - 1 which don&amp;#039;t have decimal points or exponents are&lt;br /&gt;
	-- coerced to integers, while any others are coerced to doubles if possible;&lt;br /&gt;
	-- otherwise, they remain as strings. PHP and Lua have the same precision&lt;br /&gt;
	-- for doubles, but Lua&amp;#039;s integer precision range is -2^53 + 1 to 2^53 - 1.&lt;br /&gt;
	-- Any integers within Lua&amp;#039;s precision, as well as all doubles, are simply&lt;br /&gt;
	-- coerced to numbers, but PHP integers outside of Lua&amp;#039;s precision are&lt;br /&gt;
	-- emulated as normalized strings, with leading 0s and any + sign removed.&lt;br /&gt;
	-- The `not_long` flag is used for the second comparator if the first did&lt;br /&gt;
	-- not get normalized to a long integer, as PHP will only coerce strings to&lt;br /&gt;
	-- integers if it&amp;#039;s possible for both comparators.&lt;br /&gt;
	local function php_normalize_string(str, not_long)&lt;br /&gt;
		local num = tonumber_extended(str, nil, true)&lt;br /&gt;
		-- Must be a number that isn&amp;#039;t ±infinity, NaN or hexadecimal.&lt;br /&gt;
		if not num or match(str, &amp;quot;^%s*[+-]?0[xX]()&amp;quot;) then&lt;br /&gt;
			return str&lt;br /&gt;
		-- If `not_long` is set or `num` is within Lua&amp;#039;s precision, return as a&lt;br /&gt;
		-- number.&lt;br /&gt;
		elseif not_long or num &amp;lt; 9007199254740992 and num &amp;gt; -9007199254740992 then&lt;br /&gt;
			return num, &amp;quot;number&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
		-- Check if it could be a long integer, and return as a double if not.&lt;br /&gt;
		local sign, str_no_0 = match(str, &amp;quot;^%s*([+-]?)0*(%d+)$&amp;quot;)&lt;br /&gt;
		if not str_no_0 then&lt;br /&gt;
			return num, &amp;quot;number&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
		-- Otherwise, check if it&amp;#039;s a long integer. 2^63 is 9223372036854775808,&lt;br /&gt;
		-- so slice off the last 15 digits and deal with the two parts&lt;br /&gt;
		-- separately. If the integer value would be too high/low, return as a&lt;br /&gt;
		-- string.&lt;br /&gt;
		local high = tonumber(sub(str_no_0, 1, -16))&lt;br /&gt;
		if high &amp;gt; 9223 then&lt;br /&gt;
			return str&lt;br /&gt;
		elseif high == 9223 then&lt;br /&gt;
			local low = tonumber(sub(str_no_0, -15))&lt;br /&gt;
			-- Range is -2^63 to 2^63 - 1 (not symmetrical).&lt;br /&gt;
			if low &amp;gt; 372036854775808 or low == 372036854775808 and sign ~= &amp;quot;-&amp;quot; then&lt;br /&gt;
				return str&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		return (sign == &amp;quot;+&amp;quot; and &amp;quot;&amp;quot; or sign) .. str_no_0, &amp;quot;long integer&amp;quot;, num&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	--[==[Lua equivalent of PHP&amp;#039;s {{code|php|===}} operator for strings.]==]&lt;br /&gt;
	function export.php_string_equals(str1, str2)&lt;br /&gt;
		if str1 == str2 then&lt;br /&gt;
			return true&lt;br /&gt;
		end&lt;br /&gt;
		local str1, str1_type, str1_num = php_normalize_string(str1)&lt;br /&gt;
		if str1 == str2 then&lt;br /&gt;
			return true&lt;br /&gt;
		elseif str1_type == &amp;quot;long integer&amp;quot; then&lt;br /&gt;
			local str2, str2_type = php_normalize_string(str2)&lt;br /&gt;
			return str2 == (str2_type == &amp;quot;number&amp;quot; and str1_num or str1)&lt;br /&gt;
		elseif str1_type == &amp;quot;number&amp;quot; then&lt;br /&gt;
			return str1 == php_normalize_string(str2, true)&lt;br /&gt;
		end&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[==[Lua equivalent of PHP&amp;#039;s {{code|php|trim($string)}}, which trims {&amp;quot;\0&amp;quot;}, {&amp;quot;\t&amp;quot;}, {&amp;quot;\n&amp;quot;}, {&amp;quot;\v&amp;quot;}, {&amp;quot;\r&amp;quot;} and {&amp;quot; &amp;quot;}. This is useful when dealing with template parameters, since the native parser trims them like this.]==]&lt;br /&gt;
function export.php_trim(str)&lt;br /&gt;
	return match(str, &amp;quot;[^ \t-\v\r%z].*%f[ \t-\v\r%z]&amp;quot;) or &amp;quot;&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
php_trim = export.php_trim&lt;br /&gt;
&lt;br /&gt;
--[==[Lua equivalent of PHP&amp;#039;s {{code|php|ltrim($string)}}, which trims {&amp;quot;\0&amp;quot;}, {&amp;quot;\t&amp;quot;}, {&amp;quot;\n&amp;quot;}, {&amp;quot;\v&amp;quot;}, {&amp;quot;\r&amp;quot;} and {&amp;quot; &amp;quot;} from the beginning of the input string.]==]&lt;br /&gt;
function export.php_ltrim(str)&lt;br /&gt;
	return (gsub(str, &amp;quot;^[ \t-\v\r%z]+&amp;quot;, &amp;quot;&amp;quot;))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[==[Lua equivalent of PHP&amp;#039;s {{code|php|rtrim($string)}}, which trims {&amp;quot;\0&amp;quot;}, {&amp;quot;\t&amp;quot;}, {&amp;quot;\n&amp;quot;}, {&amp;quot;\v&amp;quot;}, {&amp;quot;\r&amp;quot;} and {&amp;quot; &amp;quot;} from the end of the input string.]==]&lt;br /&gt;
function export.php_rtrim(str)&lt;br /&gt;
	return match(str, &amp;quot;^.+%f[ \t-\v\r%z]&amp;quot;) or &amp;quot;&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[==[Takes a template or module parameter name as either a string or number, and returns the Scribunto-normalized form (i.e. the key that that parameter would have in a {frame.args} table). For example, {&amp;quot;1&amp;quot;} (a string) is normalized to {1} (a number), {&amp;quot; foo &amp;quot;} is normalized to {&amp;quot;foo&amp;quot;}, and {1.5} (a number) is normalized to {&amp;quot;1.5&amp;quot;} (a string). Inputs which cannot be normalized (e.g. booleans) return {nil}.&lt;br /&gt;
&lt;br /&gt;
Strings are trimmed with {export.php_trim}, unless the `no_trim` flag is set. If it is, then string parameters are not trimmed, but strings may still be converted to numbers if they do not contain whitespace; this is necessary when normalizing keys into the form received by PHP during callbacks, before any trimming occurs (e.g. in the table of arguments when calling {frame:expandTemplates()}).&lt;br /&gt;
&lt;br /&gt;
After trimming (if applicable), keys are then converted to numbers if &amp;#039;&amp;#039;&amp;#039;all&amp;#039;&amp;#039;&amp;#039; of the following are true:&lt;br /&gt;
# They are integers; i.e. no decimals or leading zeroes (e.g. {&amp;quot;2&amp;quot;}, but not {&amp;quot;2.0&amp;quot;} or {&amp;quot;02&amp;quot;}).&lt;br /&gt;
# They are ≤ 2{{sup|53}} and ≥ -2{{sup|53}}.&lt;br /&gt;
# There is no leading sign unless &amp;lt; 0 (e.g. {&amp;quot;2&amp;quot;} or {&amp;quot;-2&amp;quot;}, but not {&amp;quot;+2&amp;quot;} or {&amp;quot;-0&amp;quot;}).&lt;br /&gt;
# They contain no leading or trailing whitespace (which may be present when the `no_trim` flag is set).&lt;br /&gt;
&lt;br /&gt;
Numbers are converted to strings if &amp;#039;&amp;#039;&amp;#039;either&amp;#039;&amp;#039;&amp;#039;:&lt;br /&gt;
# They are not integers (e.g. {1.5}).&lt;br /&gt;
# They are &amp;gt; 2{{sup|53}} or &amp;lt; -2{{sup|53}}.&lt;br /&gt;
&lt;br /&gt;
When converted to strings, integers ≤ 2{{sup|63}} and ≥ -2{{sup|63}} are formatted as integers (i.e. all digits are given), which is the range of PHP&amp;#039;s integer precision, though the actual output may be imprecise since Lua&amp;#039;s integer precision is &amp;gt; 2{{sup|53}} to &amp;lt; -2{{sup|53}}. All other numbers use the standard formatting output by {tostring()}.]==]&lt;br /&gt;
function export.scribunto_parameter_key(key, no_trim)&lt;br /&gt;
	local key_type = type(key)&lt;br /&gt;
	if key_type == &amp;quot;string&amp;quot; then&lt;br /&gt;
		if not no_trim then&lt;br /&gt;
			key = php_trim(key)&lt;br /&gt;
		end&lt;br /&gt;
		if match(key, &amp;quot;^()-?[1-9]%d*$&amp;quot;) then&lt;br /&gt;
			local num = tonumber(key)&lt;br /&gt;
			-- Lua integers are only precise to 2^53 - 1, so specifically check&lt;br /&gt;
			-- for 2^53 and -2^53 as strings, since a numerical comparison won&amp;#039;t&lt;br /&gt;
			-- work as it can&amp;#039;t distinguish 2^53 from 2^53 + 1.&lt;br /&gt;
			return (&lt;br /&gt;
				num &amp;lt;= 9007199254740991 and num &amp;gt;= -9007199254740991 or&lt;br /&gt;
				key == &amp;quot;9007199254740992&amp;quot; or&lt;br /&gt;
				key == &amp;quot;-9007199254740992&amp;quot;&lt;br /&gt;
			) and num or key&lt;br /&gt;
		end&lt;br /&gt;
		return key == &amp;quot;0&amp;quot; and 0 or key&lt;br /&gt;
	elseif key_type == &amp;quot;number&amp;quot; then&lt;br /&gt;
		-- No special handling needed for inf or NaN.&lt;br /&gt;
		return key % 1 == 0 and (&lt;br /&gt;
			key &amp;lt;= 9007199254740992 and key &amp;gt;= -9007199254740992 and key or&lt;br /&gt;
			key &amp;lt;= 9223372036854775808 and key &amp;gt;= -9223372036854775808 and format(&amp;quot;%d&amp;quot;, key)&lt;br /&gt;
		) or tostring(key)&lt;br /&gt;
	end&lt;br /&gt;
	return nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[==[Takes a template or module parameter value as either a string, number or boolean, and returns the Scribunto-normalized form (i.e. the value that that parameter would have in a {frame.args} table), which is always a string. For example, {&amp;quot;foo&amp;quot;} remains the same, {2} (a number) is normalized to {&amp;quot;2&amp;quot;} (a string), {true} is normalized to {&amp;quot;1&amp;quot;}, and {false} is normalized to {&amp;quot;&amp;quot;}. Inputs which cannot be normalized (e.g. tables) return {nil}.&lt;br /&gt;
&lt;br /&gt;
By default, returned values are not trimmed, which matches the treatment of unnamed parameters (e.g. `bar` in {{tl|&amp;lt;nowiki/&amp;gt;foo|bar}}). If the `named` flag is set, then returned values will be trimmed, which matches the treatment of named parameters (e.g. `baz` in {{tl|&amp;lt;nowiki/&amp;gt;foo|bar=baz}}).]==]&lt;br /&gt;
function export.scribunto_parameter_value(value, named)&lt;br /&gt;
	local value_type = type(value)&lt;br /&gt;
	if value_type == &amp;quot;string&amp;quot; then&lt;br /&gt;
		return named and php_trim(value) or value&lt;br /&gt;
	elseif value_type == &amp;quot;number&amp;quot; then&lt;br /&gt;
		return tostring(value)&lt;br /&gt;
	elseif value_type == &amp;quot;boolean&amp;quot; then&lt;br /&gt;
		return value and &amp;quot;1&amp;quot; or &amp;quot;&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	return nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return export&lt;/div&gt;</summary>
		<author><name>wikt&gt;Theknightwho</name></author>
	</entry>
</feed>