Modulo:TESTTEST
Dokumentado por ĉi tiu modulo povas esti kreata ĉe Modulo:TESTTEST/dokumentado
local piktbllki = {}
local conminwidth = 11 -- safe values 8 ... 1/2 * "maxwidth"
local conmaxwidth = 216 -- safe values 40 ... 40'000 and lower is better
local tbllingvoj = mw.loadData(construsmo) -- can crash here
local constrtbl = "" -- huge table (320 (2 * "maxwidth") ... 1'000'000 chars)
if (tbllingvoj~=nil) then -- seems to be always true
constrtbl = tbllingvoj [1] -- table -> string (with a small risk)
end--if
local function lfdec1digit (num1digit) -- converts 1 digit to decimal
num1digit = num1digit - 48 -- may become invalid
if ((num1digit<0) or (num1digit>9)) then
num1digit = 255
end--if
return num1digit
end--function lfdec1digit
local function lftestlc (numcode) -- tests whether char is lowercase
local boolowerc = true
if ((numcode<97) or (numcode>122)) then
boolowerc = false
end--if
return boolowerc
end--function lftestlc
local function lfrlstrip (strrlinut) -- strips "rl .. lr" if prese & >= 8 Oct
local numsoct = 0
local numsodt = 0
local numsoet = 0
local numsoft = 0
local numsogt = 0
local numsoht = 0
local numlaengd = 0
numlaengd = string.len(strrlinut)
if (numlaengd>=8) then -- at least 2 Octet:s length "rl .. lr" after strip
numsoct = string.byte(strrlinut,1,1)
numsodt = string.byte(strrlinut,2,2)
numsoet = string.byte(strrlinut,3,3)
numsoft = string.byte(strrlinut,(numlaengd-2),(numlaengd-2))
numsogt = string.byte(strrlinut,(numlaengd-1),(numlaengd-1))
numsoht = string.byte(strrlinut,(numlaengd ),(numlaengd ))
if ((numsoct==114) and (numsodt==108) and (numsoet==32) and (numsoft==32) and (numsogt==108) and (numsoht==114)) then
strrlinut = string.sub(strrlinut,4,(numlaengd-3)) -- stri off 3+3 char:s
end--if
end--if
return strrlinut
end--function lfrlstrip
---- MAIN EXPORTED FUNCTION ----
function piktbllki.ek (mwframent)
-- special type "args"
local arxourown = 0 -- metaized "args" from our own "frame" (NOT caller's)
-- general str
local strtmp = "" -- temp for decimal conversion
local striywo = "" -- searched y-index word from mwframent.args[1]
local strret = "" -- output string
-- general num
local numoct = 0 ; -- temp
local numlong = 0 ; -- temp for decimal conversion (length of parameter)
local numinxlen = 0 ; -- length of y-index word f mwframent.args[1] (2 or 3)
local numfoulen = 0 ; -- length of found y-index word (2 or 3)
local numiwo0 = 0 ; -- searched y-index word
local numiwo1 = 0 ; -- searched y-index word
local numiwo2 = 0 ; -- searched y-index word, ZERO if only 2 chars are usd
local numxin = 255 ; -- x-index number f mwframent.args[2] (0...9, 11, 22)
local numtbllen = 0 ; -- length of the huge table seized via "mw.loadData"
local numipos = 0 ; -- octet position in "constrtbl", ZERO-based
local numfndpos = 0 ; -- position of found line with [[...]], ZERO-based
local numbinlow = 0 ; -- lower limit for binary search, ZERO-based position
local numbinhaj = 0 ; -- higher limit for binary search, ZERO-based position
-- general boo
local booerr = true -- overall error flag
local boostrip = false -- flag for stripping rl-enclosement
local booyxfnd = false -- multipurpose found flag
local boospc = false -- flag for whitespace reduction feature
local boouch = false -- flag for found a useful char when skipping element
-- only for built-in function "searchdblchr"
local isubnumlim = 0 -- octets to check (2 * "amount of iterations")
local isubnumchr = 0 -- char to search (91 for "[[" or 40 for "((")
local isubboodwn = false -- "true" for downward search
local osubboofnd = false -- "true" if the dblchar was found
-- only for built-in function "cmp2or3wordeq"
local osubbooequal = false -- "true" if found idx word equal to "numiwo"
-- only for built-in function "cmp2or3wordbi"
local osubboobiger = false -- "true" if found idx word bigger than "numiwo"
---- BUILT-IN GOSUB-STYLE FUNCTION "SEARCHDBLCHR" ----
-- PURPOSE: searches for a dblchar (91 for "[[" or 40 for "((")
-- upwards or downwards
-- IN : isubnumlim, isubnumchr, isubboodwn (unchanged)
-- OUT : osubboofnd (not in)
-- USE : constrtbl (acts as a constant in the module)
-- CHG : numipos (in and out)
-- NOTE: if "isubboodwn" is "false" then we run upwards and check
-- upwards, thus with incoming position "numipos"=10 we start checking
-- at positions 11,(12,10), with incoming "isubnumlim"=10 we will no
-- longer check positions 23,(24,22) but will check 21,(22,20) ... we
-- need 3 chars margin at the top of range
-- NOTE: if "isubboodwn" is "true" then we run downwards but still check
-- upwards, thus with incoming position "numipos"=10 we start checking
-- at positions 11,(12,10), with incoming "isubnumlim"=10 we will no
-- longer check positions -01,(00,-02) but will check 01,(02,00) ... we
-- need 3 chars margin at the top of range
-- NOTE: we are supposed to safely ignore single occurrences (ie continue
-- searching), as opposed to that triple and longer
-- occurrences are prohibited
local searchdblchr = function ()
osubboofnd = true -- pre-assume that we will find our dblchr
local usubnumsrch = 0 -- search position checker counting always up
local numokkt = 0 -- single char (giving a f**k in UTF8)
local usubnumincr = 2 -- "+2" or "-2"
if (isubboodwn==true) then
usubnumincr = -2
end--if
while (true) do -- iterate through octets searching for dblchr (up or dwn)
if (usubnumsrch>isubnumlim) then
osubboofnd = false ; -- give up, tabl broken, "numipos" irrelevant now
break ;
end--if
numokkt = string.byte (constrtbl,(numipos+2),(numipos+2)) ; -- "+1" actual
if (numokkt==isubnumchr) then
numokkt = string.byte (constrtbl,(numipos+3),(numipos+3)) ; -- "+2" above
if (numokkt==isubnumchr) then
numipos = numipos + 1 ;
break ; -- found and "numipos" valid ... otherwise try to look blw
end--if
numokkt = string.byte (constrtbl,(numipos),(numipos)) ; -- "ZERO" blw
if (numokkt==isubnumchr) then
break ; -- found and "numipos" valid ... otherwise continue search
end--if
end--if
usubnumsrch = usubnumsrch + 2 ;
numipos = numipos + usubnumincr ; -- "+2" or "-2"
end--while
end--function searchdblchr
---- BUILT-IN GOSUB-STYLE FUNCTION "CHK2OR3LIM" ----
-- PURPOSE: performs a wild guess whether the found y-index word
-- has 2 letters or 3 letters, lacks thorough checks,
-- result will be ZERO if we would hit the limit
-- IN : numipos, numtbllen
-- OUT : N/A
-- USE : constrtbl (acts as a constant in the module)
-- CHG : numfoulen (in and out)
local chk2or3lim = function ()
local usubnum1ch = 0 -- single char
if ((numipos+6)>=numtbllen) then
numfoulen = 0 -- peek +4 only but need 6 for [[aa]] or 7 for [[aaa]]
else
usubnum1ch = string.byte (constrtbl,(numipos+5),(numipos+5)) -- "+4" act
if (lftestlc(usubnum1ch)==true) then
numfoulen = 3
else
numfoulen = 2
end--if
end--if
end--function chk2or3lim
---- BUILT-IN GOSUB-STYLE FUNCTION "CMP2OR3WORDEQ" ----
-- PURPOSE: performs a comparison of 2 or 3 char:s testing for equality only
-- IN : numipos, numinxlen, numfoulen
-- OUT : osubbooequal ("true" if equal)
-- USE : constrtbl, numiwo (acts as a constant in the module)
-- CHG : N/A (in and out)
-- NOTE: it is the caller's responsibility to ensure
-- that "numinxlen" and "numfoulen" are 2 or 3 !!!
-- NOTE: it is the caller's responsibility to ensure
-- that we don't hit the limit here in
local cmp2or3wordeq = function ()
osubbooequal = true -- pre-assume found, likely abort after 1 or 2 compa
if (numinxlen~=numfoulen) then
osubbooequal = false ; -- NOT found
else
if ((string.byte (constrtbl,numipos+3,numipos+3)) ~= numiwo0) then
osubbooequal = false ; -- NOT found
else
if ((string.byte (constrtbl,numipos+4,numipos+4)) ~= numiwo1) then
osubbooequal = false ; -- NOT found
else
if (numinxlen==3) then
if ((string.byte (constrtbl,numipos+5,numipos+5)) ~= numiwo2) then
osubbooequal = false ; -- NOT found
end--if
end--if
end--if
end--if
end--if
end--function cmp2or3wordeq
---- BUILT-IN GOSUB-STYLE FUNCTION "CMP2OR3WORDBI" ----
-- PURPOSE: performs a comparison of 2 or 3 char:s testing for "bigger"
-- IN : numipos, numinxlen, numfoulen, numiwo
-- OUT : osubboobiger ("true" if found index word is bigger than "numiwo")
-- USE : constrtbl (acts as a constant in the module)
-- CHG : N/A
-- NOTE: it is the caller's responsibility to ensure
-- that "numinxlen" and "numfoulen" are 2 or 3 !!!
-- NOTE: it is the caller's responsibility to ensure
-- that we don't hit the limit here in
-- NOTE: the 2 strings are expected not to be equal on entry here,
-- but single letters may be, thus ("grc" and "grc") is impossible,
-- but ("grc" and "gro") or ("grc" and "gr") can occur, actually,
-- the code here itself tests for "bigger" vs "smaller or equal"
local cmp2or3wordbi = function ()
local usubnum1char = 0 ; -- single char
osubboobiger = false ; -- pre-assume smaller or equal, likely abort soon
usubnum1char = (string.byte (constrtbl,numipos+3,numipos+3)) ;
if (usubnum1char>numiwo0) then
osubboobiger = true ; -- bigger
else
if (usubnum1char==numiwo0) then
usubnum1char = (string.byte (constrtbl,numipos+4,numipos+4)) ;
if (usubnum1char>numiwo1) then
osubboobiger = true ; -- bigger
else
if ((usubnum1char==numiwo1) and ((numinxlen+numfoulen)>=4)) then
if (numfoulen>numinxlen) then
osubboobiger = true -- (3:2 - found:previous) and bigger
else
if (numfoulen==3) then
usubnum1char = (string.byte (constrtbl,numipos+5,numipos+5))
else
usubnum1char = 0
end--if
if (usubnum1char > numiwo2) then
osubboobiger = true -- bigger
end--if
end--if
end--if
end--if (usubnum1char>numiwo1) else
end--if
end--if
end--function cmp2or3wordbi
---- CHECK THE HUGE TABLE ----
if (type(constrtbl)=="string") then -- important check
numtbllen = string.len (constrtbl) ;
if ((numtbllen>=(2*conmaxwidth)) and (numtbllen<=800000)) then
booerr = false ; -- was preset to true
end--if
end--if
---- SEIZE 2 OBLIGATORY ARGUMENTS FROM THE CALLER (1 MORE IS OPTIONAL) ----
arxourown = mwframent.args -- "args" from our own "frame"
if ((arxourown[1]==nil) or (arxourown[2]==nil)) then
booerr = true
end--if
if (booerr==false) then
striywo = arxourown[1] -- y-index word (2 or 3 lowercase chars)
numinxlen = string.len (striywo) ;
if ((numinxlen<2) or (numinxlen>3)) then
booerr = true
else
numiwo0 = string.byte (striywo,1,1)
if (lftestlc(numiwo0)==false) then
booerr = true
end--if
numiwo1 = string.byte (striywo,2,2)
if (lftestlc(numiwo1)==false) then
booerr = true
end--if
if (numinxlen==3) then
numiwo2 = string.byte (striywo,3,3)
if (lftestlc(numiwo2)==false) then
booerr = true
end--if
end--if
end--if
end--if
if (booerr==false) then
strtmp = arxourown[2] -- x-index number (1 digit, 0...9, ZERO-based)
numlong = string.len (strtmp) -- temp for decimal conversion
if (numlong==1) then
numxin = string.byte (strtmp,1,1)
if (numxin==43) then
numxin = 11 -- special "+" (complete) special value 11
else
if (numxin==45) then
numxin = 22 -- special "-" (binary) special value 22
else
numxin = lfdec1digit (numxin) -- 255 if invalid
end--if
end--if
end--if
if (numxin==255) then
booerr = true -- damn: no valid x-index number
end--if
end--if
if (booerr==false) then
if (type(arxourown[3])=="string") then
strtmp = arxourown[3] -- optional "0" or "1"
numlong = string.len (strtmp) -- temp
if (numlong==1) then
numoct = string.byte (strtmp,1,1)
if (numoct==49) then
boostrip = true -- was preset to false
end--if
if ((numoct~=48) and (numoct~=49)) then
booerr = true -- damn
end--if
else
booerr = true -- damn
end--if
end--if (type(arxourown[3])=="string") then
end--if
---- PRESET ----
booyxfnd = false ; -- set to "true" as soon as specified y-index word found
---- SEARCH FOR THE TABLE BEGIN AKA THE 0TH Y-INDEX WORD ----
-- will succeed if we find "[[" within "maxwidth"
-- note that minimum table size guaranteed from above
-- is (2 * "maxwidth") but the table may contain much padding
-- and shrink considerably after padding is trimmed off
if (booerr==false) then
numipos = 0 -- ZERO-based position in "constrtbl"
isubnumlim = conmaxwidth -- do NOT subtract here
isubnumchr = 91 -- search for "[" ie "[["
isubboodwn = false
searchdblchr () -- OUT : osubboofnd | USE : constrtbl | CHG : numipos
if (osubboofnd==false) then
booerr = true -- give up, table is broken, "numipos" irrelevant now
end--if
end--if
-- now ZERO-based "numipos" maybe points to the found "[["
---- COMPARE THE 0TH Y-INDEX WORD ----
if (booerr==false) then
chk2or3lim () -- IN: numipos, numtbllen | USE: constrtbl | CHG: numfoulen
if (numfoulen==0) then
booerr = true -- barely can occur
else
cmp2or3wordeq () ; -- OUT: osubbooequal | USE: constrtbl, numiwo
if (osubbooequal==true) then
numfndpos = numipos ;
booyxfnd = true ; -- found the y-index word !!!
else
numbinlow = numipos ; -- points to found "[[", will need this later
end--if
end--if
end--if
-- now ZERO-based "numfndpos" maybe points to the found "[[...]]"
-- now "numipos" is irrelevant
---- SEARCH FOR THE LAST Y-INDEX WORD ----
-- will succeed if we find "[[" within "maxwidth"
-- if we have only one line then found last index word will
-- be the same as the found 0th index word
if ((booerr==false) and (booyxfnd==false)) then
numipos = numtbllen - conminwidth -- ZERO-based positi in "constrtbl"
isubnumlim = 2 * conmaxwidth - conminwidth -- allow full "maxwidth" of garb
isubnumchr = 91 -- search for "[" ie "[["
isubboodwn = true -- downwards
searchdblchr () -- OUT : osubboofnd | USE : constrtbl | CHG : numipos
if (osubboofnd==false) then
booerr = true -- give up, table is broken, "numipos" irrelevant now
end--if
end--if
-- now ZERO-based "numipos" maybe points to the found "[["
---- COMPARE THE LAST Y-INDEX WORD ----
if ((booerr==false) and (booyxfnd==false)) then
chk2or3lim () -- IN: numipos, numtbllen | USE: constrtbl | CHG: numfoulen
if (numfoulen==0) then
booerr = true -- barely can occur
else
cmp2or3wordeq () ; -- OUT: osubbooequal | USE: constrtbl, numiwo
if (osubbooequal==true) then
numfndpos = numipos ;
booyxfnd = true ; -- found the y-index word !!!
else
numbinhaj = numipos ; -- points to found "[[", will need this later
end--if
end--if
end--if
-- now ZERO-based "numfndpos" maybe points to the found "[[...]]"
-- now "numipos" is irrelevant
---- PERFORM THE BINARY SEARCH ----
-- ZERO-based "numbinlow" and "numbinhaj" always point to begi of "[[...]]"
-- note that here SUB "searchdblchr" can fail with "osubboofnd==false"
-- if the table exceeds "maxwidth", this is an error
-- the other risk with SUB "searchdblchr" is that could hit "numbinhaj"
-- and find the "[[" there, this is highly undesirable as this would
-- cause a subsequent invalid comparison with random result, we prevent
-- this by aborting the binary search at this point
if ((booerr==false) and (booyxfnd==false)) then
while (true) do -- reduce size by halving until it becomes too small
numipos = math.floor ((numbinlow + numbinhaj) / 2) -- ZERO-based positi
if ((numipos+conmaxwidth+conminwidth)>numbinhaj) then
break -- NOT found, continue with desperate last step linear search
end--if
isubnumlim = conmaxwidth -- do NOT subtract here
isubnumchr = 91 -- search for "[" ie "[["
isubboodwn = false -- upwards
searchdblchr () -- OUT : osubboofnd | USE : constrtbl | CHG : numipos
if (osubboofnd==false) then
booerr = true
break ; -- give up, not found or table brokn, "numipos" irrelevant now
end--if
chk2or3lim () ; -- IN: numipos, numtbllen | USE: constrtbl | CHG: numfoulen
cmp2or3wordeq () ; -- OUT: osubbooequal | USE: constrtbl, numiwo
if (osubbooequal==true) then
numfndpos = numipos ;
booyxfnd = true ;
break ; -- found the y-index word !!!
end--if
cmp2or3wordbi () -- OUT: osubboobiger | USE: constrtbl, numiwo
if (osubboobiger==true) then -- "true" if found y-index word > "numiwo"
numbinhaj = numipos -- was too high, check below, reduce "numbinhaj"
else
numbinlow = numipos -- was too low, check above, increas "numbinlow"
end--if
end--while
end--if
-- below look at "booerr", then at "booyxfnd",
-- then at "numfndpos" or ("binlow" and "binhaj")
---- PERFORM THE DESPERATE LAST STEP LINEAR SEARCH ----
-- search through range "binlow" to "binhaj", this can be more than
-- "maxwidth" (almost double size in worst case)
-- there definitely is "[[" at both "binlow" and "binhaj" and there can
-- be ZERO, ONE or several further "[[" in the range
-- so we indeed subtract "minwidth" from the range size two times
if ((booerr==false) and (booyxfnd==false)) then
numipos = numbinlow ;
while (true) do -- there can be several lines left
numipos = numipos + conminwidth ;
isubnumlim = numbinhaj - numipos - conminwidth ; -- is "[[" at "binhaj"
if (isubnumlim<conminwidth) then
booerr = true
break ; -- give up, not found or table brokn, "numipos" irrelevant now
end--if
isubnumchr = 91 -- search for "[" ie "[["
isubboodwn = false -- upwards
searchdblchr () -- OUT : osubboofnd | USE : constrtbl | CHG : numipos
if (osubboofnd==false) then
booerr = true
break ; -- give up, not found or table brokn, "numipos" irrelevant now
end--if
chk2or3lim () ; -- IN: numipos, numtbllen | USE: constrtbl | CHG: numfoulen
cmp2or3wordeq () ; -- OUT: osubbooequal | USE: constrtbl, numiwo
if (osubbooequal==true) then
numfndpos = numipos ;
break ; -- found the y-index word but "booyxfnd" not needed anymore !!
end--if
end--while
end--if
-- below not look at "booyxfnd", look at "booerr" only and maybe "numfndpos"
---- RETURN ONE ELEMENT PICKED ACCORDING TO X-INDEX NUMBER IF 0...9 ----
-- This is done in 3 + 1 steps:
-- * skip possible unsuitable elements
-- * skip possible whitespace preceding the searched element
-- * copy the searched element (takes a char from previous step)
-- * strip off rl-enclosement if requested (boostrip=true) and present
-- this is a copy of module "mpiksubstrind" with minimal modifications
if ((booerr==false) and (numxin<10)) then
booxyfnd = false
numipos = numfndpos + 4 + numinxlen ; -- ZERO-based index in "constrtbl"
numite = numxin -- count down
while (true) do -- iterate through elements in order to skip them
if (numite==0) then -- nothing to skip anymore
booxyfnd = true ;
break ; -- exit the outer loop, nothing to skip anymore
end--if
numite = numite - 1
booxyfnd = false
boouch = false
while (true) do -- iterate through whspc & chars mix looking for comma
if (numipos>=numtbllen) then
break ; -- exit the inner loop, NOT found, give up
end--if
numipos = numipos + 1 ;
numoct = string.byte (constrtbl,numipos,numipos) ;
if ((numoct<32) and (numoct~=9)) then
break -- EOL: exit the inner loop, NOT found, give up
end--if
if ((numoct>32) and (numoct~=44)) then
boouch = true ; -- found a valid char (empty field is an error)
end--if
if (numoct==44) then
if (boouch==true) then
booxyfnd = true ; -- field was not empty
end--if
break ; -- exit the inner loop, found a comma, this is good or bad
end--if
end--while
if (booxyfnd==false) then
break -- exit the outer loop, NOT found or empty field, give up
end--if
end--while
if (booxyfnd==true) then
booxyfnd = false ;
while (true) do -- iterate through chars skipping whitespace
if (numipos>=numtbllen) then
break ; -- exit the loop, NOT found, give up
end--if
numipos = numipos + 1 ;
numoct = string.byte (constrtbl,numipos,numipos)
if ((numoct<32) and (numoct~=9)) then
break -- EOL: exit the loop, NOT found, give up
end--if
if (numoct>32) then
if (numoct==44) then
break ; -- exit loop, found comma, give up according to rules
end--if
booxyfnd = true ;
break ; -- exit the loop, found valid char, start copying now
end--if
end--while
end--if
if (booxyfnd==true) then
while (true) do -- iterate through chars copying the found element
if ((numoct==32) or (numoct==9)) then
boospc=true
else
if (boospc==true) then
strret = strret .. " " -- was preset to empty
boospc = false ;
end--if
strret = strret .. string.char (numoct) ;
end--if
if (numipos>=numtbllen) then
break ; -- exit the loop, done
end--if
numipos = numipos + 1 ;
numoct = string.byte (constrtbl,numipos,numipos) ;
if ((numoct<32) and (numoct~=9)) then
break ; -- EOL: exit the loop, done
end--if
if (numoct==44) then
break -- comma: exit the loop, done
end--if
end--while
end--if
if (booxyfnd==false) then
booerr = true -- damn: failed in the x-search
end--if
end--if
-- strip off rl-enclosement if requested (boostrip=true) and present
if ((booerr==false) and (numxin<10) and (boostrip==true)) then
strret = lfrlstrip (strret)
end--if
---- RETURN COMPLETE LINE IF SPECIAL "+" AKA 11 ----
-- we do reduce excessive whitespace
if ((booerr==false) and (numxin==11)) then
boospc = false ;
numipos = 0 -- limit width again
while (true) do -- iterate through chars copying the found line
if (numipos>=conmaxwidth) then
booerr = true
break -- damn: violated "maxwidth"
end--if
numoct = string.byte (constrtbl,(numfndpos+1),(numfndpos+1)) ;
if ((numoct<32) and (numoct~=9)) then
break -- done (anything < 32 other than TAB counts as EOL)
end--if
if ((numoct==32) or (numoct==9)) then
boospc=true
else
if (boospc==true) then
strret = strret .. " " -- was preset to empty
boospc = false
end--if
strret = strret .. string.char (numoct) -- was preset to empty
end--if
numipos = numipos + 1
numfndpos = numfndpos + 1
end--while
end--if
---- CARE ABOUT ERRORS ----
if (booerr==true) then
strret = "=" -- was preset to empty -- not final or valid for "-" AKA 22
end--if
---- RETURN BINARY DIGIT IF SPECIAL "-" AKA 22 ----
if (numxin==22) then
if (booerr==true) then
strret = "0" -- y-index word NOT found or error
else
strret = "1" -- y-index word found
end--if
end--if
return strret
end
return piktbllki