Modul:msngtbllin
Tampilan
Dokumentasi untuk modul ini dapat dibuat di Modul:msngtbllin/doc
--[===[
MODULE "MSNGTBLLIN" (single tabelo kun lingvoj)
"eo.wiktionary.org/wiki/Modulo:msngtbllin" <!--2024-Dec-05-->
"id.wiktionary.org/wiki/Modul:msngtbllin"
Purpose: brews a table with info about one language
Utilo: generas tabelon kun informoj pri unu lingvo
Manfaat: membuat tabel dengan informasi tentang satu bahasa
Syfte: skapar en tabell med information kring ett spraak
Used by templates / Uzata far sxablonoj /
Digunakan oleh templat / Anvaent av mallar:
* "montablng" (EO) / "mpltabbah" (ID)
Required submodules / Bezonataj submoduloj / Submodul yang diperlukan:
* "loaddata-tbllingvoj" T78 in turn requiring template "tbllingvoj" (EO)
* "loaddata-tblbahasa" T78 in turn requiring template "tblbahasa" (ID)
Incoming: * 2 parameters
* anonymous obligatory parameter
* string with 2 or 3 char:s -- language access code
* named obligatory parameter
* "infsel=" control string for lines -- 6 digits (boolean
options: "0" do not show | "1" show and query |
value "2" NOT available here)
* "d07" "tln" top lng cat
* "d07" "kap" cat
* "d08" "vor" cat
* "d08" "mal" cat
* "d09" "apx" appendix
* "d09" "ind" index
Returned: * one big string
This module is unbreakable (when called with correct module name
and function name). Every imaginable input from the caller and
from the imported module "loaddata-tbllingvoj" will output either
a useful result or at least the string "Grava eraro".
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 importata modulo "loaddata-tbllingvoj" eldonos aux
utilan rezulton aux almenaux signocxenon "Grava eraro".
In "msngtbllin" we walk down and for every d-item /d00/ ... /d13/ we brew a
row with two cells title and content. In "bigtable-tbllingvoj" "mkomtbllin" we
walk right and for every d-item /d00/ ... /d13/ we brew one cell in a column.
Note that the parameter "infsel=" (control string with 6 char:s) has almost
same function in both "bigtable-tbllingvoj" "mkomtbllin" and "msngtbllin", but
some of the values are tristate in "bigtable-tbllingvoj" "mkomtbllin", whereas
all are boolean in "msngtbllin", and querying is always on.
It is possible to control whether to show link to appendix page in "d09"
or not. This is provided for consistency with "mkomtbllin", but since
this module "msngtbllin" is supposed to be called from exactly those
appendix pages (via "montablng" or "mpltabbah"), this subparameter will
usually be false ie "0".
Line numbering in the source table:
- numbering starts from ZERO
- /cy/ does not count (it has theoretically index "-1")
- note that there is no comma between /cy/ and /c0/
Structure of a line in the source table with 1+11 values
for 1+11 lines in the generated table:
- /cy/ : y-index marker (2 or 3 digits)
- /c0/ : name of the language in the site language
* EO: usually AJ lowercase, alternatively SB uppercase begin
* ID: without "bahasa " and begins with uppercase letter
- /c1/ : QID (for example "Q5432") "Q" + 2...8 digits, earliest digit
"1"..."9", further digits "0"..."9"
- /c2/ : name of the language in the language itself
("propralingve")
- /c3/ : constructed and antique status (digit "0"..."3")
- /c4/ : ISO 639-1:2002 2-letter code (only lowercase)
- /c5/ : ISO 639-3:2007 3-letter code (only lowercase)
- /c6/ : wiki access code, itself usually same as /cy/, but may be different
and longer up to 10 char:s, for example "zh-min-nan", leave it "-"
here if code is same or unknown, use "??" if code belongs to
other language ("als.pedia.org")
- c7 : wiki availability code (2 digits "0"..."2" ie "00"..."22"),
"-" causes reddish background and no info about availability
- c8 : name of ipedia article, base principle usually
followed (there are some exceptions):
- EO: core word usually AJ name with uppercased begin
followed by " lingvo", no "la" article
- ID: prefixed by "Bahasa " and core word begins with uppercase letter
- c9 : category with our site language ("eo" or "id") in other tionary
(with category NS prefix, but without language prefix, without "]]"
or other nonsense, can be absurdly long
"Rummad:Wikeriadur:Distagaduriou' a vank en indonezeg" has 52
octet:s and even worse 2 apo:s)
- ca : number of pages in that category, apo:s ("16'384") are
tolerable (this cannot be peeked automatically)
Note that /cy/ and /c0/ are ultimately obligatory, the remaining
ones are only highly desirable.
Overall structure of the generated destination table:
* title cell "colspan=2" with fixed string (big, bold, no link)
* body part
* 14 rows per 2 cells with info
or
* one single cell "colspan=2" with lagom error #E12 "Nekonata lingvokodo"
* bottom cell "colspan=2" with update/purge link (depends on pagename)
and link to source table (fixed) and link to complete table (fixed)
Structure of the right column in the destination table with 14 rows:
- /d00/ : * incoming language access code (bold) only if valid and found
# adjust background for "eo" only
- /d01/ : * name of the language in the site language with link to the
lemma page (name literally peeked from /c0/ in the source table,
must be available and valid, link augmented by "lfiultpl5repl"
according to control string "contabpages[0]")
- /d02/ : * QID (for example "Q5432")
- /d03/ : * name of the language in the language itself
(literally peeked from /c1/ in the source table)
- d04 : - constructed and antique status (expanded from digit "0"..."3"
peeked from "c2" in the source table)
# adjust background to greenish or grey if applicable
- d05 : - "ISO 639-1:2002" 2-letter langcode
(literally peeked from "c3" in the source table)
- d06 : - "ISO 639-3:2007" 3-letter langcode
(literally peeked from /c4/ in the source table)
- d07 : - ? link to the "tln" top lng category in own tionary if
desired, no page count here
- ? EOL (only if both cat:s are desired)
- ? link to the "kap" category in own tionary with all words in
the language (constructed from constant string "strpikkatns"
(category namespace prefix without ":") and /c0/ augmented by
"lfiultpl5repl" according to control string "contabpages[6]")
- ? EOL (if complaint below exists)
- ? complaint about not existing if applicable
- ? EOL (if the "parent" link to the "kap" category is present)
- ? number of pages (queried) or "??" if querying does not work
# adjust background to reddish if the category (one of two)
does not exist
! depends on variables "tabctl.tlnsow" and "tabctl.tlnexp" and "tabctl.kapsow"
and "tabctl.kapexp" and includes expensive querying (2), column
can be completely hidden by "tabkol.d07"
- d08 : - ? link to the "vor" category in own tionary with all dictionaries in
the language (constructed from constant string "strpikkatns"
(category namespace prefix without ":") and /c0/ augmented by
"lfiultpl5repl" according to control string "contabpages[3]"), no
page count here
- ? EOL (only if both cat:s are desired)
- ? link to the "mal" template cat
- ? EOL (if complaint below exists)
- ? complaint about not existing if applicable
- ? EOL (if the "parent" link to the "mal" template cat is present)
- ? number of pages (queried) or "??" if querying does not work
# adjust background to reddish if the category (one of two)
does not exist
! depends on variables "tabctl.vorsow" and "tabctl.vorexp" and "tabctl.malsow"
and "tabctl.malexp" and includes expensive querying (2), column
can be completely hidden by "tabkol.d08"
- d09 : - link to the appendix page (constructed from constant string
"strpikapxns" (appendix namespace prefix without ":") and /c0/
augmented by "lfiultpl5repl" according to control string
"contabpages[1]") controlled by "tabctl.apxsow"
- EOL (only if both pages are desired)
- link to the index page in own tionary with
the language (constructed from constant string "strpikindns"
(index namespace prefix without ":") and /c0/ augmented by
"lfiultpl5repl" according to control string "contabpages[2]")
# adjust background to reddish if at least one of them does not exist
! depends on variables "tabctl.apxsow" and "tabctl.apxexp" and "tabctl.indsow"
and "tabctl.indexp" and includes expensive querying (1), column
can be completely hidden by "tabkol.d09"
- d10 : - quasi-external link to wikipedia in the language concerned
(constructed from "c5" and "c6" and /cy/, irrespective availability)
- EOL (if note below exists)
- note about bad availability if applicable
# adjust background to grey according to bad availability
! no expensive querying here
- d11 : - quasi-external link to tionary in the language concerned
(constructed from "c5" and "c6" and /cy/, irrespective availability)
- EOL (if note below exists)
- note about bad availability if applicable
# adjust background to grey according to bad availability
! no expensive querying here
& special rule ie blocking for own site language
- d12 : - quasi-external link to the article in own ipedia about the language
(article name constructed from "c7", or alternatively if "c7" is
not available then it is guessed using "lfiultpl5repl" from /c0/
and "contabpages[7]" and " (??)" is added)
# adjust background to reddish if "c7" is not available
! no expensive querying here
- d13 : - quasi-external link to EO or ID category in the tionary in the
language concerned (peeked from "c8" in the source table)
- EOL (if number of articles below exists)
- number of articles (peeked from "c9" in the source table)
# adjust background to reddish if "c8" or "c9" is not available
! no expensive querying here
& special rule ie blocking for own site language
Expensive querying: !!!FIXME!!!
There are 6 expensive queries (2 cat:s plus appendix plus index, one cat
costs 2 bucks ("ifexist" and "pagesincategory") per page, appendix and index
cost one buck per page) per language and thus per table row. This is a big
problem in "bigtable-tbllingvoj" "mkomtbllin" but here in "msngtbllin"
it is no problem at all.
Error handling (here in "msngtbllin" we are much stricter than
"bigtable-tbllingvoj" "mkomtbllin" is and do NOT show broken stuff, and do NOT
use red background, but reddish background is still applied when appropriate):
- argument supplied from the caller is bad, or neither the requested language
nor our own language could be
peeked, or the peeked complete line contains syntax errors,
output is minimal with huge error "Grava eraro" then, no big table
(replace the output string if we already began to brew the table)
- #E12 unknown langcode still show table with lagom "Nekonata lingvokodo"
- if there are too many elements in a line then we ignore the
superfluous ones
- if there are too few elements (but at least one ie /c0/) in a line
then we show "-" (not "=") and adjust the background color in
cells not getting any content
- if /c0/ is not available then #E15 "Grava eraro"
- if "mw.title.getCurrentTitle().prefixedText" does not reveal our
pagename (needed for purge link) then we don't whine but use a bad
default "Special:Recent changes" instead
Errors codes in "numerr":
* #E01 -- internal
* #E02
* #E03
* #E08 -- number of anon param
* #E11 -- obviously invalid langcode from anon param {{{1}}} (only msng)
* #E12 -- unknown langcode from anon param {{{1}}} (only msng,
only error showed inside table)
* #E13 -- anon param {{{1}}} boolean is bad (only big)
* #E14 -- anon param {{{2}}} integer is bad (only big)
* #E15 -- fatal (only msng)
* #E16 -- named param "infsel=" missing
* #E17 -- named param "infsel=" invalid
]===]
local exporttable = {}
require('strict')
------------------------------------------------------------------------
---- CONSTANTS [O] ----
------------------------------------------------------------------------
-- uncommentable (imports)
-- local constringvoj = "Modulo:loaddata-tbllingvoj" -- EO
local constringvoj = "Modul:loaddata-tblbahasa" -- ID
-- constant table -- ban list -- add obviously invalid access codes (2-letter or 3-letter) only
-- length of the list is NOT stored anywhere, the processing stops
-- when type "nil" is encountered, used by "lfivalidatelnkoadv" only
-- controversial codes (sh sr hr), (zh cmn)
-- "en.wiktionary.org/wiki/Wiktionary:Language_treatment" excluded languages
-- "en.wikipedia.org/wiki/Spurious_languages"
-- "iso639-3.sil.org/code/art" only valid in ISO 639-2
-- "iso639-3.sil.org/code/gem" only valid in ISO 639-2 and 639-5, "collective"
-- "iso639-3.sil.org/code/zxx" "No linguistic content"
local contabisbanned = {}
contabisbanned = {'by','dc','ll','jp','art','deu','eng','epo','fra','gem','ger','ido','lat','por','rus','spa','swe','tup','zxx'} -- 1...19
-- background colour translation for
-- lng status "d04" sub "lfhintegertocol6d"
local contabwarnlng = {}
contabwarnlng [0] = '?' -- default (yellow) -> ordinary lang
contabwarnlng [1] = 'D0FFD8' -- greenish -> semiconlang
contabwarnlng [2] = 'A0FFC0' -- more greenish, but still not green -> conlang
contabwarnlng [3] = 'D0D0D0' -- grey -> dead lang
-- background colour translation for
-- wiki availability "d10" & "d11" sub "lfhintegertocol6d"
local contabwarnwik = {}
contabwarnwik [0] = 'B0B0B0' -- darker grey -> dead domain
contabwarnwik [1] = 'D0D0D0' -- grey -> closed wiki
contabwarnwik [2] = '?' -- default (yellow) -> good wiki
-- uncommentable text
-- local constrtop = '<big><b>Informoj pri lingvo</b></big>' -- EO (komp NO sng YES)
local constrtop = '<big><b>Informasi bahasa</b></big>' -- ID (komp NO sng YES)
-- uncommentable text for lng status /d04/ and wiki availability /d10/ & /d11/
local contabd04ap = {}
-- contabd04ap = {'ne planita','parte planita','planita','antikva'} -- EO (index 1...4, no spaces)
contabd04ap = {'tidak buatan','agak buatan','buatan','kuno'} -- ID (index 1...4, no spaces)
local contabd10d11w = {}
-- contabd10d11w = {'fermita aux malplena','nedisponebla'} -- EO
contabd10d11w = {'tertutup atau kosong','tidak ada'} -- ID
-- surrogate transcoding table (only needed for LFIKODEOSG in turn LFHFILLSURRSTRTAB)
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 table (color)
local contabwarna = {}
contabwarna['frame'] = '2020E0' -- table frame color (blue) (used only below)
contabwarna['bkgud'] = 'FFFFD0' -- default cell background color (light yellow) (used in sub and main)
contabwarna['reddi'] = 'FFD8D8' -- cell background color on minor error (reddish) (used in main)
-- constant table (HTML)
local constrbord = 'border:0.25em solid #' .. contabwarna['frame'] .. ';' -- part of "style" element (used only here in this block)
local contabhtml = {} -- various <table> and <div>
contabhtml['bigbeg'] = '<table style="' .. constrbord .. 'float:right;margin:0 0 1em 1em;border-collapse:collapse;">'
local constrtdbg = '<td style="' .. constrbord .. 'text-align:center;padding:0.4em;">' -- colspan NO color NO
local constrtdcs = '<td style="' .. constrbord .. 'text-align:center;padding:0.4em;" colspan="2">' -- colspan YES color NO (komp NO sng YES)
local constrtddf = '<td style="' .. constrbord .. 'text-align:center;padding:0.4em;background:#' -- colspan NO color YES
local constrtdfd = ';">' -- part of HTML table code after HEX color
local constrtden = '</td>'
-- constant strings err
local constrkros = ' # # ' -- lagom -> huge circumfix
local constremibg = '<span class="error">' -- minimal whining begin
local constremien = '</span>' -- minimal whining end
local constrelabg = '<span class="error"><b>' -- lagom whining begin
local constrelaen = '</b></span>' -- lagom whining end
local constrehubg = constrkros .. constrelabg -- huge whining begin
local constrehuen = constrelaen .. constrkros -- huge whining end
-- uncommentable error messages
local contaberaroj = {}
-- contaberaroj[12] = 'Nekonata lingvokodo'
contaberaroj[12] = 'Kode bahasa tidak dikenal' -- #E12
-- contaberaroj[15] = 'Grava eraro'
contaberaroj[15] = 'Kesalahan jahat' -- #E15
-- contaberaroj[16] = 'Parametro "infsel=" ne transdonita'
contaberaroj[16] = 'Parameter "infsel=" tidak diterima' -- #E16
-- contaberaroj[17] = 'Parametro "infsel=" nevalida'
contaberaroj[17] = 'Parameter "infsel=" tidak benar' -- #E17
-- uncommentable EO vs ID constant table (titles for the table)
-- * see "lfhbrewtitsel" and note that contabmisc[0] is needed too
-- * note that we can have 2 items in one cell but the non-bold title part
-- "kvanto" cannot be doubled and must be shared if needed !!!FIXME!!!
local contabdestit = {}
-- contabdestit[00] = 'Alira lingva kodo' -- EO
contabdestit[00] = 'Kode akses bahasa' -- ID
-- contabdestit[01] = 'Nomo de la lingvo en EO kaj kapvorta pagxo' -- EO (complete title bold)
contabdestit[01] = 'Nama bahasa dalam ID dan halaman lema' -- ID (complete title bold)
-- contabdestit[02] = 'Vikidatumeja pagxo' -- EO
contabdestit[02] = 'Halaman wikidata' -- ID
-- contabdestit[03] = 'Lingvonomo propralingve' -- EO
contabdestit[03] = 'Nama bahasa dalam bahasa itu' -- ID
-- contabdestit[04] = 'Planlingva kaj antikva statuso' -- EO
contabdestit[04] = 'Status buatan dan kuno' -- ID
-- contabdestit[05] = 'ISO 639-1:2002 2-litera kodo' -- EO
contabdestit[05] = 'ISO 639-1:2002 kode 2 huruf' -- ID
-- contabdestit[06] = 'ISO 639-3:2007 3-litera kodo' -- EO
contabdestit[06] = 'ISO 639-3:2007 kode 3 huruf' -- ID
-- contabdestit[07] = 'Cxefa kategorio%Kapvorta kategorio#kvanto da pagxoj' -- EO (colu can be hidden)
contabdestit[07] = 'Kategori utama%Kategori lema#jumlah halaman' -- ID (colu can be hidden)
-- contabdestit[08] = 'Vortara kategorio%Sxablona kategorio#kvanto da pagxoj' -- EO (colu can be hidden)
contabdestit[08] = 'Kategori kamus%Kategori templat#jumlah halaman' -- ID (colu can be hidden)
-- contabdestit[09] = 'Aldono%Indekso' -- EO (colu can be hidden)
contabdestit[09] = 'Lampiran%Indeks' -- ID (colu can be hidden)
-- contabdestit[10] = 'Vikipedio en la lingvo' -- EO
contabdestit[10] = 'Wikipedia dalam bahasa itu' -- ID
-- contabdestit[11] = 'Vikivortaro en la lingvo' -- EO
contabdestit[11] = 'Wikikamus dalam bahasa itu' -- ID
-- contabdestit[12] = 'Artikolo pri la lingvo en EO vikipedio' -- EO
contabdestit[12] = 'Artikel tentang bahasa itu dalam wikipedia ID' -- ID
-- contabdestit[13] = 'Kategorio pri EO en vikivortaro en la lingvo#kvanto da pagxoj' -- EO
contabdestit[13] = 'Kategori tentang ID dalam wikikamus dalam bahasa itu#jumlah halaman' -- ID
-- uncommentable EO vs ID constant strings and tables (misc)
local contabmisc = {}
-- contabmisc[0] = "kaj" -- EO coordinator "&"
contabmisc[0] = "dan" -- ID coordinator "&"
-- contabmisc[1] = "ne ekzistas" -- EO status of category pages lng kap vor
contabmisc[1] = "tidak ada" -- ID status of category pages lng kap vor
-- uncommentable EO vs ID constant table (pagenames to be constructed)
-- syntax of the request string:
-- * "@" followed by 2 uppercase letters and 2 hex digits,
-- otherwise the content is not expanded, but copied as-is instead
-- * 2 letters select the substitute string from table supplied by the
-- caller, see below
-- * 2 hex numbers control dropping left and right (0...15 char:s)
-- substitute strings defined:
-- * LK langcode (for example "da" or "io" or "grc")
-- * LN langname native case (for example "dana" or "Ido")
-- * LU langname uppercased (for example "Dana" or "Ido")
-- see "lfiultpl5repl" and "tabstuff" and use space here and avoid "_"
local contabpages = {}
-- contabpages[0] = "@LN00" -- EO lemma page in NS ZERO
contabpages[0] = "bahasa @LN00" -- ID lemma page in NS ZERO
-- contabpages[1] = "@LU00" -- EO appendix-NS page
contabpages[1] = "Bahasa @LN00" -- ID appendix-NS page
-- contabpages[2] = "@LU00" -- EO index-NS page
contabpages[2] = "Bahasa @LN00" -- ID index-NS page
-- contabpages[3] = "Vortaro (@LN00)" -- EO "vor" dict cat
contabpages[3] = "Kamus bahasa @LN00" -- ID "vor" dict cat
-- contabpages[4] = "Sxablonaro -@LK00-" -- EO "mal" template cat "Kategorio:Sxablonaro -ja-"
contabpages[4] = "Templat bahasa @LN00" -- ID "mal" template cat "Kategori:Templat bahasa Jepang"
-- contabpages[5] = "@LU00" -- EO "tln" top lng cat
contabpages[5] = "Bahasa @LN00" -- ID "tln" top lng cat
-- contabpages[6] = "Kapvorto (@LN00)" -- EO "kap" lemma cat
contabpages[6] = "Kata bahasa @LN00" -- ID "kap" lemma cat
-- contabpages[7] = "@LU00 lingvo" -- EO ipedia page guessing
contabpages[7] = "Bahasa @LN00" -- ID ipedia page guessing
-- uncommentable EO vs ID
local contabligiloj = {}
-- contabligiloj[0] = 'gxisdatigo' -- EO (no dot "." here)
contabligiloj[0] = 'pemutakhiran' -- ID (no dot "." here)
-- contabligiloj[1] = '[[SXablono:tbllingvoj|fonta tabelo]]' -- EO (no dot "." here)
contabligiloj[1] = '[[Templat:tblbahasa|tabel sumber]]' -- ID (no dot "." here)
-- contabligiloj[2] = '[[Aldono:Listo kun lingvoj|kompleta tabelo]]' -- EO
contabligiloj[2] = '[[Lampiran:Daftar bahasa|tabel lengkap]]' -- ID
-- diverse tuning values in one table
local contabtunmisc = {}
contabtunmisc[0] = 44 -- limit, safe values 16 ... 96, eval "tabevalu.maxc0n"
contabtunmisc[1] = 68 -- limit, safe values 16 ... 96, eval "tabevalu.maxc2n" (for exa "ae" "lad" are very long)
contabtunmisc[2] = 100 -- limit, safe values 64 ... 256, eval "tabevalu.maxkal"
contabtunmisc[3] = false -- "true" to allow long codes like "zh-min-nan" (komp commented out, sng defined)
contabtunmisc[4] = false -- "true" to allow middle digit "s7a" (komp commented out, sng defined)
contabtunmisc['tifi'] = false -- tight-fisted for "lfwifexist" copied into qtcostquery[1] (komp true, sng false)
contabtunmisc['cats'] = 0 -- category style: 0 raw | 1 "Ka:" | 2 <br> (komp 1, sng 0)
-- 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['indprefi'] = 'Indekso' -- "Index"
-- contabovrd['indprefi'] = 'Indeks'
-- contabovrd['apxprefi'] = 'Aldono' -- "Appendix"
-- contabovrd['apxprefi'] = 'Lampiran'
------------------------------------------------------------------------
---- SPECIAL STUFF OUTSIDE MAIN [B] ----
------------------------------------------------------------------------
---- SPECIAL VAR:S ----
local qldingvoj = {} -- type "table" and nested
local qtcostquery = {} -- for IfExists and PagesInCategory with 5 elements
local qtabbunch = {} -- bunch strings here for "lfhoptconcat"
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="
local qstrret = '' -- declare here if "lfhoptconcat" used
---- GUARD AGAINST INTERNAL ERROR AND IMPORT ONE VIA LOADDATA ----
qbooguard = (type(constringvoj)~='string')
if (not qbooguard) then
qldingvoj = mw.loadData(constringvoj) -- can crash here
qbooguard = (type(qldingvoj)~='table') -- seems to be always false
end--if
------------------------------------------------------------------------
---- 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
-- 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
------------------------------------------------------------------------
---- MATH FUNCTIONS [E] ----
------------------------------------------------------------------------
local function mathisintrange (numzjinput, numzjmin, numzjmax)
local booisclean = false -- preASSume guilt
if (type(numzjinput)=='number') then -- no non-numbers, thanks
if (numzjinput==math.floor(numzjinput)) then -- no transcendental
booisclean = ((numzjinput>=numzjmin) and (numzjinput<=numzjmax)) -- rang
end--if
end--if
return booisclean
end--function mathisintrange
local function mathdiv (xdividens, xdivisero)
local resultdiv = 0 -- DIV operator lacks in LUA :-(
resultdiv = math.floor (xdividens / xdivisero)
return resultdiv
end--function mathdiv
local function mathmod (xdividendo, xdivisoro)
local resultmod = 0 -- MOD operator is "%" and bitwise AND operator lack too
resultmod = xdividendo % xdivisoro
return resultmod
end--function mathmod
------------------------------------------------------------------------
-- 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
------------------------------------------------------------------------
---- SOME FUNCTIONS [?] ----
------------------------------------------------------------------------
local function lfcountchr (strqq,numascii) -- count occurrences of char in str
local numrezalt = 0
local numciar = 0
local numukuran = 0
local numindxe = 0 -- ZERO-based
numukuran = string.len(strqq)
while true do
if (numindxe==numukuran) then
break
end--if
numciar = string.byte(strqq,(numindxe+1),(numindxe+1))
if (numciar==numascii) then
numrezalt = numrezalt + 1
end--if
numindxe = numindxe + 1
end--while
return numrezalt
end--function lfcountchr
------------------------------------------------------------------------
-- Local function LFCOUNTNDG
-- Count occurrences of non-digits in string.
-- Tolerable char:s that do not count are:
-- - digits "0"..."9"
-- - space
-- - apo
local function lfcountndg (strzzz)
local numjrezalt = 0
local numcair = 0
local numjukuran = 0
local numjindxe = 0 -- ZERO-based
numjukuran = string.len(strzzz)
while true do
if (numjindxe==numjukuran) then
break
end--if
numcair = string.byte(strzzz,(numjindxe+1),(numjindxe+1))
if (((numcair<48) or (numcair>57)) and (numcair~=32) and (numcair~=39)) then
numjrezalt = numjrezalt + 1
end--if
numjindxe = numjindxe + 1
end--while
return numjrezalt
end--function lfcountndg
------------------------------------------------------------------------
-- Local function LFREMOVENONDI
-- Remove non-digits from a string, return "0" if no digits available.
local function lfremovenondi (strmess)
local strnumautnum = ''
local numcchhrr = 0
local numwukur = 0
local numwindxe = 0 -- ZERO-based
numwukur = string.len(strmess)
while true do
if (numwindxe==numwukur) then
break
end--if
numcchhrr = string.byte(strmess,(numwindxe+1),(numwindxe+1))
if ((numcchhrr>47) and (numcchhrr<58)) then
strnumautnum = strnumautnum .. string.char(numcchhrr) -- cpy digits only
end--if
numwindxe = numwindxe + 1
end--while
if (strnumautnum=='') then
strnumautnum = '0' -- result CANNOT be empty, always a valid number
end--if
return strnumautnum
end--function lfremovenondi
------------------------------------------------------------------------
---- NUMBER CONVERSION FUNCTIONS [N] ----
------------------------------------------------------------------------
-- Local function LFDEC1DIGIT
-- Convert 1 decimal ASCII digit to integer 0...9 (255 if invalid).
local function lfdec1digit (num1digit)
num1digit = num1digit - 48 -- may become invalid
if ((num1digit<0) or (num1digit>9)) then
num1digit = 255 -- report ERROR on invalid input digit
end--if
return num1digit
end--function lfdec1digit
------------------------------------------------------------------------
-- Local function LFDEC1DIGLM
-- Convert 1 digit decimal to UINT8 with inclusive upper limit.
local function lfdec1diglm (num1dygyt,num1lim)
num1dygyt = num1dygyt - 48 -- may become invalid
if ((num1dygyt<0) or (num1dygyt>num1lim)) then
num1dygyt = 255
end--if
return num1dygyt
end--function lfdec1diglm
------------------------------------------------------------------------
local function lfnonehextoint (numdigit)
local numresult = 255
if ((numdigit>47) and (numdigit<58)) then
numresult = numdigit-48
end--if
if ((numdigit>64) and (numdigit<71)) then
numresult = numdigit-55
end--if
return numresult
end--function lfnonehextoint
------------------------------------------------------------------------
-- 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
------------------------------------------------------------------------
-- Local function LFNUMTODECBUN
-- Convert non-negative integer to decimal string with bunching.
-- Depends on functions :
-- [E] mathdiv mathmod
local function lfnumtodecbun (numnomoriin)
local strnomorut = ''
local numindeex = 0
local numcaar = 0
numnomoriin = math.floor (numnomoriin) -- transcendental numbers suck
if (numnomoriin<0) then
numnomoriin = 0 -- negative numbers suck
end--if
while true do
numcaar = mathmod(numnomoriin,10) + 48 -- get digit moving right to left
numnomoriin = mathdiv(numnomoriin,10)
if (numindeex==3) then
strnomorut = "'" .. strnomorut -- ueglstr apo
numindeex = 0
end--if
strnomorut = string.char(numcaar) .. strnomorut -- ueglstr digit
numindeex = numindeex + 1
if (numnomoriin==0) then
break
end--if
end--while
return strnomorut
end--function lfnumtodecbun
------------------------------------------------------------------------
---- 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
-- Input : * strinpokeout -- empty legal
-- * numpokepoz -- ZERO-based, out of range legal
-- * numpokeval -- new value
-- This is inefficient by design of LUA. The caller is responsible to
-- minimize the number of invocations of this, in particular, not to
-- call if the new value is equal the existing one.
local function lfgpokestring (strinpokeout, numpokepoz, numpokeval)
local numpokelen = 0
numpokelen = string.len(strinpokeout)
if ((numpokelen==1) and (numpokepoz==0)) then
strinpokeout = string.char(numpokeval) -- totally replace
end--if
if (numpokelen>=2) then
if (numpokepoz==0) then
strinpokeout = string.char(numpokeval) .. string.sub (strinpokeout,2,numpokelen)
end--if
if ((numpokepoz>0) and (numpokepoz<(numpokelen-1))) then
strinpokeout = string.sub (strinpokeout,1,numpokepoz) .. string.char(numpokeval) .. string.sub (strinpokeout,(numpokepoz+2),numpokelen)
end--if
if (numpokepoz==(numpokelen-1)) then
strinpokeout = string.sub (strinpokeout,1,(numpokelen-1)) .. string.char(numpokeval)
end--if
end--if (numpokelen>=2) then
return strinpokeout
end--function lfgpokestring
------------------------------------------------------------------------
local function lfgtestnum (numkaad)
local boodigit = false
boodigit = ((numkaad>=48) and (numkaad<=57))
return boodigit
end--function lfgtestnum
local function lfgtestuc (numkode)
local booupperc = false
booupperc = ((numkode>=65) and (numkode<=90))
return booupperc
end--function lfgtestuc
local function lfgtestlc (numcode)
local boolowerc = false
boolowerc = ((numcode>=97) and (numcode<=122))
return boolowerc
end--function lfgtestlc
------------------------------------------------------------------------
---- UTF8 FUNCTIONS [U] ----
------------------------------------------------------------------------
-- Local function LFULNUTF8CHAR
-- Evaluate length of a single UTF8 char in octet:s.
-- Input : * numbgoctet -- beginning octet of a UTF8 char
-- Output : * numlen1234x -- 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 LFISPACUNDR
-- Spaces to underscores or vice-versa.
-- Incoming boolean "true" for output underscores and "false" for spaces.
local function lfispacundr (strxxin, boounderlig)
local numleang = 0
local numandex = 0 -- ZERO-based
local numcxarr = 0
local strkatrol = ''
numleang = string.len (strxxin)
while true do -- genuine loop
if (numandex==numleang) then
break
end--if
numcxarr = string.byte (strxxin,(numandex+1),(numandex+1))
if ((numcxarr==32) or (numcxarr==95)) then
if (boounderlig) then
numcxarr = 95
else
numcxarr = 32
end--if
end--if
strkatrol = strkatrol .. string.char (numcxarr)
numandex = numandex + 1
end--while
return strkatrol
end--function lfispacundr
------------------------------------------------------------------------
-- Local function LFIVALIDATESTR
-- Validate string according to a huge bunch of criteria.
-- Input : - stryn : string
-- - varalt : alternative valid string (for example "??" or "-")
-- that can "jump over" all other checks, note that empty
-- string can be used here, use type "nil" if none defined
-- - nummyn : minimal length
-- - nummex : maximal length
-- - numapo : apo rules
-- 0 : no restrictions
-- 1 : leading and trailing and multiple apo:s prohibited
-- (no-wiki-bolding-policy)
-- 2 : apo:s totally prohibited
-- - numpoz : positive list of tolerable char:s
-- 0 : none
-- 1 : only ASCII digits and maybe
-- apo:s (see also "numapo" above)
-- 2 : only ASCII uppercase letters
-- 3 : only ASCII lowercase letters
-- Output : - booisvalid : true if string is valid
local function lfivalidatestr (stryn,varalt,nummyn,nummex,numapo,numpoz)
local booisvalid = true -- for the caller
local numlencx = 0
local numynx = 0
local numcxar = 0
local numcxur = 0
local vartnp = 0
while true do -- fake loop
if (type(varalt)=='string') then
if (stryn==varalt) then
break -- to join mark -- string is valid
end--if
end--if
numlencx = string.len(stryn)
if ((numlencx<nummyn) or (numlencx>nummex)) then
booisvalid = false
break -- to join mark -- string is faulty
end--if
if (numlencx==0) then
break -- to join mark -- string is empty but valid
end--if
if (numapo==1) then
numcxar = string.byte(stryn,1,1)
numcxur = string.byte(stryn,numlencx,numlencx)
vartnp = string.find(stryn, "''", 1, true) -- plain text search for apo
if ((numcxar==39) or (numcxur==39) or vartnp) then
booisvalid = false
break -- to join mark -- string is faulty
end--if
end--if (numapo==1) then
if ((numpoz~=0) or (numapo==2)) then
numynx = 0 -- ZERO-based index
while true do
if (numynx==numlencx) then
break -- done search, all OK
end--if
numcxar = string.byte(stryn,(numynx+1),(numynx+1))
if ((numapo==2) and (numcxar==39)) then
booisvalid = false
break -- abort search, crime detected (apo)
end--if
if ((numpoz==1) and (numcxar~=39)) then
if ((numcxar<48) or (numcxar>57)) then
booisvalid = false
break -- abort search, crime detected (non-digit)
end--if
end--if
if (numpoz==2) then
if ((numcxar<65) or (numcxar>90)) then
booisvalid = false
break -- abort search, crime detected (non-uppercase)
end--if
end--if
if (numpoz==3) then
if ((numcxar<97) or (numcxar>122)) then
booisvalid = false
break -- abort search, crime detected (non-lowercase)
end--if
end--if
numynx = numynx + 1 -- ZERO-based index
end--while
end--if ((numpoz~=0) or (numapo==2)) then
break -- finally to join mark
end--while -- fake loop -- join mark
return booisvalid
end--function lfivalidatestr
------------------------------------------------------------------------
-- Local function LFIVALIDATEQUACK
-- Validate a Q-item.
-- Input : * strqynq -- string
-- Output : * booqisvalid -- true if string is valid
-- Depends on functions :
-- [G] lfgtestnum
-- Criteria:
-- * length totally 3...9 chars ("Q" plus 2...8 digits)
-- * zeroth char "Q"
-- * then "1"..."9"
-- * subsequent chars (1...7 left) "0"..."9"
local function lfivalidatequack (strqynq)
local booqisvalid = false -- preASSume guilt
local numlendx = 0
local numuinx = 0
local numcyaar = 0
while true do -- fake loop
numlendx = string.len(strqynq)
if ((numlendx<3) or (numlendx>9)) then
break -- to join mark -- string is faulty, length
end--if
if (string.byte(strqynq,1,1)~=81) then
break -- to join mark -- string is faulty, no "Q"
end--if
if (string.byte(strqynq,2,2)==48) then
break -- to join mark -- string is faulty, ZERO "0" prohibited here
end--if
numuinx = 1 -- ZERO-based -- skip "Q"
booqisvalid = true -- preASSume innocence
while true do
if (numuinx>=numlendx) then
break -- done search, all OK
end--if
numcyaar = string.byte(strqynq,(numuinx+1),(numuinx+1))
if (not lfgtestnum(numcyaar)) then
booqisvalid = false -- guilty, no number
break -- abort search
end--if
numuinx = numuinx + 1 -- ZERO-based
end--while
break -- finally to join mark
end--while -- fake loop -- join mark
return booqisvalid
end--function lfivalidatequack
------------------------------------------------------------------------
-- Local function LFIVALIDATELNKOADV
-- Advanced test whether a string (intended to be a langcode) is valid
-- containing only 2 or 3 lowercase letters, or 2...10 char:s and with some
-- dashes, or maybe a digit in middle position or maybe instead equals to "-"
-- or "??" and maybe additionally is not included on the ban list.
-- Input : * strqooq -- string (empty is useless and returns
-- "true" ie "bad" but cannot cause any major harm)
-- * booyesdsh -- "true" to allow special code dash "-"
-- * booyesqst -- "true" to allow special code doublequest "??"
-- * booloonkg -- "true" to allow long codes such as "zh-min-nan"
-- * boodigit -- "true" to allow digit in middle position
-- * boonoban -- (inverted) "true" to skip test against ban table
-- Output : * booisvaladv -- true if string is valid
-- Depends on functions :
-- [G] lfgtestnum lfgtestlc
-- Depends on constants :
-- * table "contabisbanned"
-- Incoming empty string is safe but type "nil" is NOT.
-- Digit is tolerable only ("and" applies):
-- * if boodigit is "true"
-- * if length is 3 char:s
-- * in middle position
-- Dashes are tolerable (except in special code "-") only ("and" applies):
-- * if length is at least 4 char:s (if this is permitted at all)
-- * in inner positions
-- * NOT adjacent
-- * maximally TWO totally
-- There may be maximally 3 adjacent letters, this makes at least ONE dash
-- obligatory for length 4...7, and TWO dashes for length 8...10.
local function lfivalidatelnkoadv (strqooq, booyesdsh, booyesqst, booloonkg, boodigit, boonoban)
local varomongkosong = 0 -- for check against the ban list
local numchiiar = 0
local numukurran = 0
local numindeex = 0 -- ZERO-based -- two loops
local numadjlet = 0 -- number of adjacent letters (max 3)
local numadjdsh = 0 -- number of adjacent dashes (max 1)
local numtotdsh = 0 -- total number of dashes (max 2)
local booislclc = false
local booisdigi = false
local booisdash = false
local booisvaladv = true -- preASSume innocence -- later final verdict here
while true do -- fake (outer) loop
if (strqooq=="-") then
booisvaladv = booyesdsh
break -- to join mark -- good or bad
end--if
if (strqooq=="??") then
booisvaladv = booyesqst
break -- to join mark -- good or bad
end--if
numukurran = string.len (strqooq)
if ((numukurran<2) or (numukurran>10)) then
booisvaladv = false
break -- to join mark -- evil
end--if
if (not booloonkg and (numukurran>3)) then
booisvaladv = false
break -- to join mark -- evil
end--if
numindeex = 0
while true do -- inner genuine loop over char:s
if (numindeex>=numukurran) then
break -- done -- good
end--if
numchiiar = string.byte (strqooq,(numindeex+1),(numindeex+1))
booisdash = (numchiiar==45)
booisdigi = lfgtestnum(numchiiar)
booislclc = lfgtestlc(numchiiar)
if (not (booislclc or booisdigi or booisdash)) then
booisvaladv = false
break -- to join mark -- inherently bad char
end--if
if (booislclc) then
numadjlet = numadjlet + 1
else
numadjlet = 0
end--if
if (booisdigi and ((numukurran~=3) or (numindeex~=1) or (not boodigit))) then
booisvaladv = false
break -- to join mark -- illegal digit
end--if
if (booisdash) then
if ((numukurran<4) or (numindeex==0) or ((numindeex+1)==numukurran)) then
booisvaladv = false
break -- to join mark -- illegal dash
end--if
numadjdsh = numadjdsh + 1
numtotdsh = numtotdsh + 1 -- total
else
numadjdsh = 0 -- do NOT zeroize the total !!!
end--if
if ((numadjlet>3) or (numadjdsh>1) or (numtotdsh>2)) then
booisvaladv = false
break -- to join mark -- evil
end--if
numindeex = numindeex + 1 -- ZERO-based
end--while -- inner genuine loop over char:s
if (not boonoban) then -- if "yesban" then
numindeex = 0
while true do -- lower inner genuine loop
varomongkosong = contabisbanned[numindeex+1] -- number of elem unknown
if (type(varomongkosong)~='string') then
break -- abort inner loop (then outer fake loop) due to end of table
end--if
numukurran = string.len (varomongkosong)
if ((numukurran<2) or (numukurran>3)) then
break -- abort inner loop (then outer fake loop) due to faulty table
end--if
if (strqooq==varomongkosong) then
booisvaladv = false
break -- abort inner loop (then outer fake loop) due to violation
end--if
numindeex = numindeex + 1 -- ZERO-based
end--while -- lower inner genuine loop
end--if (not boonoban) then
break -- finally to join mark
end--while -- fake loop -- join mark
return booisvaladv
end--function lfivalidatelnkoadv
------------------------------------------------------------------------
-- Local function LFIVALIUMDCTLSTR
-- Validate control string against restrictive pattern (dec).
-- Input : * strresdpat -- restrictive pattern (max 200 char:s)
-- * strctldstr -- incoming suspect
-- Output : * numbadpos -- bad position, or 254 wrong length, or 255 success
-- Depends on functions :
-- [N] lfdec1digit
-- Content of restrictive pattern:
-- * "." -- skip check
-- * "-" and "?" -- must match literally
-- * digit "1"..."9" ("0" invalid) -- inclusive upper limit (min ZERO)
local function lfivaliumdctlstr (strresdpat, strctldstr)
local numlenresdpat = 0
local numldninkom = 0
local numcomperindex = 0 -- ZERO-based
local numead2 = 0
local numead3 = 0
local numbadpos = 254 -- preASSume guilt (len differ or too long or ...)
local booddaan = false
numlenresdpat = string.len(strresdpat)
numldninkom = string.len(strctldstr)
if ((numlenresdpat<=200) and (numlenresdpat==numldninkom)) then
while true do
if (numcomperindex==numlenresdpat) then
numbadpos = 255
break -- success
end--if
numead2 = string.byte(strresdpat,(numcomperindex+1),(numcomperindex+1)) -- rest
numead3 = string.byte(strctldstr,(numcomperindex+1),(numcomperindex+1)) -- susp
booddaan = false
if ((numead2==45) or (numead2==63)) then
if (numead2~=numead3) then
numbadpos = numcomperindex
break -- "-" and "?" must match literally
end--if
booddaan = true -- position OK
end--if
if (numead2==46) then -- skip for dot "."
booddaan = true -- position OK
end--if
if (not booddaan) then
numead2 = lfdec1digit(numead2) -- rest
if (numead2>9) then -- limit defined or bad ??
numbadpos = 254
break -- bad restrictive pattern
else
numead3 = lfdec1digit(numead3) -- susp
if (numead3>numead2) then
numbadpos = numcomperindex
break -- value limit violation
end--if
end--if (numead2>9) else
end--if (not booddaan) then
numcomperindex = numcomperindex + 1
end--while
end--if ((numlenresdpat<=200) and (numlenresdpat==numldninkom)) then
return numbadpos
end--function lfivaliumdctlstr
------------------------------------------------------------------------
-- Local function LFIKODEOSG
-- Transcode eo X-surrogates to cxapeloj in a single string (eo only).
-- Input : * streosurr -- ANSI string (empty is useless but cannot
-- cause major harm)
-- Output : * strutf8eo -- UTF8 string
-- Depends on functions :
-- [E] mathdiv mathmod
-- Depends on constants :
-- * table "contabtransluteo" inherently holy
-- To be called ONLY from "lfhfillsurrstrtab".
-- * the "x" in a surr pair is case insensitive,
-- for example both "kacxo" and "kacXo" give same result
-- * avoid "\", thus for example "ka\cxo" would get converted but the "\" kept
-- * double "x" (both case insensitive) prevents conversion and becomes
-- reduced to single "x", for example "kacxxo" becomes "kacxo"
local function lfikodeosg (streosurr)
local vareopeek = 0
local strutf8eo = ''
local numeoinplen = 0
local numinpinx = 0 -- ZERO-based source index
local numknar0k = 0 -- current char
local numknaf1x = 0 -- next char (ZERO is NOT valid)
local numknaf2x = 0 -- post next char (ZERO is NOT valid)
local boonext1x = false
local boonext2x = false
local boosudahdone = false
numeoinplen = string.len(streosurr)
while true do
if (numinpinx>=numeoinplen) then
break
end--if
numknar0k = string.byte(streosurr,(numinpinx+1),(numinpinx+1))
numknaf1x = 0 -- preASSume no char
numknaf2x = 0 -- preASSume no char
if ((numinpinx+1)<numeoinplen) then
numknaf1x = string.byte(streosurr,(numinpinx+2),(numinpinx+2))
end--if
if ((numinpinx+2)<numeoinplen) then
numknaf2x = string.byte(streosurr,(numinpinx+3),(numinpinx+3))
end--if
boonext1x = ((numknaf1x==88) or (numknaf1x==120)) -- case insensitive
boonext2x = ((numknaf2x==88) or (numknaf2x==120)) -- case insensitive
boosudahdone = false
if (boonext1x and boonext2x) then -- got "xx"
strutf8eo = strutf8eo .. string.char(numknar0k,numknaf1x) -- keep one "x" only
numinpinx = numinpinx + 3 -- eaten 3 written 2
boosudahdone = true
end--if
if (boonext1x and (not boonext2x)) then -- got yes-"x" and no-"x"
vareopeek = contabtransluteo[numknar0k] -- UINT16 or type "nil"
if (type(vareopeek)=='number') then
strutf8eo = strutf8eo .. string.char(mathdiv(vareopeek,256),mathmod(vareopeek,256)) -- add UTF8 char
numinpinx = numinpinx + 2 -- eaten 2 written 2
boosudahdone = true
end--if
end--if
if (not boosudahdone) then
strutf8eo = strutf8eo .. string.char(numknar0k) -- copy char
numinpinx = numinpinx + 1 -- eaten 1 written 1
end--if
end--while
return strutf8eo
end--function lfikodeosg
------------------------------------------------------------------------
-- Local function LFIKODSVSG
-- Transcode sv blackslash-surrogates in a single string (sv only).
-- Input : * strsvsurr -- ANSI string (empty is useless but cannot
-- cause major harm)
-- Output : * strutf8sv -- UTF8 string
-- Depends on functions :
-- [E] mathdiv mathmod
-- Depends on constants :
-- * table "contabtranslutsv" inherently holy
-- To be called ONLY from "lfhfillsurrstrtab".
-- * the latter letter in a surr triple is case insensitive,
-- for example both "\AEgare" and "\Aegare" give same result
local function lfikodsvsg (strsvsurr)
local varsvpeek = 0
local strutf8sv = ''
local strsvdouble = ''
local numsvinplen = 0
local numinpinx = 0 -- ZERO-based source index
local numsvonechar = 0 -- current char
numsvinplen = string.len(strsvsurr)
while true do
if (numinpinx>=numsvinplen) then
break
end--if
numsvonechar = string.byte(strsvsurr,(numinpinx+1),(numinpinx+1))
strsvdouble = '' -- preASSume no dblchar
if ((numsvonechar==92) and ((numinpinx+2)<numsvinplen)) then
strsvdouble = string.sub(strsvsurr,(numinpinx+2),(numinpinx+3))
end--if
varsvpeek = contabtranslutsv[strsvdouble] -- UINT16 or type "nil"
if (type(varsvpeek)=='number') then
strutf8sv = strutf8sv .. string.char(mathdiv(varsvpeek,256),mathmod(varsvpeek,256)) -- add UTF8 char
numinpinx = numinpinx + 3 -- eaten 3 written 2
else
strutf8sv = strutf8sv .. string.char(numsvonechar) -- copy char
numinpinx = numinpinx + 1 -- eaten 1 written 1
end--if
end--while
return strutf8sv
end--function lfikodsvsg
------------------------------------------------------------------------
-- Local function LFITEST5PLEJS
-- Test one placeholder against spec and table of known placeholders.
-- Input : * stroneplejs -- 5 octet:s
-- * tabsubtitu -- optional table, list with substitute strings using
-- two-letter codes as keys, type "nil" for none
-- Output : * numtriplejs -- main status: ZERO not valid | ONE valid unknown |
-- TWO found
-- * numpl5left, numpl5right -- only for non-ZERO
-- * strvaljuk -- * if optional table given then contains value
-- only for status TWO
-- * if no table then contains the key
-- only for status ONE
-- * in all other cases empty string
-- Depends on functions :
-- [G] lfgstringrange lfgtestuc
-- [N] lfnonehextoint
local function lfitest5plejs (stroneplejs, tabsubtitu)
local varduahuruf = 0
local strmajky = ''
local strvaljuk = '' -- preASSume guilt
local numtriplejs = 0 -- preASSume guilt
local numplejoct = 0 -- maybe "@"
local numpl5left = 0 -- hex and discard left
local numpl5right = 0 -- hex and discard right
local numplejodt = 0 -- UC
local numplejoet = 0 -- UC
local numplejx5u = 0 -- maybe hex
local numplejx5v = 0 -- maybe hex
while true do -- fake loop
if (not lfgstringrange(stroneplejs,5,5)) then
break -- internal error
end--if
numplejoct = string.byte(stroneplejs,1,1) -- also returned
if (numplejoct~=64) then
break -- not valid per spec
end--if
numplejodt = string.byte(stroneplejs,2,2)
numplejoet = string.byte(stroneplejs,3,3)
if ((not lfgtestuc(numplejodt)) or (not lfgtestuc(numplejoet))) then
break -- not valid per spec
end--if
numplejx5u = lfnonehextoint(string.byte(stroneplejs,4,4))
numplejx5v = lfnonehextoint(string.byte(stroneplejs,5,5))
if ((numplejx5u==255) or (numplejx5v==255)) then
break -- not valid per spec
end--if
numtriplejs = 1 -- valid now
numpl5left = numplejx5u -- do NOT copy in invalid value
numpl5right = numplejx5v -- do NOT copy in invalid value
strmajky = string.char (numplejodt,numplejoet) -- key
if (type(tabsubtitu)=='table') then -- got optional table ??
varduahuruf = tabsubtitu[strmajky] -- risk of type "nil"
if (lfgstringrange(varduahuruf,1,255)) then
strvaljuk = varduahuruf -- else keep empty string and status ONE
numtriplejs = 2 -- table here and placeholder found, return value
end--if
else
strvaljuk = strmajky -- no table but placeholder valid, return key
end--if (type(tabsubtitu)=='table') else
break -- finally to join mark
end--while -- fake loop -- join mark
return numtriplejs, numpl5left, numpl5right, strvaljuk
end--function lfitest5plejs
------------------------------------------------------------------------
-- Local function LFIULTPL5REPL
------------------------------------------------------------------------
---- HIGH LEVEL FUNCTIONS [H] ----
------------------------------------------------------------------------
-- Local function LFHOPTCONCAT
-- Optimizing concatenator as workaround for poor memory management in LUA
-- during string concatenations. Add incoming string to upvalue "qstrret".
-- Input : * "varincom" either string (add) or type "nil" (flush)
-- * "qtabbunch" either table or type "nil" (ignore "varincom")
-- Depends on upvalues :
-- * qtabbunch qstrret
-- CHG : qtabbunch (table), qstrret (string)
-- NOTE: to be inited by <<local qstrret = ''>> and <<local qtabbunch = {}>>
-- NOTE: to be flushed by "lfhoptconcat (nil)" before using "qstrret"
-- NOTE: if the "qstrret" string has to be changed directly
-- (by concatenation or replace), then either "lfhoptconcat (nil)"
-- (flush) or "qtabbunch = {}" (discard) must be done before !!!
local function lfhoptconcat (varincom)
if (type(qtabbunch)=='table') then
if (type(varincom)=='string') then
if (#qtabbunch>20) then
qstrret = qstrret .. table.concat (qtabbunch) .. varincom
qtabbunch = {}
else
table.insert (qtabbunch, varincom) -- ONE-based numbering
end--if
end--if
if ((varincom==nil) and (#qtabbunch>0)) then
qstrret = qstrret .. table.concat (qtabbunch)
qtabbunch = {}
end--if
end--if
end--function lfhoptconcat
------------------------------------------------------------------------
-- 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
------------------------------------------------------------------------
-- nope LFHBREWERRSVR
------------------------------------------------------------------------
-- Local function LFIULTPL5REPL !!!FIXME!!! move
-- Insert selected substitute strings into request string at given positions
-- with optional dropping if the substitute string is empty.
-- Input : * strrekvest -- request string containing placeholders
-- (syntax see below, empty
-- string legal, other data type NOT legal)
-- * tabsubstut -- obligatory table, list with substitute strings
-- using two-letter codes as keys
-- Output : * strhazil
-- Depends on functions :
-- [I] lfitest5plejs
-- [G] lfgstringrange lfgtestuc
-- [N] lfnonehextoint
-- Syntax of the named and variable placeholder:
-- * fixed "@" followed by 2 uppercase ASCII letters and 2 hex digits
-- * "@"
-- * 2 letters select the substitute from table supplied by the caller
-- * 2 hex digits control dropping left and right (0...15 char:s)
-- Anything not valid as placeholder is kept ie literally copied
-- as-is instead.
-- Empty item in "tabsubstut" (key does not exist, empty string "", or
-- non-string value, the latter discouraged) is legal and safe and results
-- in dropping if some of the control numbers is non-ZERO. Left dropping
-- is practically performed on "strhazil" whereas right dropping on
-- "strrekvest" and "numrekvinx". Dropping is protected from access
-- out of range.
-- ZERO iterations of the loop over request string are possible,
-- namely if "strrekvest" is empty.
-- If uppercasing or other adjustment is needed, then the caller must
-- take care of it by providing several separate substitute strings with
-- separate names in the table.
local function lfiultpl5repl (strrekvest, tabsubstut)
local strhazil = ''
local stronevalue = ''
local numrekvlen = 0
local numrekvinx = 0 -- src index ZERO-based
local numremainder = 0
local numpltristeta = 0
local numnonhitoct = 0
local numammlef = 0 -- discard left
local numammrig = 0 -- discard right
numrekvlen = string.len(strrekvest)
while true do -- genuine loop over request string, "numrekvinx" is counter
if (numrekvinx>=numrekvlen) then
break -- done
end--if
numnonhitoct = string.byte(strrekvest,(numrekvinx+1),(numrekvinx+1))
numpltristeta = 0 -- preASSume no valid placeholder here
if ((numrekvinx+5)<=numrekvlen) then -- beware of risk of overflow
numpltristeta, numammlef, numammrig, stronevalue = lfitest5plejs (string.sub(strrekvest,(numrekvinx+1),(numrekvinx+5)), tabsubstut)
end--if
if (numpltristeta==2) then -- found
strhazil = strhazil .. stronevalue -- insert non-empty substitute
numrekvinx = numrekvinx + 5 -- consumed 5 char:s, cannot overflow here
end--if
if (numpltristeta==1) then -- placeholder valid per spec but empty unknown
numremainder = string.len(strhazil) - numammlef -- this can underflow
if (numremainder<=0) then
strhazil = '' -- discard left -- leaving nothing behind
else
strhazil = string.sub(strhazil,1,numremainder) -- discard left
end--if
numrekvinx = numrekvinx + 5 + numammrig -- discard right this can overflow
end--if
if (numpltristeta==0) then -- no valid placeholder here
strhazil = strhazil .. string.char(numnonhitoct) -- copy octet as-is
numrekvinx = numrekvinx + 1 -- consumed 1 char
end--if
end--while -- genuine loop over request string, "numrekvinx" is counter
return strhazil
end--function lfiultpl5repl
------------------------------------------------------------------------
-- 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 NOPE filling in own name "\@",
-- and optional transcoding of eo and NOPE sv surrogates (via 3 separate
-- functions). Optionally even string keys/indexes are transcoded but
-- NOT filled in.
-- Input : * varinkommen -- type "string" or "table"
-- * varfyllo -- NOPE string, or type "nil" if no filling-in desired
-- * strlingkod -- "eo" or NOPE "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] lfikodeosg (only if conv of eo X-surrogates desired)
-- [I] NOPE lfikodsvsg
-- [I] NOPE lfipl2altwre (only if filling-in desired)
-- [G] NOPE lfgstringrange (via "lfipl2altwre")
-- [E] mathdiv mathmod (via "lfikodeosg" and NOPE "lfikodsvsg")
-- Depends on constants :
-- * table "contabtransluteo" inherently holey (via "lfikodeosg")
-- * NOPE table "contabtranslutsv"
-- 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 = lfipl2altwre (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
------------------------------------------------------------------------
-- nope LFHTABLETOHTMLLISTA
------------------------------------------------------------------------
-- nope LFHTABLETOHTMLLISNT
------------------------------------------------------------------------
-- Local function LFINUMBERINKAT !!!FIXME!!! move
local function lfinumberinkat (numjumlahorminone)
local strnothing = '' -- "(16'384 pages)" or "(?? pages)"
if (numjumlahorminone<0) then -- expected type integer, value -1 for unknown
strnothing = '(??'
else
strnothing = '(' .. lfnumtodecbun(numjumlahorminone) -- ZERO is valid
end--if
strnothing = strnothing .. ' pages)'
return strnothing
end--function lfinumberinkat
------------------------------------------------------------------------
-- nope LFAVAILCO
------------------------------------------------------------------------
-- Local function LFIAVAILNT !!!FIXME!!! move to [I]
-- Translate number 2...0 to text with "<br>".
-- Depends on constants :
-- * table "contabd10d11w" with 2 strings at indexes ONE and TWO
local function lfiavailnt (numalb)
local strnote = '' -- preASSume no extra complaint
if (numalb==1) then
strnote = '<br>(' .. contabd10d11w[1] .. ')' -- closed or empty
end--if
if (numalb==0) then
strnote = '<br>(' .. contabd10d11w[2] .. ')' -- inaccessible
end--if
return strnote
end--function lfiavailnt
------------------------------------------------------------------------
-- Local function LFHBREWTITSEL
-- Brew content of title cell (for column or row) from index
-- number and two booleans.
-- Input : * numindxe -- index number of column (ZERO-based)
-- * bootopp, boobotm
-- Depends on functions :
-- [N] lfnumto2digit
-- Depends on constants :
-- * table "contabdestit"
-- * contabmisc[0] (translated coordinator "and")
-- * (begin of bold) is always added at the very beginning
-- * (end of bold) is added at the very end if no "#" is present
-- * "#" is expanded to (end of bold) + EOL + word "and" + EOL
-- * maximally ONE "#" is permitted
-- * "%" is border between 2 selectable items, it is expanded to
-- (end of bold) + EOL + word "and" + EOL + (begin of bold) only
-- if both items are active
-- * maximally ONE "%" is permitted
-- An entry in the table "contabdestit" is NOT supposed to contain
-- "<b>" (even less triple-apo "'''"), nor "</b>" at end nor "<br>".
local function lfhbrewtitsel (numindxe, bootopp, boobotm)
local strraw = ''
local strdesc = ''
local strandkajdan = ''
local numlimiit = 0
local numoindex = 1 -- ONE-based
local numpycker = 0
local numfragmm = 0 -- NOT relevant if both "bootopp" and "boobotm" are true
local booslutbold = false
local bootakeit = false
strandkajdan = "<br>" .. contabmisc[0] .. "<br>" -- for both % and #
strraw = contabdestit[numindxe]
strdesc = '<b>'
numlimiit = string.len (strraw)
while true do
if (numoindex>numlimiit) then
break
end--if
bootakeit = true
numpycker = string.byte(strraw,numoindex,numoindex)
numoindex = numoindex + 1
if (numpycker==35) then -- 35 is "#"
strdesc = strdesc .. "</b>" .. strandkajdan -- no (begin of bold) !!!
booslutbold = true
bootakeit = false
numfragmm = 2 -- following text taken unconditionally
end--if
if (numpycker==37) then -- 37 is "%"
if (bootopp and boobotm) then
strdesc = strdesc .. "</b>" .. strandkajdan .. "<b>"
end--if
numfragmm = numfragmm + 1
bootakeit = false
end--if
if ((numfragmm==0) and (not bootopp)) then
bootakeit = false
end--if
if ((numfragmm==1) and (not boobotm)) then
bootakeit = false
end--if
if (bootakeit) then
strdesc = strdesc .. string.char(numpycker)
end--if
end--while
if (not booslutbold) then
strdesc = strdesc .. '</b>' -- add "</b>" only if it is not yet in
end--if
strdesc = strdesc .. '<br>(d' .. lfnumto2digit (numindxe) .. ')'
return strdesc
end--function lfhbrewtitsel
------------------------------------------------------------------------
---- MEDIAWIKI INTERACTION FUNCTIONS [W]
------------------------------------------------------------------------
-- Local function LFWBREW3URL
-- Brew httplink to current project from title + http parameters + visible
-- text, making it look like an ordinary wikilink.
-- Input : * arxinp4
-- * strwikipage -- title ie {{FULLPAGENAME}} or
-- for example "Special:WhatLinksHere"
-- * strhttpparam -- for example "hidetrans=1&hidelinks=1" or empty
-- * strvisible -- for example "do NOT click here" or empty
-- * boozordinary -- "true" to look like an ordinary wikilink,
-- "false" if this is undesirable or done outside
-- URL structure:
-- * https://en.wiktionary.org/wiki/Category:Vulgarities
-- * https://en.wiktionary.org/wiki/Category:Vulgarities?action=purge
-- * https://en.wiktionary.org/w/index.php?title=Category:Vulgarities
-- * https://en.wiktionary.org/w/index.php?title=Category:Vulgarities&action=purge
-- * https://en.wiktionary.org/wiki/Special:AllPages
-- * https://en.wiktionary.org/wiki/Special:AllPages?namespace=5
-- * https://en.wiktionary.org/wiki/Special:WhatLinksHere/Template:Bugger
-- * https://en.wiktionary.org/wiki/Special:WhatLinksHere/Template:Bugger?hidetrans=1&hidelinks=1
-- * https://en.wiktionary.org/w/index.php?title=Special:WhatLinksHere/Template:Bugger&hidetrans=1&hidelinks=1
-- * https://en.wiktionary.org/w/index.php?title=Special:WhatLinksHere&target=Template:Bugger&hidetrans=1&hidelinks=1
-- Only 4 ways to brew a URL:
-- * {{canonicalurl:{{FULLPAGENAME}}|action=purge}}
-- we use this one via ":preprocess", will work on any project
-- * {{SERVER}}{{SCRIPTPATH}}/index.php?title={{urlencode:{{FULLPAGENAME}}}}&action=purge
-- unnecessarily complicated
-- * LUA field "canonicalUrl" or "fullUrl" on "mw.uri" or "title object"
-- complicated and dubious
-- * manually
-- where to take project URL from ?? plus routine would land in [I] then
-- <span class="plainlinks">...</span>
local function lfwbrew3url (arxinp4, strwikipage, strhttpparam, strvisible, boozordinary)
local strourresult = ''
if (strhttpparam~='') then
strwikipage = strwikipage .. '|' .. strhttpparam
end--if
strourresult = arxinp4:preprocess ('{{canonicalurl:' .. strwikipage .. '}}')
if (strvisible=='') then
strourresult = '[' .. strourresult .. ' ' .. strourresult .. ']'
else
strourresult = '[' .. strourresult .. ' ' .. strvisible .. ']'
end--if
if (boozordinary) then
strourresult = '<span class="plainlinks">' .. strourresult .. '</span>'
end--if
return strourresult
end--function lfwbrew3url
------------------------------------------------------------------------
-- Local function LFWIFEXIST
-- Optionally tight-fisted check whether a wiki page exists, counting cost.
-- Input : * strpgname -- fullpagename (default NS 0, not template NS 10)
-- Output : * boomemangada -- "true" on success
-- Depends on upvalues :
-- * heterogeneous table "qtcostquery"
-- Extra colon is tolerable for non-NS-ZERO and non-template-NS-10 pages
-- such as "{{msgnw::Help:TOC}}" and returns ...":Help:TOC"... if the
-- page does not exist.
-- Maybe expensive, the caller must use "pcall".
local function lfwifexist (strpgname)
local boomemangada = false
local arxxx = 0
local metaa = 0
qtcostquery[6] = qtcostquery[6] + 1 -- total counter
if (qtcostquery[1]) then
arxxx = qtcostquery[0] -- trick below does NOT work with substitution
boomemangada = ( '[[:' .. strpgname .. ']]' ~= arxxx:preprocess ('{{msgnw::' .. strpgname .. '}}') )
qtcostquery[8] = qtcostquery[8] + 1 -- tight-fisted counter
else
metaa = mw.title.new (strpgname) -- 1 param
boomemangada = metaa.exists -- expensive here
qtcostquery[7] = qtcostquery[7] + 1 -- cost
end--if
return boomemangada
end--function lfwifexist
------------------------------------------------------------------------
-- Local function LFWKATROCL
-- Peek summary of a category, counting cost.
-- Input : * strcat9name -- without prefix
-- Output : * numpages, numsubcats -- 2 values, value -1 for unknown
-- Depends on upvalues :
-- * heterogeneous table "qtcostquery"
-- Always expensive, the caller must use "pcall".
local function lfwkatrocl (strcat9name)
local metab = 0
local numpages = -1 -- preASSume unknown
local numsubcats = -1 -- preASSume unknown
metab = mw.site.stats.pagesInCategory ( strcat9name, '*' ) -- expensive here
qtcostquery[3] = qtcostquery[3] + 1 -- total counter
qtcostquery[4] = qtcostquery[4] + 1 -- cost
if (type(metab)=='table') then -- risk of type "number" or "nil"
numpages = metab.pages
numsubcats = metab.subcats
if (numpages<0) then
numpages = -1 -- YES MediaWiki is stupid
end--if
if (numsubcats<0) then
numsubcats = -1 -- YES MediaWiki is stupid
end--if
end--if
return numpages, numsubcats
end--function lfwkatrocl
------------------------------------------------------------------------
---- SOME FUNCTIONS [?] ----
------------------------------------------------------------------------
-- Local function LFHINTEGERTOCOL6D
-- Output : * varfromtable -- 6 hex quasi-digits, maybe copied from
-- "strdefault", or "=" if index bad
-- Depends on constants :
-- * tables "contabwarnlng" and "contabwarnwik" both ZERO-based
local function lfhintegertocol6d (numkoloindex,bootype,strdefault)
local varfromtable = 0
if (bootype) then
varfromtable = contabwarnwik[numkoloindex]
else
varfromtable = contabwarnlng[numkoloindex]
end--if
if (type(varfromtable)~='string') then
varfromtable = "=" -- index bad
end--if
if (varfromtable=="?") then
varfromtable = strdefault
end--if
return varfromtable
end--function lfhintegertocol6d
------------------------------------------------------------------------
-- Local function LFIBREWURL
-- Brew an external link [] to a different wiki.
-- Input : * straxk : wiki access code (2...10 char:s), "??" for invalid
-- * bootip : type (false -> ipedia | true -> tionary)
-- * varpage : pagename string (article, or category with
-- prefix) or type "nil"
-- Depends on functions :
-- [I] lfispacundr
-- Here we replace spaces in URL by underscores, no further encoding
-- is performed.
-- No link if wiki access code is "??", only plain text instead.
local function lfibrewurl (straxk,bootip,varpage)
local strurlkita = ''
local strsite = ''
local boolinkvalid = false
local boohavepage = false
if (bootip) then
strsite = 'tionary'
else
strsite = 'ipedia'
end--if
boolinkvalid = (straxk~='??')
boohavepage = (type(varpage)=='string')
if (boolinkvalid) then
strurlkita = '[http://' .. straxk .. '.wik' .. strsite .. '.org'
if (boohavepage) then -- string (article or category with prefix) or nil
strurlkita = strurlkita .. '/wiki/' .. lfispacundr(varpage,true) -- replace in URL
end--if
strurlkita = strurlkita .. ' ' -- separation space
end--if
strurlkita = strurlkita .. straxk .. '.' .. strsite .. '...' -- visible text
if (boohavepage) then -- string (article or category with prefix) or nil
strurlkita = strurlkita .. '<br>/' .. varpage -- do NOT replace here
end--if
if (boolinkvalid) then
strurlkita = strurlkita .. ']' -- done
end--if
return strurlkita
end--function lfibrewurl
------------------------------------------------------------------------
---- VERY HIGH LEVEL FUNCTIONS [Y]
------------------------------------------------------------------------
-- Local function LFYKATTLAENK
-- Brew link to category possibly saving screen space and
-- optionally check existence and content.
-- Input : * strkattnamn -- without ns prefix
-- * strkattnspr -- ns prefix NOT ending with colon
-- * boocheckdabl -- enable 2 maybe expensive checks
-- * num012style -- 0 raw | 1 "Ka:" | 2 <br>
-- Output : * booisbiru
-- * strlikatter -- main string
-- Depends on functions :
-- [W] lfwifexist lfwkatrocl
-- [I] lfinumberinkat
-- Depends on upvalues :
-- * heterogeneous table "qtcostquery"
-- Depends on constants :
-- * contabmisc[1] (statement "does not exist")
local function lfykattlaenk (strkattnamn,strkattnspr,boocheckdabl,num012style)
local strfullcatname = ''
local strlikatter = ''
local straltprefix = ''
local numjumlah = 0
local booisbiru = true -- preASSume innocence
strfullcatname = strkattnspr .. ':' .. strkattnamn
if (num012style==0) then
strlikatter = "[[:" .. strfullcatname .. "]]" -- raw
else
if (num012style==1) then
straltprefix = string.sub (strkattnspr,1,2) .. ':' -- "Ca:" or "Ka:"
else
straltprefix = strkattnspr .. ':<br>' -- "Category:" + EOL
end--if
strlikatter = "[[:" .. strfullcatname .. "|" .. straltprefix .. strkattnamn.. "]]"
end--if
if (boocheckdabl) then
booisbiru = lfwifexist (strfullcatname)
if (not booisbiru) then -- incidents reported here but counted by caller
strlikatter = strlikatter .. '<br>(' .. contabmisc[1] .. ')' -- "does not exist"
end--if
numjumlah = lfwkatrocl (strkattnamn) -- discard 1 of 2 results, both can be -1
strlikatter = strlikatter .. '<br>' .. lfinumberinkat(numjumlah) -- can be -1
end--if
return booisbiru,strlikatter
end--function lfykattlaenk
------------------------------------------------------------------------
-- Local function LFYAPXINDLAENK
-- Brew link to appendix or index page and optionally check existence.
-- Input : * strapxindnamn -- without ns prefix
-- * strapxindnspr -- ns prefix NOT ending with colon
-- * boocekexx -- enable 1 maybe expensive check
-- Output : * booitisblue
-- * strailiink -- main string
-- Depends on functions :
-- [W] lfwifexist
-- Depends on upvalues :
-- * heterogeneous table "qtcostquery"
-- Depends on constants :
-- * contabmisc[1] (statement "does not exist")
local function lfyapxindlaenk (strapxindnamn,strapxindnspr,boocekexx)
local strfullainame = ''
local strailiink = ''
local booitisblue = true -- preASSume innocence
strfullainame = strapxindnspr .. ':' .. strapxindnamn -- needed two times
strailiink = '[[' .. strfullainame .. ']]' -- "Appendix:" "Index:"
if (boocekexx) then
booitisblue = lfwifexist (strfullainame)
if (not booitisblue) then -- incidents reported here but counted by caller
strailiink = strailiink .. '<br>(' .. contabmisc[1] .. ')' -- "does not exist"
end--if
end--if
return booitisblue,strailiink
end--function lfyapxindlaenk
------------------------------------------------------------------------
-- Local function LFYDOONELANG
-- Input : * strsitelangcode -- site langcode
-- * strpykkatns strpykindns strpykapxns
-- * stronecy -- processed langcode /cy/
-- * tabonelang -- ZERO-based
-- * tabxctl
-- * tabxkol -- "d01" ... "d13"
-- Modif : * qtabbunch qstrret (no flush)
-- Depends on functions :
-- [Y] lfykattlaenk
-- [H] lfhoptconcat lfhbrewtitsel
-- [I] lfivalidatestr lfivalidatequack
local function lfydoonelang (strsitelangcode, strpykkatns, strpykindns, strpykapxns, stronecy, tabonelang, tabxctl, tabxkol)
local tabstuff = {} -- double-letter indexes for "lfiultpl5repl"
local strbkn = '' -- HTML HEX color (6 digits)
local strt3d = '' -- HTML "td" element concatenated from 3 parts
local strdeste = '' -- destinat table element with both "td" HTML elements
local strtblc0 = '' -- src column 0 (both /cy/ and /c0/) (obligatory)
local strtblc1 = '' -- src column 1 (nice to have) Q-item
local strtblc2 = '' -- src column 2 (nice to have) propralingve
local strtblc3 = '' -- src column 3 (nice to have) 1 digit
local strtblc4 = '' -- src column 4 (nice to have) 2 letters ISO
local strtblc5 = '' -- src column 5 (nice to have) 3 letters ISO
local strtblc6 = ''
local strtblc7 = ''
local strtblc8 = '' -- src column 8
local strtblc9 = '' -- src column 9
local strtblca = '' -- src column 10
local strtmp = ''
local strtpm = ''
local numc7pedi = 0 -- ipedia code "0"..."2" ("3" for "-" and reddish)
local numc7tion = 0 -- tionary code "0"..."2" ("3" for "-" and reddish)
local numafstbfcl = 0 -- string length aftr stripping rl lr before clamping
local numafstbfkp = 0 -- string length aftr stripping rl lr before clamping
local numlokera = 0 -- local error code, returned
local numtamp = 0
local numoct = 0
local bootjmp = false
while true do -- fake loop
-- begin /d00/ -- our access code
strtpm = '<tr>' .. constrtdbg .. lfhbrewtitsel (0,true,true) .. constrtden
lfhoptconcat (strtpm) -- "lfhbrewtitsel" does not add "<td"...">" "</td>"
strbkn = contabwarna['bkgud'] -- color code without "#" cross
if (stronecy=='eo') then
strbkn = '90FF90' -- green decoration
end--if
strt3d = constrtddf .. strbkn .. constrtdfd -- long "td" eleme
lfhoptconcat (strt3d .. '<b>' .. stronecy .. '</b>' .. constrtden .. '</tr>')
-- done /d00/
-- begin /c0/ -- lingvonomo in site language
strtblc0 = tabonelang[0] or ''
if (not lfivalidatestr(strtblc0,nil,2,contabtunmisc[0],0,0)) then
numlokera = 15 -- #E15 /c0/ faulty
break -- to join mark -- no table and huge error
end--if
-- done /c0/ -- ultimately obligatory -- even "-" is bad here
-- crucial task
tabstuff["LK"] = stronecy -- for "lfiultpl5repl" -- this is /cy/
tabstuff["LN"] = strtblc0 -- for "lfiultpl5repl"
tabstuff["LU"] = lfucaserest(strtblc0,true,false,strsitelangcode) -- lang name uppercase
-- begin /d01/ -- lemma page
if (tabxkol.d01) then
lfhoptconcat ('<tr>')
strtpm = constrtdbg .. lfhbrewtitsel (1,true,true) .. constrtden
lfhoptconcat (strtpm) -- "lfhbrewtitsel" does not add "<td"...">" "</td>"
strtpm = lfiultpl5repl(contabpages[0],tabstuff) -- augment and maybe uc
strdeste = '[[' .. strtpm .. '|' .. strtblc0 .. ']]' -- wl to lem page
strt3d = constrtddf .. contabwarna['bkgud'] .. constrtdfd -- long "td" eleme
lfhoptconcat (strt3d .. strdeste .. constrtden) -- here "strdeste" used
lfhoptconcat ('</tr>')
end--if
-- done /d01/
-- begin /c1/ -- Q-item
strtblc1 = tabonelang[1] or ''
if (strtblc1~="-") then
if (not lfivalidatequack(strtblc1)) then
numlokera = 15 -- #E15 /c1/ faulty
break -- to join mark -- no table and huge error
end--if
end--if
-- done /c1/
-- begin /d02/ -- Q-item
if (tabxkol.d02) then
lfhoptconcat ('<tr>')
strtpm = constrtdbg .. lfhbrewtitsel (2,true,true) .. constrtden
lfhoptconcat (strtpm) -- "lfhbrewtitsel" does not add "<td"...">" "</td>"
strbkn = contabwarna['bkgud'] -- color code without "#" cross
if (strtblc1=="-") then -- nice to have, do not abort
strbkn = 'FFD8D8' -- reddish if no "lang in the lang"
else
strtblc1 = '[[d:' .. strtblc1 .. '|' .. strtblc1 .. ']]'
end--if
strt3d = constrtddf .. strbkn .. constrtdfd -- long "td" eleme
lfhoptconcat (strt3d .. strtblc1 .. constrtden) -- no "strdeste" here c1
lfhoptconcat ('</tr>')
end--if
-- done /d02/
-- begin "c2" -- name of lang propralingve -- nice to have
strtblc2 = tabonelang[2] or '' -- submodule cares about RLLR
if (not lfivalidatestr(strtblc2,"-",2,contabtunmisc[1],0,0)) then
numlokera = 15 -- #E15 /c2/ is faulty ("-" tolerable here)
break -- to join mark -- no table and huge error
end--if
-- done "c2"
-- begin dest "d03" -- name of lang propralingve
if (tabxkol.d03) then
lfhoptconcat ('<tr>')
strtpm = constrtdbg .. lfhbrewtitsel (3,true,true) .. constrtden
lfhoptconcat (strtpm) -- "lfhbrewtitsel" does not add "<td"...">" "</td>"
strbkn = contabwarna['bkgud'] -- color code without "#" cross
if (strtblc2=="-") then -- nice to have, do not abort
strbkn = 'FFD8D8' -- reddish if no propralingve
end--if
strt3d = constrtddf .. strbkn .. constrtdfd -- long "td" eleme
lfhoptconcat (strt3d .. strtblc2 .. constrtden) -- no "strdeste" here c1
lfhoptconcat ('</tr>') -- done "d03"
end--if
-- begin "c3" -- constructed and antique status
strtblc3 = tabonelang[3] or ''
-- done "c3"
-- begin "d04" -- constructed and antique status
if (tabxkol.d04) then
strtpm = '<tr>' .. constrtdbg .. lfhbrewtitsel (4,true,true) .. constrtden
lfhoptconcat (strtpm) -- "lfhbrewtitsel" does not add "<td"...">" "</td>"
if (strtblc3=="-") then -- nice to have, do not abort
strbkn = 'FFD8D8' -- reddish if missing
strdeste = "-"
else
numtamp = string.len(strtblc3) -- must be "0" ... "3"
if (numtamp~=1) then
numoct = 255 -- invalid
else
numoct = lfdec1diglm(string.byte(strtblc3,1,1),3) -- 0...3 or 255
end--if
strbkn = lfhintegertocol6d(numoct,false,contabwarna['bkgud']) -- preASSume light yellow (default color)
if (strbkn=="=") then
numlokera = 15 -- #E15 "c3" is faulty
break -- to join mark -- no table and huge error
else
strdeste = contabd04ap[numoct+1] -- "contabd04ap" is ONE-based
strdeste = strdeste .. ' (' .. string.char(numoct+48) .. ')'
end--if
end--if (strtblc3=="-") else
strt3d = constrtddf .. strbkn .. constrtdfd -- long "td" eleme
lfhoptconcat (strt3d .. strdeste .. constrtden .. '</tr>')
end--if
-- done "d04"
-- begin /c4/
strtblc4 = tabonelang[4] or ''
if (strtblc4=="--") then
bootjmp = false -- 2 valid alternative values "-" and "--" exist
else
bootjmp = (not lfivalidatestr(strtblc4,"-",2,2,2,3))
end--if
if (bootjmp) then
numlokera = 15 -- #E15 /c4/ is faulty
break -- to join mark -- no table and huge error
end--if
-- done /c4/
if (tabxkol.d05) then
lfhoptconcat ('<tr>') -- begin "d05"
strtpm = constrtdbg .. lfhbrewtitsel (5,true,true) .. constrtden
lfhoptconcat (strtpm) -- "lfhbrewtitsel" does not add "<td"...">" "</td>"
strbkn = contabwarna['bkgud'] -- color code without "#" cross
if (strtblc4=="-") then -- nice to have ("-" is reddish, "--" is NOT)
strbkn = 'FFD8D8' -- reddish if no ISO 639-1:2002 code
end--if
strt3d = constrtddf .. strbkn .. constrtdfd -- long "td" eleme
lfhoptconcat (strt3d .. strtblc4 .. constrtden) -- no "strdeste" here c3
lfhoptconcat ('</tr>') -- done "d05"
end--if
-- begin "c5"
strtblc5 = tabonelang[5] or ''
if (strtblc5=="---") then
bootjmp = false -- 2 valid alternative values "-" and "---" exist
else
bootjmp = (not lfivalidatestr(strtblc5,"-",3,3,2,3))
end--if
if (bootjmp) then
numlokera = 15 -- #E15 "c5" is faulty
break -- to join mark -- no table and huge error
end--if
-- done "c5"
-- begin "d06" -- 3-letter code
if (tabxkol.d06) then
lfhoptconcat ('<tr>')
strtpm = constrtdbg .. lfhbrewtitsel (6,true,true) .. constrtden
lfhoptconcat (strtpm) -- "lfhbrewtitsel" does not add "<td"...">" "</td>"
strbkn = contabwarna['bkgud'] -- color code without "#" cross
if (strtblc5=="-") then -- nice to have ("-" is reddish, "---" is NOT)
strbkn = 'FFD8D8' -- reddish if no ISO 639-3:2007 code
end--if
strt3d = constrtddf .. strbkn .. constrtdfd -- long "td" eleme
lfhoptconcat (strt3d .. strtblc5 .. constrtden) -- no "strdeste" here c4
lfhoptconcat ('</tr>')
end--if
-- done "d06"
-- begin "d07" -- "tln" + "kap" (!!! can be hidden !!!)
if (tabxkol.d07) then
lfhoptconcat ('<tr>')
strtpm = constrtdbg .. lfhbrewtitsel (7,tabxctl.tlnsow,tabxctl.kapsow) .. constrtden
lfhoptconcat (strtpm) -- "lfhbrewtitsel" does not add "<td"...">" "</td>"
strbkn = contabwarna['bkgud'] -- color code without "#" cross
strdeste = '' -- crucial
if (tabxctl.tlnsow) then
strtmp = lfiultpl5repl(contabpages[5],tabstuff) -- augm maybe uc
bootjmp,strdeste = lfykattlaenk (strtmp,strpykkatns,true,contabtunmisc['cats']) -- "tln"
end--if (tabxctl.tlnsow) then
if (tabxctl.tlnsow and tabxctl.kapsow) then
strdeste = strdeste .. '<br>'
end--if
if (tabxctl.kapsow) then
strtmp = lfiultpl5repl(contabpages[6],tabstuff) -- augm maybe uc
bootjmp,strtmp = lfykattlaenk (strtmp,strpykkatns,true,contabtunmisc['cats']) -- "kap"
strdeste = strdeste .. strtmp
if (not bootjmp) then
strbkn = 'FFD8D8' -- reddish if "kap" kat does not exist
end--if
end--if (tabxctl.kapsow) then
strt3d = constrtddf .. strbkn .. constrtdfd -- long "td" eleme
lfhoptconcat (strt3d .. strdeste .. constrtden)
lfhoptconcat ('</tr>')
end--if (tabxkol.d07) then
-- done "d07"
-- begin "d08" -- "vor" + "mal" (!!! can be hidden !!!)
if (tabxkol.d08) then
lfhoptconcat ('<tr>')
strtpm = constrtdbg .. lfhbrewtitsel (8,tabxctl.vorsow,tabxctl.malsow) .. constrtden
lfhoptconcat (strtpm) -- "lfhbrewtitsel" does not add "<td"...">" "</td>"
strbkn = contabwarna['bkgud'] -- color code without "#" cross
strdeste = '' -- crucial
if (tabxctl.vorsow) then
strtmp = lfiultpl5repl(contabpages[3],tabstuff) -- augm maybe uc
bootjmp,strdeste = lfykattlaenk (strtmp,strpykkatns,true,contabtunmisc['cats']) -- "vor"
end--if (tabxctl.vorsow) then
if (tabxctl.vorsow and tabxctl.malsow) then
strdeste = strdeste .. '<br>'
end--if
if (tabxctl.malsow) then
strtmp = lfiultpl5repl(contabpages[4],tabstuff) -- augm maybe uc
bootjmp,strtmp = lfykattlaenk (strtmp,strpykkatns,true,contabtunmisc['cats']) -- "mal"
strdeste = strdeste .. strtmp
if (not bootjmp) then
strbkn = 'FFD8D8' -- reddish if "mal" kat does not exist
end--if
end--if (tabxctl.malsow) then
strt3d = constrtddf .. strbkn .. constrtdfd -- long "td" eleme
lfhoptconcat (strt3d .. strdeste .. constrtden)
lfhoptconcat ('</tr>')
end--if (tabxkol.d08) then
-- done "d08"
-- begin "d09" -- Appendix + Index (!!! can be hidden !!!)
if (tabxkol.d09) then
lfhoptconcat ('<tr>')
strtpm = constrtdbg .. lfhbrewtitsel (9,tabxctl.apxsow,tabxctl.indsow) .. constrtden
lfhoptconcat (strtpm) -- "lfhbrewtitsel" does not add "<td"...">" "</td>"
strbkn = contabwarna['bkgud'] -- color code without "#" cross
strdeste = '' -- crucial
if (tabxctl.apxsow) then
strtmp = lfiultpl5repl(contabpages[1],tabstuff) -- augm maybe uc
bootjmp,strdeste = lfyapxindlaenk (strtmp,strpykapxns,false,true) -- "apx"
end--if (tabxctl.apxsow) then
if (tabxctl.apxsow and tabxctl.indsow) then
strdeste = strdeste .. '<br>'
end--if
if (tabxctl.indsow) then
strtmp = lfiultpl5repl(contabpages[2],tabstuff) -- augm maybe uc
bootjmp,strtmp = lfyapxindlaenk (strtmp,strpykindns,true,true) -- "ind"
strdeste = strdeste .. strtmp
if (not bootjmp) then
strbkn = 'FFD8D8' -- reddish if "ind" page does not exist
end--if
end--if (tabxctl.indsow) then
strt3d = constrtddf .. strbkn .. constrtdfd -- long "td" eleme
lfhoptconcat (strt3d .. strdeste .. constrtden)
lfhoptconcat ('</tr>')
end--if (tabxkol.d09) then
-- done "d09"
-- begin /c6/ -- wiki access code
strtblc6 = tabonelang[6] or ''
if (strtblc6=="-") then -- nice to have, long codes permitted, "??" permitted
strtblc6 = stronecy -- copy access code from /cy/
else
if (not lfivalidatelnkoadv(strtblc6,false,true,true,false,false)) then -- function returns true if valid
numlokera = 15 -- #E15 "c6" is faulty
break -- to join mark -- no table and huge error
end--if
end--if
-- done /c6/
-- begin "c7" -- wiki availability code
strtblc7 = tabonelang[7] or ''
if (strtblc7~="-") then -- nice to have
numtamp = string.len(strtblc7) -- length
if (numtamp==2) then
numc7pedi = string.byte(strtblc7,1,1) -- availability code
numc7tion = string.byte(strtblc7,2,2) -- availability code
numc7pedi = lfdec1diglm (numc7pedi,2) -- 0...2 or 255 if invalid
numc7tion = lfdec1diglm (numc7tion,2) -- 0...2 or 255 if invalid
if ((numc7pedi==255) or (numc7tion==255)) then
numlokera = 15 -- #E15 /c7/ is faulty
break -- to join mark -- no table and huge error
end--if
else
numlokera = 15 -- #E15 /c7/ is faulty
break -- to join mark -- no table and huge error
end--if
end--if
-- done "c7"
-- begin "d10" -- other ipedia main page
if (tabxkol.d10) then
strtpm = '<tr>' .. constrtdbg .. lfhbrewtitsel (10,true,true) .. constrtden
lfhoptconcat (strtpm) -- "lfhbrewtitsel" does not add "<td"...">" "</td>"
strbkn = lfhintegertocol6d(numc7pedi,true,contabwarna['bkgud']) -- preASSume light yellow (default color)
strdeste = lfibrewurl(strtblc6,false,nil) .. lfiavailnt(numc7pedi)
strt3d = constrtddf .. strbkn .. constrtdfd -- long "td" eleme
lfhoptconcat (strt3d .. strdeste .. constrtden .. '</tr>')
end--if
-- done "d10"
-- begin "d11" -- other tionary main page
if (tabxkol.d11) then
strtpm = '<tr>' .. constrtdbg .. lfhbrewtitsel (11,true,true) .. constrtden
lfhoptconcat (strtpm) -- "lfhbrewtitsel" does not add "<td"...">" "</td>"
if (strtblc6==strsitelangcode) then
strbkn = contabwarna['bkgud'] -- color code without "#" cross -- light yellow (default color)
strdeste = ':-)' -- reserved for "d11" cell
else
strbkn = lfhintegertocol6d(numc7tion,true,contabwarna['bkgud']) -- preASSume light yellow (default color)
strdeste = lfibrewurl (strtblc6,true,nil) .. lfiavailnt(numc7tion)
end--if
strt3d = constrtddf .. strbkn .. constrtdfd -- long "td" eleme
lfhoptconcat (strt3d .. strdeste .. constrtden .. '</tr>')
end--if
-- done "d11"
-- begin "c8" -- article in own wikipedia
strtblc8 = tabonelang[8] or ''
if (not lfivalidatestr(strtblc8,"-",2,32,0,0)) then
numlokera = 15 -- #E15 "c8" is faulty
break -- to join mark -- no table and huge error
end--if -- done "c8"
-- begin "d12" -- article in own wikipedia
if (tabxkol.d12) then
strtpm = '<tr>' .. constrtdbg .. lfhbrewtitsel (12,true,true) .. constrtden
lfhoptconcat (strtpm) -- "lfhbrewtitsel" does not add "<td"...">" "</td>"
strbkn = contabwarna['bkgud'] -- color code without "#" cross
strtmp = strtblc8 -- name of wp article, BEWARE: may contain space
bootjmp = false
if (strtmp=="-") then
bootjmp = true -- this is semi-evil, we have to guess
strtmp = lfiultpl5repl(contabpages[7],tabstuff) -- augment and maybe uc
end--if
strdeste = lfibrewurl (strsitelangcode,false,strtmp) -- own ipedia article
if (bootjmp) then
strbkn = 'FFD8D8' -- reddish if we had to guess
strdeste = strdeste .. ' (??)' -- tagg the quess
end--if
strt3d = constrtddf .. strbkn .. constrtdfd -- long "td" eleme
lfhoptconcat (strt3d .. strdeste .. constrtden .. '</tr>')
end--if
-- done "d12"
-- begin "c9" -- cat in other tionary
strtblc9 = tabonelang[9] or '' -- submodule cares about RLLR
numafstbfcl = string.len(strtblc9)
-- done "c9"
-- begin /ca/ -- number of lemmas in that cat
strtblca = tabonelang[10] or ''
numafstbfkp = string.len(strtblca)
-- done /ca/
-- begin /d13/ -- cat in other tionary with number of lemmas
if (tabxkol.d13) then
do -- scope
local strta13mp = ''
local numtaamp = 0
local numtuump = 0
local boolocerx = false -- local error flag
local boolocery = false -- other local error flag
lfhoptconcat ('<tr>')
strta13mp = constrtdbg .. lfhbrewtitsel (13,true,true) .. constrtden
lfhoptconcat (strta13mp) -- "lfhbrewtitsel" not add "<td"...">" "</td>"
strbkn = contabwarna['bkgud'] -- color code without "#" cross
boolocerx = false
boolocery = false
if (strtblc9~="-") then -- do NOT evaluate evilness of "-" in "c9"
if ((numafstbfcl<8) or (numafstbfcl>contabtunmisc[2])) then -- "c9" bad
boolocerx = true -- length out of range
else
numtaamp = lfcountchr(strtblc9,58)
if ((numtaamp==0) or (numtaamp>2)) then -- "c9" bad
boolocerx = true -- bad number of colons, ONE or TWO required
end--if
end--if
end--if
if (strtblca~="-") then -- do NOT evaluate evilness of "-" in /ca/
if (numafstbfkp>8) then -- /ca/ bad
boolocery = true -- length out of range (no minimum)
else
if (lfcountndg(strtblca)~=0) then -- /ca/ bad
boolocery = true -- faulty char:s, a number is expected
end--if
end--if
end--if
if (boolocerx or boolocery) then
numlokera = 15 -- #E15 "c9" or /ca/ is faulty
break -- to join mark -- no table and huge error
else
if (strtblc9=='-') then
strbkn = 'FFD8D8' -- reddish if no category
strdeste = '-'
else
strdeste = lfibrewurl (strtblc6,true,strtblc9) .. '<br>' -- other tionary cat
if (strtblca=="-") then
strdeste = strdeste .. lfinumberinkat(-1) -- NOT count as error
else
numtuump = tonumber(lfremovenondi(strtblca)) -- apo:s tolerable
strdeste = strdeste .. lfinumberinkat(numtuump) -- apo:s added
end--if (strtblca=='-') else
end--if (strtblc9=='-') else
end--if (boolocerx or boolocery) else
strt3d = constrtddf .. strbkn .. constrtdfd -- long "td" eleme
lfhoptconcat (strt3d .. strdeste .. constrtden) -- here "strdeste" used
lfhoptconcat ('</tr>')
end--do scope
end--if
-- done /d13/
break -- finally
end--while -- fake loop -- join mark
return numlokera
end--function lfydoonelang
------------------------------------------------------------------------
---- VARIABLES [R] ----
------------------------------------------------------------------------
function exporttable.ek (arxframent)
-- general unknown type "var"
local vartomp = 0
-- special type "args" AKA "arx"
local arxourown = 0 -- metaized "args" from our own "frame" (NOT caller's)
-- general "tab"
local tablg78ysubt = {} -- all langcodes (komp NO sng YES)
local tabc0toca = {} -- one langcode (komp NO sng YES)
local tabctl = {} -- tlnsow tlnexp kapsow kapexp vorsow vorexp malsow malexp apxsow apxexp indsow indexp
local tabkol = {} -- columns "d01" ... "d13"
-- peeked stuff
local strpiklangcode = '' -- "en" privileged site language
local strpikkatns = '' -- "Category"
local strpikindns = '' -- "Index"
local strpikapxns = '' -- "Appendix"
-- general "str"
local striywocy = '' -- incoming parameter with langcode is the y-index word
local strinfsel = '' -- incoming parameter with 6 digi, converted into 9 boo
local strpurge = '' -- purge quasi-external link complete with "[" and "]"
local strtopm = ''
-- general "num"
local numerr = 0 -- #E01 internal #E12 unknown
local num2statcode = 0
-- general "boo"
local boohavtbl = false -- have table on OK or #E12
local bootimp = false
------------------------------------------------------------------------
---- MAIN [Z] ----
------------------------------------------------------------------------
---- GUARD AGAINST INTERNAL ERROR AGAIN ----
lfdtracemsg ('This is module "msngtbllin", requested "detrc" report')
if (qbooguard) then
numerr = 1 -- #E01 internal
end--if
qtcostquery[0] = arxframent -- quasi-constant
qtcostquery[1] = contabtunmisc['tifi'] -- control constant -- be tight-fisted
qtcostquery[2] = 0 -- pass number (ZERO single | ONE collect | TWO retrieve)
qtcostquery[3] = 0 -- total counter PagesInCategory
qtcostquery[4] = 0 -- cost PagesInCategory (batched is cheaper, currently impossible)
qtcostquery[5] = 0 -- counter tight-fisted PagesInCategory (currently impossible)
qtcostquery[6] = 0 -- total counter IfExists
qtcostquery[7] = 0 -- cost IfExists (batched is cheaper, soon possible)
qtcostquery[8] = 0 -- counter tight-fisted IfExists
---- PEEK STUFF THAT IS NOT OVERRIDDEN MINIMAL ----
-- this depends on "arxframent" (only if parent requested) but NOT on "arx"
-- "strpikkatns" and "strpikindns" and "strpikapxns" do NOT
-- include a trailing ":" colon, and are for "lfykattlaenk"
-- and "lfyapxindlaenk" and "lfikatpaldigu"
-- no "strpikparent" and no "strpikpareuf" here
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
strpikindns = contabovrd['indprefi'] or (mw.site.namespaces[100] or {})['name'] or 'Index' -- custom namespace
strpikapxns = contabovrd['apxprefi'] or (mw.site.namespaces[102] or {})['name'] or 'Appendix' -- custom namespace
if ((type(strpiklangcode)~='string') or (type(strpikkatns)~='string') or (type(strpikindns)~='string') or (type(strpikapxns)~='string')) then
numerr = 1 -- #E01 internal (unlikely)
end--if
end--if (numerr==0) then
lfdtracemsg ('Peeking done, strpiklangcode=' .. tostring(strpiklangcode))
lfdtracemsg ('Further strpikkatns=' .. tostring(strpikkatns) .. ', strpikindns=' .. tostring(strpikindns) .. ', strpikapxns=' .. tostring(strpikapxns))
---- SEIZE ONE ANON AND OBLIGATORY PARAMETER ----
-- in arxourown[1] expecting lang code (2 or 3 lowercase letters,
-- everythig else is criminal but this can be changed easily)
-- result in "striywocy" will be later used as index for T78 but
-- also displayed in right column in row /d00/
arxourown = arxframent.args -- "args" from our own "frame"
if ((arxourown[1]==nil) or (arxourown[2])) then
numerr = 8 -- #E08 need one obligatory anon param, NOT more
else
striywocy = arxourown[1] -- y-index word (langcode)
if (not lfivalidatelnkoadv(striywocy,false,false,contabtunmisc[3],contabtunmisc[4],false)) then
numerr = 11 -- #E11 obviously invalid langcode
end--if
end--if
---- SEIZE ONE NAMED AND OBLIGATORY PARAMETER ----
-- obligatory 6 digits about 6 items in 3 columns into 9
-- tabbed boolean:s
-- in "infsel=" expecting 6 decimal digits, value "2" NOT accepted here
if (numerr==0) then
do -- scope
local varselinf = 0
local numsilur = 0
while true do
varselinf = arxourown['infsel'] -- 6 digits: tln kap vor mal apx ind
if (type(varselinf)~='string') then
numerr = 16 -- #E16 named param "infsel=" missing
break
end--if
strinfsel = varselinf
numsilur = lfivaliumdctlstr ('111111',strinfsel) -- less than 255 bad
if (numsilur~=255) then
numerr = 17 -- #E17 named param "infsel=" invalid
break
end--if
numsilur = lfdec1digit(string.byte(strinfsel,1,1)) -- "tln"
tabctl.tlnsow = (numsilur~=0) -- show tln in d07
tabctl.tlnexp = false
numsilur = lfdec1digit(string.byte(strinfsel,2,2)) -- "kap"
tabctl.kapsow = (numsilur~=0) -- show kap in d07
tabctl.kapexp = false
numsilur = lfdec1digit(string.byte(strinfsel,3,3)) -- "vor"
tabctl.vorsow = (numsilur~=0) -- show vor in d08
tabctl.vorexp = false
numsilur = lfdec1digit(string.byte(strinfsel,4,4)) -- "mal"
tabctl.malsow = (numsilur~=0) -- show mal in d08
tabctl.malexp = false
numsilur = lfdec1digit(string.byte(strinfsel,5,5)) -- "apx"
tabctl.apxsow = (numsilur~=0) -- show apx
tabctl.apxexp = false
numsilur = lfdec1digit(string.byte(strinfsel,6,6)) -- "ind"
tabctl.indsow = (numsilur~=0) -- show ind
tabctl.indexp = false
break -- finally to join mark
end--while -- fake loop -- join mark
end--do scope
end--if
---- SEIZE NAMED AND OPTIONAL PARAMETER "DETRC" EVEN IF WE ALREADY SUCK ----
-- try to pick named param "detrc=" even if we already have an error, so
-- far we have collected to "qstrtrace" unconditionally, maybe shut up now
if (arxourown['detrc']=='true') then
lfdtracemsg ('Seized "detrc=true"')
else
qboodetrc = false -- was preassigned to "true"
qstrtrace = '' -- shut up now
end--if
lfdtracemsg ('All params done, numerr=' .. tostring(numerr))
---- PROCESS MESSAGES ----
contaberaroj = lfhfillsurrstrtab(contaberaroj, nil, strpiklangcode, nil)
contabd10d11w = lfhfillsurrstrtab(contabd10d11w, nil, strpiklangcode, nil) -- 1,2 -- "fermita aux malplena"
contabdestit = lfhfillsurrstrtab(contabdestit, nil, strpiklangcode, nil) -- 0...13 -- table headings
contabpages = lfhfillsurrstrtab(contabpages, nil, strpiklangcode, nil) -- 0...7 -- "Sxablonaro -@LK00-"
contabligiloj = lfhfillsurrstrtab(contabligiloj, nil, strpiklangcode, nil) -- 0,1,2
---- PICK ONE SUBTABLE T78 ----
-- here risk of #E02 #E03
-- on error we assign "numerr" and maybe "num2statcode" both used far below
while true do -- fake loop
if (numerr~=0) then -- #E01 possible
break -- to join mark
end--if
num2statcode, bootimp = lfhvali1status99code (qldingvoj[2]) -- 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
vartomp = qldingvoj['T78']
if (type(vartomp)~='table') then -- important check
numerr = 2 -- #E02 malica
break -- to join mark
end--if
tablg78ysubt = vartomp -- has sub-sub-tables for langcodes
break -- finally to join mark
end--while -- fake loop -- join mark
lfdtracemsg ('Picking of T78 done, numerr=' .. tostring(numerr) .. ', num2statcode=' .. tostring(num2statcode))
---- SEIZE THE PAGENAME AND BREW THE PURGE LINK FROM IT ----
-- we use contabligiloj[0] with one word
strtopm = 'Special:Recent changes' -- bad default
vartomp = mw.title.getCurrentTitle().prefixedText -- with namespace prefix !!
if (lfgstringrange(vartomp,1,255)) then
strtopm = vartomp -- fullpagename here (otherwise "Special:Recent changes")
end--if
strpurge = lfwbrew3url (arxframent,strtopm,'action=purge',contabligiloj[0],true)
---- CHECK LANGCODE ----
if (numerr==0) then
tabc0toca = tablg78ysubt[striywocy]
if (type(tabc0toca)~='table') then
numerr = 12 -- #E12 unknown langcode
end--if
end--if
-- if "striywocy" fails !!!FIXME!!!
-- if own code works then
-- xboonotfnd = true -- lagom error (since at least our own code found)
-- else
-- xnumerr = 15 -- #E15 huge error (since our own code NOT found either)
-- endif
-- endif
lfdtracemsg ('Langcode checked, numerr=' .. tostring(numerr))
---- ASSIGN MANY ----
if (numerr==0) then
tabkol.d01 = true
tabkol.d02 = true
tabkol.d03 = true
tabkol.d04 = true
tabkol.d05 = true
tabkol.d06 = true
tabkol.d07 = tabctl.tlnsow or tabctl.kapsow
tabkol.d08 = tabctl.vorsow or tabctl.malsow
tabkol.d09 = tabctl.apxsow or tabctl.indsow
tabkol.d10 = true
tabkol.d11 = true
tabkol.d12 = true
tabkol.d13 = true
end--if
---- BEGIN OUTPUT TABLE (1+14+1 ROWS) AND BREW TOP CELL "COLSPAN=2" ----
-- using constants "constrtdcs" and "constrtden" for
-- "<td"...">" (with <<colspan="2">>) and "</td>"
-- table "sng" must use <<float:right;>> and margins different from "komp"
-- here we start using "lfhoptconcat", the thing has been initialized
-- by <<local qstrret = ''>> and <<local qtabbunch = {}>>
boohavtbl = (numerr==0) or (numerr==12) -- OK or #E12
if (boohavtbl) then -- OK or #E12
lfhoptconcat (contabhtml['bigbeg']) -- "<table"... and "<tr>"
lfhoptconcat ('<tr>' .. constrtdcs .. constrtop .. constrtden .. '</tr>')
end--if
---- BOTHER WITH UNKNOWN LANGCODE ----
-- using constants "constrtdcs" and "constrtden" for
-- "<td"...">" (with <<colspan="2">>) and "</td>"
if (numerr==12) then -- #E12 unknown langcode
lfhoptconcat ('<tr>' .. constrtdcs .. constrelabg .. (contaberaroj[12] or '"12"') .. constrelaen .. constrtden .. '</tr>')
end--if
---- MAIN BLOCK OF TABLE DATA ----
-- from above:
-- * strpiklangcode ...
-- * striywocy (from caller, this is /cy/)
-- * tabc0toca (from tablg78ysubt)
-- * tabctl (from "infsel=")
-- * tabkol
-- inside "lfydoonelang" using function "lfhbrewtitsel"
-- (NOT adding "<td"...">" "</td>") for every table row /d00/ ... /d13/
if (numerr==0) then -- skip also for #E12
numerr = lfydoonelang (strpiklangcode, strpikkatns, strpikindns, strpikapxns, striywocy, tabc0toca, tabctl, tabkol)
end--if
--- BREW THE BOTTOM CELL "COLSPAN=2" ----
-- using constants "constrtdcs" and "constrtden" for
-- "<td"...">" (with <<colspan="2">>) and "</td>"
-- update/purge link (depends on pagename)
-- link to source table (fixed) (template namespace)
-- link to complete table (fixed) (appendix namespace)
if (boohavtbl) then -- OK or #E12
lfhoptconcat ('<tr>' .. constrtdcs .. strpurge .. '<br>' .. contabligiloj[1] .. '<br>' .. contabligiloj[2] .. constrtden .. '</tr>')
end--if
---- CLOSE THE OUTPUT TABLE, FINALIZE STRING, WHINE IF NEEDED ----
if (boohavtbl) then -- OK or #E12
lfhoptconcat ('</table>')
lfhoptconcat (nil) -- crucial to finalize "qstrret"
else
qtabbunch = {} -- crucial to discard
qstrret = constrehubg .. (contaberaroj[numerr] or ('"' .. tostring(numerr) .. '"')).. constrehuen -- fatal error -- replace content of the string
end--if
---- RETURN THE JUNK STRING ----
if (qboodetrc) then
qstrret = "<br>" .. qstrtrace .. "<br><br>" .. qstrret
end--if
return qstrret
end--function
---- RETURN THE JUNK LUA TABLE ----
return exporttable