Modul:StringUtils
Acest modul oferă un set de funcții pentru lucrul cu șiruri de caractere, destinat în special folosirii în formate (șabloanele Wikipedia) prin Scribunto. Funcțiile sunt similare cu cele din bibliotecile de uz general pentru șiruri (de exemplu StringUtils din Apache Commons) și acoperă operații uzuale: adăugarea sau eliminarea unui prefix/sufix, verificarea începutului și sfârșitului unui text, extragerea unor subșiruri, tratarea valorilor goale etc.
Funcțiile folosesc mw.ustring, deci tratează corect caracterele Unicode (inclusiv ă, â, î, ș, ț).
Dependențe
Utilizare
Dintr-un format sau dintr-o pagină wiki
Sintaxa generală este:
{{#invoke:StringUtils|nume_funcție|parametru 1|parametru 2|...}}
Parametrii se transmit pozițional (primul este, de regulă, șirul de prelucrat, iar ceilalți sunt valorile auxiliare: prefix, sufix, separatori etc.). Parametrii cu nume nu sunt folosiți de funcții.
Din alt modul Lua
Fiecare funcție are două variante:
p.nume– varianta pentru#invoke, care preia argumentele din frame-ul curent și returnează doar prima valoare;p._nume– varianta pentru apel direct din Lua (cu numele prefixat de underscore).
local StringUtils = require('Modul:StringUtils')
-- argumentele pot fi transmise într-un singur tabel...
local rezultat = StringUtils._capitalize{ 'românia' } -- "România"
local rezultat2 = StringUtils._removeStart{ 'Categorie:Filme', 'Categorie:' } -- "Filme"
-- ...sau direct, ca parametri separați
local rezultat3 = StringUtils._capitalize('românia') -- "România"
local rezultat4 = StringUtils._removeStart('Categorie:Filme', 'Categorie:') -- "Filme"
Variantele cu prefix funcționează la fel, indiferent dacă argumentele sunt transmise într-un singur tabel sau direct, ca parametri separați. Spre deosebire de apelul cu #invoke, în acest caz valorile sunt folosite ca atare: spațiile de la margini nu sunt eliminate, iar șirurile goale nu sunt tratate ca valori absente.
Preluarea parametrilor
La apelul cu #invoke, parametrii sunt preluați prin Modul:Arguments. Consecințe practice:
- spațiile de la începutul și sfârșitul parametrilor sunt eliminate;
- parametrii goi sunt tratați ca și cum nu ar fi fost transmiși (valoarea
nil); - dacă este nevoie de un spațiu la marginea unui prefix sau sufix, se poate folosi entitatea
 (de exemplu înappendToStringsauprependToString).
În mod normal, parametrii sunt citiți din apelul #invoke în care este folosită funcția, deci modulul poate fi apelat atât direct dintr-o pagină, cât și din interiorul altor formate. Singura excepție este apelul făcut din Format:Ifempty: modulul îl declară „wrapper” pentru Modul:Arguments, așa că, atunci când funcția este apelată din acel format, parametrii sunt citiți din cei cu care a fost apelat formatul respectiv (nu din #invoke). Pentru utilizatorii obișnuiți această particularitate nu are efect; ea contează doar la editarea formatului Ifempty.
Prezentare generală
| Funcție | Descriere pe scurt | Returnează |
|---|---|---|
prependIfMissing |
Adaugă un prefix la început, dacă textul nu începe deja cu el (sau cu unul din prefixele alternative) | text |
appendIfMissing |
Adaugă un sufix la sfârșit, dacă textul nu se termină deja cu el (sau cu unul din sufixele alternative) | text |
emptyToNil |
Transformă un șir gol în nil |
text sau nil
|
capitalize |
Pune prima literă cu majusculă | text |
removeStart |
Elimină un prefix, dacă există | text |
removeEnd |
Elimină un sufix, dacă există | text |
isEmpty |
Verifică dacă valoarea este nil sau șir gol |
boolean |
trim |
Elimină spațiile de la început și sfârșit | text |
startsWithAny, startsWith |
Verifică dacă textul începe cu oricare dintre valorile date | boolean |
endsWithAny, endsWith |
Verifică dacă textul se termină cu oricare dintre valorile date | boolean |
substringBefore |
Returnează partea dinaintea primului separator | text |
substringAfter |
Returnează partea de după un separator | text |
defaultString |
Returnează prima valoare nenulă dintr-o listă, altfel șirul gol | text |
firstValue |
La fel ca defaultString |
text |
appendToString |
Adaugă un sufix, doar dacă textul nu este gol | text |
prependToString |
Adaugă un prefix, doar dacă textul nu este gol | text |
encloseString |
Încadrează textul între un prefix și un sufix, doar dacă nu este gol | text |
stripNamespace |
Elimină spațiul de nume (tot ce precede primul „:”) | text |
findLinkByTitle |
Caută o legătură internă către un articol într-un text (doar din Lua) | număr |
Descrierea funcțiilor
Exemplele de mai jos sunt generate cu {{Automarkup}}: coloana din stânga arată apelul, iar cea din dreapta rezultatul real obținut la afișarea paginii. În cod, {{((}}, {{))}} și {{!}} înlocuiesc, în această ordine, {{, }} și |.
prependIfMissing
Adaugă un prefix la începutul unui șir, dacă acesta nu începe deja cu prefixul respectiv sau cu unul dintre prefixele alternative.
{{#invoke:StringUtils|prependIfMissing|șir|prefix|prefix alternativ 1|prefix alternativ 2|...}}
Prefixul din al doilea parametru este cel care se adaugă; toți parametrii începând cu al doilea sunt verificați la începutul șirului. Dacă șirul este gol, rezultatul este gol; dacă prefixul lipsește, șirul rămâne neschimbat.
| Sintaxa | Rezultat |
|---|---|
{{#invoke:StringUtils|prependIfMissing|Filme|Categorie:}}
|
Categorie:Filme |
{{#invoke:StringUtils|prependIfMissing|Categorie:Filme|Categorie:}}
|
Categorie:Filme |
{{#invoke:StringUtils|prependIfMissing|Fișier:Imagine.jpg|Fișier:|Imagine:}}
|
Fișier:Imagine.jpg |
appendIfMissing
Adaugă un sufix la sfârșitul unui șir, dacă acesta nu se termină deja cu sufixul respectiv sau cu unul dintre sufixele alternative.
{{#invoke:StringUtils|appendIfMissing|șir|sufix|sufix alternativ 1|sufix alternativ 2|...}}
Verificarea se face numai la sfârșitul șirului: dacă sufixul apare în altă parte a textului (de exemplu în mijloc), el este totuși adăugat la sfârșit.
| Sintaxa | Rezultat |
|---|---|
{{#invoke:StringUtils|appendIfMissing|Bună ziua|!}}
|
Bună ziua! |
{{#invoke:StringUtils|appendIfMissing|Bună ziua!|!}}
|
Bună ziua! |
{{#invoke:StringUtils|appendIfMissing|Bună ziua!, dar nu|!}}
|
Bună ziua!, dar nu! |
emptyToNil
Returnează nil dacă șirul primit este gol; altfel returnează șirul neschimbat. Este utilă mai ales în apeluri din alte module Lua. Dintr-un format, un rezultat nil apare ca text gol.
{{#invoke:StringUtils|emptyToNil|șir}}
capitalize
Transformă prima literă a șirului în majusculă (restul textului rămâne neschimbat).
| Sintaxa | Rezultat |
|---|---|
{{#invoke:StringUtils|capitalize|românia}}
|
România |
{{#invoke:StringUtils|capitalize|ștefan cel Mare}}
|
Ștefan cel Mare |
removeStart
Elimină de la începutul șirului primul prefix (din lista dată) cu care acesta începe. Dacă niciunul nu se potrivește, șirul rămâne neschimbat.
{{#invoke:StringUtils|removeStart|șir|prefix 1|prefix 2|...}}
| Sintaxa | Rezultat |
|---|---|
{{#invoke:StringUtils|removeStart|Categorie:Filme|Categorie:}}
|
Filme |
{{#invoke:StringUtils|removeStart|Filme|Categorie:}}
|
Filme |
removeEnd
Elimină de la sfârșitul șirului primul sufix (din lista dată) cu care acesta se termină. Dacă niciunul nu se potrivește, șirul rămâne neschimbat.
{{#invoke:StringUtils|removeEnd|șir|sufix 1|sufix 2|...}}
| Sintaxa | Rezultat |
|---|---|
{{#invoke:StringUtils|removeEnd|Imagine.jpg|.jpg}}
|
Imagine |
isEmpty
Returnează true dacă valoarea este nil sau un șir de lungime zero, altfel false.
{{#invoke:StringUtils|isEmpty|șir}}
Pentru testarea directă a unei valori din Lua există și funcția auxiliară p.__isEmpty(valoare) (cu două caractere de subliniere), care primește direct valoarea, nu un tabel de argumente.
trim
Elimină spațiile (și alte caractere albe) de la începutul și sfârșitul șirului. Returnează nil dacă nu se primește nimic.
Întrucât parametrii transmiși prin #invoke sunt deja curățați de spațiile marginale, funcția este utilă în primul rând în apeluri directe din Lua.
startsWithAny / startsWith
Returnează true dacă șirul începe cu cel puțin una dintre valorile următoare. startsWith este un alias pentru startsWithAny.
{{#invoke:StringUtils|startsWithAny|șir|început 1|început 2|...}}
| Sintaxa | Rezultat |
|---|---|
{{#invoke:StringUtils|startsWithAny|Mihai Eminescu|Ion|Mihai}}
|
true |
{{#invoke:StringUtils|startsWithAny|Mihai Eminescu|Ion|Vasile}}
|
false |
endsWithAny / endsWith
Returnează true dacă șirul se termină cu cel puțin una dintre valorile următoare. endsWith este un alias pentru endsWithAny.
{{#invoke:StringUtils|endsWithAny|șir|sfârșit 1|sfârșit 2|...}}
| Sintaxa | Rezultat |
|---|---|
{{#invoke:StringUtils|endsWithAny|Mihai Eminescu|escu|eanu}}
|
true |
{{#invoke:StringUtils|endsWithAny|Mihai Eminescu|eanu}}
|
false |
substringBefore
Returnează partea din șir care precedă prima apariție a oricăruia dintre separatorii dați. Dacă niciun separator nu se găsește, se returnează șirul întreg.
{{#invoke:StringUtils|substringBefore|șir|separator 1|separator 2|...}}
Varianta Lua _substringBefore returnează și al doilea rezultat: separatorul care a fost găsit (sau șirul gol).
| Sintaxa | Rezultat |
|---|---|
{{#invoke:StringUtils|substringBefore|Ion Creangă, scriitor|,}}
|
Ion Creangă |
{{#invoke:StringUtils|substringBefore|Ion Creangă (scriitor)|,|(}}
|
Ion Creangă |
Rezultatul celui de-al doilea exemplu se termină cu un spațiu (Ion Creangă ), care nu se vede în coloana „Rezultat”.
substringAfter
Returnează partea din șir care urmează după separator. Dacă niciun separator nu se găsește, se returnează șirul întreg.
{{#invoke:StringUtils|substringAfter|șir|separator 1|separator 2|...}}
Varianta Lua _substringAfter returnează și al doilea rezultat: separatorul folosit.
| Sintaxa | Rezultat |
|---|---|
{{#invoke:StringUtils|substringAfter|nume:Ion|:}}
|
Ion |
{{#invoke:StringUtils|substringAfter|Ion|:}}
|
Ion |
defaultString
Returnează prima valoare transmisă (parametrii goi sunt ignorați); dacă nu există nicio valoare, returnează șirul gol. Este utilă pentru a alege prima valoare completată dintr-o listă de parametri ai unui format.
{{#invoke:StringUtils|defaultString|{{{1|}}}|{{{2|}}}|valoare implicită}}
| Sintaxa | Rezultat |
|---|---|
{{#invoke:StringUtils|defaultString||Ana|Maria}}
|
Ana |
{{#invoke:StringUtils|defaultString|||Maria}}
|
Maria |
{{#invoke:StringUtils|defaultString|||}}
|
|
În ultimul exemplu rezultatul este șirul gol, deci celula „Rezultat” apare goală. La fel se întâmplă în exemplele de mai jos în care rezultatul este gol.
firstValue
Are același efect ca defaultString: returnează prima valoare nenulă dintre parametri sau șirul gol dacă nu există niciuna.
appendToString
Adaugă un sufix la șir, doar dacă șirul nu este gol. Dacă șirul este gol, rezultatul este gol (nu se adaugă sufixul). Util pentru a afișa un text însoțit de un separator numai atunci când valoarea există.
{{#invoke:StringUtils|appendToString|șir|sufix}}
| Sintaxa | Rezultat |
|---|---|
{{#invoke:StringUtils|appendToString|Ion|, scriitor}}
|
Ion, scriitor |
{{#invoke:StringUtils|appendToString||, scriitor}}
|
|
prependToString
Adaugă un prefix la șir, doar dacă șirul nu este gol. Dacă șirul este gol, rezultatul este gol.
{{#invoke:StringUtils|prependToString|șir|prefix}}
| Sintaxa | Rezultat |
|---|---|
{{#invoke:StringUtils|prependToString|Eminescu|Poetul }}
|
Poetul Eminescu |
{{#invoke:StringUtils|prependToString||Poetul }}
|
|
encloseString
Încadrează șirul între un prefix și un sufix, doar dacă șirul nu este gol.
{{#invoke:StringUtils|encloseString|șir|prefix|sufix}}
| Sintaxa | Rezultat |
|---|---|
{{#invoke:StringUtils|encloseString|text|(|)}}
|
(text) |
{{#invoke:StringUtils|encloseString||(|)}}
|
|
stripNamespace
Elimină din titlu tot ce se află înainte de primul caracter „:” (inclusiv acesta), adică spațiul de nume. Dacă șirul nu conține „:”, este returnat neschimbat.
{{#invoke:StringUtils|stripNamespace|titlu}}
| Sintaxa | Rezultat |
|---|---|
{{#invoke:StringUtils|stripNamespace|Categorie:Filme românești}}
|
Filme românești |
{{#invoke:StringUtils|stripNamespace|București}}
|
București |
findLinkByTitle
Determină dacă un text conține o legătură internă către un anumit articol, sub forma [[Titlu]] sau [[Titlu|text afișat]]. Returnează poziția primei legături găsite sau 0 dacă nu există nicio legătură către titlul respectiv.
local StringUtils = require('Modul:StringUtils')
local poz = StringUtils._findLinkByTitle{ 'Text cu [[Română]] aici', 'Română' } -- 9
local poz2 = StringUtils._findLinkByTitle{ 'Text fără legături', 'Română' } -- 0
Căutarea ține cont de majuscule și minuscule, iar liniuțele de subliniere din text și din titlu sunt tratate ca spații. Funcția este gândită pentru folosirea din Lua (primul argument este textul, al doilea este titlul căutat).
isNilOrEmpty
Funcție auxiliară, disponibilă doar din Lua (nu are variantă pentru #invoke): StringUtils.isNilOrEmpty(valoare) returnează true dacă valoarea este nil sau un text format numai din spații.
Observații și limitări
- Valorile booleene și
nil: funcțiile care returneazătrue/falsesaunilsunt gândite în principal pentru alte module; dintr-un format, rezultatul apare ca text. - removeStart / removeEnd: prelucrarea se oprește la primul parametru auxiliar gol (
nil) și returnează șirul neschimbat. - substringAfter: dacă separatorul se află chiar la sfârșitul șirului, nu rămâne nimic după el, iar funcția returnează șirul întreg. Parcurgerea separatorilor se oprește la primul separator absent din listă.
- Parametri goi: deoarece parametrii goi sunt ignorați la preluare, nu se poate transmite explicit un șir gol ca prefix, sufix sau separator.
- Pentru spații la marginea parametrilor se folosește
 , dar în acest caz entitatea nu va fi recunoscută la comparări (de exemplu înstartsWithAny).
Vezi și
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