Sari la conținut

Modul:StringUtils

De la Wikipedia, enciclopedia liberă

local p = {}
local arguments = require('Modul:Arguments')
local TableTools = require('Modul:TableTools')

local ulen = mw.ustring.len
local usub = mw.ustring.sub
local ufind = mw.ustring.find

-- Creează funcția apelabilă cu #invoke pentru funcția internă cu numele dat.
local function makeInvokeFunc(funcName)
	return function (frame)
		local args = arguments.getArgs(frame, { wrappers = 'Format:Ifempty' })
		local firstRet = p[funcName](args)
		return firstRet
	end
end

-- Normalizează argumentele primite de funcțiile „_nume”, astfel încât acestea să
-- funcționeze la fel indiferent de modul de apelare:
--   p._funcție{ 'a', 'b', 'c' }   -- un singur tabel de argumente
--   p._funcție('a', 'b', 'c')     -- argumente transmise direct
-- Returnează întotdeauna un tabel cu argumentele pe pozițiile 1, 2, 3...
local function normalizeArgs(...)
	local first = ...
	if type(first) == 'table' then
		return first
	end
	return { ... }
end

-- Returnează cel mai mare index numeric pozitiv din tabelul de argumente
-- (funcționează și pentru tabele cu „goluri”, adică valori nil intermediare).
local function lastIndex(args)
	local max = 0
	for k in pairs(args) do
		if type(k) == 'number' and k > max and k == math.floor(k) then
			max = k
		end
	end
	return max
end

-- Verifică dacă un șir începe cu un prefix dat.
local function startsWith(str, prefix)
	str, prefix = tostring(str), tostring(prefix)
	return usub(str, 1, ulen(prefix)) == prefix
end

-- Verifică dacă un șir se termină cu un sufix dat.
local function endsWith(str, suffix)
	str, suffix = tostring(str), tostring(suffix)
	local strLen, suffixLen = ulen(str), ulen(suffix)
	if suffixLen > strLen then return false end
	return usub(str, strLen - suffixLen + 1, strLen) == suffix
end

-- Adaugă la începutul unui șir un prefix, dacă nu există deja acolo el sau unul dintre cele listate în ultimul argument
function p._prependIfMissing(...)
	local args = normalizeArgs(...)
	local str = args[1] ~= nil and tostring(args[1]) or nil
	local prefix = args[2]
	if str == nil then return nil end
	if prefix == nil then return str end

	for i = 2, lastIndex(args) do
		local eachPrefix = args[i]
		if eachPrefix ~= nil and startsWith(str, eachPrefix) then return str end
	end

	return prefix .. str
end
p.prependIfMissing = makeInvokeFunc('_prependIfMissing')

-- Adaugă la sfârșitul unui șir un sufix, dacă nu există deja acolo el sau unul dintre cele listate în ultimul argument
function p._appendIfMissing(...)
	local args = normalizeArgs(...)
	local str = args[1] ~= nil and tostring(args[1]) or nil
	local suffix = args[2]
	if str == nil then return nil end
	if suffix == nil then return str end

	for i = 2, lastIndex(args) do
		local eachSuffix = args[i]
		if eachSuffix ~= nil and endsWith(str, eachSuffix) then return str end
	end

	return str .. suffix
end
p.appendIfMissing = makeInvokeFunc('_appendIfMissing')

function p._emptyToNil(...)
	local args = normalizeArgs(...)
	local str = args[1]
	if str == '' then return nil end
	return str
end
p.emptyToNil = makeInvokeFunc('_emptyToNil')

function p._capitalize(...)
	local args = normalizeArgs(...)
	local str = args[1]
	if str == nil then return nil end
	str = tostring(str)
	return mw.ustring.upper(usub(str, 1, 1)) .. usub(str, 2)
end
p.capitalize = makeInvokeFunc('_capitalize')

function p._removeStart(...)
	local args = normalizeArgs(...)
	local str = args[1]
	if str == nil then return nil end
	str = tostring(str)
	for pfIdx = 2, lastIndex(args) do
		local prefix = args[pfIdx]
		if prefix == nil then return str end
		if startsWith(str, prefix) then
			return usub(str, ulen(tostring(prefix)) + 1, ulen(str))
		end
	end
	return str
end
p.removeStart = makeInvokeFunc('_removeStart')

function p._removeEnd(...)
	local args = normalizeArgs(...)
	local str = args[1]
	if str == nil then return nil end
	str = tostring(str)
	for sfIdx = 2, lastIndex(args) do
		local suffix = args[sfIdx]
		if suffix == nil then return str end
		if endsWith(str, suffix) then
			return usub(str, 1, ulen(str) - ulen(tostring(suffix)))
		end
	end
	return str
end
p.removeEnd = makeInvokeFunc('_removeEnd')

function p.__isEmpty(str)
	return str == nil or (type(str) == 'string' and ulen(str) == 0)
end
function p._isEmpty(...)
	local args = normalizeArgs(...)
	return p.__isEmpty(args[1])
end
p.isEmpty = makeInvokeFunc('_isEmpty')

function p._trim(...)
	local args = normalizeArgs(...)
	local str = args[1]
	if not str then return nil end
	return mw.text.trim(tostring(str))
end
p.trim = makeInvokeFunc('_trim')

function p._startsWithAny(...)
	local args = normalizeArgs(...)
	local str = args[1]
	if not str then return false end
	for idx = 2, lastIndex(args) do
		if args[idx] ~= nil and startsWith(str, args[idx]) then
			return true
		end
	end
	return false
end
p._startsWith = p._startsWithAny
p.startsWithAny = makeInvokeFunc('_startsWithAny')
p.startsWith = makeInvokeFunc('_startsWith')

function p._endsWithAny(...)
	local args = normalizeArgs(...)
	local str = args[1]
	if not str then return false end
	for idx = 2, lastIndex(args) do
		if args[idx] ~= nil and endsWith(str, args[idx]) then
			return true
		end
	end
	return false
end
p._endsWith = p._endsWithAny
p.endsWithAny = makeInvokeFunc('_endsWithAny')
p.endsWith = makeInvokeFunc('_endsWith')

function p._substringBefore(...)
	local args = normalizeArgs(...)
	local str = args[1]
	if not str then return nil end
	str = tostring(str)
	local substringEndPos = 1 + ulen(str)
	local firstSep = ''
	for idx = 2, lastIndex(args) do
		if args[idx] ~= nil then
			local substringStart = ufind(str, tostring(args[idx]), 1, true)
			if substringStart and substringStart < substringEndPos then
				substringEndPos = substringStart
				firstSep = args[idx]
			end
		end
	end
	return usub(str, 1, substringEndPos - 1), firstSep
end
p.substringBefore = makeInvokeFunc('_substringBefore')

function p._substringAfter(...)
	local args = normalizeArgs(...)
	local str = args[1]
	if not str then return nil end
	str = tostring(str)
	local idx = 2
	local substringStartPos = 1 + ulen(str)
	local firstSep = ''
	while args[idx] ~= nil do
		local sep = tostring(args[idx])
		local substringStart = ufind(str, sep, 1, true)
		if substringStart and substringStart < substringStartPos then
			substringStartPos = substringStart + ulen(sep)
			firstSep = args[idx]
		end
		idx = idx + 1
	end
	if substringStartPos > ulen(str) then return str end
	return usub(str, substringStartPos), firstSep
end
p.substringAfter = makeInvokeFunc('_substringAfter')

function p._defaultString(...)
	local args = normalizeArgs(...)
	local compressedArgs = TableTools.compressSparseArray(args)

	if #compressedArgs == 0 then return '' end
	return compressedArgs[1]
end
p.defaultString = makeInvokeFunc('_defaultString')

function p._appendToString(...)
	local args = normalizeArgs(...)
	local str = args[1]
	local suffix = args[2]
	if str and ulen(tostring(str)) > 0 then
		return tostring(str) .. tostring(suffix or '')
	end
	return ''
end
p.appendToString = makeInvokeFunc('_appendToString')

function p._prependToString(...)
	local args = normalizeArgs(...)
	local str = args[1]
	local prefix = args[2]
	if str and ulen(tostring(str)) > 0 then
		return tostring(prefix or '') .. tostring(str)
	end
	return ''
end
p.prependToString = makeInvokeFunc('_prependToString')

function p._encloseString(...)
	local args = normalizeArgs(...)
	local str = args[1]
	if str and ulen(tostring(str)) > 0 then
		return tostring(args[2] or '') .. tostring(str) .. tostring(args[3] or '')
	end
	return ''
end
p.encloseString = makeInvokeFunc('_encloseString')

function p._stripNamespace(...)
	local args = normalizeArgs(...)
	local s = p._substringAfter({args[1], ':'})
	return s
end
p.stripNamespace = makeInvokeFunc('_stripNamespace')

-- Determină dacă o secvență de text conține o legătură spre un articol anume.
-- Returnează poziția legăturii în text sau 0 dacă nu există.
function p._findLinkByTitle(...)
	local args = normalizeArgs(...)
	if args[1] == nil then return 0 end
	local text = tostring(args[1]):gsub('_', ' ')
	local title = tostring(args[2] or ''):gsub('_', ' ')
	title = mw.text.trim(title):gsub('([%^%$%(%)%%%.%[%]%*%+%-%?])', '%%%1')
	local pattern = '%[%[%s*' .. title .. '%s*[%]|]'
	return text:find(pattern, 1, false) or 0
end
p.findLinkByTitle = makeInvokeFunc('_findLinkByTitle')

function p._firstValue(...)
	local args = normalizeArgs(...)
	local compactedArgs = TableTools.compressSparseArray(args)
	return #compactedArgs > 0 and compactedArgs[1] or ''
end
p.firstValue = makeInvokeFunc('_firstValue')

function p.isNilOrEmpty(argument)
	return argument == nil or mw.text.trim(tostring(argument)) == ''
end

return p