--[===[
"eo.wiktionary.org/wiki/Modulo:loaddata-tbldialektoj" <!--2024-Oct-09-->
Purpose: translate (the transcludable part of) wikitext of a template
(name is hardcoded to "tbldialek") to 2 LUA tables that can be
used repeatedly via the infamous "mw.loadData" command
Utilo: traduki na (la transkluzivigebla parto de) vikiteksto de sxablono
(nomo fiksita al "tbldialektoj") al 2 LUA-tabeloj kiuj povas esti
uzataj ripete per la famacxa ordono "mw.loadData"
Manfaat: menerjemahkan (bagian yang bisa ditransklusikan) wikiteks templat
(namanya tetap "tbldialek") menjadi 2 tabel LUA yang bisa digunakan
beberapa kali melalui perintah "mw.loadData" yang terkenal buruk
Syfte: oeversaetta (den transkluderingsbara delen av) wikitext fraan en mall
(namn fastslaget till "tbldialektoj") till 2 LUA-tabeller som kan
anvaendas upprepade gaanger medelst det oekaenda
kommandot "mw.loadData"
Used by templates / Uzata far sxablonoj /
Digunakan oleh templat / Anvaent av mallar:
* "Vikivortaro:Testo-tbldialektoj" (NOT a template) serving as
a low-level test and diagnostic tool for the system
* "bigtable-tbldialektoj" / "bigtable-tbldialek" serving additionally as
a high-level test and diagnostic tool for the system
* "tagg"
Required submodules / Bezonataj submoduloj / Submodul yang diperlukan:
* none
Required templates:
* "tbldialek" or "tbldialektoj"
Incoming: * nothing (imported via "mw.loadData", no ordinary caller)
Returned: * LUA table containing up to 17 items of status data, and
up to 6 inner LUA tables of main data:
* status values (some can happen to be empty):
* [2] (integer) status code (see below)
* [3] (integer) full bloat of raw incoming block
* [4] (integer) remaining bloat of table content area,
after removing both outer areas and outer EOL:s but
still keeping all possible excessive inner whitespace
* [6] (integer) octet position of error (relative to table
content area, excessive inner whitespace does count,
two outer areas and outer EOL:s don't)
* [8] (integer) number of sections found, or index of section
where an error occurred (empty lines do NOT count)
* [9] (integer) number of lines found, or index of line
where an error occurred (empty lines do NOT count)
* [10] minimal length of line before space reduction
* [11] maximal length of line before space reduction
* [12] minimal length of line after space reduction
* [13] maximal length of line after space reduction
* [14] minimal number of elements in a valid line
* [15] maximal number of elements in a valid line
* [16] (string, AA) error string on some errors,
otherwise empty string
* always hardcoded settings
* [17] (string, BB) error string on some errors,
otherwise empty string
* if applicable raw complete or truncated faulty line
* [18] (string, CC) error string on some errors,
otherwise empty string
* if applicable report with length of the line before
and after space reduction, and earliest and last char
* [21] (string, DD) error string on some errors,
otherwise empty string
* on E07 number of bad char:s and code of earliest
offending char
* on E42 counted number of elements
* if applicable early participant in sorting crime
* if applicable duping string
* if applicable offending content that failed
extra validation
* [22] (string, EE) error string on some errors,
otherwise empty string
* if applicable latter participant in sorting crime
* if applicable conflicting keys of the duping string
* main data (selectable, type "nil" if not active):
* ["T75"] (table) enumeration table with key/index ZERO-based
* ["T76"] (table) y-index -> element in left-most column
* ["T77"] (table) table y-index -> complete line
* ["T78"] (table) table y-index -> subtable
* ["T80"] (table) left-most column -> y-index
* ["T81-" n] (table) other column of interest -> y-index
* ["T81-1"] (table) column ONE -> y-index
Note that this module is NOT generic and CANNOT be made generic due to the
principle that data received by "mw.loadData" must be static and thus it is
not possible to submit parameters (namely name of the template to be seized)
to this module.
Status codes:
* #E00: OK
* #E02: template not found (outside of scope of the specification)
* #E03 ... #E79: range reserved by the
specification (see "spec-picker-en.txt")
Structure:
* the useful content area is delimited:
* begins with <pre> LF 60 x cross "#" LF
* ends with LF 60 x cross "#" LF </pre>
* in the useful content area:
* empty lines are ignored
* there are 2 types of lines:
* langcode lines containing a raw langcode
prefixed by "### " (section headers)
* dialect info lines containing:
* dialect code inside "[[" & "]]"
* 1 to 5 wall-separated values (WSV)
]===]
------------------------------------------------------------------------
---- CONSTANTS [O] ----
------------------------------------------------------------------------
-- uncommentable constant strings source ie target template
local constrtarget = string.char(0xC5,0x9C) .. "ablono:tbldialektoj" -- EO -- "SXablono"
-- local constrtarget = "Templat:tbldialek" -- ID
-- 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
-- semi-hardcoded parameters (see specification "spec-picker-en.txt")
local contabqc = {}
contabqc['Q02'] = true -- use of stripping
contabqc['Q03'] = 100
contabqc['Q04'] = 1000000 -- 1M
contabqc['Q05'] = '<pre>\n############################################################\n' -- <pre> LF 60 x cross "#" LF
contabqc['Q06'] = '\n############################################################\n</pre>' -- LF 60 x cross "#" LF </pre>
contabqc['Q08'] = 100
contabqc['Q09'] = 1000000 -- 1M
contabqc['Q13'] = 6 -- minimal length of line (beware of sections)
contabqc['Q14'] = 1000 -- maximal length of line
contabqc['Q15'] = 2
contabqc['Q16'] = 10000 -- 10K number of lines
contabqc['Q17'] = 1 -- "britlanda|-|w:Brita angla lingvo|-|Flag of Great Britain.svg"
contabqc['Q18'] = 5 -- number of elements in a line, y-index marker does NOT count
contabqc['Q20'] = 10 -- ASCII code of LF
contabqc['Q21'] = 124 -- WSV
contabqc['Q22'] = '=' -- not found
contabqc['Q25'] = 2
contabqc['Q26'] = 12 -- length of index markers
contabqc['Q28'] = true -- use section headers
contabqc['Q29'] = 'S2' -- fully sorted (S1 prohibited here)
contabqc['Q30'] = 'langcode'
contabqc['Q31'] = '00' -- "zh-min-nan", digit in middle position
contabqc['Q36'] = 'Y4' -- y-index markers Y4 obligatory and sorted
contabqc['Q37'] = 'S2' -- fully sorted (must be due to section headers)
contabqc['Q38'] = 'T'
contabqc['Q39'] = '' -- no extra
contabqc['Q40'] = '' -- no extra
contabqc['Q55'] = 'D2' -- dupe prevention level in left-most column
-- contabqc['Q66'] = {} -- extra validation of values in the table, triples
-- contabqc['Q67'] = {} -- pluprocessing of values from the table, triples
contabqc['Q75'] = true -- deliver enumeration table
contabqc['Q78'] = true -- deliver table y-index -> subtable
------------------------------------------------------------------------
---- SPECIAL STUFF OUTSIDE MAIN [B] ----
------------------------------------------------------------------------
-- SPECIAL VAR:S
local qstrtca = '' -- table content area for "lfigetlinespacered" and main
------------------------------------------------------------------------
---- MATH FUNCTIONS [E] ----
------------------------------------------------------------------------
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
------------------------------------------------------------------------
---- 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 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
------------------------------------------------------------------------
-- Local function LFGTRIMWHITES
-- Trim leading and trailing whitespace in a single line
-- in a customizable manner.
-- Input : * strriskofwhite -- string, empty or only white tolerable, but
-- type other than "string" NOT permitted
-- * bootakelf
-- * bootakespc
-- * boopronelfatend -- provide exactly ONE LF at end on
-- exit, even do add if missing, only
-- together with "bootakelf"
local function lfgtrimwhites (strriskofwhite, bootakelf, bootakespc, boopronelfatend)
local str52rezulto = ''
local str52pluslf = ''
local numpos52beg = 1 -- ONE-based
local numpos52end = 0 -- ONE-based
local num52char = 0
if (bootakelf and boopronelfatend) then
str52pluslf = string.char(10)
end--if
numpos52end = string.len(strriskofwhite)
while true do -- analyze begin
if (numpos52beg>numpos52end) then
break -- consists of only whitespace or empty
end--if
num52char = string.byte(strriskofwhite,numpos52beg,numpos52beg)
if (not (((num52char==10) and bootakelf) or ((num52char==32) and bootakespc))) then
break
end--if
numpos52beg = numpos52beg + 1
end--while -- analyze begin
while true do -- analyze trailer
if (numpos52end<numpos52beg) then
break -- consists of only whitespace or empty
end--if
num52char = string.byte(strriskofwhite,numpos52end,numpos52end)
if (not (((num52char==10) and bootakelf) or ((num52char==32) and bootakespc))) then
break
end--if
numpos52end = numpos52end - 1
end--while -- analyze trailer
if (numpos52end>=numpos52beg) then
str52rezulto = string.sub(strriskofwhite,numpos52beg,numpos52end) .. str52pluslf
else
str52rezulto = str52pluslf -- empty or only LF
end--if
return str52rezulto
end--function lfgtrimwhites
------------------------------------------------------------------------
-- Local function LFGFINDONE
-- Return found position only if exactly ONE hit, otherwise
-- (on either several hits or no hit) return -1.
local function lfgfindone (str92where, str92what)
local varaa = 0
local varbb = 0
local num92posi = -1 -- preASSume NOT found
varaa = string.find (str92where, str92what, 1, true) -- >=1 or "nil"
if (varaa) then
varbb = string.find (str92where, str92what, (varaa+1), true)
end--if
if (varaa and (not varbb)) then
num92posi = varaa - 1 -- make ZERO-based
end--if
return num92posi
end--function lfgfindone
------------------------------------------------------------------------
---- HIGH LEVEL STRING FUNCTIONS [I] ----
------------------------------------------------------------------------
-- Local function LFIRLLRSTRIP
-- Strip "rl " ... " lr" if it is present and string
-- length is at least 8 octet:s.
local function lfirllrstrip (strorlinut)
if (string.len(strorlinut)>=8) then -- at least 2 octet:s length after strip
if ((string.sub(strorlinut,1,3)=='rl ') and (string.sub(strorlinut,-3,-1)==' lr')) then
strorlinut = string.sub(strorlinut,4,-4) -- strip off 3+3 char:s
end--if
end--if
return strorlinut
end--function lfirllrstrip
------------------------------------------------------------------------
-- Local function LFIVALIDATELNKOADV
-- Advanced test whether a string (intended to be a langcode) 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 LFIVALIOADV2STR
-- Optional extra validation type "langcode" of markers.
-- Depends on functions :
-- [I] lfivalidatelnkoadv
-- This sub "lfivalioadv2str" as well as the preceding
-- "lfivalidatelnkoadv", and also "contabisbanned" can be
-- omitted if none of Q30 Q39 Q49 contain the value "langcode".
local function lfivalioadv2str (str83mark, str83twodigits)
local boolng5option = false
local boolng6option = false
local boois83valid = false
if (type(str83twodigits=='string')) then
if (string.len(str83twodigits)==2) then
boolng5option = (string.sub(str83twodigits,1,1)=='1') -- "zh-min-nan"
boolng6option = (string.sub(str83twodigits,2,2)=='1') -- digit in middle
end--if
end--if
boois83valid = lfivalidatelnkoadv(str83mark,false,false,boolng5option,boolng6option,false)
return boois83valid
end--function lfivalioadv2str
------------------------------------------------------------------------
-- Local function LFIVALIDATEMARKER
-- Validate marker by content (as stipulated by specification), whereas
-- the length (restricted by Q25,Q26) was already checked earlier.
-- Depends on functions :
-- [G] lfgtestnum lfgtestuc lfgtestlc
local function lfivalidatemarker (strmarkerlensudahok)
local numtypeofmarker = 0 -- preASSume guilt
local numlen92marker = ''
local numin92dex = 0
local numch92ar = 0
local booisboulderdash = false
local booisnumber = false
local booisletter = false
local booisnumorlet = false
numlen92marker = string.len(strmarkerlensudahok)
if ((numlen92marker>=2) and (numlen92marker<=12)) then -- stipulated by spec
numtypeofmarker = 2 -- preASSume innocence now -- 2 digit 1 text 0 invalid
while true do
if (numin92dex==numlen92marker) then
break -- done good or bad
end--if
numch92ar = string.byte(strmarkerlensudahok,(numin92dex+1),(numin92dex+1))
booisboulderdash = (numch92ar==45)
booisnumber = lfgtestnum(numch92ar)
booisletter = lfgtestuc(numch92ar) or lfgtestlc(numch92ar)
booisnumorlet = booisnumberr or booisletter
if ((not booisnumorlet) and (not booisboulderdash)) then
numtypeofmarker = 0 -- fully illegal char
break
end--if
if (numin92dex==0) then
if (booisboulderdash) then
numtypeofmarker = 0 -- must begin with number or letter
break
end--if
if (not booisnumber) then
numtypeofmarker = 1 -- type must be text
end--if
else
if ((not booisnumber) and (numtypeofmarker==2)) then
numtypeofmarker = 0 -- too late dude
break
end--if
end--if
numin92dex = numin92dex + 1
if ((numin92dex==numlen92marker) and booisboulderdash) then
numtypeofmarker = 0 -- must end with number or letter
end--if
end--while
end--if ((numlen92marker>=2) and (numlen92marker<=12)) then
return numtypeofmarker
end--function lfivalidatemarker
------------------------------------------------------------------------
-- Local function LFIGETLINESPACERED
-- Read single line from buffer (upvalue) and perform space-reduction.
-- Input : * num24pos -- if not BOF ie previous line processed, then this
-- must point AFTER the EOL belonging to that line,
-- also this MUST NOT be called on EOF
-- * num24len -- must be valid
-- Output : * num24status -- ZERO success, possible bad values E09 white line
-- -- E10 multi empty -- E11 no EOL -- E12 length
-- * numnew24pos -- new position, unchanged on error
-- * num24rawsiz -- length before redu, also on E12, but max
-- 20 char:s too many
-- * numlen24baris -- length after redu, also on E12, but max
-- 20 char:s too many
-- * str24line -- line, empty on error
-- Depends on upvalues :
-- * qstrtca -- table content area
-- We expect text free of codes <32 except dedicated EOL code, and
-- exactly ONE EOL after last line (not missing, nor multiple).
-- We run up to 20 char:s over length limit Q14 (but never beyond EOF)
-- in order to give useful report on E12.
local function lfigetlinespacered (numq20eol, numq13min, numq14max, num24pos, num24len)
local str24line = ''
local num24status = 0 -- preASSume innocence
local numnew24pos = 0
local num24rawsiz = 0 -- before
local numlen24baris = 0 -- after
local numch24ar = 0
local numbadchar = 0
local booempty24line = false
local boopostpone = false
numnew24pos = num24pos -- preASSume not to move pos (kept on error)
while true do -- find a line
if (num24pos>=num24len) then
num24status = 11 -- E11 do NOT call this on EOF, now give E11 too
break
end--if
numch24ar = string.byte(qstrtca,(num24pos+1),(num24pos+1)) -- pick char
num24pos = num24pos + 1 -- do NOT increment "num24rawsiz" here
if (numch24ar==numq20eol) then
if (booempty24line) then
num24status = 10 -- E10 multi empty
break
else
booempty24line = true -- this one was good, next one will cross limit
end--if
end--if (numch24ar==numq20eol) then
if (numch24ar~=numq20eol) then
break -- found line, still risk of leading spaces
end--if
end--while -- find a line
if (numch24ar==32) then
num24status = 9 -- E09 leading spaces or white line
end--if
if (num24status==0) then
boopostpone = false
while true do -- seize a line
if ((numch24ar==numq20eol) or (num24rawsiz>=(numq14max+20))) then
break -- captured an EOL, do NOT store it anywhere, or oveflow
end--if
if (num24pos>=num24len) then
num24status = 11 -- E11 EOF instead EOL
break
end--if
if (numch24ar==32) then
boopostpone = true
else
if (boopostpone) then
str24line = str24line .. string.char(32,numch24ar) -- build the line
numlen24baris = numlen24baris + 2
boopostpone = false -- !!!CRUCIAL!!!
else
str24line = str24line .. string.char(numch24ar) -- build the line
numlen24baris = numlen24baris + 1
end--if
end--if
numch24ar = string.byte(qstrtca,(num24pos+1),(num24pos+1)) -- pick
num24pos = num24pos + 1
num24rawsiz = num24rawsiz + 1 -- YES do increment "num24rawsiz" here
end--while -- seize a line
if (boopostpone) then
num24status = 9 -- E09 trailing spaces
end--if
end--if (num24status==0) then
if (num24status==0) then -- also if E12 is coming
if ((numlen24baris<numq13min) or (num24rawsiz>numq14max)) then
num24status = 12 -- E12 bad length of line
end--if
end--if
if (num24status==0) then
numnew24pos = num24pos -- advance on success
else
str24line = '' -- empty on error
if (num24status~=12) then
num24rawsiz = 0 -- no result on error other than E12
numlen24baris = 0 -- no result on error other than E12
end--if
end--if
return num24status, numnew24pos, num24rawsiz, numlen24baris, str24line
end--function lfigetlinespacered
------------------------------------------------------------------------
local function lfireportonline (str7line, numlenbef, numlenaft)
local str7report = ''
local numchv = 0
local numchw = 0
str7report = 'lenbef=' .. tostring(numlenbef) .. ' lenaft=' .. tostring(numlenaft)
if (str7line~='') then
numchv = string.byte(str7line,1,1)
numchw = string.byte(str7line,-1,-1)
str7report = str7report .. ' beg=' .. tostring(numchv) .. ' end=' .. tostring(numchw) -- decimal codes
end--if
return str7report
end--function lfireportonline
------------------------------------------------------------------------
-- Local function LFISTRIPOFFZYMARKER
-- Input : * strfullline -- prechecked "[[" at begin & nowhere else & exactly
-- one "]]" later, or "### " at begin & nowhere else
-- Output : * num68status -- ZERO success, possible bad only E20 E25 (E18 checked
-- earlier) (see specification "spec-picker-en.txt")
local function lfistripoffzymarker (strfullline, numq25min, numq26max, boois68section)
local varmyfinder = 0
local strreducedline = ''
local str68ymarker = ''
local num68length = 0
local num68status = 0
if (boois68section) then
num68length = string.len(strfullline)
if ((num68length>=(numq25min+4)) and (num68length<=(numq26max+4))) then
str68ymarker = string.sub (strfullline,5,-1)
else
num68status = 20 -- E20 section header AKA z-dimension
end--if
else
varmyfinder = string.find(strfullline,']]',1,true)
if (varmyfinder) then -- false outcome hopefully impossible
num68length = varmyfinder - 2 -- OFF-BY-ONE
if ((num68length>=numq25min) and (num68length<=numq26max)) then
str68ymarker = string.sub (strfullline,3,(varmyfinder-1))
strreducedline = string.sub (strfullline,(varmyfinder+2),-1)
else
num68status = 25 -- E25 y-dimension
end--if
end--if
end--if
return num68status, strreducedline, str68ymarker
end--function lfistripoffzymarker
------------------------------------------------------------------------
---- HIGH LEVEL FUNCTIONS [H] ----
------------------------------------------------------------------------
-- Local function LFHSPLITTOTABLE
-- Convert one string with elements separated by dedicated separator (CSV
-- SSV WSV) char into separate non-empty strings stored in a LUA table.
-- Input : * strdinding -- must NOT contain codes below 32
-- * numseparator -- 44 for comma "," (CSV) or 59 for semicolon ";"
-- or 124 for wall "|"
-- * strreservph -- reserved other placeholder prohibited as
-- element (empty here if nothing to be prohibited)
-- * num37min -- minimal number of elements (>= 1)
-- * num37max -- maximal number of elements (>= 1)
-- Output : * num37status -- ZERO success, possible errors E40 E41 E42 E43
-- * numsubstrinx -- number of elements found, also valid on E42,
-- max 5 too many, ZERO on other errors
-- * tabyeahsplit -- ZERO-based indexes, placeholder "-" possible,
-- empty string impossible, empty table {} on error
-- Depends on functions :
-- [G] lfgtrimwhites
-- * empty elements must use dash "-" as a placeholder (applies to both
-- the incoming string and the returned table, but there is other
-- sub "lfhnildashtoempty")
-- * excessive spaces are not a problem, here they are trimmed
-- away from single elements (before and after element, not inner)
-- * we run up to 5 elements over limit in order to give useful report on E42
-- Errors:
-- * E40 discovered an empty element
-- * E41 discovered an element literally equal the reserved other placeholder
-- * E42 number of elements in the input string out of range
-- * E43 other error
-- Valid (assuming reserved other placeholder is "=", separator char
-- is wall "|", minimum is ONE, maximum 6):
-- * "-"
-- * "-|-|-| -|-"
-- * "a"
-- * " a" (leading and trailing spaces are legal)
-- * "jamak sama|nomina jamak bentuk sama"
-- * "jamak sama|nomina jamak bentuk sama|-"
-- * "jamak sama|nomina jamak bentuk sama|-|-|-|hej " (6 elements)
-- Invalid (assuming reserved other placeholder is "=", separator char
-- is wall "|", minimum is ONE, maximum 6):
-- * ""
-- * "proton| |antiproton" (inner empty element)
-- * "jamak sama|nomina jamak bentuk sama|" (empty element at end)
-- * "kato| = |lemniskato" (reserved other placeholder used as element)
-- * "jamak sama|nomina jamak bentuk sama|-|-|-|hej|nej" (too much
-- with 6 walls and 7 elements)
local function lfhsplittotable (strdinding,numseparator,strreservph,num37min,num37max)
local vartmmp = 0
local tabyeahsplit = {}
local stronesub = ''
local numinlenin = 0
local numchrindexx = 1 -- ONE-based
local numsubstrinx = 0
local num37status = 0 -- preASSume innocence
numinlenin = string.len(strdinding)
if (numinlenin==0) then
num37status = 43 -- E43 hopefully impossible
end--if
if ((numseparator~=44) and (numseparator~=59) and (numseparator~=124)) then
num37status = 43 -- E43 hopefully impossible
end--if
while true do
if (num37status~=0) then -- hopefully impossible
break
end--if
vartmmp = string.find (strdinding, string.char(numseparator), numchrindexx, true) -- plain text search
if (vartmmp==numchrindexx) then -- nothing to pick before separator char
num37status = 40 -- E40 discovered an empty element
break
end--if
if (vartmmp==numinlenin) then -- nothing to pick after separator char
num37status = 40 -- E40 discovered an empty element
break
end--if
if (vartmmp==nil) then
vartmmp = numinlenin -- ONE-based last inclusive posi is end of string
else
vartmmp = vartmmp - 1 -- ONE-based last inclusive posi
end--if
stronesub = string.sub (strdinding,numchrindexx,vartmmp) -- at least ONE
stronesub = lfgtrimwhites (stronesub,false,true,false) -- trim space only, risk of empty output
if (stronesub=='') then
num37status = 40 -- E40 empty element
break
end--if
if (stronesub==strreservph) then
num37status = 41 -- E41 reserved other placeholder
break
end--if
tabyeahsplit[numsubstrinx] = stronesub -- store it
numsubstrinx = numsubstrinx + 1 -- ZERO-based
if (vartmmp==numinlenin) then
break -- all stored, done
end--if
if (numsubstrinx>=(num37max+5)) then
break -- abort now, max count elements exceeded and no end yet, soon E42
end--if
numchrindexx = vartmmp + 2 -- at least 1 octet left !!!
end--while
if ((num37status==0) and ((numsubstrinx<num37min) or (numsubstrinx>num37max))) then
num37status = 42 -- E42 wrong number of elem -- do NOT override other err
end--if
if (num37status~=0) then
if (num37status~=42) then
numsubstrinx = 0 -- on E42 keep the count but still return empty table
end--if
tabyeahsplit = {} -- F**K
end--if
return num37status, numsubstrinx, tabyeahsplit
end--function lfhsplittotable
------------------------------------------------------------------------
-- Local function LFHREPORTQCT
-- Input : * none, based on "contabqc"
-- Output : * strhugereport
-- Depends on functions :
-- [N] lfnumto2digit
-- [E] mathisintrange mathdiv mathmod
-- Depends on constants :
-- * contabqc
local function lfhreportqct ()
local var94fragment = ''
local strhugereport = ''
local str94tabindex = ''
local num94index = 0 -- per specification the range is "Q00" to "Q99"
while true do
str94tabindex = 'Q' .. lfnumto2digit(num94index)
var94fragment = contabqc[str94tabindex] -- can be any type !!!
if (var94fragment) then
var94fragment = tostring (var94fragment)
var94fragment = '"' .. str94tabindex .. '" = "' .. var94fragment .. '"'
if (strhugereport~='') then
var94fragment = ' -- ' .. var94fragment -- add separator
end--if
strhugereport = strhugereport .. var94fragment
end--if
if (num94index==99) then
break
end--if
num94index = num94index + 1
end--while
if (strhugereport=='') then
strhugereport = 'implementation-specific parameters NOT defined'
end--if
return strhugereport
end--function lfhreportqct
------------------------------------------------------------------------
-- Local function LFHPLUPROCESS
-- Pluprocess values in table elements if desired.
-- Input : * tabpairscoltyp -- control table,
-- tripples (column <-> type <-> param)
-- * tabmysubtable -- victim table
-- Depends on functions :
-- [I] lfirllrstrip
-- The only known type is "rllr".
local function lfhpluprocess (tabpairscoltyp, tabmysubtable)
local strtypeofgg = ''
local strparaofgg = ''
local strmy87value = ''
local numin87dex = 0
local numkoluofgg = 0
if ((type(tabpairscoltyp)=='table') and (type(tabmysubtable)=='table')) then
while true do
numkoluofgg = tabpairscoltyp[numin87dex*3]
strtypeofgg = tabpairscoltyp[numin87dex*3+1]
strparaofgg = tabpairscoltyp[numin87dex*3+2]
if ((type(numkoluofgg)~='number') or (type(strtypeofgg)~='string') or (type(strparaofgg)~='string')) then
break -- end of table reached
end--if
if (strtypeofgg=='rllr') then
strmy87value = tabmysubtable[numkoluofgg]
if (type(strmy87value)=='string') then -- skip boring non-strings
tabmysubtable[numkoluofgg] = lfirllrstrip(strmy87value)
end--if
end--if (strtypeofgg=='rllr') then
numin87dex = numin87dex + 1 -- step ONE here, MUL by 3 elsewhere
end--while
end--if
return tabmysubtable
end--function lfhpluprocess
------------------------------------------------------------------------
---- VARIABLES [R] ----
------------------------------------------------------------------------
-- general unknown type and "args" AKA "arx"
local vartimp = 0
-- tab for caller
local tabtld = {} -- outer table
local tab75enum = {}
local tab76yleft = {}
local tab77ycomp = {}
local tab78ysubt = {}
local tab80lefty = {} -- also for dupe prevention
local tab81othery = {} -- also for dupe prevention
-- tab for dupe prevention
local tabnodupezz = {} -- internal, only possible value is "true"
local tabnodupey = {} -- internal, only possible value is "true"
-- general tab
local tabsplitu = {}
-- str returned
local str16aa = ''
local str17bb = ''
local str18cc = ''
local str21dd = ''
local str22ee = ''
-- str sorting enforcement
local strprevz = ''
local strprevy = ''
local strprevx = ''
-- general str
local strtymp = '' -- temp
local strliine = '' -- complete line spaces reduced and still marker
local strlinenm = '' -- spaces reduced and no more y-index marker
local strmarker = ''
local strsectionpref = ''
local strhardcoded = ''
local strotherkol = '' -- from "numothercol" in turn from Q60
-- num returned
local numerr = 0 -- status 0: OK -- 2: template not found ...
local numbiglen = 0 -- full
local numtrmlen = 0 -- after trim 2 areas + outer blank lines but not more
local numtrmpos = 0
local numtypmrk = 0 -- 2 digit | 1 text | 0 invalid
local numcntsek = 0 -- processed sections
local numcntlin = 0 -- processed lines
local numminbef = 999999 -- from "numlengthlraw"
local nummaxbef = 0
local numminaft = 999999 -- from "numlengthtred"
local nummaxaft = 0
local numminele = 999999 -- from "numelementoj" only on valid lines
local nummaxele = 0
-- general num
local numtomp = 0
local numtump = 0
local numothercol = 0 -- from Q60, number of other column of interest
local numlengthlraw = 0
local numlengthtred = 0
local numelementoj = 0
-- general boo
local boohave17bb18cc = false
local boolineissection = false
local boolineistable = false
local booislast = false -- for sorting and exit
local boonotearnorlas = false
local boote2mp = false
------------------------------------------------------------------------
---- MAIN [Z] ----
------------------------------------------------------------------------
---- SEIZE ----
boote2mp = false
if (type(constrtarget)=='string') then
vartimp = mw.title.new(constrtarget):getContent()
if (type(vartimp)=='string') then
qstrtca = vartimp -- may be empty for now
boote2mp = true
end--if
else
constrtarget = '*** NO TARGET TITLE ***'
end--if
if (not boote2mp) then
numerr = 2 -- #E02 outside of specification
end--if
--- MINIMAL CHECK ----
-- the control table Q00...Q99 is supposed to be valid and
-- consistent, these checks are NOT complete and NOT required
if (numerr==0) then
if (contabqc['Q80']) then
boote2mp = false
if ((contabqc['Q55']=='D1') or (contabqc['Q55']=='D2')) then
boote2mp = (contabqc['Q56']==true)
end--if
if (not boote2mp) then
numerr = 79 -- E79 other or internal error
end--if
end--if
end--if
if (numerr==0) then
if (contabqc['Q81']) then
boote2mp = false
if (type(contabqc['Q60'])=='number') then
if (contabqc['Q60']>=1) then
if ((contabqc['Q61']=='D1') or (contabqc['Q61']=='D2')) then
boote2mp = (contabqc['Q62']==true)
end--if
end--if
end--if
if (not boote2mp) then
numerr = 79 -- E79 other or internal error
end--if
end--if
end--if
---- CHECK LENGTH OF RAW AND TRIM AWAY TWO AREAS AND BLANK LINES ----
-- trimming empty lines is required for reliable detection
-- of EOF needed for both exit and S1
if ((numerr==0) and contabqc['Q02']) then
numbiglen = string.len(qstrtca)
if ((numbiglen<contabqc['Q03']) or (numbiglen>contabqc['Q04'])) then
numerr = 4 -- E04 bad raw BEFORE trim
end--if
end--if
if ((numerr==0) and contabqc['Q02']) then
numtomp = lfgfindone (qstrtca,contabqc['Q05']) -- beg
if (numtomp>=0) then
numtomp = numtomp + string.len(contabqc['Q05']) -- jump over it
end--if
numtump = lfgfindone (qstrtca,contabqc['Q06']) -- termi
if ((numtomp>=0) and (numtump>=0) and (numtump>numtomp)) then
qstrtca = string.sub(qstrtca,(numtomp+1),numtump) -- at least ONE
qstrtca = lfgtrimwhites (qstrtca,true,false,true) -- now can be empty
else
qstrtca = ''
numerr = 5 -- E05 strip fail
end--if
end--if
---- CHECK LENGTH OF TABLE CONTENT AREA AND FOR SOME BAD CONTENT ----
-- we pass "numtrmlen" to one section below
numtrmlen = string.len(qstrtca) -- can be ZERO
if (numerr==0) then
if ((numtrmlen<contabqc['Q08']) or (numtrmlen>contabqc['Q09'])) then
numerr = 5 -- E05 bad AFTER trim
end--if
end--if
if (numerr==0) then
if (string.find(qstrtca,'(((',1,true) or string.find(qstrtca,')))',1,true) or string.find(qstrtca,'[[[',1,true) or string.find(qstrtca,']]]',1,true)) then
numerr = 6 -- E06 triple
end--if
end--if
---- CHECK FOR SOME MORE BAD CONTENT ----
if (numerr==0) then
do -- scope
local num29index = 1
local num29d20d = 0
local num29char = 0
local num29store = 0
local numcountevil = 0
num29d20d = contabqc['Q20']
while true do
if (num29index>numtrmlen) then
break
end--if
num29char = string.byte(qstrtca,num29index,num29index)
if ((num29char<32) and (num29char~=num29d20d)) then
if (numcountevil==0) then
num29store = num29char -- store code of earliest violator
end--if
numcountevil = numcountevil + 1 -- do NOT abort
end--if
num29index = num29index + 1
end--while
if (numcountevil~=0) then
numerr = 7 -- E07 bad char
str21dd = 'discovered ' .. tostring(numcountevil) .. ' faulty chars, earliest offending code: #' .. tostring(num29store)
end--if
end--do scope
end--if
---- PREBREW ----
strhardcoded = lfhreportqct () -- for all errors
boote2mp = false
numothercol = contabqc['Q60'] -- optional
if (type(numothercol)=='number') then
if (mathisintrange(numothercol,1,10000)) then
strotherkol = 'T81-' .. tostring(numothercol)
boote2mp = true
end--if
end--if
if (not boote2mp) then
numothercol = 0
end--if
---- PARSE THE BIG TEXT TABLE AND FILL SOME LUA TABLES ----
if (numerr==0) then
strprevz = ''
strprevy = '' -- reset for every section
strprevx = '' -- reset for every line
numtrmpos = 0 -- ZERO-based position in the text
numcntsek = 0 -- ZERO-based number of processed sections
numcntlin = 0 -- ZERO-based number of processed lines, index in "tab75enum"
while true do -- loop over all lines
boohave17bb18cc = false -- reset on every iteration
numerr, numtrmpos, numlengthlraw, numlengthtred, strliine = lfigetlinespacered (contabqc['Q20'],contabqc['Q13'],contabqc['Q14'],numtrmpos,numtrmlen)
if (numerr~=0) then -- possible E09 E10 E11 E12
if (numerr==12) then -- E12 bad length of line (restricted by Q13 Q14)
str18cc = lfireportonline ('', numlengthlraw, numlengthtred) -- no text available
end--if
break
end--if
boohave17bb18cc = true -- now we have a line in "strliine"
numminbef = math.min(numminbef,numlengthlraw)
nummaxbef = math.max(nummaxbef,numlengthlraw)
numminaft = math.min(numminaft,numlengthtred)
nummaxaft = math.max(nummaxaft,numlengthtred)
booislast = (numtrmpos>=numtrmlen) -- for sorting and exit
boonotearnorlas = (numcntlin>=2) and (not booislast) -- for sorting only
boolineissection = (string.sub(strliine,1,4)=='### ') and (lfgfindone(strliine,'###')~=-1)
boolineistable = (string.sub(strliine,1,2)=='[[') and (lfgfindone(strliine,'[[')~=-1) and (lfgfindone(strliine,']]')~=-1)
if ((not boolineissection) and (not boolineistable)) then
numerr = 18 -- E18 line not identifiable as a valid type
break -- both false error, both true IMPOSSIBLE
end--if
if (boolineissection and (not contabqc['Q28'])) then
numerr = 19 -- E19 not enabled
break
end--if
if (contabqc['Q36']~='Y4') then
numerr = 79 -- E79 other or internal error -- unsupported
break
end--if
numerr, strlinenm, strmarker = lfistripoffzymarker (strliine,contabqc['Q25'],contabqc['Q26'],boolineissection)
if (numerr~=0) then -- possible E20 E25
break
end--if
numtypmrk = lfivalidatemarker (strmarker) -- 2 digit 1 text 0 invalid
if (boolineissection) then
if (numtypmrk~=1) then -- must be text, digit inherently impossible
numerr = 20 -- E20 structurally faulty section header
break
end--if
if (contabqc['Q30']=='langcode') then
if (not lfivalioadv2str(strmarker,contabqc['Q31'])) then
str21dd = strmarker -- offending code
numerr = 23 -- E23 failed extra vali z-dimension
break
end--if
end--if
else
if (numtypmrk==0) then -- 0 means faulty
numerr = 25 -- E25 structurally faulty y-index marker
break
end--if
if (numtypmrk==2) then -- 2 means digit
numerr = 26 -- E26 unsupp
break
end--if
if (contabqc['Q39']=='langcode') then
if (not lfivalioadv2str(strmarker,contabqc['Q40'])) then
str21dd = strmarker -- offending code
numerr = 29 -- E29 failed extra vali y-dimension
break
end--if
end--if
end--if (boolineissection) else
if (boolineissection) then
if (tabnodupezz[strmarker]) then -- dupe markers prohibited per spec
str21dd = strmarker -- duping string section, no conf key
numerr = 21 -- E21 dupe section
break
end--if
tabnodupezz[strmarker] = true
if (contabqc['Q29']=='S2') then -- "S1" is prohibited for sections
if (strmarker<strprevz) then
numerr = 22 -- E22 sorting violation section header
str21dd = strprevz
str22ee = strmarker
break
end--if
strprevz = strmarker
end--if
else
if (tabnodupey[strmarker]) then -- dupe markers prohibited per spec
str21dd = strmarker -- duping string y-index, no conf key
numerr = 27 -- E27 dupe y-index
break
end--if
tabnodupey[strmarker] = true
if ((strmarker<strprevy) and (boonotearnorlas or (contabqc['Q37']=='S2'))) then
numerr = 28 -- E28 sorting violation y-index marker
str21dd = strprevy
str22ee = strmarker
break
end--if
strprevy = strmarker
end--if (boolineissection) else
if (boolineissection) then
strsectionpref = strmarker -- store prefix for later use
tabnodupey = {} -- reset dupe check for every section
strprevy = '' -- reset sorting check for every section
numcntsek = numcntsek + 1 -- last step
else
if (contabqc['Q28']) then
strmarker = strsectionpref .. '-' .. strmarker -- attach prefix
end--if
end--if (boolineissection) else
if (boolineistable) then -- !!!FIXME!!! enforce sorting use "strprevx" and other sub
numerr, numelementoj, tabsplitu = lfhsplittotable (strlinenm,contabqc['Q21'],contabqc['Q22'],contabqc['Q17'],contabqc['Q18'])
if (numerr~=0) then -- possible E40 E41 E42 E43
if (numerr==42) then -- E42 wrong number of elements
str21dd = 'counted ' .. tostring (numelementoj) .. ' elements'
end--if
break
end--if
numminele = math.min(numminele,numelementoj) -- & only on
nummaxele = math.max(nummaxele,numelementoj) -- & valid lines
tabsplitu = lfhpluprocess (contabqc['Q67'],tabsplitu) -- YES T76 T78 T80 T81, NOT T75 T77
if ((contabqc['Q55']=='D1') or (contabqc['Q55']=='D2')) then
strtymp = tabsplitu[0] -- left-most maybe dupecheck, no sort
if ((contabqc['Q55']=='D2') and (strtymp=='-')) then
numerr = 51 -- E51 illegal placeholder left-most
break
end--if
if (strtymp~='-') then -- exclude placeholder from dupecheck and store
vartimp = tab80lefty[strtymp]
if (vartimp) then
str21dd = strtymp -- duping string
str22ee = vartimp .. ' vs ' .. strmarker -- conflicting keys
numerr = 50 -- E50 dupe left-most
break
end--if
tab80lefty[strtymp] = strmarker -- store for dual purpose
end--if (strtymp~='-') then
end--if
if (numothercol~=0) then -- "Q60" >=1, cannot be left-most again
if ((contabqc['Q61']=='D1') or (contabqc['Q61']=='D2')) then
strtymp = tabsplitu[numothercol] -- other maybe dupecheck, no sort
if ((contabqc['Q61']=='D2') and (strtymp=='-')) then
numerr = 56 -- E56 illegal placeholder other column
break
end--if
if (strtymp~='-') then -- exclude placeholder from dupecheck and store
vartimp = tab81othery[strtymp]
if (vartimp) then
str21dd = strtymp -- duping string
str22ee = vartimp .. ' vs ' .. strmarker -- conflicting keys
numerr = 55 -- E55 dupe other column
break
end--if
tab81othery[strtymp] = strmarker -- store for dual purpose
end--if (strtymp~='-') then
end--if
end--if -- (numothercol~=0) then -- "Q60"
if (contabqc['Q75']) then
tab75enum [numcntlin] = strmarker -- store marker at key/index ZERO-based
end--if
if (contabqc['Q76']) then
tab76yleft [strmarker] = tabsplitu[0] -- store element in left-most
end--if
if (contabqc['Q77']) then
tab77ycomp [strmarker] = strliine -- store line at key/index marker
end--if
if (contabqc['Q78']) then
tab78ysubt [strmarker] = tabsplitu -- store subtable
end--if
numcntlin = numcntlin + 1 -- last step -- NOT reset on new section
end--if (boolineistable) then
if (booislast) then
break
end--if
end--while -- loop over all lines
end--if (numerr==0) then
---- DEAL WITH ERRORS ----
if (numerr==0) then
if ((numcntlin<contabqc['Q15']) or (numcntlin>contabqc['Q16'])) then
numerr = 46 -- E46 bad number of lines
end--if
end--if
if ((numerr==0) and (contabqc['Q80']) and (tab80lefty=={})) then
numerr = 52 -- E52 no prey
end--if
if ((numerr==0) and (contabqc['Q81']) and (tab81othery=={})) then
numerr = 57 -- E57 no prey
end--if
if (numerr~=0) then -- whole line including possible y-index marker
str16aa = '"title" = "' .. constrtarget .. '" -- ' .. strhardcoded -- for all errors
if (boohave17bb18cc) then
str17bb = strliine -- additionally for most errors
str18cc = lfireportonline (strliine, numlengthlraw, numlengthtred)
end--if
end--if
---- RETURN THE JUNK ----
tabtld[2] = numerr
tabtld[3] = numbiglen
tabtld[4] = numtrmlen
tabtld[6] = numtrmpos -- either error posi, or equal "numtrmlen" on success
tabtld[8] = numcntsek
tabtld[9] = numcntlin
tabtld[10] = numminbef
tabtld[11] = nummaxbef
tabtld[12] = numminaft
tabtld[13] = nummaxaft
tabtld[14] = numminele
tabtld[15] = nummaxele
tabtld[16] = str16aa -- empty or whining
tabtld[17] = str17bb -- empty or whining
tabtld[18] = str18cc -- empty or whining
tabtld[21] = str21dd -- empty or whining
tabtld[22] = str22ee -- empty or whining
if (numerr==0) then
if (contabqc['Q75']) then
tabtld['T75'] = tab75enum
end--if
if (contabqc['Q76']) then
tabtld['T76'] = tab76yleft
end--if
if (contabqc['Q77']) then
tabtld['T77'] = tab77ycomp -- NOT pluprocessed, with y-index marker
end--if
if (contabqc['Q78']) then
tabtld['T78'] = tab78ysubt
end--if
if (contabqc['Q80']) then
tabtld['T80'] = tab80lefty
end--if
if (contabqc['Q81']) then
tabtld[strotherkol] = tab81othery -- custom key here
end--if
end--if
return tabtld -- per LUA only allowed data type is "table"