Moduli:Scribunto

Nga Enciklopedi Puro Shqiptare
Versioni i datës 10 gusht 2025 09:00 nga Kujdestari7 (diskuto | kontribute) (Krijoi faqen me "local export = {} local math_module = "Module:math" 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 = { ["\""] = """, ["&"] = "&",...")
(ndrysh) ← Version më i vjetër | shikoni versionin e tanishëm (ndrysh) | Version më i ri → (ndrysh)
Jump to navigation Jump to search

Udhëzuesi për këtë modul mund të krijohet te Moduli:Scribunto/doc.

local export = {}

local math_module = "Module:math"

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 = {
			["\""] = """,
			["&"] = "&",
			["'"] = "'",
			["<"] = "&lt;",
			[">"] = "&gt;",
		}, nil
		return php_htmlspecialchars_data
	end

	--[==[Lua equivalent of PHP's {{code|php|htmlspecialchars($string)}}, which converts the characters `&"'<>` to HTML entities.

	If the `quotes` flag is set to {"compat"}, then `'` will not be converted, and if it is set to {"noquotes"}, then neither `"` nor `'` will be converted.]==]
	function export.php_htmlspecialchars(str, quotes)
		if quotes == nil or quotes == "quotes" then
			quotes = "'\""
		elseif quotes == "compat" then
			quotes = "\""
		elseif quotes == "noquotes" then
			quotes = ""
		else
			local quotes_type = type(quotes)
			error('`quotes` must be "quotes", "compat", "noquotes" or nil; received ' ..
				(quotes_type == "string" and dump(quotes) or "a " .. quotes_type))
		end
		return (gsub(str, "[&<>" .. quotes .. "]", php_htmlspecialchars_data or get_php_htmlspecialchars_data()))
	end
end

do
	local function tonumber_extended(...)
		tonumber_extended = require(math_module).tonumber_extended
		return tonumber_extended(...)
	end

	-- Normalizes a string for use in comparisons which emulate PHP's equals
	-- operator, which coerces certain strings to numbers: those within the
	-- range -2^63 to 2^63 - 1 which don't have decimal points or exponents are
	-- coerced to integers, while any others are coerced to doubles if possible;
	-- otherwise, they remain as strings. PHP and Lua have the same precision
	-- for doubles, but Lua's integer precision range is -2^53 + 1 to 2^53 - 1.
	-- Any integers within Lua's precision, as well as all doubles, are simply
	-- coerced to numbers, but PHP integers outside of Lua's precision are
	-- emulated as normalized strings, with leading 0s and any + sign removed.
	-- The `not_long` flag is used for the second comparator if the first did
	-- not get normalized to a long integer, as PHP will only coerce strings to
	-- integers if it's possible for both comparators.
	local function php_normalize_string(str, not_long)
		local num = tonumber_extended(str, nil, true)
		-- Must be a number that isn't ±infinity, NaN or hexadecimal.
		if not num or match(str, "^%s*[+-]?0[xX]()") then
			return str
		-- If `not_long` is set or `num` is within Lua's precision, return as a
		-- number.
		elseif not_long or num < 9007199254740992 and num > -9007199254740992 then
			return num, "number"
		end
		-- Check if it could be a long integer, and return as a double if not.
		local sign, str_no_0 = match(str, "^%s*([+-]?)0*(%d+)$")
		if not str_no_0 then
			return num, "number"
		end
		-- Otherwise, check if it's a long integer. 2^63 is 9223372036854775808,
		-- so slice off the last 15 digits and deal with the two parts
		-- separately. If the integer value would be too high/low, return as a
		-- string.
		local high = tonumber(sub(str_no_0, 1, -16))
		if high > 9223 then
			return str
		elseif high == 9223 then
			local low = tonumber(sub(str_no_0, -15))
			-- Range is -2^63 to 2^63 - 1 (not symmetrical).
			if low > 372036854775808 or low == 372036854775808 and sign ~= "-" then
				return str
			end
		end
		return (sign == "+" and "" or sign) .. str_no_0, "long integer", num
	end

	--[==[Lua equivalent of PHP's {{code|php|===}} operator for strings.]==]
	function export.php_string_equals(str1, str2)
		if str1 == str2 then
			return true
		end
		local str1, str1_type, str1_num = php_normalize_string(str1)
		if str1 == str2 then
			return true
		elseif str1_type == "long integer" then
			local str2, str2_type = php_normalize_string(str2)
			return str2 == (str2_type == "number" and str1_num or str1)
		elseif str1_type == "number" then
			return str1 == php_normalize_string(str2, true)
		end
		return false
	end
end

--[==[Lua equivalent of PHP's {{code|php|trim($string)}}, which trims {"\0"}, {"\t"}, {"\n"}, {"\v"}, {"\r"} and {" "}. This is useful when dealing with template parameters, since the native parser trims them like this.]==]
function export.php_trim(str)
	return match(str, "[^ \t-\v\r%z].*%f[ \t-\v\r%z]") or ""
end
php_trim = export.php_trim

--[==[Lua equivalent of PHP's {{code|php|ltrim($string)}}, which trims {"\0"}, {"\t"}, {"\n"}, {"\v"}, {"\r"} and {" "} from the beginning of the input string.]==]
function export.php_ltrim(str)
	return (gsub(str, "^[ \t-\v\r%z]+", ""))
end

--[==[Lua equivalent of PHP's {{code|php|rtrim($string)}}, which trims {"\0"}, {"\t"}, {"\n"}, {"\v"}, {"\r"} and {" "} from the end of the input string.]==]
function export.php_rtrim(str)
	return match(str, "^.+%f[ \t-\v\r%z]") or ""
end

--[==[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, {"1"} (a string) is normalized to {1} (a number), {" foo "} is normalized to {"foo"}, and {1.5} (a number) is normalized to {"1.5"} (a string). Inputs which cannot be normalized (e.g. booleans) return {nil}.

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()}).

After trimming (if applicable), keys are then converted to numbers if '''all''' of the following are true:
# They are integers; i.e. no decimals or leading zeroes (e.g. {"2"}, but not {"2.0"} or {"02"}).
# They are ≤ 2{{sup|53}} and ≥ -2{{sup|53}}.
# There is no leading sign unless < 0 (e.g. {"2"} or {"-2"}, but not {"+2"} or {"-0"}).
# They contain no leading or trailing whitespace (which may be present when the `no_trim` flag is set).

Numbers are converted to strings if '''either''':
# They are not integers (e.g. {1.5}).
# They are > 2{{sup|53}} or < -2{{sup|53}}.

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's integer precision, though the actual output may be imprecise since Lua's integer precision is > 2{{sup|53}} to < -2{{sup|53}}. All other numbers use the standard formatting output by {tostring()}.]==]
function export.scribunto_parameter_key(key, no_trim)
	local key_type = type(key)
	if key_type == "string" then
		if not no_trim then
			key = php_trim(key)
		end
		if match(key, "^()-?[1-9]%d*$") then
			local num = tonumber(key)
			-- Lua integers are only precise to 2^53 - 1, so specifically check
			-- for 2^53 and -2^53 as strings, since a numerical comparison won't
			-- work as it can't distinguish 2^53 from 2^53 + 1.
			return (
				num <= 9007199254740991 and num >= -9007199254740991 or
				key == "9007199254740992" or
				key == "-9007199254740992"
			) and num or key
		end
		return key == "0" and 0 or key
	elseif key_type == "number" then
		-- No special handling needed for inf or NaN.
		return key % 1 == 0 and (
			key <= 9007199254740992 and key >= -9007199254740992 and key or
			key <= 9223372036854775808 and key >= -9223372036854775808 and format("%d", key)
		) or tostring(key)
	end
	return nil
end

--[==[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, {"foo"} remains the same, {2} (a number) is normalized to {"2"} (a string), {true} is normalized to {"1"}, and {false} is normalized to {""}. Inputs which cannot be normalized (e.g. tables) return {nil}.

By default, returned values are not trimmed, which matches the treatment of unnamed parameters (e.g. `bar` in {{tl|<nowiki/>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|<nowiki/>foo|bar=baz}}).]==]
function export.scribunto_parameter_value(value, named)
	local value_type = type(value)
	if value_type == "string" then
		return named and php_trim(value) or value
	elseif value_type == "number" then
		return tostring(value)
	elseif value_type == "boolean" then
		return value and "1" or ""
	end
	return nil
end

return export