Modulo:mrooteo
Salti al navigilo
Salti al serĉilo
![]() | ||
Memtesto disponeblas sur la paĝo Ŝablono:kat-elemento-eo. |
- dependas de
{{radikoj}}
- ĉi tiu modulo efektivigas laboron de ŝablono
{{kat-elemento-eo}}
- aldone vokata far
((mfarado))
--[===[
MODULE "MROOTEO" (root eo ie Esperanto root)
"eo.wiktionary.org/wiki/Modulo:mrooteo" <!--2023-Jan-24-->
Purpose: describes and categorizes an Esperanto morpheme according to a
list stored in a separate template, to be used on category pages
Utilo: priskribas kaj kategoriigas esperantan morfemon laux
listo konservita en aparta sxablono, uzinda sur kategoriaj pagxoj
Manfaat: ...
Syfte: beskriver och kategoriserar morfem paa esperanto ...
Used by templates / Uzata far sxablonoj:
- "kat-elemento-eo"
Used by modules:
- "mfarado"
Required submodules / Bezonataj submoduloj:
- none / neniuj
Required templates:
- "SXablono:radikoj"
Incoming: * named obligatory "in=" one of 3 types:
* bare root (I: -il-, M: nul, N: mov, P: fi-, U: -j) only lowercase !!!FIXME!!! NOT yet
ASCII plus 6 lowercase -eo- letters, identified by NOT
containing any space
* new-style pagename "Vorto -eo- enhavanta morfemon N (kapt)"
identified by containing at least one space and last character
being a bracket ")"
* legacy-style pagename, identified by containing at least one
space and last character NOT being a bracket ")"
colons ":" and underscores "_" prohibited in order to prevent
things like "Kategorio:Radiko arb'" (fullpagename) or
"Radiko_arb'" (URL-style)
* named optional "vs=" word class "o" "a" "i" one or two letters !!!FIXME!!! NOT yet
* 1 special parameter
"givetable=" value "true" if called from a module
* 2 hidden parameters
* "nocat=" no error possible
* "detrc=" no error possible
Pagename is never accessed, since this module is intended to be
called from other module at the end, rather than from a template.
For same reason there is no point to peek the caller's frame. No
anonymous parameters are tolerated. !!!FIXME!!! not yet checked
Reads template "SXablono:radikoj":
* empty lines skipped
* length of a nonempty line 2 ... 100'000 octet:s !!!FIXME!!! NOT yet checked
* nonempty lines must alternate level-2 wiki headings with root lists
* leading spaces, trailing spaces and multiple spaces are prohibited
* headings
* 7 ... 200 octet:s !!!FIXME!!! NOT yet checked
* headings must be formed like "== " ... " ==" with exactly ONE
separation space at every side
* legal char:s in headings: !!!FIXME!!! NOT yet checked
* dash "-"
* 10 ASCII numbers
* 26 ASCII UPPERCase
* 26 ASCII lowercase
* 6 -eo- UPPERCase
* 6 -eo- lowercase
* sorting of the headings is not required but dupes are prohibited
* root lists
* 2 ... 100'000 octet:s (checked already before)
* root lists contain a list of roots, all in one line, separated by spaces
* legal char:s in root lists: !!!FIXME!!! NOT yet checked
* dash "-" earliest or last in a root only
* 26 ASCII lowercase
* 6 -eo- lowercase
* sorting of the roots is not required but dupes are prohibited
Strategy:
* identify the type of incoming root from "in=" by dashes and a constant
table with nonstandalone roots !!!FIXME!!! NOT yet
* read the template and convert the raw text block into single non-empty
lines (at least 2 char:s, prohibit leading and trailing spaces) in a table
* we have more 3 tables (besides the one for lines), one for all headings,
one for hits by headings, and one for roots collected from a line
* every new heading is added into the table for all headings with
the stripped heading being the key/index, and value always "true"
avoiding dupes that way
* every new heading is also temporarily stored in a string
* walk through the roots putting them all into a table (emptied at the
beginning of the line) with the root being the key/index, and value
always "true" avoiding dupes that way, if the root from the list is equal
the incoming root, then store the heading into the table for hits by
headings, still do NOT abort search at a hit
* for categories translate the found headings into names by means of
a constant table, pass unchanged if no translation found
* add an extra category based on the number of hits ZERO or non-ZERO
Error codes:
* #E01 internal
* #E02 "in=" bad (wrong length, or contains colon or underscore)
* #E03 "in=" bad (later type identification failed)
* #E04 template obviously bad (not found or empty or quasi-empty)
* #E05 empty or bad line (too short (<2) or leading or trailing space
or double space)
* #E06 number of lines bad (must be even and at least 2)
* #E07 overall pattern bad (alternating lines required)
* #E09 heading bad (too short or bad equal signs or bad char)
* #E10 dupe heading
* #E11 root list bad char (other than eo lowercase)
* #E12 root list illegal use of "-" (root equals "-", two consecutive
dashes, dash in other position than earliest and last)
* #E14 dupe root in one line (2 details follow)
]===]
local exporttable = {}
------------------------------------------------------------------------
---- CONSTANTS [O] ----
------------------------------------------------------------------------
local constrtemplate = string.char(0xC5,0x9C) .. "ablono:radikoj"
local contabvisi = {}
contabvisi [0] = 'La elemento "'
contabvisi [1] = '" (tipo ' -- needs terminating ") "
contabvisi [2] = 'troveblas en '
contabvisi [3] = 'ne troveblas en iu listo kaj do estas neoficiala' -- NO dot at end
local contabcats = {}
contabcats [0] = "Ne-AV-elemento" -- ZERO hits
contabcats [1] = "AV-elemento" -- non-ZERO hits
contabcats ['OA0'] = "Fundamenta elemento"
contabcats ['OA1'] = "Elemento de la 1-a Oficiala Aldono"
contabcats ['OA2'] = "Elemento de la 2-a Oficiala Aldono"
contabcats ['OA3'] = "Elemento de la 3-a Oficiala Aldono"
contabcats ['OA4'] = "Elemento de la 4-a Oficiala Aldono"
contabcats ['OA5'] = "Elemento de la 5-a Oficiala Aldono"
contabcats ['OA6'] = "Elemento de la 6-a Oficiala Aldono"
contabcats ['OA7'] = "Elemento de la 7-a Oficiala Aldono"
contabcats ['OA8'] = "Elemento de la 8-a Oficiala Aldono"
contabcats ['OA9'] = "Elemento de la 9-a Oficiala Aldono"
------------------------------------------------------------------------
---- SPECIAL STUFF OUTSIDE MAIN [B] ----
------------------------------------------------------------------------
-- SPECIAL VAR:S
local qboodetrc = true -- from "detrc=true" but default is "true" !!!
local qstrtrace = '<br>' -- for main & sub:s, debug report request by "detrc="
------------------------------------------------------------------------
---- DEBUG FUNCTIONS [D] ----
------------------------------------------------------------------------
-- Local function LFTRACEMSG
-- Enhance upvalue "qstrtrace".
-- for variables the other sub "lfshowvar" is preferable but in exceptional
-- cases it can be justified to send text with values of variables to this sub
-- no size limit, use this one also to import detrc text from submodule
-- upvalue "qstrtrace" must NOT be type "nil" on entry (is inited to "<br>")
-- uses upvalue "qboodetrc"
local function lftracemsg (strshortlineorbigtext)
local strseparator = ''
if (qboodetrc and (type(strshortlineorbigtext)=='string')) then
if (string.find(strshortlineorbigtext,'<br>',1,true)) then
strseparator = '<br> ######################<br>'
qstrtrace = qstrtrace .. strseparator .. strshortlineorbigtext .. strseparator .. '<br>'
else
qstrtrace = qstrtrace .. strshortlineorbigtext .. '.<br>' -- dot added !!!
end--if
end--if
end--function lftracemsg
------------------------------------------------------------------------
-- Local function LFDMINISANI
-- Input : * strdangerous -- must be type "string", empty legal
-- Output : * strsanitized -- can happen to be quasi-empty with <<"">>
-- Disallow: cross "#" 35 | apo "'" 39 | "<" 60 | ">" 62 | "[" 91 | "]" 93
-- To be called from "lfdshowvcore" <- "lfshowvar" only.
local function lfdminisani (strdangerous)
local strsanitized = '"' -- begin quot
local numlecnx = 0
local numindabx = 1 -- ONE-based
local numsigno = 0
numlecnx = string.len (strdangerous)
while true do
if (numindabx>numlecnx) then
break -- done string char after char
end--if
numsigno = string.byte (strdangerous,numindabx,numindabx)
if ((numsigno<36) or (numsigno==39) or (numsigno==42) or (numsigno==58) or (numsigno==60) or (numsigno==62) or (numsigno==91) or (numsigno==93) or (numsigno>122)) then
strsanitized = strsanitized .. '{' .. tostring (numsigno) .. '}'
else
strsanitized = strsanitized .. string.char (numsigno)
end--if
if ((numlecnx>50) and (numindabx==20)) then
numindabx = numlecnx - 20 -- jump
strsanitized = strsanitized .. '" ... "'
else
numindabx = numindabx + 1
end--if
end--while
strsanitized = strsanitized .. '"' -- don't forget final quot
return strsanitized
end--function lfdminisani
------------------------------------------------------------------------
-- Local function LFDSHOWVCORE
-- Prebrew report about content of a variable (including optional full
-- listing of a table with integer indexes starting from ZERO). !!!FIXME!!!
-- Input : * vardubious -- content (any type including "nil")
-- * strname -- name of the variable (string)
-- * vardescri -- optional, defa empty
-- * vartablim -- optional, defa 0
-- Depends on functions :
-- [D] lfdminisani
local function lfdshowvcore (vardubious, strname, vardescri, vartablim)
local strtype = ''
local strreport = ''
local numindax = 0
local numlencx = 0
local numkeynumber = 0
local numkeycetera = 0
if (type(vartablim)~='number') then
vartablim = 0 -- deactivate listing of a table
end--if
if (type(vardescri)~='string') then
vardescri = '' -- omit comment
else
vardescri = ' (' .. vardescri .. ')' -- augment only if used !!!
end--if
if (type(strname)~='string') then -- this must be below "type(vardescri)"
strname = '??' -- bite the bullet
else
strname = '"' .. strname .. '"' .. vardescri -- combo
end--if
strtype = type(vardubious)
if (strtype=='table') then
for k,v in pairs(vardubious) do
if (type(k)=='number') then
numkeynumber = numkeynumber + 1
else
numkeycetera = numkeycetera + 1
end--if
end--for
strreport = 'Table ' .. strname .. ' contains ' .. tostring (numkeynumber)
strreport = strreport .. ' numeric keys and ' .. tostring (numkeycetera)
strreport = strreport .. ' other keys'
if ((numkeynumber~=0) and (vartablim~=0)) then -- !!!FIXME!!!
strreport = strreport .. ', content :'
numindax = 0
while true do
if (numindax>vartablim) then
break -- done table
end--if
strreport = strreport .. ' ' .. tostring (numindax) .. ' -> ' .. lfdminisani (tostring (vardubious[numindax]) )
numindax = numindax + 1
end--while
end--if
else
strreport = 'Variable ' .. strname .. ' has type "' .. strtype .. '"'
if (strtype=='string') then
numlencx = string.len (vardubious)
strreport = strreport .. ' and length ' .. tostring (numlencx)
if (numlencx~=0) then
strreport = strreport .. ' and content ' .. lfdminisani (vardubious)
end--if
else
if (strtype~='nil') then
strreport = strreport .. ' and content "' .. tostring (vardubious) .. '"'
end--if
end--if
end--if (strtype=='table') else
return strreport
end--function lfdshowvcore
------------------------------------------------------------------------
-- Local function LFSHOWVAR
-- Enhance upvalue "qstrtrace" with report about content of a variable
-- (including optional full listing of a table with integer indexes
-- starting from ZERO). !!!FIXME!!!
-- Depends on functions :
-- [D] lfdminisani lfdshowvcore
-- upvalue "qstrtrace" must NOT be type "nil" on entry (is inited to "<br>")
-- uses upvalue "qboodetrc"
local function lfshowvar (varduubious, strnaame, vardeskkri, vartabljjm)
if (qboodetrc) then
qstrtrace = qstrtrace .. lfdshowvcore (varduubious, strnaame, vardeskkri, vartabljjm) .. '.<br>' -- dot added !!!
end--if
end--function lfshowvar
------------------------------------------------------------------------
---- MATH FUNCTIONS [E] ----
------------------------------------------------------------------------
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
------------------------------------------------------------------------
---- UTF8 FUNCTIONS [U] ----
------------------------------------------------------------------------
-- Local function LFUTRISTLETR
-- Evaluate letter (ASCII + selectable set) to nope vs upper vs lower.
-- Input : * strsinleutf : single unicode letter (1 or 2 octet:s)
-- * numselkset : 0 ASCII -- 2 eo -- 5 sv (value 255 NOT here)
-- Output : * numtypex : 0 no letter or invalid UTF8 -- 1 upper -- 2 lower
-- Depends on functions :
-- [U] lfulnutf8char
-- [G] lftestuc lftestlc
-- [E] mathdiv mathmod mathbitwrit
-- Defined sets:
-- 2: 2 x 6 uppercase and lowercase -eo- (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
-- 5: 2 x 4 uppercase and lowercase -sv- (AA AE OE EE aa ae oe ee)
-- upper AE $00C4 AA $00C5 EE $00C9 OE $00D6 lower +$20
local function lfutristletr (strsinleutf, numselkset)
local numtypex = 0 -- preASSume invalid
local numlaangdn = 0 -- length of input
local numchuerr = 0 -- UINT8 beginning char
local numchuess = 0 -- UINT8 later char (BIG ENDIAN, lower value here up)
local numchureel = 0 -- UINT8 code relative to beginning of block $00...$FF
local numthemmp = 0
local booyysuppr = false
local booyyslowr = false
while true do -- fake loop
numlaangdn = string.len (strsinleutf)
if ((numlaangdn<1) or (numlaangdn>2)) then -- only 1 or 2 accepted
break -- bad string length
end--if
numchuerr = string.byte (strsinleutf,1,1)
if ((lfulnutf8char(numchuerr))~=numlaangdn) then
break -- mismatch with length
end--if
if (numlaangdn==1) then
booyysuppr = lftestuc(numchuerr)
booyyslowr = lftestlc(numchuerr)
break -- success with ASCII, almost done
end--if
numchuess = string.byte (strsinleutf,2,2) -- only $80 to $BF
numchureel = (mathmod(numchuerr,4)*64) + (numchuess-128) -- 4 times 64
if ((numselkset==2) and ((numchuerr==196) or (numchuerr==197))) then -- eo
numthemmp = mathbitwrit (numchureel,0,false) -- bad way to do AND $FE
if ((numthemmp==8) or (numthemmp==28) or (numthemmp==36) or (numthemmp==52) or (numthemmp==92) or (numthemmp==108)) then
booyysuppr = (numthemmp==numchureel) -- UC below and even
booyyslowr = not booyysuppr
break -- success with -eo-, almost done
end--if
end--if ((numselkset==2) and ...
if ((numselkset==5) and (numchuerr==195)) then -- sv
numthemmp = mathbitwrit (numchureel,5,false) -- bad way to do AND $DF
if ((numthemmp==196) or (numthemmp==197) or (numthemmp==201) or (numthemmp==214)) then
booyysuppr = (numthemmp==numchureel) -- UC below and bit is ZERO
booyyslowr = not booyysuppr
break -- success with -sv-, almost done
end--if
end--if ((numselkset==5) and ...
break -- finally to join mark -- unknown non-ASCII char is a fact :-(
end--while -- fake loop -- join mark
if (booyysuppr) then
numtypex = 1
end--if
if (booyyslowr) then
numtypex = 2
end--if
return numtypex
end--function lfutristletr
------------------------------------------------------------------------
---- HIGH LEVEL STRING FUNCTIONS [I] ----
------------------------------------------------------------------------
-- Local function LFIDEBRACKET
-- Separate bracketed part of a string and return the inner or outer
-- part. On failure the string is returned complete and unchanged.
-- There must be exactly ONE "(" and exactly ONE ")" in correct order.
-- Input : * numxminlencz -- minimal length of inner part, must be >= 1 !!!
-- Note that for length of hit ZERO ie "()" we 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" or "crap " (note the trailing space)
-- Example: "(XX) YES" -> len = 8
-- 12345678
-- "begg" = 1 and "endd" = 4
-- Expected result: "XX" or " YES" (note the leading space)
local function lfidebracket (strdeath, boooutside, numxminlencz)
local numindoux = 1 -- ONE-based
local numdlong = 0
local numwesel = 0
local numbegg = 0 -- ONE-based, ZERO invalid
local numendd = 0 -- ONE-based, ZERO invalid
numdlong = string.len (strdeath)
while true do
if (numindoux>numdlong) then
break -- ONE-based -- if both "numbegg" "numendd" non-ZERO then maybe
end--if
numwesel = string.byte(strdeath,numindoux,numindoux)
if (numwesel==40) then -- "("
if (numbegg==0) then
numbegg = numindoux -- pos of "("
else
numbegg = 0
break -- damn: more than 1 "(" present
end--if
end--if
if (numwesel==41) then -- ")"
if ((numendd==0) and (numbegg~=0) and ((numbegg+numxminlencz)<numindoux)) then
numendd = numindoux -- pos of ")"
else
numendd = 0
break -- damn: more than 1 ")" present or ")" precedes "("
end--if
end--if
numindoux = numindoux + 1
end--while
if ((numbegg~=0) and (numendd~=0)) then
if (boooutside) then
strdeath = string.sub(strdeath,1,(numbegg-1)) .. string.sub(strdeath,(numendd+1),numdlong)
else
strdeath = string.sub(strdeath,(numbegg+1),(numendd-1)) -- separate substring
end--if
end--if
return strdeath -- same string variable
end--function lfidebracket
------------------------------------------------------------------------
local function lfkatigu (strkatnomo, strhint) -- !!!FIXME!!! use "lfikataldigu"
local strbmb = ''
if (type(strhint)=="string") then
strbmb = '[[Kategorio:' .. strkatnomo .. '|' .. strhint .. ']]'
else
strbmb = '[[Kategorio:' .. strkatnomo .. ']]'
end--if
return strbmb
end--function lfkatigu
------------------------------------------------------------------------
---- VARIABLES [R] ----
------------------------------------------------------------------------
function exporttable.ek (arxframent)
-- general unknown type
local vartymp = 0 -- temp variable without type
local varret = 0 -- final result string or table
-- special type "args" AKA "arx"
local arxourown = 0 -- metaized "args" from our own "frame"
local arxexxtra = 0 -- for methods via mw.getCurrentFrame()
-- general table
local tabinput = {} -- all non-empty lines from template
local taballheadingsnodupe = {}
local tabheadingshit = {}
local tablistwithrootsnodupe = {}
-- general str
local strinrootin = '' -- from named 'in='
local strtext = '' -- huge string from the source template
local strtypofrut = '' -- from "numtyperoot" converted to string
local strdupesexx = ''
local strduperoot = ''
local strtmp = ''
local strvisgud = '' -- visible good output
local strvisred = '' -- reduced visible good output for output table
local strinvkat = '' -- invisible category part
local strviserr = '' -- visible error message
local strtrakat = '' -- invisible tracking categories
-- general num
local numlong = 0 -- length of parameter
local numerr = 0 -- 0 OK | 1 internal | 2 "in=" bad | 3 template bad ...
local numdcba = 0
local numtypeinpu = 0 -- 0 raw | 1 new | 2 leg
local numtyperoot = 0 -- 0 unknown | (67 C) 73 I 77 M 78 N 80 P 85 U
local numlines3mi = 0 -- number of lines from template
local numhitshits = 0 -- number of hits
-- general boo
local boonocat = false -- from "nocat=true"
local boogivet = false -- from "givetable=true"
---- GET THE ARX (OUR OWN) ----
-- must be seized independently on "numerr" even if we already suck
arxourown = arxframent.args -- "args" from our own "frame"
if (type(arxourown)~="table") then
arxourown = {} -- guard against indexing error
numerr = 1 -- #E01 internal
end--if
---- SEIZE ONE NAMED AND OBLIGATORY PARAM ----
strinrootin = ''
if (numerr==0) then
vartymp = arxourown["in"]
if (type(vartymp)=="string") then
numlong = string.len (vartymp)
if ((numlong>0) and (numlong<200)) then
strinrootin = vartymp
end--if
end--if
if (strinrootin=='') then
numerr = 2 -- #E02 missing or bad length
else
if ((string.find(strinrootin,":",1,true)) or (string.find(strinrootin,"_",1,true))) then
numerr = 2 -- #E02 colon or underscore
end--if
end--if (strinrootin=='') else
end--if
lftracemsg ('This is "mrootero", requested "detrc" report')
lfshowvar (numerr,'numerr','after seizure of anon param')
lfshowvar (constrtemplate,'constrtemplate')
---- PROCESS 1 SPECIAL AND 2 HIDDEN NAMED PARAMS ----
-- "detrc=" and "nocat=" must be seized independently on "numerr"
-- even if we already suck, but type "table" must be ensured above !!!
boogivet = (arxourown['givetable']=='true')
boonocat = (arxourown['nocat']=='true')
if (arxourown["detrc"]=="true") then
lftracemsg ('Param "detrc=true" seized')
else
qboodetrc = false -- was preassigned to "true"
qstrtrace = '' -- shut up now
end--if
lfshowvar (numerr,'numerr','done with special&hidden params')
lfshowvar (boogivet,'boogivet')
lfshowvar (boonocat,'boonocat')
---- FIND OUT THE TYPE OF INPUT AND ROOT ----
-- "Vorto -eo- enhavanta morfemon N (kapt)"
-- "Postfiksajxo ar'" -- "Radiko ide'" -- "Finajxo as"
-- "Memstara elemento da" -- "Liternomo co" -- "Antauxfiksajxo fi'"
-- note that minimal length of "Postfiksajxo" is 1 due to "-i-" and "-t-"
-- apo:s in the legacy patterns are troublesome in many ways, stupid
-- {{PAGENAME}} encodes apo to "'" and we must use "mw.text.decode"
numtypeinpu = 0 -- 0 raw | 1 new | 2 leg
numtyperoot = 0 -- 0 unknown | (67 C) 73 I 77 M 78 N 80 P 85 U
if (numerr==0) then
vartymp = string.find(strinrootin," ",1,true) -- space means more than bare
if (type(vartymp)=="number") then
if (string.byte(strinrootin,-1,-1)==41) then -- ")"
numtypeinpu = 1 -- new
else
numtypeinpu = 2 -- leg
end--if
end--if
lfshowvar (numtypeinpu,'numtypeinpu')
end--if
if ((numerr==0) and (numtypeinpu==1)) then -- new
strtmp = lfidebracket(strinrootin,true,2) -- extract outer packaging
while true do -- fake loop
if (string.len(strtmp)~=32) then
numerr = 3 -- #E03
break -- to join mark
end--if
if (string.sub(strtmp,1,30)~="Vorto -eo- enhavanta morfemon ") then
numerr = 3 -- #E03
break -- to join mark
end--if
if (string.byte(strtmp,32,32)~=32) then
numerr = 3 -- #E03
break -- to join mark
end--if
numtyperoot = string.byte(strtmp,31,31)
if ((numtyperoot~=73) and (numtyperoot~=77) and (numtyperoot~=78) and (numtyperoot~=80) and (numtyperoot~=85)) then
numerr = 3 -- #E03
break -- to join mark
end--if
strinrootin = lfidebracket(strinrootin,false,2) -- all OK -> extract root
break -- finally to join mark
end--while -- fake loop -- join mark
end--if ((numerr==0) and (numtypeinpu==1)) then
if ((numerr==0) and (numtypeinpu==2)) then -- leg
strinrootin = mw.text.decode(strinrootin) -- fix possible apo
while true do -- fake loop
numlong = string.len(strinrootin)
if (numlong>=15) then
if (string.sub(strinrootin,1,9)=="Postfiksa") then
strinrootin = string.sub(strinrootin,14,-2) -- cut off apo too
strinrootin = '-' .. strinrootin .. '-'
numtyperoot = 73 -- "I" minimal length 1 (dubious "-i-" "-t-")
break -- to join mark -- success
end--if
end--if
if (numlong>=10) then
if (string.sub(strinrootin,1,7)=="Radiko ") then
strinrootin = string.sub(strinrootin,8,-2) -- cut off apo too
numtyperoot = 78 -- "N" minimal length 2
break -- to join mark -- success
end--if
end--if
if (numlong>=9) then
if (string.sub(strinrootin,1,4)=="Fina") then
strinrootin = string.sub(strinrootin,9,-1) -- no apo here
numtyperoot = 83 -- "U" minimal length 1
strinrootin = '-' .. strinrootin
break -- to join mark -- success
end--if
end--if
if (numlong>=20) then
if (string.sub(strinrootin,1,18)=="Memstara elemento ") then
strinrootin = string.sub(strinrootin,19,-1) -- no apo here
numtyperoot = 77 -- "M" minimal length 2
break -- to join mark -- success
end--if
end--if
if (numlong>=11) then
if (string.sub(strinrootin,1,10)=="Liternomo ") then
strinrootin = string.sub(strinrootin,11,-1) -- no apo here
numtyperoot = 77 -- "M" minimal length 1
break -- to join mark -- success
end--if
end--if
if (numlong>=18) then
if (string.sub(strinrootin,1,4)=="Anta") then
strinrootin = string.sub(strinrootin,16,-2) -- cut off apo too
strinrootin = strinrootin .. '-'
numtyperoot = 80 -- "P" minimal length 2, no like "abiotic" in -eo-
break -- to join mark -- success
end--if
end--if
numerr = 3 -- #E03 -- nothing found, invalid string legacy type fed in
break -- finally to join mark
end--while -- fake loop -- join mark
end--if ((numerr==0) and (numtypeinpu==2)) then
if (numerr==0) then
if (numtyperoot==0) then
strtypofrut = '??' -- unknown
else
strtypofrut = string.char(numtyperoot) -- 73 I 77 M 78 N 80 P 85 U
end--if
lfshowvar (numerr,'numerr','done with root analysis')
lfshowvar (numtyperoot,'numtyperoot')
lfshowvar (strtypofrut,'strtypofrut')
lfshowvar (strinrootin,'strinrootin','the isolated root')
end--if
---- CHECK WHETHER THE POINTED TEMPLATE EXISTS AT ALL AND EXPAND IT ----
-- we expect "constrtemplate" as the FULLPAGENAME
-- note that "mw.text.unstrip" is required due to wiki headings in the text
-- note that we need a separate "frame" if called from a module, pick
-- it using "mw.getCurrentFrame()"
strtext = ''
if (numerr==0) then
arxexxtra = mw.getCurrentFrame()
vartymp = arxexxtra:callParserFunction ('#ifexist:'..constrtemplate,'1','0')
if (vartymp=='1') then
vartymp = arxexxtra:expandTemplate { title = constrtemplate }
if ((type(vartymp))=='string') then
strtext = mw.text.unstrip (vartymp) -- result may be empty
end--if
end--if (vartymp=='1') then
if (strtext=='') then
numerr = 4 -- #E04 empty template
end--if
end--if
lfshowvar (numerr,'numerr','done with template expansion')
lfshowvar (strtext,'strtext')
---- COPY INTO TABLE STRIPPING OFF ALL BLANK LINES ----
-- * note that incoming "strtext" may be quasi-empty (empty lines and EOL:s)
-- * we always add an EOL to the text
if (numerr==0) then
do -- scope
local varkernel = 0
local strsingle = ''
local numsrclen = 0
local numsrcpos = 1 -- ONE based
local numtabinx = 0 -- ONE based -- INC-before-write
strtext = strtext .. string.char(10)
numsrclen = string.len(strtext) -- at least 2
while true do
if (numsrcpos>=numsrclen) then
break -- no chance for a non-empty line anymore
end--if
varkernel = string.find(strtext,string.char(10),numsrcpos,true)
if (type(varkernel)~="number") then
numerr = 1 -- #E01 internal
break -- ??
end--if
strsingle = ''
if (numsrcpos<varkernel) then
strsingle = string.sub(strtext,numsrcpos,(varkernel-1)) -- omit the LF
end--if
numsrcpos = varkernel + 1
if (strsingle~='') then
if (string.len(strsingle)==1) then
numerr = 5 -- #E05 empty or bad line -- too short (<2)
break
end--if
if ((string.byte(strsingle,1,1)==32) or (string.byte(strsingle,-1,-1)==32)) then
numerr = 5 -- #E05 empty or bad line -- leading or trailing space
break
end--if
numtabinx = numtabinx + 1
tabinput[numtabinx] = strsingle
end--if
end--while
numlines3mi = numtabinx
end--do scope
if ((numlines3mi<3) or (mathmod(numlines3mi,2)==1)) then
numerr = 6 -- #E06 -- at least 2 lines required and must be even
end--if
end--if
lfshowvar (numerr,'numerr','done with tabelization')
lfshowvar (numlines3mi,'numlines3mi','at least 2 lines required and must be even')
---- CORE HARD WORK WALKING THROUGH OUR TABLE AND PROCESSING LINES ----
if (numerr==0) then
do -- scope
local varoden = 0
local strprevhed = '' -- stripped previous heading used for hit & dupe
local stroneroot = ''
local numindelx = 1 -- ONE-based read index in table
local numlinnlen = 0
local numrootiex = 0 -- ONE-based read octet position in line
local numhitindx = 0 -- number of found hits -- INC-before-write
local boonowhead = true -- on "false" it is list with roots
while true do -- outer loop over alternating lines
if (numindelx>numlines3mi) then
break -- done
end--if
strtmp = tabinput [numindelx] -- pick line
if ((string.byte(strtmp,1,1)==61)~=boonowhead) then -- "="
numerr = 7 -- #E07 overall pattern bad (alternating lines needed)
break
end--if
if (boonowhead) then
if (string.len(strtmp)<7) then
numerr = 9 -- #E09 heading too short
break
end--if
if ((string.sub(strtmp,1,3)~="== ") or (string.sub(strtmp,-3,-1)~=" ==")) then
numerr = 9 -- #E09 bad equal signs
break
end--if
strtmp = string.sub(strtmp,4,-4) -- at least ONE char left
if (taballheadingsnodupe[strtmp]) then
numerr = 10 -- #E10 dupe heading
break
end--if
taballheadingsnodupe[strtmp] = true -- we can't do this twice !!!
strprevhed = strtmp -- maybe we will need it later
else
tablistwithrootsnodupe = {} -- reset on every line
numrootiex = 1 -- ONE-based -- reset on every line
strtmp = strtmp .. ' ' -- have always a termination space
numlinnlen = string.len(strtmp) -- at least 3
while true do -- inner loop over roots
if (numrootiex>=numlinnlen) then
break -- no chance for a root anymore -- exit inner loop
end--if
varoden = string.find(strtmp,' ',numrootiex,true)
if (type(varoden)~="number") then
numerr = 1 -- #E01 internal
break -- ??
end--if
if (numrootiex<varoden) then
stroneroot = string.sub(strtmp,numrootiex,(varoden-1)) -- avoid the space
else
numerr = 12 -- #E12 empty root is no fun :-( !!!FIXME!!! dashes
break
end--if
numrootiex = varoden + 1
if (tablistwithrootsnodupe[stroneroot]) then
numerr = 14 -- #E14 dupe root
strdupesexx = strprevhed
strduperoot = stroneroot
break
end--if
tablistwithrootsnodupe[stroneroot] = true -- we can't do this twice !!!
if (stroneroot==strinrootin) then -- !!! HERE WE GOT A HIT !!!
numhitindx = numhitindx + 1
tabheadingshit [numhitindx] = strprevhed -- do NOT abort search
end--if
end--while -- inner loop over roots
if (numerr~=0) then
break -- don't forget to exit outer loop too
end--if
end--if (boonowhead) else
numindelx = numindelx + 1 -- ONE-based read index in table
boonowhead = not boonowhead -- alternate
end--while -- outer loop over alternating lines
numhitshits = numhitindx
end--do scope
end--if (numerr==0) then
lfshowvar (numerr,'numerr','done with processing lines')
lfshowvar (tabheadingshit,'tabheadingshit')
lfshowvar (numhitshits,'numhitshits')
---- BREW VISIBLE TEXT ----
-- "strinrootin" contains the raw morpheme or word but dashes can persist
-- based on "tabheadingshit" and "numhitshits"
-- here we fill "strvisred" and "strvisgud"
if (numerr==0) then
if (numhitshits==0) then
strvisred = contabvisi [3] -- "ne troveblas" ...
else
strvisred = contabvisi [2] -- "troveblas en " follows list
numdcba = 1
while true do -- at least ONE iteration
if (numdcba>numhitshits) then
break
end--if
if (numdcba~=1) then
strvisred = strvisred .. ' kaj '
end--if
strvisred = strvisred .. tabheadingshit [numdcba]
numdcba = numdcba + 1
end--while
end--if (numhitshits==0) else
strvisgud = contabvisi [0] .. strinrootin .. contabvisi [1] .. strtypofrut .. ') ' .. strvisred .. '.'
end--if (numerr==0) then
---- BREW ROOT CAT:S ----
-- "strinrootin" contains the raw morpheme or word but dashes can persist
-- based on "tabheadingshit" and "numhitshits"
-- all will receive the same sorting hint ... if the morpheme or word
-- begins with a dash then remove it so that "-o" falls under "O" not
-- under "-" ... still keep possible irrelevant trailing dash
if ((numerr==0) and (not boonocat)) then
do -- scope
local strcathint = ''
local strfoundheading = ''
strcathint = strinrootin
if (string.byte(strcathint,1,1)==45) then
strcathint = string.sub (strcathint,2,-1) -- remove Boulder Dash
end--if
if (numhitshits==0) then
strinvkat = lfkatigu(contabcats [0],strcathint)
else
strinvkat = lfkatigu(contabcats [1],strcathint)
numdcba = 1
while true do -- at least ONE iteration
if (numdcba>numhitshits) then
break
end--if
strfoundheading = tabheadingshit [numdcba]
vartymp = contabcats [strfoundheading] -- risk of type "nil"
if (type(vartymp)=="string") then
strfoundheading = vartymp -- use the translated one
end--if
strinvkat = strinvkat .. lfkatigu(strfoundheading,strcathint)
numdcba = numdcba + 1
end--while
end--if (numhitshits==0) else
end--do scope
end--if ((numerr==0) and (not boonocat)) then
---- BREW TRACKING CAT:S #E02...#E99 ----
-- no tracking cat:s for #E01
-- "nocat=true" suppresses even tracking cat:s
if ((numerr>1) and (not boonocat)) then
strtrakat = lfkatigu('Eraro (mrooteo)') -- !!!FIXME!!!
end--if
---- WHINE IF YOU MUST #E01...#E99 ----
if (numerr~=0) then
strviserr = '<b>Eraro #E' .. tonumber(numerr) .. '</b>' -- !!!FIXME!!!
end--if
if (numerr==11) then -- #E11
strviserr = strviserr .. '<br>Root list bad char (other than eo lowercase)' -- !!!FIXME!!! NOT yet detected
end--if
if (numerr==14) then -- #E14
strviserr = strviserr .. '<br>Dupe in section "' .. strdupesexx .. '" with root "' .. strduperoot .. '".'
end--if
---- RETURN THE STRING OR INNER TABLE ----
-- on #E02 and higher we risk partial results in "strvisgud" and "strinvkat"
lftracemsg ('Ready to return string glued together from 1 + 1 + 4 parts or table')
lfshowvar (strvisgud,'strvisgud')
lfshowvar (strvisred,'strvisred','table only')
lfshowvar (strinvkat,'strinvkat')
lfshowvar (strviserr,'strviserr')
lfshowvar (strtrakat,'strtrakat')
if (boogivet) then
varret = { [0]=numerr, strvisgud, strinvkat, strvisred, qstrtrace }
else
if (numerr==0) then
varret = strvisgud .. strinvkat
else
varret = strviserr .. strtrakat
end--if
if (qboodetrc) then -- "qstrtrace" declared separately outside main function
varret = "<br>" .. qstrtrace .. "<br><br>" .. varret
end--if
end--if
return varret
end--function
---- RETURN THE JUNK OUTER TABLE ----
return exporttable