Modulo:ligald
MODULO | ||
Memtesto disponeblas sur la paĝo Ŝablono:ligald. |
- havigas funkcion de
{{ligald}}
kaj vokata sole de tie - dependas de
((loaddata-tbllingvoj))
(tabeloj T76 T80) kaj de{{tbllingvoj}}
--[===[
MODULE "LIGALD" (ligu al aldono)
"eo.wiktionary.org/wiki/Modulo:ligald" <!--2024-Jul-23-->
Purpose: links to appendix page from a pink box located at
the left margin of the screen
Utilo: ligas al aldona pagxo el rugxeta skatolo lokigita cxe
maldekstra flanko de la ekrano
Manfaat: menyediakan pranala ...
Syfte: laenkar till appendixsida fraan en skaer ...
Used by templates / Uzata far sxablonoj /
Digunakan oleh templat / Anvaent av mallar:
* only "ligald"
Required submodules / Bezonataj submoduloj /
Submodul yang diperlukan / Behoevda submoduler:
* "loaddata-tbllingvoj" T76 T80 in turn requiring template "tbllingvoj" (EO)
* "loaddata-tblbahasa" T76 T80 in turn requiring template "tblbahasa" (ID)
This module can accept parameters whether sent to itself (own frame) or
to the caller (caller's frame). If there is a parameter "caller=true"
on the own frame then that own frame is discarded in favor of the
caller's one.
Incoming: * ONE anonymous and obligatory parameter
* conditional parameter lang code (obligatory for alias
lemma pages in ns ZERO, otherwise prohibited), more than
one anonymous parameter is an error (strictly checked)
* 2 hidden parameters
* pagenameoverridetestonly
* nsnumberoverridetestonly
Returned: * box or error message, tracking cat:s only on error
This module is unbreakable (when called with correct module name
and function name). Every imaginable input from the caller and
from the imported modules will output either a useful result or
at least a helpful error string.
Cxi tiu modulo estas nerompebla (kiam vokita kun gxustaj nomo de modulo
kaj nomo de funkcio). Cxiu imagebla enigo de la vokanto kaj
de la importataj moduloj eldonos aux utilan rezulton aux
almenaux helpeman eraranoncan signocxenon.
Possible errors:
* <<#E01 Internal error in module "ligald">>
Possible causes:
* strings not uncommented
* function "mw.title.getCurrentTitle().text" AKA "{{PAGENAME}}" failed
* <<#E02 Malica eraro en subprogramaro uzata far sxablono "ligald">>
Possible causes:
* submodule "loaddata-tbllingvoj" not found
* submodule "loaddata-tbllingvoj" caused unspecified failure
* <<#E03 Nombrigita eraro en subprogramaro uzata far sxablono "ligald">>
Possible causes:
* submodule failed and returned valid error code
* <<#E08 Erara uzo de sxablono (ligald), maksimume UNU anonima parametro permeseblas>>
* <<#E09 Erara uzo de sxablono (ligald), anonima parametro malplena aux tro longa>>
* <<#E10 Erara uzo de sxablono (ligald), uzebla nur en nomspacoj NUL (kapvorto) kaj 14 (kategorio)>>
* <<#E11 Erara uzo de sxablono (ligald), evidente nevalida lingvokodo>>
* <<#E12 Erara uzo de sxablono (ligald), nekonata lingvokodo>>
* <<#E13 Erara uzo de sxablono (ligald), lingvokodo estas malpermesita por ne-aliasa kapvorto>>
* <<#E15 Erara uzo de sxablono (ligald), nekonata lingvonomo en kapvorta pagxonomo>>
* <<#E16 Erara uzo de sxablono (ligald), lingvokodo estas malpermesita por kategorio>>
* <<#E18 Erara uzo de sxablono (ligald), nevalida aux nesubtenata pagxonomo en kategorio>>
Possible tracking cat:s:
* [[Kategorio:Evidente nevalida lingvokodo]] #E11
* [[Kategorio:Nekonata lingvokodo]] #E12
* [[Kategorio:Nekonata lingvokodo loke (ligald)]] #E12
* [[Kategorio:Nekonata lingvokodo nome (fy)]] #E12
* [[Kategorio:Erara pagxonomo]] NO DETAILS HERE #E15 #E18
* [[Kategorio:Erara uzo de sxablono]] all >=#E08 except #E11 #E12 #E15 #E18
* [[Kategorio:Erara uzo de sxablono (ligald)]] all >=#E08 except #E11 #E12 #E15 #E18
* [[Kategorio:Erara uzo de sxablono (ligald, E18)]] all >=#E08 except #E11 #E12 #E15 #E18
Misc:
* decide what to do based on ns and pagename and one parameter (see below)
Supported types of fullpagenames:
* a) "dana" main lang name
* b) "Ido" main lang name
* c) "taja" alias lang name
* d) "Latino" alias lang name
* e) "Kategorio:Ido"
* f) "Kategorio:Kapvorto (dana)"
Two intermediate strings ("early" and "latter"):
* boasting and linking step on success takes two strings
from the evaluation step:
* a) pagename "dana" main lang name ->
''la "<b>dana</b>"'' and ''dana'' (latter becomes ''[[Aldono:Dana]]'')
* b) pagename "Ido" main lang name ->
''"<b>Ido</b>"'' and ''Ido'' (latter becomes ''[[Aldono:Ido]]'')
* c) pagename "taja" alias lang name ->
''la "<b>siama</b>" (la "<b>taja</b>")'' and ''siama'' (latter
becomes ''[[Aldono:Siama]]'')
* pagename "Latino" alias lang name ->
''la "<b>latina</b>" ("<b>Latino</b>")'' and ''latina'' (latter
becomes ''[[Aldono:Latina]]'')
Possible texts:
* a) Por pliaj informoj pri la "<b>dana</b>" rigardu
la pagxon [[Aldono:Dana]].
* c) Por pliaj informoj pri la "<b>siama</b>" (la "<b>taja</b>") rigardu
la pagxon [[Aldono:Siama]].
* e) Por pliaj informoj pri "<b>Ido</b>" rigardu
la pagxon [[Aldono:Ido]].
* f) Por pliaj informoj pri la "<b>dana</b>" rigardu
la pagxon [[Aldono:Dana]].
Strategy:
* check for up to 3 anon parameters and length
* if (more than ONE parameter found) then
* #E08 maksimume
* abort
* endif
* if (parameter here but length not sane) then
* #E09
* abort
* endif
* seize ns (separately as number)
* seize pagename (separately as unfull) (p)
* if (ns is other than ZERO or 14) then
* #E10 nomspaco
* abort
* endif
* if (lang code given) then
* check obvious
* if (obviously invalid) then
* #E11 evidente
* abort
* endif
* endif
* if (ns is ZERO) then
* if (lang code given) then
* do forward query with lang code maybe getting name (j)
* if (query failed) then
* #E02 subprogramaro or #E12 nekonata lingvokodo
* abort
* endif
* compare both lang names (p) vs (j)
* if (same) then
* #E13 lingvokodo malpermesita por ne-aliasa
* abort
* endif
* assign "early" intermediate string using both lang
names, to both adding quot and bold unconditionally, as well
as "la " as needed ie if final letter is not "o"
* assign "latter" intermediate string from (j)
* else
* do reverse query with (p) maybe getting lang code
* if (query failed) then
* #E02 subprogramaro or #E15 nekonata lingvonomo en kapvorta
* abort
* endif
* discard the found lang code
* assign "early" intermediate string from (p), adding quot
and bold unconditionally, as well as "la " as needed
ie if final letter is not "o"
* assign "latter" intermediate string from (p)
* endif (lang code given) else
* else
* if (lang code given) then
* #E16 lingvokodo malpermesita por kategorio
* abort
* endif
* if (NOT pagename (p) begins with uppercase) then
* #E18 nevalida pagxonomo en kato
* abort
* endif
* take pagename (p) and try to isolate language name from brackets (m)
* if (isolate success) then
* if (NOT remainder equal "Kapvorto ()") then
* #E18 nevalida pagxonomo en kato
* abort
* endif
* take pagename (p) unchanged (m)
* else
* take pagename (p) and convert it to lowercase (unicode
restricted) unless final letter is "o" (m)
* endif
* do reverse query with (m) maybe getting lang code
* if (NOT lang code found) then
* #E18 nevalida pagxonomo en kato
* abort
* endif
* discard the found lang code
* assign "early" intermediate string from (m), adding quot
and bold unconditionally, as well as "la " as needed
ie if final letter is not "o"
* assign "latter" intermediate string from (m)
* endif (ns is ZERO) else
* if (success so far) then
* brew the box from "contabbeg" and "contabend", from "contabmesagxoj",
from "strpikapxns", as well as from the two intermediate
strings ("early" and "latter")
* else
* brew error message
* brew tracking cat:s
* endif
]===]
local exporttable = {}
------------------------------------------------------------------------
---- CONSTANTS [O] ----
------------------------------------------------------------------------
-- uncommentable (site-related features)
local constringvoj = 'Modulo:loaddata-tbllingvoj' -- EO
-- local constringvoj = 'Modul:loaddata-tblbahasa' -- ID
-- uncommentable constant table (error messages)
-- #E02...#E99, holes permitted
-- note that #E00 and #E01 are NOT supposed to be included here
-- separate "strpikparent" needed for "\\@"
local contaberaroj = {}
contaberaroj[02] = 'Malica eraro en submodulo uzata far \\@' -- EO #E02
-- contaberaroj[02] = 'Kesalahan jahat dalam submodul digunakan oleh \\@' -- ID #E02
contaberaroj[03] = 'Nombrigita eraro en submodulo uzata far \\@' -- EO #E03
-- contaberaroj[03] = 'Kesalahan ternomor dalam submodul digunakan oleh \\@' -- ID #E03
contaberaroj[10] = 'Erara uzo de \\@, uzebla nur en nomspacoj NUL (kapvorto) kaj 14 (kategorio)' -- EO #E10
-- contaberaroj[10] = 'Penggunaan salah \\@, hanya bisa digunakan dalam ruang nama NOL (lema) dan 14 (kategori)' -- ID #E10
contaberaroj[11] = 'Evidente nevalida lingvokodo sendita al \\@' -- EO #E11
-- contaberaroj[11] = 'Kode bahasa jelas-jelas salah dikirim ke \\@' -- ID #E11
contaberaroj[12] = 'Nekonata lingvokodo sendita al \\@' -- EO #E12
-- contaberaroj[12] = 'Kode bahasa tidak dikenal dikirim ke \\@' -- ID #E12
contaberaroj[18] = 'Erara uzo de \\@, nevalida aux nesubtenata pagxonomo en kategorio' -- EO #E18
-- contaberaroj[18] = 'Penggunaan salah \\@, judul halaman kategori tidak valid atau tidak didukung' -- ID #E18
-- uncommentable constant table (misc messages and tracking cat:s)
local contabmesagxoj = {[0]='Por pliaj informoj pri ', ' rigardu la pagxon '} -- EO
local contabtrack = {[0]='Evidente nevalida lingvokodo', 'Nekonata lingvokodo', 'Nekonata lingvokodo loke', 'Nekonata lingvokodo nome'} -- EO
contabtrack[4] = 'Erara pagxonomo' -- EO
contabtrack[5] = 'Erara uzo de sxablono' -- EO
-- constant strings (HTML table with one cell only)
local contabbeg = '<table style="margin:0.5em auto 0.5em 0;padding:0;border:1px solid #000000;"><tr><td style="padding:0.2em;background:#E0C0C0;">'
local contabend = '</td></tr></table>'
-- constant table -- ban list -- add obviously invalid access codes (2-letter or 3-letter) only
-- length of the list is NOT stored anywhere, the processing stops
-- when type "nil" is encountered, used by "lfivalidatelnkoadv" only
-- controversial codes (sh sr hr), (zh cmn)
-- "en.wiktionary.org/wiki/Wiktionary:Language_treatment" excluded languages
-- "en.wikipedia.org/wiki/Spurious_languages"
-- "iso639-3.sil.org/code/art" only valid in ISO 639-2
-- "iso639-3.sil.org/code/gem" only valid in ISO 639-2 and 639-5, "collective"
-- "iso639-3.sil.org/code/zxx" "No linguistic content"
local contabisbanned = {}
contabisbanned = {'by','dc','ll','jp','art','deu','eng','epo','fra','gem','ger','ido','lat','por','rus','spa','swe','tup','zxx'} -- 1...19
-- surrogate transcoding table (only needed for EO)
local contabtransluteo = {}
contabtransluteo[ 67] = 0xC488 -- CX
contabtransluteo[ 99] = 0xC489 -- cx
contabtransluteo[ 71] = 0xC49C -- GX
contabtransluteo[103] = 0xC49D -- gx
contabtransluteo[ 74] = 0xC4B4 -- JX
contabtransluteo[106] = 0xC4B5 -- jx
contabtransluteo[ 83] = 0xC59C -- SX
contabtransluteo[115] = 0xC59D -- sx
contabtransluteo[ 85] = 0xC5AC -- UX breve
contabtransluteo[117] = 0xC5AD -- ux breve
-- constant strings (error circumfixes)
local constrelabg = '<span class="error"><b>' -- lagom whining begin
local constrelaen = '</b></span>' -- lagom whining end
local constrlaxhu = ' ** ' -- lagom -> huge circumfix " ** "
-- constants to control behaviour from source AKA semi-hardcoded parameters
local conbookodlng = false -- "true" to allow long codes like "zh-min-nan"
local conboomiddig = false -- "true" to allow middle digit "s7a"
-- uncommentable (override)
-- * name of table MUST always be defined, OTOH elements are usually NOT
-- * for testing only, values automatically peeked otherwise
local contabovrd = {}
-- contabovrd['sitelang'] = 'eo' -- "en"
-- contabovrd['sitelang'] = 'id'
-- contabovrd['katprefi'] = 'Kategorio' -- "Category"
-- contabovrd['katprefi'] = 'Kategori'
-- contabovrd['apxprefi'] = 'Aldono' -- "Appendix"
-- contabovrd['apxprefi'] = 'Lampiran'
-- contabovrd['parentfn'] = string.char(0xC5,0x9C) .. 'ablono:ligald' -- "Template:ligald" (!!! no surr translation !!!)
------------------------------------------------------------------------
---- SPECIAL STUFF OUTSIDE MAIN [B] ----
------------------------------------------------------------------------
-- SPECIAL VAR:S
require('strict')
local qldingvoj = {} -- type "table", metaized, has subtables, only data
local qbooguard = false -- only for the guard test, pass to other var ASAP
---- GUARD AGAINST INTERNAL ERROR AND IMPORT ONE VIA LOADDATA ----
qbooguard = (type(constringvoj)~='string')
if (not qbooguard) then
qldingvoj = mw.loadData(constringvoj) -- can crash here
qbooguard = (type(qldingvoj)~='table') -- seems to be always false
end--if
------------------------------------------------------------------------
local function mathisintrange (numzjinput, numzjmin, numzjmax)
local booisclean = false -- preASSume guilt
if (type(numzjinput)=='number') then -- no non-numbers, thanks
if (numzjinput==math.floor(numzjinput)) then -- no transcendental
booisclean = ((numzjinput>=numzjmin) and (numzjinput<=numzjmax)) -- rang
end--if
end--if
return booisclean
end--function mathisintrange
local function mathdiv (xdividens, xdivisero)
local resultdiv = 0 -- DIV operator lacks in LUA :-(
resultdiv = math.floor (xdividens / xdivisero)
return resultdiv
end--function mathdiv
local function mathmod (xdividendo, xdivisoro)
local resultmod = 0 -- MOD operator is "%" and bitwise AND operator lack too
resultmod = xdividendo % xdivisoro
return resultmod
end--function mathmod
local function mathbitwrit (numinkoming, numbityndex, boowrite)
local numpatched = 0
local numcountup = 0
local numweight = 1 -- single bit value 1 -> 2 -> 4 -> 8 ...
local boosinglebit = false
while true do
if ((numinkoming==0) and (numcountup>numbityndex)) then
break -- we have run out of bits on BOTH possible sources
end--if
if (numcountup==numbityndex) then
boosinglebit = boowrite -- overwrite bit
else
boosinglebit = (mathmod(numinkoming,2)==1) -- pick bit
end--if
numinkoming = mathdiv(numinkoming,2) -- shift right
if (boosinglebit) then
numpatched = numpatched + numweight -- add one bit rtl only if true
end--if
numcountup = numcountup + 1 -- count up here until we run out of bits
numweight = numweight * 2
end--while
return numpatched
end--function mathbitwrit
------------------------------------------------------------------------
---- NUMBER CONVERSION FUNCTIONS [N] ----
------------------------------------------------------------------------
-- Local function LFNUMTO2DIGIT
-- Convert integer 0...99 to decimal ASCII string always 2 digits "00"..."99".
-- Depends on functions :
-- [E] mathisintrange mathdiv mathmod
local function lfnumto2digit (numzerotoninetynine)
local strtwodig = '??' -- always 2 digits
if (mathisintrange(numzerotoninetynine,0,99)) then
strtwodig = tostring(mathdiv(numzerotoninetynine,10)) .. tostring(mathmod(numzerotoninetynine,10))
end--if
return strtwodig
end--function lfnumto2digit
------------------------------------------------------------------------
---- LOW LEVEL STRING FUNCTIONS [G] ----
------------------------------------------------------------------------
-- Local function LFGPOKESTRING
-- Input : * strinpokeout -- empty legal
-- * numpokepoz -- ZERO-based, out of range legal
-- * numpokeval -- new value
-- This is inefficient by design of LUA. The caller is responsible to
-- minimize the number of invocations of this, in particular, not to
-- call if the new value is equal the existing one.
local function lfgpokestring (strinpokeout, numpokepoz, numpokeval)
local numpokelen = 0
numpokelen = string.len(strinpokeout)
if ((numpokelen==1) and (numpokepoz==0)) then
strinpokeout = string.char(numpokeval) -- totally replace
end--if
if (numpokelen>=2) then
if (numpokepoz==0) then
strinpokeout = string.char(numpokeval) .. string.sub (strinpokeout,2,numpokelen)
end--if
if ((numpokepoz>0) and (numpokepoz<(numpokelen-1))) then
strinpokeout = string.sub (strinpokeout,1,numpokepoz) .. string.char(numpokeval) .. string.sub (strinpokeout,(numpokepoz+2),numpokelen)
end--if
if (numpokepoz==(numpokelen-1)) then
strinpokeout = string.sub (strinpokeout,1,(numpokelen-1)) .. string.char(numpokeval)
end--if
end--if (numpokelen>=2) then
return strinpokeout
end--function lfgpokestring
------------------------------------------------------------------------
local function lfgtestnum (numkaad)
local boodigit = false
boodigit = ((numkaad>=48) and (numkaad<=57))
return boodigit
end--function lfgtestnum
local function lfgtestuc (numkode)
local booupperc = false
booupperc = ((numkode>=65) and (numkode<=90))
return booupperc
end--function lfgtestuc
local function lfgtestlc (numcode)
local boolowerc = false
boolowerc = ((numcode>=97) and (numcode<=122))
return boolowerc
end--function lfgtestlc
------------------------------------------------------------------------
---- UTF8 FUNCTIONS [U] ----
------------------------------------------------------------------------
-- Local function LFULNUTF8CHAR
-- Evaluate length of a single UTF8 char in octet:s.
-- Input : * numbgoctet -- beginning octet of a UTF8 char
-- Output : * numlen1234x -- unit octet, number 1...4, or ZERO if invalid
-- Does NOT thoroughly check the validity, looks at ONE octet only.
local function lfulnutf8char (numbgoctet)
local numlen1234x = 0
if (numbgoctet<128) then
numlen1234x = 1 -- $00...$7F -- ANSI/ASCII
end--if
if ((numbgoctet>=194) and (numbgoctet<=223)) then
numlen1234x = 2 -- $C2 to $DF
end--if
if ((numbgoctet>=224) and (numbgoctet<=239)) then
numlen1234x = 3 -- $E0 to $EF
end--if
if ((numbgoctet>=240) and (numbgoctet<=244)) then
numlen1234x = 4 -- $F0 to $F4
end--if
return numlen1234x
end--function lfulnutf8char
------------------------------------------------------------------------
-- Local function LFUTRISTLETR
-- Evaluate char (from ASCII + selectable extra set from UTF8) to
-- tristate result (no letter vs uppercase letter vs lowercase letter).
-- Input : * strin5trist : single unicode char (1 or 2 octet:s) or
-- longer string
-- * strsel5set : "ASCII" (default, empty string or type "nil"
-- will do too) "eo" "sv" (value "GENE" NOT here)
-- Output : * numtype5x : 0 no letter or invalid UTF8 -- 1 upper -- 2 lower
-- Depends on functions : (this is LFUTRISTLETR)
-- [U] lfulnutf8char
-- [G] lfgtestuc lfgtestlc
-- [E] mathdiv mathmod mathbitwrit
-- Possible further char:s or fragments of such are disregarded, the
-- question answered is "Is there one uppercase or lowercase letter
-- available at begin?".
-- Defined sets:
-- "eo" 2 x 6 uppercase and lowercase (CX GX HX JX SX UX cx gx hx jx sx ux)
-- upper CX $0108 GX $011C HX $0124 JX $0134 SX $015C UX $016C lower +1
-- "sv" 2 x 4 uppercase and lowercase (AE AA EE OE ae aa ee oe)
-- upper AE $00C4 AA $00C5 EE $00C9 OE $00D6 lower +$20
local function lfutristletr (strin5trist, strsel5set)
local numtype5x = 0 -- preASSume invalid
local numlong5den = 0 -- actual length of input string
local numlong5bor = 0 -- expected length of single char
local numcha5r = 0 -- UINT8 beginning char
local numcha5s = 0 -- UINT8 later char (BIG ENDIAN, lower value here above)
local numcxa5rel = 0 -- UINT8 code relative to beginning of block $00...$FF
local numtem5p = 0
local boois5uppr = false
local boois5lowr = false
while true do -- fake loop -- this is LFUTRISTLETR
numlong5den = string.len (strin5trist)
if (numlong5den==0) then
break -- bad string length
end--if
numcha5r = string.byte (strin5trist,1,1)
numlong5bor = lfulnutf8char(numcha5r)
if ((numlong5bor==0) or (numlong5den<numlong5bor)) then
break -- truncated char or invalid
end--if
if (numlong5bor==1) then
boois5uppr = lfgtestuc(numcha5r)
boois5lowr = lfgtestlc(numcha5r)
break -- success with ASCII, almost done
end--if
numcha5s = string.byte (strin5trist,2,2) -- only $80 to $BF
numcxa5rel = (mathmod(numcha5r,4)*64) + (numcha5s-128) -- 4 times 64
if ((strsel5set=='eo') and ((numcha5r==196) or (numcha5r==197))) then
numtem5p = mathbitwrit (numcxa5rel,0,false) -- bad way to do AND $FE
if ((numtem5p==8) or (numtem5p==28) or (numtem5p==36) or (numtem5p==52) or (numtem5p==92) or (numtem5p==108)) then
boois5uppr = (numtem5p==numcxa5rel) -- UC below, block of 1
boois5lowr = not boois5uppr
break -- success with -eo-, almost done
end--if
end--if ((strsel5set=='eo') and ...
if ((strsel5set=='sv') and (numcha5r==195)) then
numtem5p = mathbitwrit (numcxa5rel,5,false) -- bad way to do AND $DF
if ((numtem5p==196) or (numtem5p==197) or (numtem5p==201) or (numtem5p==214)) then
boois5uppr = (numtem5p==numcxa5rel) -- UC below, block of 32
boois5lowr = not boois5uppr
break -- success with -sv-, almost done
end--if
end--if ((strsel5set=='sv') and ...
break -- finally to join mark -- unknown non-ASCII char is a fact :-(
end--while -- fake loop -- join mark
if (boois5uppr) then
numtype5x = 1
end--if
if (boois5lowr) then
numtype5x = 2
end--if
return numtype5x
end--function lfutristletr
------------------------------------------------------------------------
-- Local function LFUCASEREST
-- Adjust (restricted) case of a single letter (from ASCII + selectable
-- extra set from UTF8) or longer string. (this is REST)
-- Input : * strinco6cs : single unicode letter (1 or 2 octet:s) or
-- longer string
-- * booup6cas : for desired output uppercase "true" and for
-- lowercase "false"
-- * boodo6all : "true" to adjust all letters, "false"
-- only beginning letter
-- * strsel6set : "ASCII" (default, empty string or type "nil"
-- will do too) "eo" "sv" (value "GENE" NOT here)
-- Output : * strinco6cs
-- Depends on functions : (this is REST)
-- [U] lfulnutf8char
-- [G] lfgpokestring lfgtestuc lfgtestlc
-- [E] mathdiv mathmod mathbitwrit
-- This process never changes the length of a string in octet:s. Empty string
-- on input is legal and results in an empty string returned. When case is
-- adjusted, a 1-octet or 2-octet letter is replaced by another letter of same
-- length. Unknown valid char:s (1-octet ... 4-octet) are copied. Broken UTF8
-- stream results in remaining part of the output string (from 1 char to
-- complete length of the incoming string) filled by "Z".
-- Defined sets:
-- "eo" 2 x 6 uppercase and lowercase (CX GX HX JX SX UX cx gx hx jx sx ux)
-- upper CX $0108 GX $011C HX $0124 JX $0134 SX $015C UX $016C lower +1
-- "sv" 2 x 4 uppercase and lowercase (AE AA EE OE ae aa ee oe)
-- upper AE $00C4 AA $00C5 EE $00C9 OE $00D6 lower +$20
-- We peek max 2 values per iteration, and change the string in-place, doing
-- so strictly only if there indeed is a change. This is important for LUA
-- where the in-place write access must be emulated by means of a less
-- efficient function.
local function lfucaserest (strinco6cs, booup6cas, boodo6all, strsel6set)
local numlong6den = 0 -- actual length of input string
local numokt6index = 0
local numlong6bor = 0 -- expected length of single char
local numdel6ta = 0 -- quasi-signed +32 or -32 or +1 or -1 or ZERO
local numcha6r = 0 -- UINT8 beginning char
local numcha6s = 0 -- UINT8 later char (BIG ENDIAN, lower value here above)
local numcxa6rel = 0 -- UINT8 code relative to beginning of block $00...$FF
local numtem6p = 0
local boowan6tlowr = false
local boois6uppr = false
local boois6lowr = false
local boodo6adj = true -- preASSume innocence -- continue changing
local boobotch6d = false -- preASSume innocence -- NOT yet botched
booup6cas = not (not booup6cas)
boowan6tlowr = (not booup6cas)
numlong6den = string.len (strinco6cs)
while true do -- genuine loop over incoming string (this is REST)
if (numokt6index>=numlong6den) then
break -- done complete string
end--if
if ((not boodo6all) and (numokt6index~=0)) then -- loop can skip index ONE
boodo6adj = false
end--if
boois6uppr = false -- preASSume on every iteration
boois6lowr = false -- preASSume on every iteration
numdel6ta = 0 -- preASSume on every iteration
numlong6bor = 1 -- preASSume on every iteration
while true do -- fake loop (this is REST)
numcha6r = string.byte (strinco6cs,(numokt6index+1),(numokt6index+1))
if (boobotch6d) then
numdel6ta = 90 - numcha6r -- "Z" -- delta must be non-ZERO to write
break -- fill with "Z" char:s
end--if
if (not boodo6adj) then
break -- copy octet after octet
end--if
numlong6bor = lfulnutf8char(numcha6r)
if ((numlong6bor==0) or ((numokt6index+numlong6bor)>numlong6den)) then
numlong6bor = 1 -- reassign to ONE !!!
numdel6ta = 90 - numcha6r -- "Z" -- delta must be non-ZERO to write
boobotch6d = true
break -- truncated char or broken stream
end--if
if (numlong6bor>=3) then
break -- copy UTF8 char, no chance for adjustment
end--if
if (numlong6bor==1) then
boois6uppr = lfgtestuc(numcha6r)
boois6lowr = lfgtestlc(numcha6r)
if (boois6uppr and boowan6tlowr) then
numdel6ta = 32 -- ASCII UPPER->lower
end--if
if (boois6lowr and booup6cas) then
numdel6ta = -32 -- ASCII lower->UPPER
end--if
break -- success with ASCII and one char almost done
end--if
numcha6s = string.byte (strinco6cs,(numokt6index+2),(numokt6index+2)) -- only $80 to $BF
numcxa6rel = (mathmod(numcha6r,4)*64) + (numcha6s-128) -- 4 times 64
if ((strsel6set=='eo') and ((numcha6r==196) or (numcha6r==197))) then
numtem6p = mathbitwrit (numcxa6rel,0,false) -- bad way to do AND $FE
if ((numtem6p==8) or (numtem6p==28) or (numtem6p==36) or (numtem6p==52) or (numtem6p==92) or (numtem6p==108)) then
boois6uppr = (numtem6p==numcxa6rel) -- UC below, block of 1
boois6lowr = not boois6uppr
if (boois6uppr and boowan6tlowr) then
numdel6ta = 1 -- UPPER->lower
end--if
if (boois6lowr and booup6cas) then
numdel6ta = -1 -- lower->UPPER
end--if
break -- success with -eo- and one char almost done
end--if
end--if ((strsel6set=='eo') and ...
if ((strsel6set=='sv') and (numcha6r==195)) then
numtem6p = mathbitwrit (numcxa6rel,5,false) -- bad way to do AND $DF
if ((numtem6p==196) or (numtem6p==197) or (numtem6p==201) or (numtem6p==214)) then
boois6uppr = (numtem6p==numcxa6rel) -- UC below, block of 32
boois6lowr = not boois6uppr
if (boois6uppr and boowan6tlowr) then
numdel6ta = 32 -- UPPER->lower
end--if
if (boois6lowr and booup6cas) then
numdel6ta = -32 -- lower->UPPER
end--if
break -- success with -sv- and one char almost done
end--if
end--if ((strsel6set=='sv') and ...
break -- finally to join mark -- unknown non-ASCII char is a fact :-(
end--while -- fake loop -- join mark (this is REST)
if ((numlong6bor==1) and (numdel6ta~=0)) then -- no risk of carry here
strinco6cs = lfgpokestring (strinco6cs,numokt6index,(numcha6r+numdel6ta))
end--if
if ((numlong6bor==2) and (numdel6ta~=0)) then -- no risk of carry here
strinco6cs = lfgpokestring (strinco6cs,(numokt6index+1),(numcha6s+numdel6ta))
end--if
numokt6index = numokt6index + numlong6bor -- advance in incoming string
end--while -- genuine loop over incoming string (this is REST)
return strinco6cs
end--function lfucaserest
------------------------------------------------------------------------
---- HIGH LEVEL STRING FUNCTIONS [I] ----
------------------------------------------------------------------------
-- Local function LFIKATALDIGU
-- Brew cat insertion (no extra colon ":") or link to
-- appendix from 3 elements.
local function lfikataldigu (strprefixx, strkataldnomo, strhintvisi)
local strrbkma = ''
if (type(strhintvisi)=='string') then
strrbkma = '[[' .. strprefixx .. ':' .. strkataldnomo .. '|' .. strhintvisi .. ']]'
else
strrbkma = '[[' .. strprefixx .. ':' .. strkataldnomo .. ']]'
end--if
return strrbkma
end--function lfikataldigu
------------------------------------------------------------------------
-- Local function LFISEPBRACKET
-- Separate bracketed part of a string and return the inner and outer
-- part, the outer one with the brackets. There must be exactly ONE "("
-- and exactly ONE ")" in correct order.
-- Input : * strsep33br
-- * numxmin33len -- minimal length of inner part, must be >= 1
-- Output : * boosaxes, strinner, strouter
-- Note that for length of hit ZERO ie "()" we would have "begg" + 1 = "endd"
-- and for length of hit ONE ie "(x)" we have "begg" + 2 = "endd".
-- Example: "crap (NO)" -> len = 9
-- 123456789
-- "begg" = 6 and "endd" = 9
-- Expected result: "NO" and "crap ()"
-- Example: "(XX) YES" -> len = 8
-- 12345678
-- "begg" = 1 and "endd" = 4
-- Expected result: "XX" and "() YES"
local function lfisepbracket (strsep33br, numxmin33len)
local strinner = ''
local strouter = ''
local num33idx = 1 -- ONE-based
local numdlong = 0
local num33wesel = 0
local numbegg = 0 -- ONE-based, ZERO invalid
local numendd = 0 -- ONE-based, ZERO invalid
local boosaxes = false -- preASSume guilt
numdlong = string.len (strsep33br)
while true do
if (num33idx>numdlong) then
break -- ONE-based -- if both "numbegg" "numendd" non-ZERO then maybe
end--if
num33wesel = string.byte(strsep33br,num33idx,num33idx)
if (num33wesel==40) then -- "("
if (numbegg==0) then
numbegg = num33idx -- pos of "("
else
numbegg = 0
break -- damn: more than 1 "(" present
end--if
end--if
if (num33wesel==41) then -- ")"
if ((numendd==0) and (numbegg~=0) and ((numbegg+numxmin33len)<num33idx)) then
numendd = num33idx -- pos of ")"
else
numendd = 0
break -- damn: more than 1 ")" present or ")" precedes "("
end--if
end--if
num33idx = num33idx + 1
end--while
if ((numbegg~=0) and (numendd~=0)) then
boosaxes = true
strouter = string.sub(strsep33br,1,numbegg) .. string.sub(strsep33br,numendd,-1)
strinner = string.sub(strsep33br,(numbegg+1),(numendd-1))
end--if
return boosaxes, strinner, strouter
end--function lfisepbracket
------------------------------------------------------------------------
-- Local function LFIVALIDATELNKOADV
-- Advanced test whether a string (intended to be a language code) is valid
-- containing only 2 or 3 lowercase letters, or 2...10 char:s and with some
-- dashes, or maybe a digit in middle position or maybe instead equals to "-"
-- or "??" and maybe additionally is not included on the ban list.
-- Input : * strqooq -- string (empty is useless and returns
-- "true" ie "bad" but cannot cause any major harm)
-- * booyesdsh -- "true" to allow special code dash "-"
-- * booyesqst -- "true" to allow special code doublequest "??"
-- * booloonkg -- "true" to allow long codes such as "zh-min-nan"
-- * boodigit -- "true" to allow digit in middle position
-- * boonoban -- (inverted) "true" to skip test against ban table
-- Output : * booisvaladv -- true if string is valid
-- Depends on functions :
-- [G] lfgtestnum lfgtestlc
-- Depends on constants :
-- * table "contabisbanned"
-- Incoming empty string is safe but type "nil" is NOT.
-- Digit is tolerable only ("and" applies):
-- * if boodigit is "true"
-- * if length is 3 char:s
-- * in middle position
-- Dashes are tolerable (except in special code "-") only ("and" applies):
-- * if length is at least 4 char:s (if this is permitted at all)
-- * in inner positions
-- * NOT adjacent
-- * maximally TWO totally
-- There may be maximally 3 adjacent letters, this makes at least ONE dash
-- obligatory for length 4...7, and TWO dashes for length 8...10.
local function lfivalidatelnkoadv (strqooq, booyesdsh, booyesqst, booloonkg, boodigit, boonoban)
local varomongkosong = 0 -- for check against the ban list
local numchiiar = 0
local numukurran = 0
local numindeex = 0 -- ZERO-based -- two loops
local numadjlet = 0 -- number of adjacent letters (max 3)
local numadjdsh = 0 -- number of adjacent dashes (max 1)
local numtotdsh = 0 -- total number of dashes (max 2)
local booislclc = false
local booisdigi = false
local booisdash = false
local booisvaladv = true -- preASSume innocence -- later final verdict here
while true do -- fake (outer) loop
if (strqooq=="-") then
booisvaladv = booyesdsh
break -- to join mark -- good or bad
end--if
if (strqooq=="??") then
booisvaladv = booyesqst
break -- to join mark -- good or bad
end--if
numukurran = string.len (strqooq)
if ((numukurran<2) or (numukurran>10)) then
booisvaladv = false
break -- to join mark -- evil
end--if
if (not booloonkg and (numukurran>3)) then
booisvaladv = false
break -- to join mark -- evil
end--if
numindeex = 0
while true do -- inner genuine loop over char:s
if (numindeex>=numukurran) then
break -- done -- good
end--if
numchiiar = string.byte (strqooq,(numindeex+1),(numindeex+1))
booisdash = (numchiiar==45)
booisdigi = lfgtestnum(numchiiar)
booislclc = lfgtestlc(numchiiar)
if (not (booislclc or booisdigi or booisdash)) then
booisvaladv = false
break -- to join mark -- inherently bad char
end--if
if (booislclc) then
numadjlet = numadjlet + 1
else
numadjlet = 0
end--if
if (booisdigi and ((numukurran~=3) or (numindeex~=1) or (not boodigit))) then
booisvaladv = false
break -- to join mark -- illegal digit
end--if
if (booisdash) then
if ((numukurran<4) or (numindeex==0) or ((numindeex+1)==numukurran)) then
booisvaladv = false
break -- to join mark -- illegal dash
end--if
numadjdsh = numadjdsh + 1
numtotdsh = numtotdsh + 1 -- total
else
numadjdsh = 0 -- do NOT zeroize the total !!!
end--if
if ((numadjlet>3) or (numadjdsh>1) or (numtotdsh>2)) then
booisvaladv = false
break -- to join mark -- evil
end--if
numindeex = numindeex + 1 -- ZERO-based
end--while -- inner genuine loop over char:s
if (not boonoban) then -- if "yesban" then
numindeex = 0
while true do -- lower inner genuine loop
varomongkosong = contabisbanned[numindeex+1] -- number of elem unknown
if (type(varomongkosong)~='string') then
break -- abort inner loop (then outer fake loop) due to end of table
end--if
numukurran = string.len (varomongkosong)
if ((numukurran<2) or (numukurran>3)) then
break -- abort inner loop (then outer fake loop) due to faulty table
end--if
if (strqooq==varomongkosong) then
booisvaladv = false
break -- abort inner loop (then outer fake loop) due to violation
end--if
numindeex = numindeex + 1 -- ZERO-based
end--while -- lower inner genuine loop
end--if (not boonoban) then
break -- finally to join mark
end--while -- fake loop -- join mark
return booisvaladv
end--function lfivalidatelnkoadv
------------------------------------------------------------------------
-- Local function LFIFILLNAME
-- Replace placeholder "\@" "\\@" by augmented name of the caller.
-- To be called ONLY from "lfhfillsurrstrtab".
-- The name of the caller is submitted to us as a parameter thus we
-- do NOT access any constants and do NOT have to peek it either.
local function lfifillname (strmessage, strcaller)
local strhasill = ''
local numstrloen = 0
local numindfx = 1 -- ONE-based
local numcjar = 0
local numcjnext = 0
numstrloen = string.len (strmessage)
while true do
if (numindfx>numstrloen) then
break -- empty input is useless but cannot cause major harm
end--if
numcjar = string.byte (strmessage,numindfx,numindfx)
numindfx = numindfx + 1
numcjnext = 0 -- preASSume no char
if (numindfx<=numstrloen) then
numcjnext = string.byte (strmessage,numindfx,numindfx)
end--if
if ((numcjar==92) and (numcjnext==64)) then
strhasill = strhasill .. strcaller -- invalid input is caller's risk
numindfx = numindfx + 1 -- skip 2 octet:s of the placeholder
else
strhasill = strhasill .. string.char (numcjar)
end--if
end--while
return strhasill
end--function lfifillname
------------------------------------------------------------------------
-- Local function LFIKODEOSG
-- Transcode eo X-surrogates to cxapeloj in a single string (eo only).
-- Input : * streosurr -- ANSI string (empty is useless but cannot
-- cause major harm)
-- Output : * strutf8eo -- UTF8 string
-- Depends on functions :
-- [E] mathdiv mathmod
-- Depends on constants :
-- * table "contabtransluteo" inherently holy
-- To be called ONLY from "lfhfillsurrstrtab".
-- * the "x" in a surr pair is case insensitive,
-- for example both "kacxo" and "kacXo" give same result
-- * avoid "\", thus for example "ka\cxo" would get converted but the "\" kept
-- * double "x" (both case insensitive) prevents conversion and becomes
-- reduced to single "x", for example "kacxxo" becomes "kacxo"
local function lfikodeosg (streosurr)
local vareopeek = 0
local strutf8eo = ''
local numeoinplen = 0
local numinpinx = 0 -- ZERO-based source index
local numknar0k = 0 -- current char
local numknaf1x = 0 -- next char (ZERO is NOT valid)
local numknaf2x = 0 -- post next char (ZERO is NOT valid)
local boonext1x = false
local boonext2x = false
local boosudahdone = false
numeoinplen = string.len(streosurr)
while true do
if (numinpinx>=numeoinplen) then
break
end--if
numknar0k = string.byte(streosurr,(numinpinx+1),(numinpinx+1))
numknaf1x = 0 -- preASSume no char
numknaf2x = 0 -- preASSume no char
if ((numinpinx+1)<numeoinplen) then
numknaf1x = string.byte(streosurr,(numinpinx+2),(numinpinx+2))
end--if
if ((numinpinx+2)<numeoinplen) then
numknaf2x = string.byte(streosurr,(numinpinx+3),(numinpinx+3))
end--if
boonext1x = ((numknaf1x==88) or (numknaf1x==120)) -- case insensitive
boonext2x = ((numknaf2x==88) or (numknaf2x==120)) -- case insensitive
boosudahdone = false
if (boonext1x and boonext2x) then -- got "xx"
strutf8eo = strutf8eo .. string.char(numknar0k,numknaf1x) -- keep one "x" only
numinpinx = numinpinx + 3 -- eaten 3 written 2
boosudahdone = true
end--if
if (boonext1x and (not boonext2x)) then -- got yes-"x" and no-"x"
vareopeek = contabtransluteo[numknar0k] -- UINT16 or type "nil"
if (type(vareopeek)=='number') then
strutf8eo = strutf8eo .. string.char(mathdiv(vareopeek,256),mathmod(vareopeek,256)) -- add UTF8 char
numinpinx = numinpinx + 2 -- eaten 2 written 2
boosudahdone = true
end--if
end--if
if (not boosudahdone) then
strutf8eo = strutf8eo .. string.char(numknar0k) -- copy char
numinpinx = numinpinx + 1 -- eaten 1 written 1
end--if
end--while
return strutf8eo
end--function lfikodeosg
------------------------------------------------------------------------
-- Local function LFICONDIADDLAUQB
local function lficondiaddlauqb (stringvonomo)
if (string.byte(stringvonomo,-1,-1)==97) then -- 'a'
stringvonomo = 'la ' .. stringvonomo
end--if
stringvonomo = '"<b>' .. stringvonomo .. '</b>"'
return stringvonomo
end--function lficondiaddlauqb
------------------------------------------------------------------------
---- HIGH LEVEL FUNCTIONS [H] ----
------------------------------------------------------------------------
-- Local function LFHVALI1STATUS99CODE
-- Depends on functions :
-- [E] mathisintrange
local function lfhvali1status99code (varvalue)
local boovalid = false -- preASSume guilt
while true do -- fake loop
if (varvalue==0) then
break -- success thus keep false since no valid error code ;-)
end--if
if (mathisintrange(varvalue,1,99)) then
boovalid = true -- got an error and valid error code returned
else
varvalue = 255 -- failed to return valid status code
end--if
break -- finally to join mark
end--while -- fake loop -- join mark
return varvalue, boovalid
end--function lfhvali1status99code
------------------------------------------------------------------------
-- Local function LFHCONSTRUCTERAR
-- Input : * numerar6code -- 1 ... 99 or 2 ... 99 (resistent against invalid
-- data type, giving "??" on such)
-- * boopeek6it -- do peek description #E02...#E99 from table
-- Depends on functions :
-- [N] lfnumto2digit
-- [E] mathisintrange mathdiv mathmod
-- Depends on constants :
-- * maybe table contaberaroj TWO-based (holes permitted)
-- To be called ONLY from lfhbrewerror, lfhbrewerrsm,
-- lfhbrewerrsvr, lfhbrewerrinsi.
local function lfhconstructerar (numerar6code, boopeek6it)
local vardes6krip = 0
local numbottom6limit = 1
local stryt6sux = '#E'
if (boopeek6it) then
numbottom6limit = 2 -- #E01 is a valid code for submodule only
end--if
if (mathisintrange(numerar6code,numbottom6limit,99)) then
stryt6sux = stryt6sux .. lfnumto2digit(numerar6code)
if (boopeek6it) then
vardes6krip = contaberaroj[numerar6code] -- risk of type "nil"
if (type(vardes6krip)=='string') then
stryt6sux = stryt6sux .. ' ' .. vardes6krip
else
stryt6sux = stryt6sux .. ' ??' -- no text found
end--if
end--if (boopeek6it) then
else
stryt6sux = stryt6sux .. '??' -- no valid error code
end--if
return stryt6sux
end--function lfhconstructerar
------------------------------------------------------------------------
-- Local function LFHBREWERROR
-- Input : * numerar7code -- 2 ... 99
-- Depends on functions :
-- [H] lfhconstructerar
-- [N] lfnumto2digit
-- [E] mathisintrange mathdiv mathmod
-- Depends on constants :
-- * 3 strings constrelabg constrelaen constrlaxhu
-- * table contaberaroj TWO-based (holes permitted)
-- #E02...#E99, note that #E00 and #E01 are NOT supposed to be included here.
local function lfhbrewerror (numerar7code)
local stryt7sux = ''
stryt7sux = constrlaxhu .. constrelabg .. lfhconstructerar (numerar7code,true) .. constrelaen .. constrlaxhu
return stryt7sux
end--function lfhbrewerror
------------------------------------------------------------------------
-- Local function LFHFILLSURRSTRTAB
-- Process (fill in, transcode surr) either a single string, or all string
-- items in a table (even nested) using any type of keys/indexes (such as
-- a holy number sequence and non-numeric ones). Items with a non-string
-- value are kept as-is. For filling in own name, and converting eo and
-- NOPE sv surrogates (via 3 separate sub:s).
-- Input : * varinkommen -- type "string" or "table"
-- * varfyllo -- string, or type "nil" if no filling-in desired
-- * strlingkod -- "eo" or NOPE "sv" to convert surrogates, anything
-- else (preferably type "nil") to skip this
-- Depends on functions :
-- [I] lfifillname (only if filling-in desired)
-- [I] lfikodeosg (only if converting of eo X-surrogates desired)
-- NOPE [I] lfikodsvsg
-- [E] mathdiv mathmod (via "lfikodeosg" and NOPE "lfikodsvsg")
-- Depends on constants :
-- * table "contabtransluteo" inherently holy (via "lfikodeosg")
-- NOPE * table "contabtranslutsv"
local function lfhfillsurrstrtab (varinkommen, varfyllo, strlingkod)
local varkey = 0 -- variable without type
local varele = 0 -- variable without type
local varutmatning = 0
local boodone = false
if (type(varinkommen)=='string') then
if (type(varfyllo)=='string') then
varinkommen = lfifillname (varinkommen,varfyllo) -- fill-in
end--if
if (strlingkod=='eo') then
varinkommen = lfikodeosg (varinkommen) -- surr
end--if
-- if (strlingkod=='sv') then
-- varinkommen = lfikodsvsg (varinkommen) -- surr
-- end--if
varutmatning = varinkommen -- copy, risk for no change
boodone = true
end--if
if (type(varinkommen)=='table') then
varutmatning = {} -- brew new table
varkey = next (varinkommen) -- try to pick 0:th (in no order) key/index
while true do
if (varkey==nil) then
break -- empty table or end reached
end--if
varele = varinkommen[varkey] -- pick element of unknown type
if ((type(varele)=='string') or (type(varele)=='table')) then
varele = lfhfillsurrstrtab (varele, varfyllo, strlingkod) -- RECURSION
end--if
varutmatning[varkey] = varele -- write at same place in dest table
varkey = next (varinkommen, varkey) -- try to pick next key/index
end--while
boodone = true
end--if
if (not boodone) then
varutmatning = varinkommen -- copy as-is whatever it is
end--if
return varutmatning
end--function lfhfillsurrstrtab
------------------------------------------------------------------------
---- VARIABLES [R] ----
------------------------------------------------------------------------
function exporttable.ek (arxframent)
-- general unknown type
local vartmp = 0 -- variable without type multipurpose
-- special type "args" AKA "arx"
local arxsomons = 0 -- metaized "args" from our own or caller's "frame"
-- general tab
local tablg76yleft = {} -- y-index -> leftmost column (langcode to langname)
local tablg80lefty = {} -- leftmost column -> y-index (langname to langcode)
-- peeked stuff
local strpiklangcode = '' -- "en" privileged site language
local strpikkatns = '' -- "Category"
local strpikapxns = '' -- "Appendix"
local strpikparent = '' -- "Template:attack" FULLPAGENAME
local strpikpareuf = '' -- "attack" PAGENAME unfull
-- general str
local strpagenam = '' -- {{PAGENAME}} or "pagenameoverridetestonly="
local strruangna = '' -- {{NAMESPACENUMBER}} or "nsnumberoverridetestonly="
local strkodbah = '' -- language code maybe from arxsomons[1]
local strnambah = '' -- language name
local strintear = '' -- "early"
local strintlat = '' -- "latter"
local strtomp = '' -- temp
local strtump = '' -- temp
local strvisgud = '' -- visible output on success
local strviserr = '' -- visible error message on error
local strtrakat = '' -- invisible tracking categories on error
local strret = '' -- final result string
-- general num
local numerr = 0 -- 0 OK | 1 inter | 2 sub fail | 3 sub statuscode
local num2statcode = 0
local numtamp = 0
-- general boo
local bootimp = false
------------------------------------------------------------------------
---- MAIN [Z] ----
------------------------------------------------------------------------
---- GUARD AGAINST INTERNAL ERROR AGAIN ----
-- later reporting of #E01 must NOT depend on uncommentable stuff
if (qbooguard) then
numerr = 1 -- #E01 internal
end--if
------------------------------------------------------------------------
---- PEEK STUFF THAT IS NOT OVERRIDDEN GENEROUS ----
-- this depends on "arxframent" (only if parent requested) but NOT on "arx"
-- "strpikkatns" and "strpikindns" and "strpikapxns" do NOT
-- include a trailing ":" colon, and are for "lfykattlaenk"
-- and "lfyapxindlaenk" and "lfikatpaldigu"
-- full "strpikparent" is used for error messages
-- unfull "strpikpareuf" is used for tracking cat:s
if (numerr==0) then
strpiklangcode = contabovrd['sitelang'] or mw.getContentLanguage():getCode() or 'en' -- privileged site language
strpikkatns = contabovrd['katprefi'] or (mw.site.namespaces[ 14] or {})['name'] or 'Category' -- standard namespace
strpikapxns = contabovrd['apxprefi'] or (mw.site.namespaces[102] or {})['name'] or 'Appendix' -- custom namespace
strpikparent = contabovrd['parentfn'] or arxframent:getParent():getTitle() or 'Template:ligald' -- fullpagename
if ((type(strpiklangcode)~='string') or (type(strpikkatns)~='string') or (type(strpikapxns)~='string') or (type(strpikparent)~='string')) then
numerr = 1 -- #E01 internal
end--if
vartmp = string.find(strpikparent,':',1,true)
if (mathisintrange(vartmp,2,(string.len(strpikparent)-1))) then
strpikpareuf = string.sub(strpikparent,(vartmp+1),-1) -- make unfull
else
strpikpareuf = strpikparent -- dubi call from ns ZERO or misplaced ":"
end--if
end--if (numerr==0) then
------------------------------------------------------------------------
---- GET THE ARX (ONE OF TWO) ----
-- must be seized independently on "numerr" even if we
-- already suck due to possible "detrc=true"
-- give a f**k in possible params other than "caller=true"
arxsomons = arxframent.args -- "args" from our own "frame"
if (type(arxsomons)~='table') then
arxsomons = {} -- guard against indexing error from our own
numerr = 1 -- #E01 internal
end--if
if (arxsomons['caller']=='true') then
arxsomons = arxframent:getParent().args -- "args" from caller's "frame"
end--if
if (type(arxsomons)~='table') then
arxsomons = {} -- guard against indexing error again
numerr = 1 -- #E01 internal
end--if
------------------------------------------------------------------------
---- PROCESS MESSAGES, FILL IN ALWAYS, SURR ONLY IF NEEDED ----
-- only for some languages the surr-transcoding is subsequently performed
if (numerr==0) then
contaberaroj = lfhfillsurrstrtab (contaberaroj, ('"' .. strpikparent .. '"'), strpiklangcode)
contabmesagxoj = lfhfillsurrstrtab (contabmesagxoj, nil, strpiklangcode)
contabtrack = lfhfillsurrstrtab (contabtrack, nil, strpiklangcode)
end--if
------------------------------------------------------------------------
---- PICK TWO SUBTABLES T76 T80 FROM ONE SUBMODULE ----
-- here risk of #E02 #E03
-- on error we assign "numerr" and maybe "num2statcode" both used far below
while true do -- fake loop
if (numerr~=0) then -- #E01 possible
break -- to join mark
end--if
num2statcode, bootimp = lfhvali1status99code (qldingvoj[2])
if (num2statcode~=0) then
if (bootimp) then
numerr = 3 -- #E03 nombrigita
else
numerr = 2 -- #E02 malica
end--if
break -- to join mark
end--if
vartmp = qldingvoj['T76'] -- from "loaddata-tbllingvoj"
if (type(vartmp)~='table') then -- important check
numerr = 2 -- #E02 malica
break -- to join mark
end--if
tablg76yleft = vartmp -- y-index -> leftmost column (langcode to langname)
vartmp = qldingvoj['T80'] -- from "loaddata-tbllingvoj"
if (type(vartmp)~='table') then -- important check
numerr = 2 -- #E02 malica
break -- to join mark
end--if
tablg80lefty = vartmp -- leftmost column -> y-index (langname to langcode)
break -- finally to join mark
end--while -- fake loop -- join mark
------------------------------------------------------------------------
---- PROCESS 2 HIDDEN NAMED PARAMS INTO 2 STRING:S ----
-- this may override "mw.title.getCurrentTitle().text" and
-- stipulate content in "strpagenam", empty is NOT valid
-- bad "pagenameoverridetestonly=" can give #E01
-- no error is possible from other hidden parameters
strpagenam = ''
if (numerr==0) then
vartmp = arxsomons['pagenameoverridetestonly']
if (type(vartmp)=='string') then
numtamp = string.len(vartmp)
if ((numtamp>=1) and (numtamp<=200)) then
strpagenam = vartmp -- empty is not legal, whine if bad
else
numerr = 1 -- #E01 internal
end--if
end--if
end--if
strruangna = ''
if (numerr==0) then
vartmp = arxsomons['nsnumberoverridetestonly']
if (type(vartmp)=='string') then
numtamp = string.len(vartmp)
if ((numtamp>=1) and (numtamp<=4)) then
strruangna = vartmp -- empty is not legal, skip if bad
end--if
end--if
end--if
---- SEIZE THE PAGENAME FROM MW ----
-- "pagenameoverridetestonly=" is processed above
-- later reporting of #E01 must NOT depend on uncommentable stuff
-- must be 1...200 octet:s keep consistent with "pagenameoverridetestonly="
if ((numerr==0) and (strpagenam=='')) then
vartmp = mw.title.getCurrentTitle().text -- without namespace prefix
if (type(vartmp)=='string') then -- this can leave bhd "strpagenam" empty
numtamp = string.len(vartmp)
if ((numtamp>=1) and (numtamp<=200)) then
strpagenam = vartmp -- empty is not legal, whine if bad
else
numerr = 1 -- #E01 internal
end--if
end--if
end--if
if (numerr==0) and (strpagenam=='') then
numerr = 1 -- #E01 internal
end--if
------------------------------------------------------------------------
---- WHINE IF YOU MUST #E01 ----
-- reporting of this error #E01 must NOT depend on uncommentable
-- or peekabe stuff such as "strpikparent" and "contaberaroj"
-- do NOT use sub "lfhbrewerror", report our name (NOT of template), in EN
if (numerr==1) then
strtump = '#E01 Internal error in "Module:ligald".'
strviserr = constrlaxhu .. constrelabg .. strtump .. constrelaen .. constrlaxhu
end--if
------------------------------------------------------------------------
--- CHECK FOR ONE POSSIBLE ANON PARAM ----
-- here risk of #E08 #E09
strkodbah = ''
if (numerr==0) then
if ((arxsomons[2]~=nil) or (arxsomons[3]~=nil)) then
numerr = 8 -- #E08 maksimume
else
vartmp = arxsomons[1]
if (type(vartmp)=='string') then
numtamp = string.len(vartmp)
if ((numtamp==0) or (numtamp>20)) then
numerr = 9 -- #E09 anon param empty or too long
else
strkodbah = vartmp -- deeper check later
end--if
end--if
end--if
end--if
------------------------------------------------------------------------
---- SEIZE THE NAMESPACE FROM MW AND CHECK IT ----
-- here risk of #E10
-- "nsnumberoverridetestonly=" is processed above
if ((numerr==0) and (strruangna=='')) then
vartmp = mw.title.getCurrentTitle().namespace -- type is "number"
if (mathisintrange(vartmp,0,9999)) then
strruangna = tostring(vartmp) -- negative not legal, skip if bad
end--if
end--if
if ((numerr==0) and (strruangna~='0') and (strruangna~='14')) then
numerr = 10 -- #E10 wrong ns
end--if
------------------------------------------------------------------------
---- CHECK LANG CODE IF GIVEN ----
if ((numerr==0) and (strkodbah~='')) then
if (not lfivalidatelnkoadv(strkodbah,false,false,conbookodlng,conboomiddig,false)) then
numerr = 11 -- #E11 obviously invalid lang code
end--if
end--if
------------------------------------------------------------------------
---- PROCESS NS ZERO ----
if ((numerr==0) and (strruangna=='0')) then
if (strkodbah~='') then
while true do -- fake loop
vartmp = tablg76yleft[strkodbah] -- forward query
if (type(vartmp)~='string') then
if (type(tablg76yleft[strpiklangcode])=='string') then
numerr = 12 -- #E12 unknown lang code (site code works)
else
numerr = 2 -- #E02 broken submodule (site code does NOT work either)
end--if
break
end--if (type(vartmp)~='string') then
if (string.len(vartmp)<2) then -- less than 2 letters is not legal
numerr = 2 -- #E02 broken submodule
break
end--if
strnambah = vartmp -- got lang name :-)
if (strnambah==strpagenam) then
numerr = 13 -- #E13 lingvokodo malpermesita por ne-aliasa
break
end--if
strintear = lficondiaddlauqb(strnambah) .. ' (' .. lficondiaddlauqb(strpagenam) .. ')'
strintlat = strnambah
break -- finally to join mark
end--while -- fake loop -- join mark
else
while true do -- fake loop
vartmp = tablg80lefty[strpagenam] -- reverse query (discard later)
if (type(vartmp)~='string') then
numerr = 15 -- #E15 nekonata lingvonomo en kapvorta
break
end--if
if (not lfivalidatelnkoadv(vartmp,false,false,conbookodlng,conboomiddig,false)) then
numerr = 2 -- #E02 broken submodule
break
end--if
strintear = lficondiaddlauqb(strpagenam)
strintlat = strpagenam
break -- finally to join mark
end--while -- fake loop -- join mark
end--if (strkodbah~='') else
end--if ((numerr==0) and (strruangna=='0')) then
------------------------------------------------------------------------
---- PROCESS NS 14 ----
if ((numerr==0) and (strruangna=='14')) then
while true do -- fake loop
if (strkodbah~='') then
numerr = 16 -- #E16 lingvokodo malpermesita por kategorio
break
end--if
if (lfutristletr(strpagenam,strpiklangcode)~=1) then -- UPPERCAse eo letter required
numerr = 18 -- #E18 nevalida pagxonomo en kato
break
end--if
bootimp, strtomp, strtump = lfisepbracket(strpagenam,3)
if (bootimp) then
if (strtump~='Kapvorto ()') then
numerr = 18 -- #E18 nevalida pagxonomo en kato
break
end--if
strpagenam = strtomp -- no need to adjust letter case here
else
if (string.byte(strpagenam,-1,-1)~=111) then -- 'o' adjust letter case
strpagenam = lfucaserest(strpagenam,false,false,strpiklangcode)
end--if
end--if (bootimp) else
vartmp = tablg80lefty[strpagenam] -- reverse query (discard later)
if (type(vartmp)~='string') then
numerr = 18 -- #E18 nevalida pagxonomo en kato
break
end--if
if (not lfivalidatelnkoadv(vartmp,false,false,conbookodlng,conboomiddig,false)) then
numerr = 2 -- #E02 broken submodule
break
end--if
strintear = lficondiaddlauqb(strpagenam)
strintlat = strpagenam
break -- finally to join mark
end--while -- fake loop -- join mark
end--if ((numerr==0) and (strruangna=='14')) then
------------------------------------------------------------------------
---- BREW THE BOX ----
if (numerr==0) then
strtomp = '[[' .. strpikapxns .. ':' .. lfucaserest(strintlat,true,false,strpiklangcode) .. ']]'
strvisgud = contabbeg .. contabmesagxoj[0] .. strintear .. contabmesagxoj[1] .. strtomp .. contabend
end--if (numerr==0) then
------------------------------------------------------------------------
---- WHINE IF YOU MUST #E02...#E99 SIMPLE ----
-- reporting of errors #E02...#E99 depends on uncommentable or peekable
-- stuff and on name of the caller filled in from "strpikparent"
if (numerr>=2) then
strviserr = lfhbrewerror(numerr)
end--if
------------------------------------------------------------------------
---- TRACKING CAT:S ON #E08...#E99 ----
-- here we use "strpikpareuf" ie the UNFULL name of the parent
-- #E06 and #E07 not used in this module
if (numerr>=8) then
while true do -- fake loop
if (numerr==11) then -- #E11
strtrakat = lfikataldigu(strpikkatns,contabtrack[0])
break
end--if
if (numerr==12) then -- #E12
strtrakat = lfikataldigu(strpikkatns, contabtrack[1])
strtrakat = strtrakat .. lfikataldigu(strpikkatns,(contabtrack[2] .. ' (' .. strpikpareuf .. ')')) -- loke
strtrakat = strtrakat .. lfikataldigu(strpikkatns,(contabtrack[3] .. ' (' .. strkodbah .. ')')) -- nome
break
end--if
if ((numerr==15) or (numerr==18)) then -- #E15 #E18 NO DETAILS
strtrakat = lfikataldigu(strpikkatns,contabtrack[4])
break
end--if
strtrakat = lfikataldigu(strpikkatns,contabtrack[5])
strtrakat = strtrakat .. lfikataldigu(strpikkatns,contabtrack[5] .. ' (' .. strpikpareuf .. ')')
strtrakat = strtrakat .. lfikataldigu(strpikkatns,contabtrack[5] .. ' (' .. strpikpareuf .. ', E' .. lfnumto2digit(numerr) .. ')')
break -- finally to join mark
end--while -- fake loop -- join mark
end--if
------------------------------------------------------------------------
---- RETURN THE JUNK STRING ----
-- on #E02 and higher we risk partial results in "strvisgud"
if (numerr==0) then
strret = strvisgud
else
strret = strviserr .. strtrakat
end--if
return strret
------------------------------------------------------------------------
end--function
---- RETURN THE JUNK LUA TABLE ----
return exporttable