MODULO
| |
|
|
- Ĉi tiu modulo efektivigas laboron de ŝablono
{{k}}
kaj estas vokata sole de tie.
- Dependas de:
--[===[
MODULE "MTAGG" (tag)
"eo.wiktionary.org/wiki/Modulo:mtagg" <!--2024-Nov-10-->
"id.wiktionary.org/wiki/Modul:mtagg"
Purpose: adds extra information ("tag") to a single meaning of a word
or the complete lemma (covering all meanings), showed as
an inline list of coloured hints (that can contain links
and images), and generates cat insertions
Utilo: aldonas na kroma informaro ("etikedo") al signifo de vorto
aux la tuta kapvorto (kovrante cxiujn signifojn), montrite kiel
enlinia listo kun koloraj konsiloj (kiuj povas enhavi ligilojn
kaj bildojn), kaj generas kategorienmetojn
Manfaat: menambahkan informasi ekstra ("tag") ke arti kata atau lema ...
Syfte: tillaegger extra information ...
Used by templates / Uzata far sxablonoj / Digunakan oleh templat:
* k (EO) , k (ID)
Required submodules / Bezonataj submoduloj / Submodul yang diperlukan:
* "loaddata-tbllingvoj" T76 in turn requiring template "tbllingvoj" (EO)
* "loaddata-tbllingvoj" T76 in turn requiring template "tblbahasa" (ID)
* "loaddata-tbldialektoj" T78 in turn requiring template "tbldialektoj" (EO)
This module can accept parameters whether sent to itself (own frame) or
to the caller (caller's frame). If there is a parameter "caller=true"
on the own frame then that own frame is discarded in favor of the
caller's one.
Incoming: * 2...25 anonymous obligatory parameters
* langcode (2 or 3 lowercase letters or more if enabled)
* 1...24 further parameters elements of the main control
chain, each 2...50 octet:s (see below)
* 3 hidden parameters
* "pagenameoverridetestonly=" can cause #E01
* "nocat=" no error possible
* "detrc=" no error possible
Returned: * one string intended to be showed after the numbered "#" list sign
if relating to a meaning, or after the bulletized "*" list sign
if relating to the complete lemma
This module is unbreakable (when called with correct module name
and function name). Every imaginable input from the caller and
from the 2 imported modules will output either a useful
result or at least an error string.
Cxi tiu modulo estas nerompebla (kiam vokita kun gxustaj nomo de modulo
kaj nomo de funkcio). Cxiu imagebla enigo de la vokanto kaj
de la 2 importataj moduloj eldonos aux utilan
rezulton aux almenaux eraranoncan signocxenon.
Structure of the control chain:
- Groups and elements:
- The chain may contain 1...24 elements belonging to following
groups (see "contablimahuruf"):
- "T" translingual -- "FFC8C8" pink
- "D" dialect -- "FFF0C0" orange
- "G" grammar -- "FFFFB0" yellow or "D0FFD0" green for "eo"
- "F" field -- "D0F0FF" bluish cyan
- "S" style -- "FFD0FF" violet
- "C" other -- "D8D8D8" grey
There can be several elements belonging to same group, and groups can be
omitted, but the order of groups is crucial, at least one element and one
group is required, and same type of group must be introduced exactly one
time. The elements are separated by wall "|", and groups are introduced by
an UPPERCase letter followed by a colon and space ie ": " at the beginning
of an element (NOT by a separate element).
- Special char:s:
- Absolutely reserved:
- wall "|" (wikisyntax) used to separate elements
as well as params of the call
- curly brackets "{" and "}" in double or higher multiplicity
(wikisyntax) used to begin and end the call
- rectangular brackets "[" and "]" in double or higher
multiplicity (wikisyntax) absolutely prohibited
- TAB and LF absolutely prohibited
- In some positions reserved:
- space " "
- colon ":" (reserved after whitelisted name only)
- dot "." (reserved at end of element only)
- dash "-" (reserved at end of element only)
- percent-sign "%" and and-sign "&"
- Examples:
- <<D: % predominantly-|qeb.|G: VRF:|% only in negative contexts|S: sla.|C: % about abstract stuff>>
- <<G: VIT.-|% kun prepozicio "pri"|% ecx-|VTR.|C: % celante personon>>
- <<MS: ark.>>
- <<RS: ark.>>
- Global reduction prefixes (recognized at the very beginning of the
chain only): !!!FIXME!!! imple incomplete
- The prefix "M" should be used if the template is called from
other places than a definition or overview above the definitions,
it reduces the generosity of the output in following ways:
- no categories
- no colours
- no links
- no tooltips
- no images
- The prefix "R" removes the categories only. As opposed to "nocat=true" !!!FIXME!!! nocat is DEPRECATED
it does not suppress tracking categories. Furthermore "nocat=true" must
not be used on lemma pages.
- Types of elements:
- An element may be of one of two types:
* plain text element, must NOT end with a dot, categorized by
default, cannot provide a translated category, cannot suppress
the language-dependent category, cannot provide a link, tooltip
or image, as a base rule any text of sane length without reserved
char:s is permitted, but some texts may !!!FIXME!!! not checked yet
be either simply disallowed, or disallowed in favor of an
abbreviation (see below), or have one of the element prefixes (see
below) obligatory or prohibited, or be reserved for a certain group
* abbreviation element (2...12 char:s of a limited set (ASCII UPPERCase, !!!FIXME!!! not checked yet
ASCII lowercase, EO UPPERCase, EO lowercase, dash "-") will be
peeked from a list, specific to a group (thus same abbreviation
may be defined in different groups with different meanings, error if
not found, categorized by default, may contain a translated category,
may suppress the language-dependent category, may contain a link, may
contain a tooltip, may contain an image), 2 subtypes:
* "dot-type" ending with a dot "." (thus 3...13 char:s totally)
* "colon-type" ie abbreviation element with extra information with
2 more subsubtypes:
* 3 UPPERCase letters followed by colon only for
automatic extra information
or
* 3 UPPERCase letters followed by colon and space ": " and at least
one more octet of manual extra information
both automatic and manual only available for explicitly whitelisted
triples (only "VRF" "VRG" "VRH" so far) that can be used in 3 ways:
* "VRG." no extra information
* "VRG:" automatic extra information
* "VRG: ta sig an" manual extra information
- Element prefixes (usable with both plain text elements and abbreviation
elements, but latter only the subtype without extra content ie "dot-type"):
* By default an element generates both visible text and a category. If
only one of those effects is desirable then an element prefix (one
non-letter char followed by obligatory space) can be used:
* "%" show text but do not categorize ("nopercatcent")
* "&" categorize only but do not show text
- Element suffix for join request (usable with both plain text elements
and abbreviation elements, even "colon-type") is a dash "-". Element
having it will be joined with following element (show space only and keep
continuous colour, instead of white semicolon plus space "; " between). Not
more than 2 elements can be joined, and exactly one of those must use the
prefix "%" too (show text but do not categorize), and none of them may
have prefix "&" (categorize only but do not show text).
- Special rules for some groups:
* group "T" translingual
* the langcode must be "mul", otherwise #E23
* the language-dependent category is always omitted (as it obviously
would not make sense) and control code "1" in abbreviation expansion
is thus prohibited
* group "D" dialect
* special language-dependent mode of translation, see below
* the language-dependent category is always omitted (as it obviously
would not make sense) and control code "1" in abbreviation expansion
is thus prohibited
- Translation of abbreviation elements: !!!FIXME!!! add exclusive langcode ie 6 -> 7 sections
- The translation is provided by LUA tables. All elements are named and
use a key/index (2...12 UPPERCase or lowercase letters, always without
dot "." or colon ":", special rule applies for the dialect) and a value
(expansion string) with 1 to 6 sections separated by walls "|". Missing
sections are legal if at least the earliest one is present, truly
empty ones (without dash "-" placeholder) are not.
- The sections are:
- (required) visible text and auto category
- (optional) differring category
* string without "Category:" prefix and without unnecessary
capitalization, for example "fiziko"
* default is same as the visible text
* use dash "-" to "jump over" this section and take same
as the visible text
- (optional) link (lowercase string), default is no link,
use dash "-" to "jump over" this section ie omit link
- (optional) tooltip, default is no tooltip, use dash "-" to
"jump over" this section ie omit tooltip
- (optional) image (string without "File:" prefix),
default is no image, image precedes the text in the output,
use dash "-" to "jump over" this section ie omit image
- (optional) control code
* "1" (digit ONE) suppress language-dependent category, this is useful
for language peculiarities that exist in one language only, by
default both the generic and language-dependent category include are
generated, note that this effect CANNOT be achieved with a plain
text element, and this code is prohibited in groups T and D where
this effect is always active
- Dialect abbreviations (D):
Two types are defined:
- state -- 2 UPPERCase letters (code of a state, example "FI" or "US") !!!FIXME!!! "RP" "GA"
- region -- 3...8 lowercase letters (regions that are not states)
A dialect abbreviation is specific for one langcode, for example "UK"
meaning "British" is valid with "en" but not with "sv". It could have some
other meaning within an other language. Note that for example only "UK" has
to be used in the control chain in the template call, but the index is
"en-UK" in the imported LUA table, and finally "en" is the z-dimension
whereas "UK" is the y-dimension in the separate module. Following special
rules apply:
* langcode enters the translation process
* in the LUA table, the LUA key/index is prepended by the langcode
(example: "en" -> en-ZA")
* both the visible text and the category later generated by the module
are prefixed by language name obtained from that langcode (example:
"ZA" -> "Afrika Selatan" -> "Inggris Afrika Selatan", or
"MX" -> "meksiklanda" -> "hispana meksiklanda"), and generated in two
versions, one with small text for the screen, and one raw for the category
- Grammar abbreviations (G):
There is a special handling of some types of verbs. For this reason, all
7 abbreviations related to transitivity of verbs consist of 3 UPPERCase
letters, but only 3 of them (VRF VRG VRH) can have the subtype "abbreviation
element with extra information" (colon-type), besides the ordinary
"abbreviation element" (dot-type).
- VTR - transitive verb
- VDT - doubly transitive verb
- VOD - transitive verb with required object (in languages where the
object usually can be omitted and thus implied)
- VIT - intransitive verb
- VRF - reflexive form of verb
- VRG - exclusively reflexive verb (non-reflexive form does not exist)
- VRH - quasi-exclusively reflexive verb (non-reflexive form exists but
has a different meaning)
For VRF VRG VRH the reflexive form can be autogenerated (depends on
langcode, unsupported language gives #E28) or manually provided.
- Field abbreviations (F):
(see list below)
- Style abbreviations (S):
(see list below)
- Other abbreviations (C):
(see list below)
Following errors can occur:
- #E01 Internal error in module "mtagg"
Possible causes:
- strings not uncommented
- function "mw.title.getCurrentTitle().text" AKA "{{PAGENAME}}" failed
- pagename is invalid such as empty or too long or contains
invalid brackets []{} or more than one consecutive apo, even if
coming from "pagenameoverridetestonly="
* #E08 Erara uzo de sxablono "k", legu gxian dokumentajxon
Possible causes (early detected obvious problems with parameters):
* less than 2 or more than 25 parameters supplied
* #E09
* wrong length of single parameter (must be 2...60 octet:s)
* #E03 Eraro en subsxablonoj uzataj far sxablono "k" !!!FIXME!!!
Possible causes:
- submodule failure (or not found ??) or returned invalid
- #E04 Evidente nevalida lingvokodo en sxablono "k"
Possible causes:
- the earliest parameter
- #E05 Nekonata lingvokodo en sxablono "k"
Possible causes:
- the earliest parameter
- #E06 Erara uzo de sxablono "k" pro rezervita signo en la stircxeno !!!FIXME!!! NOT yet used
- #E07 Gxenerala eraro en la stircxeno
Possible causes:
* string too short (<2 octet:s) after removing valid
prefixes (before removing this gives #E09 instead)
- #E15 Nevalida kodo de grupo en la stircxeno ... indekso
Possible causes:
* found UPPERCase letter different from T D G F S C + ": "
- #E16 Redunda aux nevalida grupa prefikso en la stircxeno
Possible causes:
- stuff like "D: D:" or "C: F:" ie redundant or conflicting group
prefixes (note that the order of groups is checked only later)
- stuff like "% % " "% & " ie redundant or conflicting element prefixes
- stuff like "% F:" ie reversed order between group
prefix and element prefix
- #E17 Erara ordo de grupoj en la stircxeno
Possible causes:
- wrong order, ie prefix of lower group appearing later
- #E19 Ripeta grupa prefikso en la stircxeno
Possible causes:
- prefix of same group appearing again later
- #E20 Enhavo ekstere de grupo
Possible causes:
- no group defined at the beginning
- #E21 Elementa prefikso uzata kun mallongiga elemento kun kroma enhavo
Possible causes:
- element prefix used together with abbreviation element
with extra content ("colon-type"), this is prohibited
- #E23 Grupo T uzata kun lingvokodo alia ol mul
Possible causes: !!!FIXME!!!
- #E24 Nekonata translingva mallongigo en la stircxeno
Possible causes: !!!FIXME!!!
- #E25 Nekonata dialekta mallongigo en la stircxeno
Possible causes: !!!FIXME!!!
- #E26 Nekonata kvargrupa (G F S C) mallongigo en la stircxeno
Possible causes: !!!FIXME!!!
- #E28 Ne eblas auxtogeneri kroman enhavon
Possible causes:
- not supported for given language
- #E29 Nevalida kunigpostulo
Possible causes:
- rule that exactly one of two elements must have "%" is violated
- attempt to merge more than two elements
EO:
Kategorio:Fiziko
Kategorio:Fiziko (angla)
Kategorio:Fiziko (Esperanto)
ID: !!!FIXME!!! NOT yet
Kategori:Mamalia
Kategori:id:Mamalia
]===]
local exporttable = {}
require('strict')
------------------------------------------------------------------------
---- CONSTANTS [O] ----
------------------------------------------------------------------------
-- uncommentable submodules
local constringvoj = "Modulo:loaddata-tbllingvoj" -- EO
-- local constringvoj = "Modul:loaddata-tblbahasa" -- ID
local constrlektoj = "Modulo:loaddata-tbldialektoj" -- EO
-- local constrlektoj = "Modul:loaddata-tbldialek" -- ID
-- surrogate
local contabtransluteo = {}
contabtransluteo[ 67] = 0xC488 -- CX
contabtransluteo[ 99] = 0xC489 -- cx
contabtransluteo[ 71] = 0xC49C -- GX
contabtransluteo[103] = 0xC49D -- gx
contabtransluteo[ 74] = 0xC4B4 -- JX
contabtransluteo[106] = 0xC4B5 -- jx
contabtransluteo[ 83] = 0xC59C -- SX
contabtransluteo[115] = 0xC59D -- sx
contabtransluteo[ 85] = 0xC5AC -- UX breve
contabtransluteo[117] = 0xC5AD -- ux breve
-- constant strings (error circumfixes)
local constrelabg = '<span class="error"><b>' -- lagom whining begin
local constrelaen = '</b></span>' -- lagom whining end
local constrlaxhu = ' [] ' -- lagom -> huge circumfix " [] "
-- constant strings and table (tooltip and misc to be sent to the screen)
local contabscrmisc = {}
contabscrmisc['tootip'] = 'style="border-bottom:1px dotted; cursor:help;"' -- lousy tooltip !!!FIXME!!! NOT yet used
-- 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
local contablimahuruf = {} -- T D G F S C
contablimahuruf [1] = {'T','FFC8C8',''} -- pink
contablimahuruf [2] = {'D','FFF0C0',''} -- orange
contablimahuruf [3] = {'G','FFFFB0','D0FFD0'} -- yellow, green for "eo" (valid irrespective of "strpiklangcode")
contablimahuruf [4] = {'F','D0F0FF',''} -- bluish cyan (bluebluegreen)
contablimahuruf [5] = {'S','FFD0FF',''} -- violet
contablimahuruf [6] = {'C','D8D8D8',''} -- grey
-- uncommentable EO vs ID table (tracking cat:s)
local contabtrako = {}
contabtrako ['cetgen'] = 'Erara uzo de sxablono'
contabtrako [1] = 'Evidente nevalida'
contabtrako [2] = 'Nekonata'
contabtrako [3] = 'lingvokodo'
contabtrako [4] = 'loke'
contabtrako [5] = 'nome'
-- uncommentable EO vs ID table (error messages)
-- #E02...#E99, holes permitted, separate ... needed for "\\@"
-- note that #E00 and #E01 are NOT supposed to be included here
local contaberaroj = {}
contaberaroj[02] = 'Malica eraro en subprogramaro uzata far \\@' -- EO #E02
-- contaberaroj[02] = 'Kesalahan jahat dalam subprogram digunakan oleh \\@' -- ID #E02
contaberaroj[03] = 'Nombrigita eraro en subprogramaro uzata far \\@' -- EO #E03
-- contaberaroj[03] = 'Kesalahan ternomor dalam subprogram digunakan oleh \\@' -- ID #E03
contaberaroj[08] = 'Erara uzo de \\@, legu gxian dokumentajxon' -- EO #E08
-- contaberaroj[08] = 'Penggunaan salah \\@, bacalah dokumentasinya' -- ID #E08
contaberaroj[04] = 'Evidente nevalida lingvokodo sendita al \\@' -- EO #E04 !!!FIXME!!! double use
-- contaberaroj[04] = 'Kode bahasa jelas-jelas salah dikirim ke \\@' -- ID #E04
contaberaroj[05] = 'Nekonata lingvokodo sendita al \\@' -- EO #E05 !!!FIXME!!! double use
-- contaberaroj[05] = 'Kode bahasa tidak dikenal dikirim ke \\@' -- ID #E05
contaberaroj[06] = 'Riservita signo en la stircxeno por \\@' -- EO #E06 !!!FIXME!!! must be 13
-- contaberaroj[06] = 'Karakter direservasi dalam rantai pengendali untuk \\@' -- ID #E06
contaberaroj[07] = 'Gxenerala eraro en la stircxeno por \\@' -- EO #E07 !!!FIXME!!! must be 14
-- contaberaroj[07] = 'Kesalahan umum dalam rantai pengendali untuk \\@' -- ID #E07
contaberaroj[15] = 'Nevalida kodo de grupo en la stircxeno por \\@, indekso \\~, subtenataj T D G F S C' -- EO #E15
-- contaberaroj[15] = 'Huruf golongan salah dalam rantai pengendali untuk \\@, indeks \\~, didukung T D G F S C' -- ID #E15
contaberaroj[16] = 'Redunda aux nevalida grupa prefikso en la stircxeno por \\@' -- EO #E16
-- contaberaroj[16] = 'Prefiks golongan redundan atau tidak valid dalam rantai pengendali untuk \\@' -- ID #E16
contaberaroj[17] = 'Erara ordo de grupoj en la stircxeno por \\@, estu T D G F S C' -- EO #E17
-- contaberaroj[17] = 'Urutan golongan salah dalam rantai pengendali untuk \\@, sebaiknya T D G F S C' -- ID #E17
contaberaroj[19] = 'Ripeta grupa prefikso en la stircxeno por \\@' -- EO #E19
-- contaberaroj[19] = 'Prefiks golongan ulang dalam rantai pengendali untuk \\@' -- ID #E19
contaberaroj[20] = 'Enhavo ekstere de grupo en la stircxeno por \\@' -- EO #E20
-- contaberaroj[20] = 'Keterangan luar golongan dalam rantai pengendali untuk \\@' -- ID #E20
contaberaroj[21] = 'Elementa prefikso uzata kun mallongigo kroma en la stircxeno por \\@' -- EO #E21
-- contaberaroj[21] = 'Prefiks element digunakan dengan singkatan ekstra dalam rantai pengendali untuk \\@' -- ID #E21
contaberaroj[23] = 'Grupo T uzata kun lingvokodo alia ol mul en la stircxeno por \\@' -- EO #E23
-- contaberaroj[23] = 'Golongan T digunakan dengan kode berbeda dari mul dalam rantai pengendali untuk \\@' -- ID #E23
contaberaroj[24] = 'Nekonata translingva mallongigo en la stircxeno por \\@' -- EO #E24
-- contaberaroj[24] = 'Singkatan antarbahasa tidak dikenal dalam rantai pengendali untuk \\@' -- ID #E24
contaberaroj[25] = 'Nekonata dialekta mallongigo en la stircxeno por \\@' -- EO #E25
-- contaberaroj[25] = 'Singkatan dialek tidak dikenal dalam rantai pengendali untuk \\@' -- ID #E25
contaberaroj[26] = 'Nekonata kvargrupa (G F S C) mallongigo en la stircxeno por \\@' -- EO #E26
-- contaberaroj[26] = 'Singkatan empat golongan (G F S C) tidak dikenal dalam rantai pengendali untuk \\@' -- ID #E26
contaberaroj[28] = 'Ne eblas auxtogeneri kroman enhavon en \\@' -- EO #E28
-- contaberaroj[28] = 'Tidak berhasil membangkitkan konten ekstra secara otomatis dalam \\@' -- ID #E28
contaberaroj[29] = 'Nevalida kunigpostulo en \\@' -- EO #E29
-- contaberaroj[29] = 'Permintaan tempel yang tidak valid dalam \\@' -- ID #E29
-- uncommentable EO vs ID group "T"
local contabtt = {} -- "T" -- translingual -- vis cat link tool image -- NOT ctl here -- code must be "mul"
contabtt ['ASKI'] = 'askia signo'
contabtt ['ARAB'] = 'araba cifero'
contabtt ['ROMA'] = 'roma cifero' -- EO single unicode character even if multiple digits
contabtt ['ASKL'] = 'askia litero'
contabtt ['LATI'] = 'latina litero'
contabtt ['CIRI'] = 'cirila litero'
contabtt ['CNTR'] = 'cxina signo tradicia'
contabtt ['CNSI'] = 'cxina signo simpligita'
contabtt ['CNKO'] = 'cxina signo komuna'
contabtt ['JAKA'] = 'japana signo kanjxia'
contabtt ['TIBE'] = 'tibeta signo'
contabtt ['GRKO'] = 'greka aux kopta signo'
contabtt ['MATE'] = 'matematika signo'
contabtt ['IFAS'] = 'IFA-signo'
contabtt ['VALU'] = 'signo de valuto'
contabtt ['BILD'] = 'bilda signo'
contabtt ['VALSI'] = 'simbolo de valuto'
contabtt ['MATSI'] = 'matematika simbolo'
contabtt ['KEMSI'] = 'kemia simbolo' -- EO (YES "Pu" but NO "DDT")
-- uncommentable EO vs ID group "D" -- dialect -- dialekto -- vis cat link tool image -- NOT ctl here
local contabgg = {} -- "G" -- grammar -- vis(obligatory) cat link tool image ctl
contabgg["kofr"] = "kofrovorto" -- EO (en: smog transponder, eo: foklea, id: miras, sv: flextid bankomat)
-- contabgg["kofr"] = "kata lakuran" -- ID
contabgg["miks"] = "miksajxo" -- EO (eo: volapugajxo, sv: snarkofag)
-- contabgg["miks"] = "kata campuran" -- ID
contabgg["deta"] = "derivajxo de tabelvorto" -- EO (nur eo: "iama", "kialo") (!!! tabelvorto mem estas vortospeco !!!)
-- contabgg["deta"] = "derivasi kata tabel" -- ID (hanya eo)
contabgg["sing"] = "nursingulara|substantivo nursingulara" -- EO (nur SB: en: "music" , eo: "kupro")
-- contabgg["sing"] = "tidak terhitung|nomina tidak terhitung" -- ID (hanya SB)
contabgg["plpl"] = "nurplurala|substantivo nurplurala" -- EO (nur SB: en: "trousers" , eo: "okulvitroj")
-- contabgg["plpl"] = "selalu jamak|nomina selalu jamak" -- ID (hanya SB)
contabgg["sapl"] = "samformplurala|substantivo samformplurala" -- EO (nur SB: en: "sheep")
-- contabgg["sapl"] = "jamak bentuk sama|nomina jamak bentuk sama" -- ID (hanya SB)
contabgg["nutr"] = "utruma(n)|substantivo utruma(n)" -- EO (nur sv, eble ecx da: nur SB)
-- contabgg["nutr"] = "utrum(n)|nomina utrum(n)" -- ID (hanya sv, mungkin bahkan da)
contabgg["tneu"] = "neuxtruma(t)|substantivo neuxtruma(t)" -- EO (nur sv, eble ecx da: nur SB)
-- contabgg["tneu"] = "neutrum(t)|nomina neutrum(t)" -- ID (hanya sv, mungkin bahkan da)
contabgg["kole"] = "kolektiva|substantivo kolektiva" -- EO
-- contabgg["kole"] = "kolektif|nomina kolektif" -- ID
contabgg["senk"] = "sen komparado|adjektivo sen komparado" -- EO (nur AJ -- en "trigonometric")
-- contabgg["senk"] = "tanpa komparasi|adjektif tanpa komparasi" -- ID (hanya AJ -- en "trigonometric")
contabgg["stat"] = "loka statika|adverbo loka statika" -- EO (nur AV)
-- contabgg["stat"] = "tempat statik|adverbia tempat statik" -- ID (hanya AV)
contabgg["dyna"] = "loka dinamika|adverbo loka dinamika" -- EO (nur AV)
-- contabgg["dyna"] = "tempat dinamik|adverbia tempat dinamik" -- ID (hanya AV)
contabgg["onom"] = "onomatopeo" -- EO (nur IN)
-- contabgg["onom"] = "onomatope" -- ID (hanya IN)
contabgg["avaux"] = "-aux|esperanta adverbo finigxanta per (-aux)|-|-|-|1"
contabgg["ajly"] = "-ly|angla adjektivo finigxanta per (-ly)|-|-|-|1"
contabgg["VTR"] = "transitiva|verbo transitiva" -- EO (nur VE)
contabgg["VDT"] = "duoble transitiva verbo|verbo duoble transitiva" -- EO (nur VE)
contabgg["VOD"] = "transitiva verbo kaj objekto deviga|verbo transitiva" -- EO (nur VE)
contabgg["VIT"] = "netransitiva|verbo netransitiva" -- EO (nur VE)
contabgg["VRF"] = "refleksiva formo|verbo refleksiva" -- EO (nur VE)
contabgg["VRG"] = "nepre refleksiva verbo|verbo refleksiva" -- EO (nur VE)
contabgg["VRH"] = "kvazauxnepre refleksiva verbo|verbo refleksiva" -- EO (nur VE)
local contabf = {} -- "F" -- field -- fako -- vis(obligatory) cat link tool image ctl
contabf["pers"] = "persona nomo" -- EO (nur SB)
-- contabf["pers"] = "nama orang" -- ID (hanya SB)
contabf["lokn"] = "loknomo" -- EO (nur SB)
-- contabf["lokn"] = "nama tempat" -- ID (hanya SB)
local contabs = {} -- "S" -- stilo, lingvoregistro -- vis(obligatory) cat link tool image ctl
contabs["sla"] = "slanga" -- EO
-- contabs["sla"] = "bahasa gaul" -- ID
contabs["vul"] = "vulgara" -- EO
-- contabs["vul"] = "bahasa jahat" -- ID
local contabc = {} -- "C" -- misc -- ceteraj -- vis(obligatory) cat link tool image ctl
contabc["idi"] = "idioma vortgrupo" -- EO (eo: "nigra sxafo") (esprimo/idiomajxo) (subklaso de vortospeco vortgrupo GR)
-- contabc["idi"] = "kumpulan kata idioma" -- ID
contabc["par"] = "idioma vortoparo" -- EO (sv: "hugget som stucket") (subklaso de vortospeco vortgrupo GR)
-- contabc["par"] = "dua kata idioma" -- ID
contabc["prov"] = "proverbo" -- EO (sv: "Lika barn leka baest.") (subklaso de vortospeco frazo KA)
-- contabc["prov"] = "peribahasa" -- ID
contabc["bas"] = "baza vortoprovizo" -- EO
-- contabc["bas"] = "kosa kata dasar" -- ID
contabc["plen-inv"] = "vorto de la plena inventaro de Kotapedia|-|-|-|-|1" -- EO suppress language-dependent category
-- constants to control behaviour from source AKA semi-hardcoded parameters
local conbookodlng = false -- "true" to allow long codes like "zh-min-nan"
local conboomiddig = false -- "true" to allow middle digit "s7a"
-- uncommentable (override)
-- * name of table MUST always be defined, OTOH elements are usually NOT
-- * for testing only, values automatically peeked otherwise
local contabovrd = {}
-- contabovrd['sitelang'] = 'eo' -- "en"
-- contabovrd['sitelang'] = 'id'
-- contabovrd['katprefi'] = 'Kategorio' -- "Category"
-- contabovrd['katprefi'] = 'Kategori'
-- contabovrd['parentfn'] = string.char(0xC5,0x9C) .. 'ablono:nope' -- "Template:nope" (!!! no surr translation !!!)
------------------------------------------------------------------------
---- SPECIAL STUFF OUTSIDE MAIN [B] ----
------------------------------------------------------------------------
-- SPECIAL VAR:S
local qldingvoj = {} -- type "table" and nested
local qldlektoj = {} -- type "table" and nested
local qbooguard = false -- only for the guard test, pass to other var ASAP
local qboodetrc = true -- from "detrc=true" but default is "true" !!!
local qstrtrace = '<br>' -- for main & sub:s, debug report request by "detrc="
---- GUARD AGAINST INTERNAL ERROR AND IMPORT TWO VIA LOADDATA ----
qbooguard = ((type(constringvoj)~='string') or (type(constrlektoj)~='string'))
if (not qbooguard) then
qldingvoj = mw.loadData(constringvoj) -- can crash here
qbooguard = (type(qldingvoj)~='table') -- seems to be always false
end--if
if (not qbooguard) then
qldlektoj = mw.loadData(constrlektoj) -- can crash here
qbooguard = (type(qldlektoj)~='table') -- seems to be always false
end--if
------------------------------------------------------------------------
---- DEBUG FUNCTIONS [D] ----
------------------------------------------------------------------------
-- Local function LFDTRACEMSG
-- Enhance upvalue "qstrtrace" with fixed text.
-- for variables the other sub "lfdshowvar" is preferable but in exceptional
-- cases it can be justified to send text with values of variables to this sub
-- no size limit
-- upvalue "qstrtrace" must NOT be type "nil" on entry (is inited to "<br>")
-- uses upvalue "qboodetrc"
local function lfdtracemsg (strshortline)
if (qboodetrc and (type(strshortline)=='string')) then
qstrtrace = qstrtrace .. strshortline .. '.<br>' -- dot added !!!
end--if
end--function lfdtracemsg
------------------------------------------------------------------------
-- Local function LFDMINISANI
-- Input : * strdangerous -- must be type "string", empty legal
-- * numlimitdivthree
-- Output : * strsanitized -- can happen to be quasi-empty with <<"">>
-- To be called from "lfdshowvcore" <- "lfdshowvar" only.
-- * we absolutely must disallow: cross "#" 35 | apo "'" 39 |
-- star "*" 42 | dash 45 | colon 58 | "<" 60 | ">" 62 | "[" 91 | "]" 93
-- * spaces are showed as "{32}" if repetitive or at begin or at end
local function lfdminisani (strdangerous, numlimitdivthree)
local strsanitized = '"' -- begin quot
local num38len = 0
local num38index = 1 -- ONE-based
local num38signo = 0
local num38prev = 0
local boohtmlenc = false
local boovisienc = false
num38len = string.len (strdangerous)
while true do
boohtmlenc = false -- % reset on
boovisienc = false -- % every iteration
if (num38index>num38len) then -- ONE-based
break -- done string char after char
end--if
num38signo = string.byte (strdangerous,num38index,num38index)
if ((num38signo<43) or (num38signo==45) or (num38signo==58) or (num38signo==60) or (num38signo==62) or (num38signo==91) or (num38signo==93) or (num38signo>122)) then
boohtmlenc = true
end--if
if ((num38signo<32) or (num38signo>126)) then
boovisienc = true -- overrides "boohtmlenc"
end--if
if ((num38signo==32) and ((num38prev==32) or (num38index==1) or (num38index==num38len))) then
boovisienc = true -- overrides "boohtmlenc"
end--if
if (boovisienc) then
strsanitized = strsanitized .. '{' .. tostring (num38signo) .. '}'
else
if (boohtmlenc) then
strsanitized = strsanitized .. '&#' .. tostring (num38signo) .. ';'
else
strsanitized = strsanitized .. string.char (num38signo)
end--if
end--if
if ((num38len>(numlimitdivthree*3)) and (num38index==numlimitdivthree)) then
num38index = num38len - numlimitdivthree -- jump forwards
strsanitized = strsanitized .. '" ... "'
else
num38index = num38index + 1 -- ONE-based
end--if
num38prev = num38signo
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 numeric and string keys. !!!FIXME!!!
-- Input : * vardubious -- content (any type including "nil" is acceptable)
-- * str77name -- name of the variable (string)
-- * vardescri -- optional comment, default empty, begin with "@" to
-- place it before name of the variable, else after
-- * varlim77tab -- optional limit, limits both string keys and
-- numeric keys, default ZERO no listing
-- Depends on functions :
-- [D] lfdminisani
local function lfdshowvcore (vardubious, str77name, vardescri, varlim77tab)
local taballkeystring = {}
local strtype = ''
local strreport = ''
local numindax = 0
local numlencx = 0
local numkeynumber = 0
local numkeystring = 0
local numkeycetera = 0
local numkey77min = 999999
local numkey77max = -999999
local boobe77fore = false
if (type(str77name)~='string') then
str77name = '??' -- bite the bullet
else
str77name = '"' .. str77name .. '"'
end--if
if (type(vardescri)~='string') then
vardescri = '' -- omit comment
end--if
if (string.len(vardescri)>=2) then
boobe77fore = (string.byte(vardescri,1,1)==64) -- prefix "@"
if (boobe77fore) then
vardescri = string.sub(vardescri,2,-1) -- CANNOT become empty
end--if
end--if
if (type(varlim77tab)~='number') then
varlim77tab = 0 -- deactivate listing of a table
end--if
if ((vardescri~='') and (not boobe77fore)) then
str77name = str77name .. ' (' .. vardescri .. ')' -- now a combo
end--if
strtype = type(vardubious)
if (strtype=='table') then
for k2k,v2v in pairs(vardubious) do
if (type(k2k)=='number') then
numkey77min = math.min (numkey77min,k2k)
numkey77max = math.max (numkey77max,k2k)
numkeynumber = numkeynumber + 1
else
if (type(k2k)=='string') then
taballkeystring [numkeystring] = k2k
numkeystring = numkeystring + 1
else
numkeycetera = numkeycetera + 1
end--if
end--if
end--for
strreport = 'Table ' .. str77name
if ((numkeynumber==0) and (numkeystring==0) and (numkeycetera==0)) then
strreport = strreport .. ' is empty'
else
strreport = strreport .. ' contains '
if (numkeynumber==0) then
strreport = strreport .. 'NO numeric keys'
end--if
if (numkeynumber==1) then
strreport = strreport .. 'a single numeric key equal ' .. tostring (numkey77min)
end--if
if (numkeynumber>=2) then
strreport = strreport .. tostring (numkeynumber) .. ' numeric keys ranging from ' .. tostring (numkey77min) .. ' to ' .. tostring (numkey77max)
end--if
strreport = strreport .. ' and ' .. tostring (numkeystring) .. ' string keys and ' .. tostring (numkeycetera) .. ' other keys'
end--if
if ((numkeynumber~=0) and (varlim77tab~=0)) then -- !!!FIXME!!!
strreport = strreport .. ' ### content num keys :'
numindax = numkey77min
while true do
if ((numindax>varlim77tab) or (numindax>numkey77max)) then
break -- done table
end--if
strreport = strreport .. ' ' .. tostring(numindax) .. ' -> ' .. lfdminisani(tostring(vardubious[numindax]),30)
numindax = numindax + 1
end--while
end--if
if ((numkeystring~=0) and (varlim77tab~=0)) then -- !!!FIXME!!!
strreport = strreport .. ' ### content string keys :'
end--if
else
strreport = 'Variable ' .. str77name .. ' 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,30)
end--if
else
if (strtype~='nil') then
strreport = strreport .. ' and content "' .. tostring (vardubious) .. '"'
end--if
end--if (strtype=='string') else
end--if (strtype=='table') else
if ((vardescri~='') and boobe77fore) then
strreport = vardescri .. ' : ' .. strreport -- very last step
end--if
return strreport
end--function lfdshowvcore
------------------------------------------------------------------------
-- Local function LFDSHOWVAR
-- Enhance upvalue "qstrtrace" with report about content of a variable
-- including optional full listing of a table with numeric and string keys. !!!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 lfdshowvar (varduubious, strnaame, vardeskkri, vartabljjm)
if (qboodetrc) then
qstrtrace = qstrtrace .. lfdshowvcore (varduubious, strnaame, vardeskkri, vartabljjm) .. '.<br>' -- dot added !!!
end--if
end--function lfdshowvar
------------------------------------------------------------------------
---- 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 (xdividend, xdivisor)
local resultdiv = 0 -- DIV operator lacks in LUA :-(
resultdiv = math.floor (xdividend / xdivisor)
return resultdiv
end--function mathdiv
local function mathmod (xdividendo, xdivisoro)
local resultmod = 0 -- MOD operator is "%" and bitwise AND operator lack too
resultmod = xdividendo % xdivisoro
return resultmod
end--function mathmod
------------------------------------------------------------------------
-- Local function MATHBITWRIT
-- Write bit selected by ZERO-based index assigning it to "1" or "0".
-- Depends on functions :
-- [E] mathdiv mathmod
local function mathbitwrit (numinkoming, numbityndex, boowrite)
local numpatched = 0
local numcountup = 0
local numweight = 1 -- single bit value 1 -> 2 -> 4 -> 8 ...
local boosinglebit = false
while true do
if ((numinkoming==0) and (numcountup>numbityndex)) then
break -- we have run out of bits on BOTH possible sources
end--if
if (numcountup==numbityndex) then
boosinglebit = boowrite -- overwrite bit
else
boosinglebit = (mathmod(numinkoming,2)==1) -- pick bit
end--if
numinkoming = mathdiv(numinkoming,2) -- shift right
if (boosinglebit) then
numpatched = numpatched + numweight -- add one bit rtl only if true
end--if
numcountup = numcountup + 1 -- count up here until we run out of bits
numweight = numweight * 2
end--while
return numpatched
end--function mathbitwrit
------------------------------------------------------------------------
-- Local function MATHBITTEST
-- Find out whether single bit selected by ZERO-based index is "1" / "true".
-- Result has type "boolean".
-- Depends on functions :
-- [E] mathdiv mathmod
local function mathbittest (numincoming, numbitindex)
local boores = false
while true do
if ((numbitindex==0) or (numincoming==0)) then
break -- we have either reached our bit or run out of bits
end--if
numincoming = mathdiv(numincoming,2) -- shift right
numbitindex = numbitindex - 1 -- count down to ZERO
end--while
boores = (mathmod(numincoming,2)==1) -- pick bit
return boores
end--function mathbittest
------------------------------------------------------------------------
---- 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 LFGSTRINGRANGE
local function lfgstringrange (varvictim, nummini, nummaxi)
local nummylengthofstr = 0
local booveryvalid = false -- preASSume guilt
if (type(varvictim)=='string') then
nummylengthofstr = string.len(varvictim)
booveryvalid = ((nummylengthofstr>=nummini) and (nummylengthofstr<=nummaxi))
end--if
return booveryvalid
end--function lfgstringrange
------------------------------------------------------------------------
-- Local function LFGPOKESTRING
-- Replace single octet in a string.
-- Input : * strinpokeout -- empty legal
-- * numpokepoz -- ZERO-based, out of range legal
-- * numpokeval -- new value
-- This is inefficient by design of LUA. The caller is responsible to
-- minimize the number of invocations of this, in particular, not to
-- call if the new value is equal the existing one.
local function lfgpokestring (strinpokeout, numpokepoz, numpokeval)
local numpokelen = 0
numpokelen = string.len(strinpokeout)
if ((numpokelen==1) and (numpokepoz==0)) then
strinpokeout = string.char(numpokeval) -- totally replace
end--if
if (numpokelen>=2) then
if (numpokepoz==0) then
strinpokeout = string.char(numpokeval) .. string.sub (strinpokeout,2,numpokelen)
end--if
if ((numpokepoz>0) and (numpokepoz<(numpokelen-1))) then
strinpokeout = string.sub (strinpokeout,1,numpokepoz) .. string.char(numpokeval) .. string.sub (strinpokeout,(numpokepoz+2),numpokelen)
end--if
if (numpokepoz==(numpokelen-1)) then
strinpokeout = string.sub (strinpokeout,1,(numpokelen-1)) .. string.char(numpokeval)
end--if
end--if (numpokelen>=2) then
return strinpokeout
end--function lfgpokestring
------------------------------------------------------------------------
local function lfgtestnum (numkaad)
local boodigit = false
boodigit = ((numkaad>=48) and (numkaad<=57))
return boodigit
end--function lfgtestnum
local function lfgtestuc (numkode)
local booupperc = false
booupperc = ((numkode>=65) and (numkode<=90))
return booupperc
end--function lfgtestuc
local function lfgtestlc (numcode)
local boolowerc = false
boolowerc = ((numcode>=97) and (numcode<=122))
return boolowerc
end--function lfgtestlc
------------------------------------------------------------------------
-- Local function LFGTRIMSPCM
-- Trim leading and trailing spaces in a single line (minimal).
-- Input : * strkanskevit -- string, empty or only spaces tolerable, codes
-- below 32 discouraged as not handled in a useful
-- way, type other than "string" NOT permitted
-- There is also "mw.text.trim".
local function lfgtrimspcm (strkanskevit)
local str51rezulto = ''
local numpos51beg = 1 -- ONE-based
local numpos51end = 0 -- ONE-based
local num51char = 0
numpos51end = string.len(strkanskevit)
while true do -- analyze begin
if (numpos51beg>numpos51end) then
break -- empty or consists of only spaces
end--if
num51char = string.byte(strkanskevit,numpos51beg,numpos51beg)
if (num51char~=32) then
break
end--if
numpos51beg = numpos51beg + 1
end--while -- analyze begin
while true do -- analyze trailer
if (numpos51end<numpos51beg) then
break -- empty or consists of only spaces
end--if
num51char = string.byte(strkanskevit,numpos51end,numpos51end)
if (num51char~=32) then
break
end--if
numpos51end = numpos51end - 1
end--while -- analyze trailer
if (numpos51end>=numpos51beg) then
str51rezulto = string.sub(strkanskevit,numpos51beg,numpos51end)
end--if
return str51rezulto
end--function lfgtrimspcm
------------------------------------------------------------------------
---- UTF8 FUNCTIONS [U] ----
------------------------------------------------------------------------
-- Local function LFULNUTF8CHAR
-- Evaluate length of a single UTF8 char in octet:s.
-- Input : * numbgoctet -- beginning octet of a UTF8 char
-- Output : * numlen1234x -- number 1...4 or ZERO if invalid
-- Does NOT thoroughly check the validity, looks at 1 octet only.
local function lfulnutf8char (numbgoctet)
local numlen1234x = 0
if (numbgoctet<128) then
numlen1234x = 1 -- $00...$7F -- ANSI/ASCII
end--if
if ((numbgoctet>=194) and (numbgoctet<=223)) then
numlen1234x = 2 -- $C2 to $DF
end--if
if ((numbgoctet>=224) and (numbgoctet<=239)) then
numlen1234x = 3 -- $E0 to $EF
end--if
if ((numbgoctet>=240) and (numbgoctet<=244)) then
numlen1234x = 4 -- $F0 to $F4
end--if
return numlen1234x
end--function lfulnutf8char
------------------------------------------------------------------------
-- Local function LFUCASEREST
-- Adjust (restricted) case of a single letter (from ASCII + selectable
-- extra set from UTF8) or longer string. (this is REST)
-- Input : * strinco6cs : single unicode letter (1 or 2 octet:s) or
-- longer string
-- * booup6cas : for desired output uppercase "true" and for
-- lowercase "false"
-- * boodo6all : "true" to adjust all letters, "false"
-- only beginning letter
-- * strsel6set : "ASCII" (default, empty string or type "nil"
-- will do too) "eo" "sv" (value "GENE" NOT here)
-- Output : * strinco6cs
-- Depends on functions : (this is REST)
-- [U] lfulnutf8char
-- [G] lfgpokestring lfgtestuc lfgtestlc
-- [E] mathdiv mathmod mathbitwrit
-- This process never changes the length of a string in octet:s. Empty string
-- on input is legal and results in an empty string returned. When case is
-- adjusted, a 1-octet or 2-octet letter is replaced by another letter of same
-- length. Unknown valid char:s (1-octet ... 4-octet) are copied. Broken UTF8
-- stream results in remaining part of the output string (from 1 char to
-- complete length of the incoming string) filled by "Z".
-- Defined sets:
-- "eo" 2 x 6 uppercase and lowercase (CX GX HX JX SX UX cx gx hx jx sx ux)
-- upper CX $0108 GX $011C HX $0124 JX $0134 SX $015C UX $016C lower +1
-- "sv" 2 x 4 uppercase and lowercase (AE AA EE OE ae aa ee oe)
-- upper AE $00C4 AA $00C5 EE $00C9 OE $00D6 lower +$20
-- We peek max 2 values per iteration, and change the string in-place, doing
-- so strictly only if there indeed is a change. This is important for LUA
-- where the in-place write access must be emulated by means of a less
-- efficient function.
local function lfucaserest (strinco6cs, booup6cas, boodo6all, strsel6set)
local numlong6den = 0 -- actual length of input string
local numokt6index = 0
local numlong6bor = 0 -- expected length of single char
local numdel6ta = 0 -- quasi-signed +32 or -32 or +1 or -1 or ZERO
local numcha6r = 0 -- UINT8 beginning char
local numcha6s = 0 -- UINT8 later char (BIG ENDIAN, lower value here above)
local numcxa6rel = 0 -- UINT8 code relative to beginning of block $00...$FF
local numtem6p = 0
local boowan6tlowr = false
local boois6uppr = false
local boois6lowr = false
local boodo6adj = true -- preASSume innocence -- continue changing
local boobotch6d = false -- preASSume innocence -- NOT yet botched
booup6cas = not (not booup6cas)
boowan6tlowr = (not booup6cas)
numlong6den = string.len (strinco6cs)
while true do -- genuine loop over incoming string (this is REST)
if (numokt6index>=numlong6den) then
break -- done complete string
end--if
if ((not boodo6all) and (numokt6index~=0)) then -- loop can skip index ONE
boodo6adj = false
end--if
boois6uppr = false -- preASSume on every iteration
boois6lowr = false -- preASSume on every iteration
numdel6ta = 0 -- preASSume on every iteration
numlong6bor = 1 -- preASSume on every iteration
while true do -- fake loop (this is REST)
numcha6r = string.byte (strinco6cs,(numokt6index+1),(numokt6index+1))
if (boobotch6d) then
numdel6ta = 90 - numcha6r -- "Z" -- delta must be non-ZERO to write
break -- fill with "Z" char:s
end--if
if (not boodo6adj) then
break -- copy octet after octet
end--if
numlong6bor = lfulnutf8char(numcha6r)
if ((numlong6bor==0) or ((numokt6index+numlong6bor)>numlong6den)) then
numlong6bor = 1 -- reassign to ONE !!!
numdel6ta = 90 - numcha6r -- "Z" -- delta must be non-ZERO to write
boobotch6d = true
break -- truncated char or broken stream
end--if
if (numlong6bor>=3) then
break -- copy UTF8 char, no chance for adjustment
end--if
if (numlong6bor==1) then
boois6uppr = lfgtestuc(numcha6r)
boois6lowr = lfgtestlc(numcha6r)
if (boois6uppr and boowan6tlowr) then
numdel6ta = 32 -- ASCII UPPER->lower
end--if
if (boois6lowr and booup6cas) then
numdel6ta = -32 -- ASCII lower->UPPER
end--if
break -- success with ASCII and one char almost done
end--if
numcha6s = string.byte (strinco6cs,(numokt6index+2),(numokt6index+2)) -- only $80 to $BF
numcxa6rel = (mathmod(numcha6r,4)*64) + (numcha6s-128) -- 4 times 64
if ((strsel6set=='eo') and ((numcha6r==196) or (numcha6r==197))) then
numtem6p = mathbitwrit (numcxa6rel,0,false) -- bad way to do AND $FE
if ((numtem6p==8) or (numtem6p==28) or (numtem6p==36) or (numtem6p==52) or (numtem6p==92) or (numtem6p==108)) then
boois6uppr = (numtem6p==numcxa6rel) -- UC below, block of 1
boois6lowr = not boois6uppr
if (boois6uppr and boowan6tlowr) then
numdel6ta = 1 -- UPPER->lower
end--if
if (boois6lowr and booup6cas) then
numdel6ta = -1 -- lower->UPPER
end--if
break -- success with -eo- and one char almost done
end--if
end--if ((strsel6set=='eo') and ...
if ((strsel6set=='sv') and (numcha6r==195)) then
numtem6p = mathbitwrit (numcxa6rel,5,false) -- bad way to do AND $DF
if ((numtem6p==196) or (numtem6p==197) or (numtem6p==201) or (numtem6p==214)) then
boois6uppr = (numtem6p==numcxa6rel) -- UC below, block of 32
boois6lowr = not boois6uppr
if (boois6uppr and boowan6tlowr) then
numdel6ta = 32 -- UPPER->lower
end--if
if (boois6lowr and booup6cas) then
numdel6ta = -32 -- lower->UPPER
end--if
break -- success with -sv- and one char almost done
end--if
end--if ((strsel6set=='sv') and ...
break -- finally to join mark -- unknown non-ASCII char is a fact :-(
end--while -- fake loop -- join mark (this is REST)
if ((numlong6bor==1) and (numdel6ta~=0)) then -- no risk of carry here
strinco6cs = lfgpokestring (strinco6cs,numokt6index,(numcha6r+numdel6ta))
end--if
if ((numlong6bor==2) and (numdel6ta~=0)) then -- no risk of carry here
strinco6cs = lfgpokestring (strinco6cs,(numokt6index+1),(numcha6s+numdel6ta))
end--if
numokt6index = numokt6index + numlong6bor -- advance in incoming string
end--while -- genuine loop over incoming string (this is REST)
return strinco6cs
end--function lfucaserest
------------------------------------------------------------------------
---- HIGH LEVEL STRING FUNCTIONS [I] ----
------------------------------------------------------------------------
-- Local function LFIBANMULTI
-- Test string for validity by banning listed single char:s by multiplicity.
-- Input : * "strkoneven" -- even and 2...24, wrong length gives
-- "true", tolerated multiplicity "0"..."9"
-- * "strsample" -- 0...1'024, empty gives "false",
-- too long gives "true"
-- Output : * "booisevil" -- "true" if evil
-- Depends on functions :
-- [G] lfgtestnum
-- [E] mathmod
-- Incoming control string "strkoneven" with pairs of char:s, for
-- example "'2&0" will tolerate 2 consecutive apo:s but
-- not 3, and completely ban the and-sign "&".
local function lfibanmulti (strkoneven, strsample)
local booisevil = false
local numkonlen = 0 -- length of control string
local numsamlen = 0 -- length of sample string
local numinndex = 0 -- ZERO-based outer index
local numinneri = 0 -- ZERO-based inner index
local numchear = 0
local numnexxt = 0
local nummultiq = 1 -- counted multiplicity
local numcrapp = 0 -- from "strkoneven" char to test
local numvrapp = 0 -- from "strkoneven" multiplicity limit
numsamlen = string.len (strsample)
if (numsamlen~=0) then
numkonlen = string.len (strkoneven)
booisevil = (numkonlen<2) or (numkonlen>24) or (mathmod(numkonlen,2)~=0) or (numsamlen>1024)
while true do -- outer loop
if (booisevil or (numinndex>=numsamlen)) then
break
end--if
numchear = string.byte (strsample,(numinndex+1),(numinndex+1))
if (numchear==0) then
booisevil = true -- ZERO is unconditionally prohibited
break
end--if
numinndex = numinndex + 1
numnexxt = 0
if (numinndex~=numsamlen) then
numnexxt = string.byte (strsample,(numinndex+1),(numinndex+1))
end--if
if (numchear==numnexxt) then
nummultiq = nummultiq + 1
end--if
if ((numchear~=numnexxt) or (numinndex==numsamlen)) then
numinneri = 0
while true do -- innner loop
if (numinneri==numkonlen) then
break
end--if
numcrapp = string.byte (strkoneven,(numinneri+1),(numinneri+1))
numvrapp = string.byte (strkoneven,(numinneri+2),(numinneri+2))
if (not lfgtestnum(numvrapp)) then
booisevil = true -- crime in control string detected
break
end--if
if ((numchear==numcrapp) and (nummultiq>(numvrapp-48))) then
booisevil = true -- multiplicity crime in sample string detected
break
end--if
numinneri = numinneri + 2 -- ZERO-based inner index and STEP 2
end--while -- innner loop
if (booisevil) then
break
end--if
nummultiq = 1 -- restart from ONE !!!
end--if ((numchear~=numnexxt) or (numinndex==numsamlen)) then
end--while -- outer loop
end--if (numsamlen~=0) then
return booisevil
end--function lfibanmulti
------------------------------------------------------------------------
-- 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 -- genuine inner 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 -- genuine inner loop over char:s
if (not boonoban) then -- if "yesban" then
numindeex = 0
while true do -- genuine lower inner loop
varomongkosong = contabisbanned[numindeex+1] -- number of elem unknown
if (type(varomongkosong)~='string') then
break -- abort inner loop (then fake outer loop) due to end of table
end--if
numukurran = string.len (varomongkosong)
if ((numukurran<2) or (numukurran>3)) then
break -- abort inner loop (then fake outer loop) due to faulty table
end--if
if (strqooq==varomongkosong) then
booisvaladv = false
break -- abort inner loop (then fake outer loop) due to violation
end--if
numindeex = numindeex + 1 -- ZERO-based
end--while -- genuine lower inner loop
end--if (not boonoban) then
break -- finally to join mark
end--while -- fake loop -- join mark
return booisvaladv
end--function lfivalidatelnkoadv
------------------------------------------------------------------------
-- Local function LFIFILLINX
-- Replace placeholders "\@" "\\@" or "\~" "\\~" by given substitute string.
-- Input : * strbeforfill -- request string with placeholders to be filled
-- in, no placeholders or empty input is useless
-- but cannot cause major harm
-- * numaskikodo -- ASCII code of placeholder, 64 for "@" or
-- 126 for "~"
-- * varsupstitu -- substitute, either string (same content reused
-- if multiple placeholders), or ZERO-based table
-- (with one element per placeholder such as
-- {[0]="none","neniu"}), length 1...60
-- Output : * strafterfill
-- Depends on functions :
-- [G] lfgstringrange
local function lfifillinx (strbeforfill, numaskikodo, varsupstitu)
local varpfiller = 0 -- risky picking
local strufiller = '' -- final validated filler
local strafterfill = ''
local numlenbigtext = 0 -- len of strbeforfill
local numsfrcindex = 0 -- char index ZERO-based
local numinsrtinde = 0 -- index in table ZERO-based
local numtecken0d = 0
local numtecken1d = 0
numlenbigtext = string.len (strbeforfill)
while true do
if (numsfrcindex>=numlenbigtext) then
break -- empty input is useless but cannot cause major harm
end--if
numtecken0d = string.byte(strbeforfill,(numsfrcindex+1),(numsfrcindex+1))
numsfrcindex = numsfrcindex + 1 -- INC here
numtecken1d = 0 -- preASSume none
if (numsfrcindex<numlenbigtext) then -- pick but do NOT INC
numtecken1d = string.byte(strbeforfill,(numsfrcindex+1),(numsfrcindex+1))
end--if
if ((numtecken0d==92) and (numtecken1d==numaskikodo)) then -- "\@" "\~"
numsfrcindex = numsfrcindex + 1 -- INC more, now totally + 2
varpfiller = 0 -- preASSume nothing available
strufiller = '??' -- preASSume nothing available
if (type(varsupstitu)=='string') then
varpfiller = varsupstitu -- take it as-is (length check below)
end--if
if (type(varsupstitu)=='table') then
varpfiller = varsupstitu [numinsrtinde] -- risk of type "nil"
numinsrtinde = numinsrtinde + 1 -- INC tab index on every placeholder
end--if
if (lfgstringrange(varpfiller,1,60)) then -- !!!FIXME!!! nowiki and other sanitization
strufiller = varpfiller -- now the substitute is finally accepted
end--if
else
strufiller = string.char (numtecken0d) -- no placeholder -> copy octet
end--if
strafterfill = strafterfill .. strufiller -- add one of 4 possible cases
end--while
return strafterfill
end--function lfifillinx
------------------------------------------------------------------------
-- Local function LFIKODEOSG
-- Transcode eo X-surrogates to cxapeloj in a single string (eo only).
-- Input : * streosurr -- ANSI string (empty is useless but cannot
-- cause major harm)
-- Output : * strutf8eo -- UTF8 string
-- Depends on functions :
-- [E] mathdiv mathmod
-- Depends on constants :
-- * table "contabtransluteo" inherently holy
-- To be called ONLY from "lfhfillsurrstrtab".
-- * the "x" in a surr pair is case insensitive,
-- for example both "kacxo" and "kacXo" give same result
-- * avoid "\", thus for example "ka\cxo" would get converted but the "\" kept
-- * double "x" (both case insensitive) prevents conversion and becomes
-- reduced to single "x", for example "kacxxo" becomes "kacxo"
local function lfikodeosg (streosurr)
local vareopeek = 0
local strutf8eo = ''
local numeoinplen = 0
local numinpinx = 0 -- ZERO-based source index
local numknar0k = 0 -- current char
local numknaf1x = 0 -- next char (ZERO is NOT valid)
local numknaf2x = 0 -- post next char (ZERO is NOT valid)
local boonext1x = false
local boonext2x = false
local boosudahdone = false
numeoinplen = string.len(streosurr)
while true do
if (numinpinx>=numeoinplen) then
break
end--if
numknar0k = string.byte(streosurr,(numinpinx+1),(numinpinx+1))
numknaf1x = 0 -- preASSume no char
numknaf2x = 0 -- preASSume no char
if ((numinpinx+1)<numeoinplen) then
numknaf1x = string.byte(streosurr,(numinpinx+2),(numinpinx+2))
end--if
if ((numinpinx+2)<numeoinplen) then
numknaf2x = string.byte(streosurr,(numinpinx+3),(numinpinx+3))
end--if
boonext1x = ((numknaf1x==88) or (numknaf1x==120)) -- case insensitive
boonext2x = ((numknaf2x==88) or (numknaf2x==120)) -- case insensitive
boosudahdone = false
if (boonext1x and boonext2x) then -- got "xx"
strutf8eo = strutf8eo .. string.char(numknar0k,numknaf1x) -- keep one "x" only
numinpinx = numinpinx + 3 -- eaten 3 written 2
boosudahdone = true
end--if
if (boonext1x and (not boonext2x)) then -- got yes-"x" and no-"x"
vareopeek = contabtransluteo[numknar0k] -- UINT16 or type "nil"
if (type(vareopeek)=='number') then
strutf8eo = strutf8eo .. string.char(mathdiv(vareopeek,256),mathmod(vareopeek,256)) -- add UTF8 char
numinpinx = numinpinx + 2 -- eaten 2 written 2
boosudahdone = true
end--if
end--if
if (not boosudahdone) then
strutf8eo = strutf8eo .. string.char(numknar0k) -- copy char
numinpinx = numinpinx + 1 -- eaten 1 written 1
end--if
end--while
return strutf8eo
end--function lfikodeosg
------------------------------------------------------------------------
---- HIGH LEVEL FUNCTIONS [H] ----
------------------------------------------------------------------------
-- Local function LFHREBUILDTABLE
-- Create a copy of a table, even nested.
-- A table from "mw.loadData" is static. It MUST NOT be unhogged, otherwise
-- mess can arise, and it MUST NOT be modified, violation gives an error.
-- Any subtable picked from a table from "mw.loadData" is still static, no
-- data has been copied. Function "mw.clone" applied to such a table crashes
-- on the spot instead of creating a copy.
local function lfhrebuildtable (vareniro)
local vareliro = 0
if (type(vareniro)=='table') then
vareliro = {}
for k3k,v3v in pairs (vareniro) do
if (type(v3v)=='table') then
vareliro[k3k] = lfhrebuildtable(v3v) -- RECURSION
else
vareliro[k3k] = v3v -- here COPY value of elem, NOT a "pointer" to it
end--if
end--for
else
vareliro = vareniro -- return untouched, useless
end--if
return vareliro
end--function lfhrebuildtable
------------------------------------------------------------------------
-- Local function LFHVALI1STATUS99CODE
-- Depends on functions :
-- [E] mathisintrange
local function lfhvali1status99code (varvalue)
local boovalid = false -- preASSume guilt
while true do -- fake loop
if (varvalue==0) then
break -- success thus keep false since no valid error code ;-)
end--if
if (mathisintrange(varvalue,1,99)) then
boovalid = true -- got an error and valid error code returned
else
varvalue = 255 -- failed to return valid status code
end--if
break -- finally to join mark
end--while -- fake loop -- join mark
return varvalue, boovalid
end--function lfhvali1status99code
------------------------------------------------------------------------
-- Local function LFHCONSTRUCTERAR
-- Input : * numerar6code -- 1 ... 99 or 2 ... 99 (resistent against invalid
-- data type, giving "??" then)
-- * boopeek6it -- do peek description #E02...#E99 from table
-- Depends on functions :
-- [N] lfnumto2digit
-- [E] mathisintrange mathdiv mathmod
-- Depends on constants :
-- * maybe table contaberaroj TWO-based (holes permitted)
-- To be called ONLY from lfhbrewerror, lfhbrewerrsm,
-- lfhbrewerrsvr, lfhbrewerrinsi.
local function lfhconstructerar (numerar6code, boopeek6it)
local vardes6krip = 0
local numbottom6limit = 1
local stryt6sux = '#E'
if (boopeek6it) then
numbottom6limit = 2 -- #E01 is a valid code for submodule only
end--if
if (mathisintrange(numerar6code,numbottom6limit,99)) then
stryt6sux = stryt6sux .. lfnumto2digit(numerar6code)
if (boopeek6it) then
vardes6krip = contaberaroj[numerar6code] -- risk of type "nil"
if (type(vardes6krip)=='string') then
stryt6sux = stryt6sux .. ' ' .. vardes6krip
else
stryt6sux = stryt6sux .. ' ??' -- no text found
end--if
end--if (boopeek6it) then
else
stryt6sux = stryt6sux .. '??' -- no valid error code
end--if
return stryt6sux
end--function lfhconstructerar
------------------------------------------------------------------------
-- Local function LFHBREWERRINSI
-- Brew error message with insertable details severity huge.
-- Input : * numerar9code -- TWO-based error code 2 ... 99 (resistent
-- against invalid data type, giving "??" on such)
-- * tabdeta9ils -- ZERO-based table, for example
-- {[0]="none","neniu"}, one element per placeholder
-- "\~" "\\~" located in description for error
-- code in question
-- Depends on functions :
-- [H] lfhconstructerar
-- [I] lfifillinx
-- [G] lfgstringrange
-- [N] lfnumto2digit
-- [E] mathisintrange mathdiv mathmod
-- Depends on constants :
-- * 3 strings constrelabg constrelaen constrlaxhu
-- * table contaberaroj TWO-based (holes permitted)
-- #E02...#E99, note that #E00 and #E01 are NOT supposed to be included here.
-- Placeholder "\@" "\\@" is used elsewhere, thus here we use "\~" "\\~".
local function lfhbrewerrinsi (numerar9code, tabdeta9ils)
local stryt9sux = ''
stryt9sux = lfifillinx(lfhconstructerar(numerar9code,true),126,tabdeta9ils)
stryt9sux = constrlaxhu .. constrelabg .. stryt9sux .. constrelaen .. constrlaxhu
return stryt9sux
end--function lfhbrewerrinsi
------------------------------------------------------------------------
-- Local function LFHFILLSURRSTRTAB
-- Process (fill in, transcode) either a single string, or all string
-- items in a table (even nested) using any type of keys/indexes (such
-- as a holey number sequence and non-numeric ones). Items with a
-- non-string value are kept as-is. Optional filling in own name,
-- and optional transcoding of eo and sv surrogates (via 3 separate
-- sub:s). Optionally even string keys/indexes are transcoded but
-- NOT filled in.
-- Input : * varinkommen -- type "string" or "table"
-- * varfyllo -- string, or type "nil" if no filling-in desired
-- * strlingkod -- "eo" or "sv" to transcode surrogates,
-- anything else (preferably type "nil") to skip this
-- * bookeys -- transcode keys too (preferably "true" or type "nil")
-- Depends on functions :
-- [I] lfifillinx (only if filling-in desired)
-- [I] lfikodeosg (only if conv of eo X-surrogates desired)
-- [I] lfikodsvsg
-- [G] lfgstringrange (via "lfifillinx")
-- [E] mathdiv mathmod (via "lfikodeosg")
-- Depends on constants :
-- * table "contabtransluteo" inherently holey (via "lfikodeosg")
-- We always fully rebrew tables from scratch, thus do NOT replace
-- single elements (doing so would break "in pairs").
local function lfhfillsurrstrtab (varinkommen, varfyllo, strlingkod, bookeys)
local varnky = 0 -- variable without type
local varutmatning = 0
local boodone = false
if (type(varinkommen)=='string') then
if (type(varfyllo)=='string') then
varinkommen = lfifillinx (varinkommen,64,varfyllo) -- fill-in "\@"
end--if
if (strlingkod=='eo') then
varinkommen = lfikodeosg (varinkommen) -- surr
end--if
-- if (strlingkod=='sv') then
-- varinkommen = lfikodsvsg (varinkommen) -- surr
-- end--if
varutmatning = varinkommen -- copy, risk for no change
boodone = true
end--if
if (type(varinkommen)=='table') then
varutmatning = {} -- brew new table from scratch
for k4k,v4v in pairs(varinkommen) do -- nothing done if table empty
if ((bookeys==true) and (type(k4k)=='string')) then
varnky = lfhfillsurrstrtab (k4k, false, strlingkod, nil) -- RECURSION
else
varnky = k4k
end--if
if ((type(v4v)=='string') or (type(v4v)=='table')) then
v4v = lfhfillsurrstrtab (v4v, varfyllo, strlingkod, bookeys) -- RECURSION
end--if
varutmatning[varnky] = v4v -- write same or diff place in dest table
end--for
boodone = true
end--if
if (not boodone) then
varutmatning = varinkommen -- copy as-is whatever it is, useless
end--if
return varutmatning
end--function lfhfillsurrstrtab
------------------------------------------------------------------------
-- Local function LFHFINDPHASE
-- Input : * numphase -- 1...6 or type "nil"
-- * numasciiphase -- ASCII code or type "nil"
-- Output : * vartbrezulto -- on success table with indexes 0...3
-- [0] phase [1] letter [2] xx color [3] eo color
-- Depends on constants :
-- * nested table "contablimahuruf" index 1...6
-- Exactly ONE of the TWO available types of input hint must be provided.
local function lfhfindphase (numphase, numasciiphase)
local varpickero = 0
local vartbrezulto = 0 -- type "nil" if NOT found
local numtabudex = 1 -- ONE-based
while true do
varpickero = contablimahuruf [numtabudex] -- risk of "nil"
if (type(varpickero)~="table") then
vartbrezulto = nil
break -- end reached and NOT found
end--if
if ((numphase==numtabudex) or (numasciiphase==string.byte(varpickero[1]))) then
vartbrezulto = varpickero -- table indexex 1...3
vartbrezulto[0] = numtabudex -- add found phase index 1...6 to index 0
break -- found
end--if
numtabudex = numtabudex + 1
end--while
return vartbrezulto
end--function lfhfindphase
------------------------------------------------------------------------
-- Local function LFHGETWARNA
-- Depends on functions :
-- [H] lfhfindphase
-- Depends on constants :
-- * nested table "contablimahuruf" index 1...6
local function lfhgetwarna (numfaazzo, boospecialeo)
local tabtaabo = {}
local strkolooro = ''
tabtaabo = lfhfindphase (numfaazzo, nil) or {} -- by index -- table or "nil"
if (boospecialeo) then
strkolooro = tabtaabo[3] -- risk of "nil" -- only for "G" and -eo-
else
strkolooro = tabtaabo[2] -- risk of "nil"
end--if
if (type(strkolooro)~='string') then -- protect against stupidity
strkolooro = '505050'
end--if
if (string.len(strkolooro)~=6) then -- protect against stupidity
strkolooro = '505050'
end--if
return strkolooro
end--function lfhgetwarna
------------------------------------------------------------------------
-- Local function LFHANALPREF
-- Analyze and remove possible group prefixes and element prefixes.
-- Input : * strelemento
-- Output : * strelemento : valid prefixes removed on success, emptied on err
-- * numzagrupfn : 0: OK and nothing found
-- 1...6: found "T" ... "C" |
-- 11: unknown letter |
-- 12: redundant prefix | 13: became empty
-- * numzaelemfn : 0: OK and nothing found
-- 1: found "%" vis only
-- 2: found "&" cat only
-- Depends on functions :
-- [H] lfhfindphase
-- [G] lfgtestuc
-- Depends on constants :
-- * nested table "contablimahuruf" index 1...6
-- here we do NOT bother about the order of groups -- T:1 D:2 G:3 F:4 S:5 C:6
-- uppercase letter + colon + space is an attempted group prefix
-- "%" show text do not categorize -- "&" categorize do not show text
-- combined prefix possible "D: & " in this order ie group then element
-- minimal remaining length after removing all prefixes is 2
-- error codes 11..13 are specific for this sub, no #E99 here
local function lfhanalpref (strelemento)
local varlimarisk = 0
local numllenq = 0
local numa0a = 0
local numa1a = 0
local numa2a = 0
local numzagrupfn = 0
local numzaelemfn = 0
local booremvd = false -- assign to true if any valid prefix found
while true do -- genuine loop but no index
booremvd = false -- reset to false on every iteration
numllenq = string.len(strelemento)
if (numllenq<2) then
break -- no chance for a prefix
end--if
numa0a = string.byte (strelemento,1,1)
numa1a = string.byte (strelemento,2,2)
numa2a = 0 -- preASSume
if (numllenq>2) then
numa2a = string.byte (strelemento,3,3)
end--if
if (lfgtestuc(numa0a) and (numa1a==58) and (numa2a==32)) then -- upper ": "
varlimarisk = lfhfindphase (nil, numa0a) -- by letter -- table or "nil"
if (type(varlimarisk)~="table") then
numzagrupfn = 11 -- unknown letter
break
end--if
if ((numzagrupfn~=0) or (numzaelemfn~=0)) then -- no group after element
numzagrupfn = 12 -- redundant or wrong order
break
end--if
numzagrupfn = varlimarisk [0] -- eat it, number 1...6 guaranteed
strelemento = string.sub(strelemento,4,-1) -- remove 3, risk of empty
booremvd = true
end--if
if (((numa0a==37) or (numa0a==38)) and (numa1a==32)) then -- "%" or "&"
if (numzaelemfn~=0) then -- element after group OK, redu still illegal
numzagrupfn = 12 -- redundant
break
end--if
numzaelemfn = numa0a - 36 -- eat it, 1 or 2 only
strelemento = string.sub(strelemento,3,-1) -- remove 2, risk of empty
booremvd = true
end--if
if (not booremvd) then
break -- out of prefixes :-(
end--if
end--while -- genuine loop but no index
if (string.len(strelemento)<2) then
numzagrupfn = 13 -- need at least 2 octet:s left :-(
end--if
if (numzagrupfn>9) then
strelemento = '' -- punishment on error
end--if
return strelemento, numzagrupfn, numzaelemfn
end--function lfhanalpref
------------------------------------------------------------------------
-- Local function LFHANALSUFF
-- Analyze and remove possible suffixes (joiner dash, abbreviation
-- colon with or without extra content, abbreviation dot).
-- Input : * strelemitno
-- * tabpositivelist : for example {"ONE","TWO"} to allow
-- "ONE:" "ONE:"... and "TWO:" "TWO:"...
-- Output : * numlokaaerr
-- * strelemitno : valid suffixes removed on success,
-- string emptied on error
-- * booreqjoin : "true" if joiner dash "-" found at end
-- * booindeedab : "true" if either type "3 UPPERCase + colon" or
-- dot "." found at end
-- * strekstera : extra content if available, colon ":" for
-- "colon-type" without extra content
-- Two of three possible discoveries ("colon-type" and "dot-type")
-- are mutually exclusive, but joiner dash is independent.
-- Type "3 UPPERCase + colon" ("colon-type") is prioritized over dot
-- ("dot-type"), but only possible for whitelisted triples supplied
-- via "tabpositivelist". If not on the whitelist, then the "dot-type"
-- has a chance.
local function lfhanalsuff (strelemitno, tabpositivelist) -- !!!FIXME!!! colon NOT yet supp
local varfromwhite = 0
local strekstera = '' -- preASSume empty
local numlokaaerr = 0 -- preASSume innocence
local numleenj = 0
local numb77b = 0
local numwhiteindex = 1 -- ONE-based
local booreqjoin = false
local booindeedab = false
numleenj = string.len(strelemitno)
numb77b = string.byte(strelemitno,-1,-1)
while true do -- fake loop
if (numb77b==45) then -- joiner dash "-"
if (numleenj<2) then
numlokaaerr = 17 -- bad ie alone dash
break
end--if
booreqjoin = true -- NOT further restricted by length of string !!!
strelemitno = string.sub(strelemitno,1,-2) -- chop it off
numleenj = numleenj - 1 -- must adjust
numb77b = string.byte(strelemitno,-1,-1) -- must be REDONE !!!
end--if
while true do -- inner genuine loop
varfromwhite = tabpositivelist[numwhiteindex]
break -- !!!FIXME!!! colon here
end--while
if (numb77b==46) then -- abbreviation dot "."
if ((numleenj<2) or (numleenj>12)) then
numlokaaerr = 36 -- bad dot !!!FIXME!!! incomplete check limited set
break
end--if
booindeedab = true
strelemitno = string.sub(strelemitno,1,-2) -- chop it off
end--if
break -- finally to join mark
end--while -- fake loop -- join mark
if (numlokaaerr~=0) then -- return both empty on error
strelemitno = ''
strekstera = ''
end--if
return numlokaaerr, strelemitno, booreqjoin, booindeedab, strekstera
end--function lfhanalsuff
------------------------------------------------------------------------
-- 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] lfgtrimspcm (NOPE alternatively "lfgtrimwhites" usable too)
-- * 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 = lfgtrimspcm (stronesub) -- 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 LFHNILDASHTOEMPTY
local function lfhnildashtoempty (tabmasukkeluar, numfromin, numtoto)
local varonepicked = 0
while true do
if (numfromin>numtoto) then -- upper limit is inclusive
break
end--if
varonepicked = tabmasukkeluar[numfromin]
if ((type(varonepicked)~='string') or (varonepicked=='-')) then
tabmasukkeluar[numfromin] = ''
end--if
numfromin = numfromin + 1
end--while
return tabmasukkeluar
end--function lfhnildashtoempty
------------------------------------------------------------------------
-- Local function LFHTRANSLATETRLI
-- Translate T ie translingual stuff (intended for signs and symbols)
-- ie phase 1. Caller must care that the langcode is "mul" only.
-- Input : * strmytrli
-- Output : * vartbtrlitrli : 5 strings at [0]...[4] and 1 boolean at
-- [33] (always false here), or type "number"
-- error code on error
-- Depends on functions :
-- [H] lfhsplittotable lfhnildashtoempty
-- In table coming from "lfhsplittotable" values are either non-empty
-- strings or type "nil". Empty string is impossible in favor of either
-- "-" or type "nil"
-- possible errors:
-- * 2 trli not found (peeking "contabtt" fails)
-- * 3 trli malformed (split via "lfhsplittotable" fails)
-- * 4 control code used (it is prohibited here for "T")
local function lfhtranslatetrli (strmytrli)
local vartbtrlitrli = 0
local varpicktrli = 0
local numgg45sta = 0
local numgg45jum = 0
local numlouklera = 0
while true do -- fake loop
varpicktrli = contabtt [strmytrli] -- risk of "nil"
if (type(varpicktrli)~='string') then
numlouklera = 2
break
end--if
numgg45sta, numgg45jum, vartbtrlitrli = lfhsplittotable (varpicktrli,124,'',1,6)
if (numgg45sta~=0) then
numlouklera = 3
break
end--if
vartbtrlitrli = lfhnildashtoempty (vartbtrlitrli,0,5)
varpicktrli = vartbtrlitrli[5] -- low risk of bad content
vartbtrlitrli[5] = nil -- remove it
if (varpicktrli~='') then -- it is completely prohibited for "T"
numlouklera = 4
break
end--if
vartbtrlitrli[33] = false -- always false for group "T"
if (vartbtrlitrli[1]=='') then
vartbtrlitrli[1] = vartbtrlitrli[0] -- this will probably be the rule
end--if
break -- finally to join mark
end--while -- fake loop -- join mark
if (numlouklera~=0) then
vartbtrlitrli = numlouklera
end--if
return vartbtrlitrli -- type "table" or "number"
end--function lfhtranslatetrli
------------------------------------------------------------------------
-- Local function LFHPOSTPROCESSDIAL
-- Postprocess table for D ie dialect ie phase 2.
-- Input : * tabdialdial : see below, 5 strings at [0]...[4],
-- fool-proof ie non-table legal
-- * strbahanomo : lang name
-- Output : * numdialerror : error code
-- * tabdialdial : see below, 5 strings at [0]...[4]
-- and one boolean at [33]
-- Depends on functions :
-- [H] lfhnildashtoempty
-- example of incoming table table picked by caller from
-- "loaddata-tbldialektoj" at index "en-ZA" :
-- [0] (visi) "Afrika Selatan
-- [1] (kato) "-"
-- [2] "-"
-- [3] (tooltip) "-"
-- [4] (image) "South_Africa_Flag.svg"
-- [5] (prohibited control code) nil
-- example of result based on table above and "strbahanomo" = "Inggris" :
-- [0] (visi) "<small>Inggris</small> Afrika Selatan"
-- [1] (kato) "Inggris Afrika Selatan"
-- [33] false
-- augmentation including "<small>" is applied only to the visible
-- text in [0] AFTER the raw content has been used to brew [1]
-- possible errors:
-- * 6 incoming table is not a table
-- * 7 control code used (it is prohibited here for "D")
local function lfhpostprocessdial (tabdialdial, strbahanomo)
local numlocalerr = 0
while true do -- fake loop
if (type(tabdialdial)~='table') then
tabdialdial = {}
numlocalerr = 6
break
end--if
tabdialdial = lfhnildashtoempty(tabdialdial,0,5) -- type "table" sure
if (tabdialdial[5]~='') then -- residual risk of bad content
tabdialdial = {} -- value here completely prohibited for "D"
numlocalerr = 7
break
end--if
tabdialdial[33] = false -- always false for group "D"
if (tabdialdial[1]=='') then
tabdialdial[1] = strbahanomo .. ' ' .. tabdialdial[0] -- the common case
end--if
tabdialdial[0] = '<small>' .. strbahanomo .. '</small> ' .. tabdialdial[0] -- special rule
break -- finally to join mark
end--while -- fake loop -- join mark
return numlocalerr, tabdialdial
end--function lfhpostprocessdial
------------------------------------------------------------------------
-- Local function LFHTRANSLATELAIN
-- Translate G F S C ie phase 3 to 6.
-- Input : * strmylain
-- * numfazo : 3 ... 6 -- nope-T nope-D G F S C
-- Output : * vartblainlain : 5 strings at [0]...[4] and 1 boolean at
-- [33], or type "number" error code on error
-- Depends on functions :
-- [H] lfhsplittotable lfhnildashtoempty
-- possible errors:
-- * 2 abbre not found (peeking "contab-gfsc" fails)
-- * 3 abbre malformed (split via "lfhsplittotable" fails)
-- * 4 optional control code faulty (different from "" or "1")
local function lfhtranslatelain (strmylain, numfazo)
local vartblainlain = 0
local varpicklain = 0
local numgg46sta = 0
local numgg46jum = 0
local numlokalera = 0
while true do -- fake loop
if (numfazo==3) then
varpicklain = contabgg [strmylain] -- risk of "nil"
end--if
if (numfazo==4) then
varpicklain = contabf [strmylain] -- risk of "nil"
end--if
if (numfazo==5) then
varpicklain = contabs [strmylain] -- risk of "nil"
end--if
if (numfazo==6) then
varpicklain = contabc [strmylain] -- risk of "nil"
end--if
if (type(varpicklain)~='string') then
numlokalera = 2
break
end--if
numgg46sta, numgg46jum, vartblainlain = lfhsplittotable (varpicklain,124,'',1,6)
if (numgg46sta~=0) then
numlokalera = 3
break
end--if
vartblainlain = lfhnildashtoempty (vartblainlain,0,5)
varpicklain = vartblainlain[5] -- low risk of bad content
vartblainlain[5] = nil -- remove it
if ((varpicklain~='') and (varpicklain~="1")) then
numlokalera = 4
break
end--if
vartblainlain[33] = (varpicklain~="1") -- usually true, false possible
if (vartblainlain[1]=='') then
vartblainlain[1] = vartblainlain[0] -- this will probably be the rule
end--if
break -- finally to join mark
end--while -- fake loop -- join mark
if (numlokalera~=0) then
vartblainlain = numlokalera
end--if
return vartblainlain -- type "table" or "number"
end--function lfhtranslatelain
------------------------------------------------------------------------
---- VARIABLES [R] ----
------------------------------------------------------------------------
function exporttable.ek (arxframent)
-- general unknown type
local vartymp = 0 -- variable without type multipurpose
-- special type "args"
local arxsomons = 0 -- metaized "args" from our own or caller's "frame"
-- general tab
local tablg76yleft = {} -- lang
local tabdk78ysubt = {} -- dial
local tabx24x = {} -- chain from arxsomons[2] ... arxsomons[25]
local taberrdetail = {} -- sent to "lfhbrewerrinsi"
-- peeked stuff
local strpiklangcode = '' -- "en" -- site language
local strpikkatns = '' -- "Category" -- namespace
-- general str
local strkodbah = '' -- langcode (2 or 3 lowercase) from arxsomons[1]
local strpagenam = '' -- from "{{PAGENAME}}" or "pagenameoverridetestonly"
local strnambah = '' -- langname (without prefix "Bahasa")
local strwarna = '' -- raw 6 hex digits
local strpikpareuf = '' -- name of templat no quot no NS prefix <<doit>>
local strpikparent = '' -- name of templat long yes quot <<"Template:doit">> !!!FIXME!!!
local strelvisi = '' -- NOT yet UPPERcased (nurplurala, fiziko, vulgara)
local strelkato = '' -- no "<small>" here !!!
local strellink = '' -- "w:" permitted, wall NOT permitted
local streltool = '' -- tooltip
local strelimag = '' -- image name
local strtymp = '' -- temp
local strvisgud = '' -- visible good output
local strinvkat = '' -- invisible category part
local strviserr = '' -- visible error message
local strtrakat = '' -- invisible tracking categories
local strret = '' -- final result string
-- general num
local numerr = 0 -- 1 in 2 pa 3 sub 4 neva 5 neko 6 res 7 gene ...
local numjumele = 0 -- number of elements (1...24) in chain
local numerrpos = 0 -- posi of error in elements (1...24) ie NOT octet:s
local numtamp = 0
local num2statcode = 0
-- general boo
local boonocat = false -- from "nocat=true"
local boonokta = false -- from "R" or "M" global prefix
local bootimp = false
local booismini = false -- "false" for full or "R" | "true" for "M" minimal
local booabbre = false -- is abbreviation element (colon-type or dot-type)
local boobrewkt = false -- brew 1 or 2 cat:s
local boobrewld = false -- brew language-dependent cat too
local booshowvi = false -- show visible text for element
------------------------------------------------------------------------
---- MAIN [Z] ----
------------------------------------------------------------------------
---- GUARD AGAINST INTERNAL ERROR AGAIN ----
-- later reporting of #E01 must NOT depend on uncommentable strings
if (qbooguard) then
numerr = 1 -- #E01 internal
end--if
lfdtracemsg ('This is "mtagg", requested "detrc" report')
lfdshowvar (conbookodlng,'conbookodlng')
lfdshowvar (conboomiddig,'conboomiddig')
lfdshowvar (numerr,'numerr','should be ZERO')
---- PEEK STUFF THAT IS NOT OVERRIDDEN SEMIGENEROUS ----
-- this depends on "arxframent" (only if parent requested) but NOT on "arx"
-- "strpikkatns" does NOT include a trailing ":" colon, and is
-- for "lfykattlaenk" and "lfyapxindlaenk" and "lfikatpaldigu"
-- full "strpikparent" is used for error messages
-- unfull "strpikpareuf" is used for tracking cat:s
if (numerr==0) then
strpiklangcode = contabovrd['sitelang'] or mw.getContentLanguage():getCode() or 'en' -- privileged site language
strpikkatns = contabovrd['katprefi'] or (mw.site.namespaces[ 14] or {})['name'] or 'Category' -- standard namespace
strpikparent = contabovrd['parentfn'] or arxframent:getParent():getTitle() or 'Template:nope' -- fullpagename
if ((type(strpiklangcode)~='string') or (type(strpikkatns)~='string') or (type(strpikparent)~='string')) then
numerr = 1 -- #E01 internal (unlikely)
end--if
vartymp = string.find(strpikparent,':',1,true)
if (mathisintrange(vartymp,2,(string.len(strpikparent)-1))) then
strpikpareuf = string.sub(strpikparent,(vartymp+1),-1) -- make unfull
else
strpikpareuf = strpikparent -- dubi call from ns ZERO or misplaced ":"
end--if
end--if (numerr==0) then
lfdshowvar (strpiklangcode,'strpiklangcode','@Peeking from MW done')
lfdshowvar (strpikkatns,'strpikkatns')
lfdshowvar (numerr,'numerr','should be ZERO')
lfdshowvar (strpikparent,'strpikparent')
---- PROCESS ERROR MESSAGES, FILL IN ALWAYS, CONVERT EO ONLY IF NEEDED ----
-- placeholder "\@" "\\@" is replaced by name of the caller
-- from "strpikparent" in any case, for example <<"SXablono:test">> or
-- <<"Templat:test">>, only for EO the X-substitution is subsequently done
if (numerr==0) then
contaberaroj = lfhfillsurrstrtab (contaberaroj, strpikparent, strpiklangcode, nil)
contabtt = lfhfillsurrstrtab (contabtt, nil, strpiklangcode, nil)
contabgg = lfhfillsurrstrtab (contabgg, nil, strpiklangcode, true) -- also keys
contabtrako = lfhfillsurrstrtab (contabtrako, nil, strpiklangcode, nil)
end--if
lfdtracemsg ('Conversion and filling done')
---- GET THE ARX (ONE OF TWO) ----
-- must be seized independently on "numerr" even if we already suck
arxsomons = arxframent.args -- "args" from our own "frame"
if (type(arxsomons)~="table") then
arxsomons = {} -- guard against indexing error
numerr = 1 -- #E01 internal
end--if
if (arxsomons['caller']=="true") then
arxsomons = arxframent:getParent().args -- "args" from caller's "frame"
end--if
if (type(arxsomons)~="table") then
arxsomons = {} -- guard against indexing error again
numerr = 1 -- #E01 internal
end--if
---- PICK TOTALLY TWO SUBTABLES FROM TWO SUBMODULES ----
-- here risk of #E02 #E03 #E04 #E05
-- on error we assign "numerr" and maybe "num2statcode" both used far below
while true do -- fake loop
if (numerr~=0) then
break -- to join mark
end--if
num2statcode, bootimp = lfhvali1status99code (qldingvoj[2]) -- from "loaddata-tbllingvoj"
if (num2statcode~=0) then
if (bootimp) then
numerr = 3 -- #E03 nombrigita
else
numerr = 2 -- #E02 malica
end--if
break -- to join mark
end--if
vartymp = qldingvoj['T76'] -- from "loaddata-tbllingvoj"
if (type(vartymp)~='table') then -- important check
numerr = 2 -- #E02 malica
break -- to join mark
end--if
tablg76yleft = vartymp -- y-index -> leftmost column (langcode to langname)
num2statcode, bootimp = lfhvali1status99code (qldlektoj[2]) -- from "loaddata-tbldialektoj"
if (num2statcode~=0) then
if (bootimp) then
numerr = 5 -- #E05 nombrigita
else
numerr = 4 -- #E04 malica
end--if
break -- to join mark
end--if
vartymp = qldlektoj['T78'] -- from "loaddata-tbldialektoj"
if (type(vartymp)~='table') then -- important check
numerr = 4 -- #E04 malica
break -- to join mark
end--if
tabdk78ysubt = vartymp -- y-index -> sub-sub-table (one table per dialcode)
break -- finally to join mark
end--while -- fake loop -- join mark
lfdshowvar (numerr,'numerr','picked two subtables T76 ling and T78 dial')
lfdshowvar (num2statcode,'num2statcode')
---- SEIZE 2...25 ANON PARAMETERS ----
-- in arxsomons[1] expecting langcode
-- in arxsomons[2]...arxsomons[25] expecting main control chain
-- result in "strkodbah" will be later used as index in "tablg76yleft"
-- chain goes into "tabx24x" with prevalidation
-- #E08 wrong number of params
-- #E09 wrong length of single param
-- #E04 bad langcode !!!FIXME!!!
-- #E06 reserved characters !!!FIXME!!!
if (numerr==0) then
if ((arxsomons[1]==nil) or (arxsomons[2]==nil) or (arxsomons[26])) then
numerr = 8 -- #E08 -- need 2 ... 25 anon params, NOT more
else
strkodbah = arxsomons[1] -- y-index word (langcode)
if (not lfivalidatelnkoadv(strkodbah,false,false,conbookodlng,conboomiddig,false)) then
numerr = 4 -- #E04 -- evidente nevalida !!!FIXME!!!
end--if
end--if
end--if
if (numerr==0) then
do -- scope
local numindxxi = 0
local varjjtmpj = ''
while true do
varjjtmpj = arxsomons[numindxxi+2] -- TWO-based
if (type(varjjtmpj)~='string') then
if (numindxxi==0) then
numerr = 8 -- #E08 -- we need at least one more
end--if
break -- abort with success or failure
end--if
if (not lfgstringrange (varjjtmpj,2,60)) then
numerr = 9 -- #E09
break
end--if
tabx24x [numindxxi] = varjjtmpj -- ZERO-based
numindxxi = numindxxi + 1
end--while
if (numerr==0) then
numjumele = numindxxi -- 1...24 save value
end--if
end--do scope
end--if
lfdshowvar (strkodbah,'strkodbah','langcode')
lfdshowvar (numjumele,'numjumele','number of elements')
lfdshowvar (tabx24x,'tabx24x',nil,26)
lfdshowvar (numerr,'numerr','after seizure of anon params')
---- PROCESS 3 HIDDEN NAMED PARAMS INTO 1 STRING AND 2 BOOLEAN:S ----
-- this may override "mw.title.getCurrentTitle().text" and
-- stipulate content in "strpagenam", empty is NOT valid
-- bad "pagenameoverridetestonly=" can give #E01
-- no error is possible from other hidden parameters
-- "detrc=" and "nocat=" must be seized independently on "numerr"
-- even if we already suck, but type "table" must be ensured !!!
strpagenam = '' -- using vartymp here
if (numerr==0) then -- get pagename (error if bad, silent if absent)
vartymp = arxsomons['pagenameoverridetestonly']
if (type(vartymp)=='string') then -- do NOT merge if:s
if (lfgstringrange(vartymp,1,120)) then -- empty or too long NOT legal
strpagenam = vartymp
else
numerr = 1 -- #E01 internal
end--if
end--if
end--if
if (arxsomons['nocat']=='true') then
boonocat = true
end--if
if (arxsomons['detrc']=='true') then
lfdtracemsg ('Param "detrc=true" seized')
else
qboodetrc = false -- was preassigned to "true"
qstrtrace = '' -- shut up now
end--if
lfdshowvar (numerr,'numerr','done with hidden params')
lfdshowvar (boonocat,'boonocat')
---- SEIZE THE PAGENAME FROM MW ----
-- later reporting of #E01 must NOT depend on uncommentable strings
-- must be 1...120 octet:s keep consistent with "pagenameoverridetestonly="
if ((numerr==0) and (strpagenam=='')) then -- get pagename (error if bad)
vartymp = mw.title.getCurrentTitle().text -- without namespace prefix
if (lfgstringrange(vartymp,1,120)) then -- empty or too long NOT legal
strpagenam = vartymp -- cannot be left empty
else
numerr = 1 -- #E01 internal
end--if
end--if
---- STRICTLY CHECK THE PAGENAME ----
-- for example "o'clock" is legal and "o'clock's" is legal too
-- but "o''clock" is a crime
if (numerr==0) then
if (strpagenam=='') then
numerr = 1 -- #E01 internal
else
if (lfibanmulti("'1[0]0{0}0",strpagenam)) then -- returns true if evil
numerr = 1 -- #E01 internal
end--if
end--if
end--if
lfdshowvar (numerr,'numerr','checked pagename')
---- WHINE IF YOU MUST #E01 ----
-- reporting of this error #E01 must NOT depend on
-- uncommentable strings as "contaberaroj"
-- do NOT use sub "brewerr", report our name (NOT of template) and in EN
if (numerr==1) then
strtymp = '#E01 Internal error in module "mtagg".'
strviserr = constrlaxhu .. constrelabg .. strtymp .. constrelaen .. constrlaxhu
end--if
---- PEEK THE LANGUAGE NAME ----
-- for lang name in site language (/c0/) peeked from "tablg76yleft":
-- * type "nil" can become #E05 (unknown code) if the site
-- langcode works, otherwise #E03 (broken submodule)
-- * "-" is unconditionally evil with #E03 (broken submodule)
-- here we depend on "strpiklangcode" and submodule "loaddata-tbllingvoj"
if (numerr==0) then
while true do -- fake loop
vartymp = tablg76yleft[strkodbah]
if (type(vartymp)~='string') then
if (type(tablg76yleft[strpiklangcode])=='string') then
numerr = 5 -- #E05 unknown code given (since site code works)
else
numerr = 3 -- #E03 broken submodule (site code does NOT work either)
end--if
break
end--if
if (string.len(vartymp)<2) then -- less than 2 letters is not legal
numerr = 3 -- #E03 broken submodule
break
end--if
strnambah = vartymp -- got lang name :-)
break -- finally to join mark
end--while -- fake loop -- join mark
end--if
lfdshowvar (strnambah,'strnambah','peeked lang name via T76')
lfdshowvar (numerr,'numerr')
---- PARSE THE CONTROL CHAIN ----
-- table "tabx24x" is guaranteed to contain at least one element at index 0
-- the stipulated order is D:1 G:2 F:3 S:4 C:5 -- ZERO means no phase yet
-- fill "strvisgud" and "strinvkat" here
-- "%" show text do not categorize -- "&" categorize only do not show text
-- combined prefix possible "D: & " in this order group -> element
-- from "lfhanalpref" : 0 nope | 1..5 "D" ... "C" | 11 unk | 12 red | 13 emp
-- 0 nope | 1 found "%" ("nopercatcent") vis only
-- | 2 found "&" cat only
-- the 5 components are "strelvisi", "strelkato", "strellink",
-- "streltool", "strelimag"
-- "[[File:Omong_Kosong.png|20px|link=]]" note that "link=" needs PD image
-- there are 4 ways to suppress lemma categorization:
-- * full suppression via "nocat=true" into "boonocat = true" (suppresses
-- also tracking categories)
-- * full suppression via "R" or "M" global prefix into "boonokta = true"
-- * full suppression via prefix "%" AKA "nopercatcent" in a plain
-- or abbreviation element (via numanlelpr==1) into "boobrewkt = false"
-- * partial suppression via control code "1" in an abbreviation
-- element into "boobrewld = false"
if (numerr==0) then
do -- scope
local tabkompon = {}
local strelemin = ''
local strexxtra = '' -- autogenerated or explicit
local strdialkey = ''
local strspankolor = ''
local numphaase = 0 -- group we are in, start from ZERO
local numsrcpoi = 0 -- index
local numanlgrpr = 0
local numanlelpr = 0 -- 0 or 1 or 2 current
local numprvelpr = 0 -- 0 or 1 or 2 previous
local numoct = 0
local numerakod = 0 -- local error code
local boojoinrekv = false -- join request copied into "boodojoin"
local boodojoin = false
while true do
if (numsrcpoi==numjumele) then -- at least ONE iteration
break
end--if
strelemin = tabx24x [numsrcpoi] -- type "nil" impossible
lfdtracemsg ('Picked one element of the control chain')
lfdshowvar (numsrcpoi,'numsrcpoi')
lfdshowvar (strelemin,'strelemin')
if (numsrcpoi==0) then
numoct = string.byte(strelemin,1,1) -- length prevalidated 2...50
if (numoct==82) then
boonokta = true -- got "R"
strelemin = string.sub(strelemin,2,-1)
end--if
if (numoct==77) then
boonokta = true -- got "M"
booismini = true -- !!!FIXME!!! implementation non-existent
strelemin = string.sub(strelemin,2,-1)
end--if
lfdtracemsg ('Inspected and eaten possible special global ZERO-position prefix')
lfdshowvar (strelemin,'strelemin','again')
lfdshowvar (boonokta,'boonokta')
lfdshowvar (booismini,'booismini')
end--if
strelemin, numanlgrpr, numanlelpr = lfhanalpref (strelemin)
lfdtracemsg ('Chopped off possible prefixes')
lfdshowvar (strelemin,'strelemin','again')
lfdshowvar (numanlgrpr,'numanlgrpr')
lfdshowvar (numanlelpr,'numanlelpr','tristate, ONE of ONE crucial for join')
if (numanlgrpr==11) then
numerr = 15 -- #E15 bad group code (message needs index too)
break
end--if
if (numanlgrpr==12) then
numerr = 16 -- #E16 redu or invalid group prefix
break
end--if
if (numanlgrpr==13) then
numerr = 7 -- #E07 generic (string became too short)
break
end--if
if (numanlgrpr~=0) then
if (numanlgrpr<numphaase) then
numerr = 17 -- #E17 wrong order of group prefixes
break
end--if
if (numanlgrpr==numphaase) then
numerr = 19 -- #E19 repetitive group prefix
break
end--if
numphaase = numanlgrpr -- OK, got a new group
boodojoin = false -- reset join request !!!FIXME!!! should be an error ??
end--if
if (numphaase==0) then -- this must be below "numphaase = numanlgrpr" !!!
numerr = 20 -- #E20 element outside of group
break
end--if
numerakod, strelemin, boojoinrekv, booabbre, strexxtra = lfhanalsuff (strelemin,{"VRF","VRG","VRH"})
lfdtracemsg ('Chopped off possible suffixes')
lfdshowvar (numerakod,'numerakod')
lfdshowvar (strelemin,'strelemin','again and maybe reduced')
lfdshowvar (boojoinrekv,'boojoinrekv')
lfdshowvar (booabbre,'booabbre')
lfdshowvar (strexxtra,'strexxtra')
if (boodojoin) then
if (boojoinrekv) then
lfdtracemsg ('Both are true, #E29')
numerr = 29 -- #E29 cannot join more than 2 elements
break
end--if
if (not (((numprvelpr==0) and (numanlelpr==1)) or ((numprvelpr==1) and (numanlelpr==0)))) then
lfdtracemsg ('NOT exactly ONE "%", #E29')
numerr = 29 -- #E29 exactly ONE of them must have "%", prohibit "&"
break
end--if
end--if
if ((numanlelpr~=0) and booabbre and (strexxtra~='')) then
lfdtracemsg ('Element prefix and colon-type, #E21')
numerr = 21 -- #E21 do not combine like that
break
end--if
-- !!!FIXME!!! #E28 failed auto
if ((numphaase==1) and (strkodbah~="mul")) then -- "T"
numerr = 23 -- #E23 group "T" requires "mul"
break
end--if
if (booabbre) then
if (numphaase==1) then -- "T"
lfdshowvar (strelemin,'strelemin','before T-translation')
tabkompon = lfhtranslatetrli (strelemin)
lfdshowvar (tabkompon,'tabkompon','after T-translation')
if (type(tabkompon)~="table") then
numerr = 24 -- #E24 unknown translang !!!FIXME!!! use local error code returned
break
end--if
end--if
if (numphaase==2) then -- "D"
strdialkey = strkodbah .. '-' .. strelemin
lfdshowvar (strdialkey,'strdialkey','before D-translation')
tabkompon = lfhrebuildtable (tabdk78ysubt [strdialkey]) -- risk of "nil"
lfdshowvar (tabkompon,'tabkompon','after D-translation')
numerakod, tabkompon = lfhpostprocessdial (tabkompon, strnambah)
lfdshowvar (tabkompon,'tabkompon','after D-postprocessing')
if (numerakod~=0) then
numerr = 25 -- #E25 unknown dialect !!!FIXME!!! local code 6 vs local code 7
break
end--if
end--if
if (numphaase>2) then -- G F S C
lfdshowvar (strelemin,'strelemin','before GFSC-translation')
tabkompon = lfhtranslatelain (strelemin,numphaase)
lfdshowvar (tabkompon,'tabkompon','after GFSC-translation')
if (type(tabkompon)~="table") then
numerr = 26 -- #E26 unknown 4 group !!!FIXME!!! use local error code returned
break
end--if
end--if
strelvisi = tabkompon[0] -- translated abbreviation element
strelkato = tabkompon[1] -- same or different here
strellink = tabkompon[2]
streltool = tabkompon[3]
strelimag = tabkompon[4]
boobrewkt = (numanlelpr~=1) -- false for "%" ("nopercatcent") vis only
boobrewld = tabkompon[33]
booshowvi = (numanlelpr~=2) -- false for "&" cat only
else
strelvisi = strelemin -- plain text element
strelkato = strelemin -- always same here
strellink = '' -- inherently impossible
streltool = '' -- inherently impossible
strelimag = '' -- inherently impossible
boobrewkt = (numanlelpr~=1)
boobrewld = true -- true here (false for T and D see below)
booshowvi = (numanlelpr~=2)
end--if
if ((numphaase==1) or (numphaase==2)) then
boobrewld = false -- always false for groups T and D
end--if
if (boobrewkt and (not boonocat) and (not boonokta)) then -- do 1 or 2 cats from "strelkato"
strtymp = lfucaserest(strelkato,true,false,'eo') -- make upper, only one char
strinvkat = strinvkat .. '[[' .. strpikkatns .. ':' .. strtymp .. ']]'
if (boobrewld) then
strinvkat = strinvkat .. '[[' .. strpikkatns .. ':' .. strtymp .. ' (' .. strnambah .. ')]]'
end--if
end--if
if (booshowvi) then -- do show text from "strelvisi" from above and more
strwarna = lfhgetwarna (numphaase,((strkodbah=="eo") and (numphaase==3))) -- only by index
strspankolor = '<span style="background-color:#' .. strwarna .. '>'
if (strellink~='') then
strelvisi = '[[' .. strellink .. '|' .. strelvisi .. ']]'
end--if
strelvisi = strspankolor .. '<i>' .. strelvisi .. '</i></span>'
if (strelimag~='') then
strelvisi = ' [[File:'.. strelimag ..'|20px]] ' .. strelvisi
end--if
if (strvisgud~='') then
if (boodojoin) then
strvisgud = strvisgud .. strspankolor .. ' ' .. '</span>' -- separate them by coloured space only
else
strvisgud = strvisgud .. '; ' -- separate them harder and interrupt color
end--if
end--if
strvisgud = strvisgud .. strelvisi
end--if
boodojoin = boojoinrekv -- join request applies to following element
numprvelpr = numanlelpr -- and crucial check of "%" will be done there
numsrcpoi = numsrcpoi + 1
end--while
numerrpos = numsrcpoi -- posi into more durable var, used on error only
end--do scope
end--if (numerr==0) then
if ((numerr==0) and (strvisgud~='')) then
strvisgud = '(' .. strvisgud .. ')'
end--if
---- BREW TRACKING CAT:S #E02...#E99 ----
-- no tracking cat:s for #E01
-- "nocat=true" suppresses even tracking cat:s !!!FIXME!!!
-- special handling of #E04 evid and #E05 neko !!!FIXME!!! error codes
-- here we use "contabtrako" (string and 1...5)
-- here we use "strpikpareuf" name of calling template
-- here we use "strkodbah"
if ((numerr>1) and (not boonocat)) then
if ((numerr==4) or (numerr==5)) then
if (numerr==4) then
strtymp = contabtrako [1] -- #E04 evid !!!FIXME!!! error codes
else
strtymp = contabtrako [2] -- #E05 neko !!!FIXME!!! error codes
end--if
strtymp = '[[' .. strpikkatns .. ':' .. strtymp .. ' ' .. contabtrako [3] -- [3] is term for "langcode"
strtrakat = strtymp .. ']]' -- generic #E04 #E05 !!!FIXME!!! error codes
strtrakat = strtrakat .. strtymp .. ' ' .. contabtrako [4] .. ' (' .. strpikpareuf .. ')]]' -- loke
strtrakat = strtrakat .. strtymp .. ' ' .. contabtrako [5] .. ' (' .. strkodbah .. ')]]' -- nome
else
strtymp = '[[' .. strpikkatns .. ':' .. contabtrako ['cetgen'] -- "bad use of template"
strtrakat = strtymp .. ']]' -- generic other errors #E02 #E03 E#06 ...
strtrakat = strtrakat .. strtymp .. ' (' .. strpikpareuf .. ')]]' -- specific
end--if
end--if
---- WHINE IF YOU MUST #E02...#E99 ---- !!!FIXME!!! from submodule
-- reporting of errors #E02...#E99 depends on uncommentable strings
-- and name of the caller filled in "lfhfillsurrstrtab"
-- some of them need "numerrpos" via "taberrdetail"
if (numerr>1) then -- NOT for #E01
if (numerr==15) then
taberrdetail = {[0]=tostring(numerrpos+2)} -- #E15 message needs index too
end--if
strviserr = lfhbrewerrinsi (numerr,taberrdetail)
end--if
---- RETURN THE JUNK STRING ----
-- on #E02 and higher we risk partial results in "strvisgud" and "strinvkat"
lfdtracemsg ('Ready to return string glued together from 1 + 4 parts')
lfdshowvar (strvisgud,'strvisgud')
lfdshowvar (strinvkat,'strinvkat')
lfdshowvar (strviserr,'strviserr')
lfdshowvar (strtrakat,'strtrakat')
if (numerr==0) then
strret = strvisgud .. strinvkat
else
strret = strviserr .. strtrakat
end--if
if (qboodetrc) then -- "qstrtrace" declared separately outside main function
strret = "<br>" .. qstrtrace .. "<br><br>" .. strret
end--if
return strret
end--function
---- RETURN THE JUNK TABLE ----
return exporttable