Modul:msngtbllin

Dari Wiktionary bahasa Indonesia, kamus bebas
Loncat ke navigasi Loncat ke pencarian

Dokumentasi untuk modul ini dapat dibuat di Modul:msngtbllin/doc

--[===[

MODULE "MSNGTBLLIN" (single tabelo kun lingvoj)

"eo.wiktionary.org/wiki/Modulo:msngtbllin" <!--2019-May-25-->
"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) (called with param other than "komp")

Required submodules / Bezonataj submoduloj / Submodul yang diperlukan:
- "mpiktbllki" in turn requiring "mtmplloaddata" in turn requiring
  template "tbllingvoj" (EO) or "tblbahasa" (ID)
- "mpiksubstrind"

Incoming: - 2 parameters
            - anonymous obligatory parameter
              - string with 2 or 3 char:s : language access code
                ("komp" NOT accepted here)
            - anonymous obligatory parameter
              - string with 4 char:s
                - "d01" show appendix page ("0" do not show | "1" show)
                - "d06" kapkat ("0" hide co | "1" show check)
                - "d07" vorkat ("0" hide co | "1" show check)
                - "d08" index  ("0" hide co | "1" show check)

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 "mtmplloaddata" 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 "mtmplloaddata" eldonos aux utilan
rezulton aux almenaux signocxenon "Grava eraro".

It is possible to control whether to show link to appendix page in "d01"
or not. This is provided for consistency with "mkomtbllin", but since
this module "msngtbllin" is supposed to be called from those appendix
pages (via "montablng" or "mpltabbah"), this subparameter will
usually be false.

Note that the "string with 4 char:s" has almost same function in both
"mkomtbllin" and "msngtbllin", but it is positionned differently in
the parameter chain, and the latter 3 char:s are tristate in
"mkomtbllin" but only bool here in "msngtbllin", checking is always on.

Column 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"
- "mpiktbllki" with special input value "+" returns the complete table line
  including the y-index word "cy", this means that unless the "cy" part is
  trimmed off, index ZERO fed into "mpiksubstrind" will return both "cy"
  and "c0", thus the indexes used by "mpiksubstrind" will NOT be OFF-by-ONE

Structure of a row in the source table with 1+10 columns:
- cy : y-index word (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 : name of the language in the language itself (may be rl-enclosed)
- c2 : constructed and antique status (digit "0"..."3")
- c3 : ISO 639-1:2002 2-letter code
- c4 : ISO 639-3:2007 3-letter code
- c5 : wiki access code (usually same as "cy" but may be different
       and longer, for example "zh-min-nan", up to 10 char:s)
- c6 : wiki availability code (2 digits "0"..."2" ie "00"..."22")
- c7 : name of ipedia article, base principle usually
       followed (there are some exceptions):
       - EO: core word usually AJ uppercase begin
             followed by " lingvo", no "la" article
       - ID: prefixed by "Bahasa " and core word begins with uppercase letter
- c8 : category with our site language ("eo" or "id") in other tionary
       (with category prefix, but without language prefix,
       without "]]" or other nonsense, may be rl-enclosed)
- c9 : amount 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 desirable.

Overall structure of the generated destination table:

- title cell "colspan=2" with fixed string (big, bold, no link)
- 13 rows per 2 cells with info or single table cell "colspan=2"
  with lagom error "constrnekl" "Nekotata lingvokodo"
- bottom cell "colspan=2" with update/purge link (depends from pagename)
  and link to source table (fixed) and link to complete table (fixed)

Structure of the right column in the desination table with 13 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 according to
          control string "constrd01lem")
        - EOL (if link to appendix page below shown)
        - link to the appendix page (constructed from constant string
          "constrapxp" (appendix namespace prefix with ":") and "c0"
          augmented by "lfpresufkap" according to control string
          "constrd01d08") named via "constrd01qal" as translation of
          the term "(appendix page)" controlled by "booaldsow"
- d02 : - name of the language in the language itself
          (literally peeked from "c1" in the source table)
- d03 : - constructed and antique status (expanded from digit "0"..."3"
          peeked from "c2" in the source table)
        # adjust background to greenish or grey if applicable
- d04 : - "ISO 639-1:2002" 2-letter language code
          (literally peeked from "c3" in the source table)
- d05 : - "ISO 639-3:2007" 3-letter language code
          (literally peeked from "c4" in the source table)
- d06 : - link to the "kap" category in own tionary with all words in
          the language (constructed from constant string "constrkatp"
          (category namespace prefix with ":") and "c0" augmented
          by "lfpresufkap" according to control string "constrd06km")
        - EOL (if complaint below exists)
        - complaint about not existing if applicable
        - EOL (in any case)
        - amount of pages (queried) or "??" if querying does not work
        # adjust background to redish if the category does not exist
        ! depends from var "boovorsow" and includes expensive querying (2)
- d07 : - link to the "vor" category in own tionary with all dictionaries in
          the language (constructed from constant string "constrkatp"
          (category namespace prefix with ":") and "c0" augmented
          by "lfpresufkap" according to control string "constrd07vm")
        - EOL (if complaint below exists)
        - complaint about not existing if applicable
        - EOL (in any case)
        - amount of pages (queried) or "??" if querying does not work
        # adjust background to redish if the category does not exist
        ! depends from var "bookapsow" and includes expensive querying (2)
- d08 : - link to the index page in own tionary with
          the language (constructed from constant string "constrindp"
          (index namespace prefix with ":") and "c0" augmented
          by "lfpresufkap" according to control string "constrd01d08")
        # adjust background to redish if index page does not exist
        ! depends from var "booidxsow" and includes expensive querying (1)
- d09 : - quasi-external link to wikipedia in the language concerned
          (constructed from "c5" and "c6", 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
- d10 : - quasi-external link to tionary in the language concerned
          (constructed from "c5" and "c6", irrespective availability, but
          special rule for own site language)
        - 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 the article in own ipedia about the language
          (article name constructed from "c7", or alternatively if "c7" is
          not available then it is guessed from "c0" and "constrd11wm"
          and " (??)" is added)
        # adjust background to redish if "c7" is not available
        ! no expensive querying here
- d12 : - quasi-external link to EO or ID category in the tionary in the
          language concerned (peeked from "c8" in the source table)
        - EOL (if amount of articles below exists)
        - amount of articles (peeked from "c9" in the source table)
        # adjust background to redish if "c8" or "c9" is not available
        ! no expensive querying here

Expensive querying:
There are only 5 expensive queries (2 times 'PAGESINCATEGORY' and
3 times '#ifexist:') per language. This is a problem in "mkomtbllin"
but here in "msngtbllin" it is no problem at all.

Error handling (here in "msngtbllin" we are much stricter than
"mkomtbllin" is and do NOT show broken stuff, and do NOT use red
background, but redish background is used when appropriate):
- "booerr" is assigned to true if 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)
- "boonotfnd" set to true if language code appears to be valid but
  is not found while our own code works, big table with lagom
  error "Nekotata lingvokodo"
- if there are too many elements in a line then we ignore the
  superfluous ones (we do not count them in advance)
- 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 "booerr" is assigned to true and "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

]===]

local sngtbllin = {}

---- CONSTANTS ----

  -- surrogate transcoding table (only needed for EO)

  local contabtransiltable = {}
  contabtransiltable[ 67] = 0xC488 -- CX
  contabtransiltable[ 99] = 0xC489 -- cx
  contabtransiltable[ 71] = 0xC49C -- GX
  contabtransiltable[103] = 0xC49D -- gx
  contabtransiltable[ 74] = 0xC4B4 -- JX
  contabtransiltable[106] = 0xC4B5 -- jx
  contabtransiltable[ 83] = 0xC59C -- SX
  contabtransiltable[115] = 0xC59D -- sx
  contabtransiltable[ 85] = 0xC5AC -- UX breve
  contabtransiltable[117] = 0xC5AD -- ux breve

  -- constant strings (generic & misc)

  local constrfrco = '2020E0'                                      -- table frame color (blue)
  local constrbkco = 'FFFFD0'                                      -- default cell background color (light yellow)
  local constrbord = 'border:0.25em solid #' .. constrfrco .. ';'  -- to be used inside "style" element
  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>'
  local constrkros = '&nbsp;#&nbsp;#&nbsp;'             -- 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

  -- constant strings EO vs ID (depends from above "generic & misc" section)

  -- local constrpriv = "eo"                    -- EO (privileged site language)
  local constrpriv = "id"                    -- ID (privileged site language)
  -- local constrplki = "Modulo:mpiktbllki"     -- EO (komp NO sng YES)
  local constrplki = "Modul:mpiktbllki"      -- ID (komp NO sng YES)
  -- local constrpiks = "Modulo:mpiksubstrind"  -- EO
  local constrpiks = "Modul:mpiksubstrind"   -- ID
  -- local constrkatp = "Kategorio:"            -- EO
  local constrkatp = "Kategori:"             -- ID
  -- local constrindp = "Indekso:"              -- EO
  local constrindp = "Indeks:"               -- ID
  -- local constrapxp = "Aldono:"               -- EO
  local constrapxp = "Lampiran:"             -- ID

  -- local constrfate = constrehubg .. 'Grava eraro' .. constrehuen                     -- EO (huge)
  local constrfate = constrehubg .. 'Kesalahan jahat' .. constrehuen                 -- ID (huge)
  -- local constrnekl = constrelabg .. 'Nekonata lingvokodo' .. constrelaen             -- EO (lagom)
  local constrnekl = constrelabg .. 'Kode bahasa yang tidak dikenal' .. constrelaen  -- ID (lagom)

  -- 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)

  local contabdestcol = {}
  -- contabdestcol[00] = 'Alira lingva kodo'                                             -- EO
  contabdestcol[00] = 'Kode akses bahasa'                                             -- ID
  -- contabdestcol[01] = 'Nomo de la lingvo en EO kaj kapvorta pagxo</b><br>kaj aldono'  -- EO (Appendix can be hidden)
  contabdestcol[01] = 'Nama bahasa dalam ID dan halaman lema</b><br>dan lampiran'     -- ID (Appendix can be hidden)
  -- contabdestcol[02] = 'Nomo en la lingvo mem'                                         -- EO
  contabdestcol[02] = 'Nama bahasa dalam bahasa itu'                                  -- ID
  -- contabdestcol[03] = 'Planlingva kaj antikva statuso'                                -- EO
  contabdestcol[03] = 'Status buatan dan kuno'                                        -- ID
  -- contabdestcol[04] = 'ISO 639-1:2002 2-litera kodo'      -- EO
  contabdestcol[04] = 'ISO 639-1:2002 kode 2 huruf'       -- ID
  -- contabdestcol[05] = 'ISO 639-3:2007 3-litera kodo'      -- EO
  contabdestcol[05] = 'ISO 639-3:2007 kode 3 huruf'       -- ID
  -- contabdestcol[06] = 'Kapvorta kategorio</b><br>kaj nombro da pagxoj'                            -- EO ("<b>" missing) (colu can be hidden in komp)
  contabdestcol[06] = 'Kategori kata</b><br>dan jumlah halaman'                                   -- ID ("<b>" missing) (colu can be hidden in komp)
  -- contabdestcol[07] = 'Vortara kategorio</b><br>kaj nombro da pagxoj'                             -- EO ("<b>" missing) (colu can be hidden in komp)
  contabdestcol[07] = 'Kategori kamus</b><br>dan jumlah halaman'                                  -- ID ("<b>" missing) (colu can be hidden in komp)
  -- contabdestcol[08] = 'Indekso kun la lingvo'                                                     -- EO (colu can be hidden in komp)
  contabdestcol[08] = 'Indeks bahasa itu'                                                         -- ID (colu can be hidden in komp)
  -- contabdestcol[09] = 'Vikipedio en la lingvo'                                                    -- EO
  contabdestcol[09] = 'Wikipedia dalam bahasa itu'                                                -- ID
  -- contabdestcol[10] = 'Vikivortaro en la lingvo'                                                        -- EO
  contabdestcol[10] = 'Wikikamus dalam bahasa itu'                                                      -- ID
  -- contabdestcol[11] = 'Artikolo pri la lingvo en EO vikipedio'                                          -- EO
  contabdestcol[11] = 'Artikel tentang bahasa itu dalam wikipedia ID'                                   -- ID
  -- contabdestcol[12] = 'Kategorio pri EO en vikivortaro en la lingvo</b><br>kaj nombro da pagxoj'        -- EO ("<b>" missing)
  contabdestcol[12] = 'Kategori tentang ID dalam vikikamus dalam bahasa itu</b><br>dan jumlah halaman'  -- ID ("<b>" missing)

  -- local constrbual = "ne ekzistas"     -- EO (status of category pages)
  local constrbual = "tidak ada"       -- ID (status of category pages)

  -- local constrd01d08 = "!|"            -- EO (wall "|" required, fixes may be empty, use space here, not "_")
  local constrd01d08 = "Bahasa |"      -- ID (wall "|" required, fixes may be empty, use space here, not "_")

  -- local constrd01lem = "|"             -- EO (wall "|" required, fixes may be empty, use space here, not "_")
  local constrd01lem = "bahasa |"      -- ID (wall "|" required, fixes may be empty, use space here, not "_")

  -- local constrd01qal = '(aldona pagxo)'      -- EO
  local constrd01qal = '(halaman lampiran)'  -- ID

  local contabd03 = {}
  -- contabd03 = {'ne planita','parte planita','planita','antikva'}  -- EO (index 1...4, no spaces)
  contabd03 = {'tidak buatan','agak buatan','buatan','kuno'}      -- ID (index 1...4, no spaces)

  -- local constrd06km = "!|"             -- EO (wall "|" required, fixes may be empty, use space here, not "_")
  local constrd06km = "Kata bahasa |"  -- ID (wall "|" required, fixes may be empty, use space here, not "_")

  -- local constrd07vm = "Vortaro (|)"    -- EO (wall "|" required, fixes may be empty, use space here, not "_")
  local constrd07vm = "Kamus (|)"      -- ID (wall "|" required, fixes may be empty, use space here, not "_")

  local contabd09d10 = {}
  -- contabd09d10 = {'fermita aux malplena','nedisponebla'}  -- EO
  contabd09d10 = {'tertutup atau kosong','tidak ada'}     -- ID

  -- local constrd11wm = "!| lingvo"      -- EO (wall "|" required, fixes may be empty, use space here, not "_")
  local constrd11wm = "Bahasa |"       -- ID (wall "|" required, fixes may be empty, use space here, not "_")

  -- local constrjlnkpu = 'gxisdatigo'                                    -- EO (no dot "." here) (komp NO sng YES)
  local constrjlnkpu = 'pemutakhiran'                                  -- ID (no dot "." here) (komp NO sng YES)
  -- local constrjsumbr = "[[%C5%9Cablono:tbllingvoj|fonta tabelo]]"      -- EO (no dot "." here) (komp NO sng YES)
  local constrjsumbr = "[[Templat:tblbahasa|tabel sumber]]"            -- ID (no dot "." here) (komp NO sng YES)
  -- local constrjkompl = "[[Aldono:Listo kun lingvoj|kompleta tabelo]]"  -- EO (komp NO sng YES)
  local constrjkompl = "[[Lampiran:Daftar bahasa|tabel lengkap]]"      -- ID (komp NO sng YES)

  -- integers "num" -- some limits for single items

  local connummaxc0c1nlen = 36   -- safe values 16 ... 96
  local connummaxc8catlen = 100  -- safe values 64 ... 256

---- IMPORTS ----

local piksubstrind = require(constrpiks) -- can crash here
local piktbllki    = require(constrplki) -- can crash here (komp NO sng YES)

------------------------------------------------------------------------

---- ORDINARY LOCAL LOW LEVEL FUNCTIONS ----

------------------------------------------------------------------------

-- Local function LFPREPROEQMI

-- Preprocess "=" to "-"

local function lfpreproeqmi (strinnandout)
  if (strinnandout=="=") then
    strinnandout = "-" -- preprocess "=" to "-"
  end--if
  return strinnandout
end--function lfpreproeqmi

------------------------------------------------------------------------

-- 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 LFTESTLC

-- Test whether char is a lowercase letter, return bool

local function lftestlc (numcode)
  local boolowerc = true
  if ((numcode<97) or (numcode>122)) then
    boolowerc = false
  end--if
  return boolowerc
end--function lftestlc

------------------------------------------------------------------------

-- Local function LFXCASEBEG

-- Case beginning letter of a word or group of words to upper or lower,
-- limited unicode support

-- Input  : - strucinut : word or group of words (may be empty)
--          - booucas : "true" for uppercase and "false" for lowercase

local function lfxcasebeg (strucinut,booucas)
  local numlein = 0
  local numchaer = 0
  local numchaes = 0
  local numcut = 1 -- becomes 2 for unicode char:s
  local booc3blok = false
  local booc4c5bl = false
  local booisuppr = false
  local booislowr = false
  numlein = string.len(strucinut)
  if (numlein~=0) then
    numchaer = string.byte(strucinut,1,1)
    if ((numchaer>127) and (numlein>=2)) then
      numchaes = string.byte(strucinut,2,2)
      numcut = 2
    end--if
    if (numcut==1) then
      booisuppr = ((numchaer>64) and (numchaer< 91))
      booislowr = ((numchaer>96) and (numchaer<123))
      if (booisuppr and (booucas==false)) then
        numchaer = numchaer+32 -- ASCII UPPER->lower
      end--if
      if (booislowr and booucas) then
        numchaer = numchaer-32 -- ASCII lower->UPPER
      end--if
    else
      booc3blok = (numchaer==195) -- case delta is 32
      booc4c5bl = ((numchaer==196) or (numchaer==197)) -- case delta is 1
      if (booc3blok) then
        if ((numchaes>=128) and (numchaes<160)) then
          booisuppr = true -- C3,80...C3,9F
        end--if
        if ((numchaes>=160) and (numchaes<192)) then
          booislowr = true -- C3,A0...C3,BF
        end--if
      end--if
      if (booc4c5bl) then
        if ((numchaes%2)==0) then
          booisuppr = true
        else
          booislowr = true
        end--if
      end--if
      if (booc3blok and booisuppr and (booucas==false)) then
        numchaes = numchaes+32 -- UC UPPER->lower -- holds f AA AE EE NN OE UE
      end--if
      if (booc3blok and booislowr and booucas) then
        numchaes = numchaes-32 -- UC lower->UPPER -- holds f aa ae ee nn oe ue
      end--if
      if (booc4c5bl and booisuppr and (booucas==false)) then
        numchaes = numchaes+1 -- UC UPPER->lower -- holds for JX SX ...
      end--if
      if (booc4c5bl and booislowr and booucas) then
        numchaes = numchaes-1 -- UC lower->UPPER -- holds for jx sx ...
      end--if
    end--if (numcut==1) else
    if (numlein>numcut) then
      strucinut = string.sub(strucinut,(numcut+1),numlein) -- remaining part
    else
      strucinut = "" -- we had just 1 char
    end--if
    if (numcut==1) then
      strucinut = string.char(numchaer) .. strucinut
    else
      strucinut = string.char(numchaer) .. string.char(numchaes) .. strucinut
    end--if
  end--if
  return strucinut
end--function lfxcasebeg

------------------------------------------------------------------------

-- add digit bunching to raw decimal number string

local function lfbunch (strnomorin)
  local strnomorut = ""
  local numlenn = 0
  local numindeex = 0 -- ZERO-based counts up
  local numcaar = 0 -- char of string
  numlenn = string.len(strnomorin)
  while (true) do
    if (numindeex==numlenn) then
      break
    end--if
    numcaar = string.byte(strnomorin,(numlenn-numindeex),(numlenn-numindeex))
    if (((numindeex%3)==0) and (numindeex~=0)) then
      strnomorut = "'" .. strnomorut -- apo
    end--if
    strnomorut = string.char(numcaar) .. strnomorut
    numindeex = numindeex + 1
  end--while
  return strnomorut
end--function lfbunch

------------------------------------------------------------------------

local function lfspctound (strinin) -- replaces spaces by underscores
  local strutut = ""
  local numleenn = 0
  local numineex = 0 -- ZERO-based counts up
  local numcaarr = 0 -- char of string
  numleenn = string.len(strinin)
  while (true) do
    if (numineex==numleenn) then
      break
    end--if
    numcaarr = string.byte(strinin,(numineex+1),(numineex+1))
    if (numcaarr==32) then
      numcaarr = 95 -- space to underscore
    end--if
    strutut = strutut .. string.char(numcaarr)
    numineex = numineex + 1
  end--while
  return strutut
end--function lfspctound

local function lfkodeosg (strsurr) -- EO transcode surrogates to cxapeloj strg
  local varpeek = 0
  local strcxapeloj = ''
  local numinputl = 0
  local numininx = 0
  local numknark = 0 -- current char (ZERO is NOT valid)
  local numknarp = 0 -- previous char (ZERO is NOT valid)
  local numlow = 0
  local numhaj = 0
  numinputl = string.len(strsurr)
  while (true) do
    if (numininx==numinputl) then
      break
    end--if
    numknark = string.byte(strsurr,(numininx+1),(numininx+1))
    numininx = numininx + 1
    numhaj = 0 -- pre-assume no translation
    if ((numknarp~=0) and ((numknark==88) or (numknark==120))) then -- got "x"
      varpeek = contabtransiltable[numknarp] -- UINT16 or nil
      if (varpeek~=nil) then
        numlow = varpeek % 256 -- MOD operator -- bitwise AND operator lacks
        numhaj = math.floor (varpeek / 256) -- DIV operator lacks in Lua :-(
      end--if
    end--if
    if (numhaj~=0) then
      strcxapeloj = strcxapeloj .. string.char(numhaj) .. string.char(numlow)
      numknark = 0 -- invalidade current char
    else
      if (numknarp~=0) then -- add previous char only if valid
        strcxapeloj = strcxapeloj .. string.char(numknarp) -- add it
      end--if
    end--if
    numknarp = numknark -- copy to previous even if invalid
  end--while
  if (numknarp~=0) then -- add previous and last char only if valid
    strcxapeloj = strcxapeloj .. string.char(numknarp) -- add it
  end--if
  return strcxapeloj
end--function lfkodeosg

local function lfkodeotb (tabsurr) -- EO transcode surrogates to cxapeloj tabl
  local varitem = 0 -- variable without type
  local tabcxapeloj = {}
  local numtblindex = 0 -- ZERO-based
  while (true) do
    varitem = tabsurr[numtblindex] -- expected type "string" or "nil"
    if (varitem==nil) then
      if (numtblindex~=0) then
        break -- index ZERO is valid (just proceed to index 1 in such a case)
      end--if
    else
      tabcxapeloj[numtblindex] = lfkodeosg(varitem)
    end--if
    numtblindex = numtblindex + 1
  end--while
  return tabcxapeloj
end--function lfkodeotb

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

------------------------------------------------------------------------

-- Local function LFPRESUFKAP

-- Augment string adding prefix and suffix (any of them may be empty)
-- and optionally uppercase beginning letter of the result

-- Input  : - strctl : control string (syntax see below)
--          - strinp : data string to be augmented

-- Syntax of "strctl" :
-- - prefix (may be empty, or "!" for uppercasing)
-- - wall "|"
-- - suffix (may be empty)
-- Examples: "|" is no change and "!|" is uppercasing without augmentation

-- We need "lfxcasebeg"

local function lfpresufkap (strctl,strinp)
  local varctlmur = 0 -- wall position ONE-based (but can be "nil")
  local numctllen = 0
  local strpre = ''
  local strsuf = ''
  local strhazil = ''
  numctllen = string.len (strctl)
  if (numctllen~=0) then -- empty is NOT valid
    varctlmur = string.find (strctl, '|', 1, true) -- plain text search
    if (varctlmur~=nil) then -- "not found" is NOT valid
      if (varctlmur>1) then
        strpre = string.sub (strctl,1,(varctlmur-1)) -- isolate prefix
      end--if
      if (varctlmur<numctllen) then
        strsuf = string.sub (strctl,(varctlmur+1),numctllen) -- isolate suffix
      end--if
      if (strpre=='!') then
        strhazil = lfxcasebeg (strinp,true) .. strsuf -- no prefix here
      else
        strhazil = strpre .. strinp .. strsuf
      end--if
    end--if (varctlmur~=nil) then
  end--if
  return strhazil
end--function lfpresufkap

------------------------------------------------------------------------

-- Local function LFVALIDATESTR

-- 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
--          - 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 lfvalidatestr (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 lfvalidatestr

------------------------------------------------------------------------

---- ORDINARY LOCAL HIGH LEVEL FUNCTIONS ----

------------------------------------------------------------------------

-- Local function LFRLSTRIP

-- Strip "rl .. lr" if present and string length is at least 8 octet:s

local function lfrlstrip (strrlinut)
  local numsoct = 0
  local numsodt = 0
  local numsoet = 0
  local numsoft = 0
  local numsogt = 0
  local numsoht = 0
  local numlaengd = 0
  numlaengd = string.len(strrlinut)
  if (numlaengd>=8) then -- at least 2 octet:s length "rl .. lr" after strip
    numsoct = string.byte(strrlinut,1,1)
    numsodt = string.byte(strrlinut,2,2)
    numsoet = string.byte(strrlinut,3,3)
    numsoft = string.byte(strrlinut,(numlaengd-2),(numlaengd-2))
    numsogt = string.byte(strrlinut,(numlaengd-1),(numlaengd-1))
    numsoht = string.byte(strrlinut,(numlaengd  ),(numlaengd  ))
    if ((numsoct==114) and (numsodt==108) and (numsoet==32) and (numsoft==32) and (numsogt==108) and (numsoht==114)) then
      strrlinut = string.sub(strrlinut,4,(numlaengd-3)) -- stri off 3+3 char:s
    end--if
  end--if
  return strrlinut
end--function lfrlstrip

------------------------------------------------------------------------

local function lfamountinkat (varjumlah) -- "(16'384 pages)" or "(?? pages)"
  local strnothing = ''
  if (varjumlah==nil) then -- expected type integer or nil
    strnothing = '(??'
  else
    strnothing = '(' .. lfbunch(tostring(varjumlah)) -- ZERO is valid
  end--if
  strnothing = strnothing .. ' pages)'
  return strnothing
end--function lfamountinkat

------------------------------------------------------------------------

local function lfquer2kat (frmftnt,strkatt) -- calls 2 parser functions
  local vartoomp = 0 -- string expected but minor risk for nil
  local strkatoj = '' -- accumulate notes here
  local boomiss = false
  vartoomp = frmftnt:callParserFunction(('#ifexist:'..constrkatp..strkatt),'1','0')
  if (vartoomp~='1') then
    boomiss = true -- category does not exist (incidents counted by caller)
    strkatoj = '<br>(' .. constrbual .. ')' -- "does not exist"
  end--if
  vartoomp = frmftnt:callParserFunction('PAGESINCATEGORY',strkatt,'pages','R')
  strkatoj = strkatoj .. '<br>'
  if (type(vartoomp)=='string') then -- it is a string despite it is a number
    strkatoj = strkatoj .. lfamountinkat(tonumber(vartoomp))
  else
    strkatoj = strkatoj .. lfamountinkat(nil) -- does NOT count as error
  end--if
  return boomiss,strkatoj
end--function lfquer2kat

------------------------------------------------------------------------

local function lfavailco (numava) -- translate number 2...0 to color (Y,grey)
  local strcolor = constrbkco -- pre-assume light yellow (default color)
  if (numava==1) then
    strcolor = 'D0D0D0' -- grey
  end--if
  if (numava==0) then
    strcolor = 'B0B0B0' -- darker grey
  end--if
  return strcolor
end--function lfavailco

------------------------------------------------------------------------

-- Local function LFAVAILNT

-- Translate number 2...0 to text with "br"

-- We need table "contabd09d10" with 2 strings at indexes ONE and TWO

local function lfavailnt (numalb)
  local strnote = '' -- pre-assume no extra complaint
  if (numalb==1) then
    strnote = '<br>(' .. contabd09d10[1] .. ')' -- closed or empty
  end--if
  if (numalb==0) then
    strnote = '<br>(' .. contabd09d10[2] .. ')' -- inaccessible
  end--if
  return strnote
end--function lfavailnt

------------------------------------------------------------------------

-- Local function LFBREWURL

-- Brew [] external link to a wiki

-- Input  : - straxk : wiki access code (2...10 char:s)
--          - bootip : type (false -> ipedia | true -> tionary)
--          - varpage : pagename string (article or category with
--                      prefix) or nil expected

-- Here we replace spaces by underscore, no further encoding is performed

-- We need "lfspctound"

local function lfbrewurl (straxk,bootip,varpage)
  local strurlkita = ''
  local strsite = ''
  if (bootip) then
    strsite = 'tionary'
  else
    strsite = 'ipedia'
  end--if
  strurlkita = '[http://' .. straxk .. '.wik' .. strsite .. '.org'
  if (varpage) then -- string (article or category with prefix) or nil
    strurlkita = strurlkita .. '/wiki/' .. lfspctound(varpage) -- repla in URL
  end--if
  strurlkita = strurlkita .. ' ' -- separation space
  strurlkita = strurlkita .. straxk .. '.' .. strsite .. '...'
  if (varpage) then -- string (article or category with prefix) or nil
    strurlkita = strurlkita .. '<br>/' .. varpage -- do NOT replace here
  end--if
  strurlkita = strurlkita .. ']' -- done
  return strurlkita
end--function lfbrewurl

------------------------------------------------------------------------

-- Local function LFBREWTITSEL

-- Brew content of title cell from index number

-- Input  : - numindxe : index number of column (ZERO-based)
--          - bootrunk : remove non-bold part after "</b><br>" if true

-- An entry in the table "contabdestcol" is NOT supposed to contain
-- "<b>" (even less "''"), nor "</b>" at end, but it may contain
-- "</b><br>" to separate a non-bold part

-- We need table "contabdestcol"

local function lfbrewtitsel (numindxe,bootrunk)
  local strdesc = ''
  local varfond = 0
  strdesc = contabdestcol[numindxe] -- may contain "</b><br>" or NOT
  strdesc = '<b>' .. strdesc -- always add "<b>" begin of bold
  varfond = string.find(strdesc, '</b><br>', 1, true) -- plain text search
  if (varfond and bootrunk) then
    strdesc = string.sub(strdesc,1,(varfond+3)) -- remove part after "</b>"
  end--if
  if (varfond==nil) then
    strdesc = strdesc .. '</b>' -- add "</b>" end o b only if it is not yet in
  end--if
  strdesc = strdesc .. '<br>(' .. tostring(numindxe) .. ')'
  return strdesc
end--function lfbrewtitsel

------------------------------------------------------------------------

---- MAIN EXPORTED FUNCTION ----

------------------------------------------------------------------------

function sngtbllin.ek (arxframent)

  -- general unknown type "var"

  local vartmp = 0     -- variable without type multipurpose

  -- special type "args" AKA "arx"

  local arxourown = 0  -- metaized "args" from our own "frame" (NOT caller's)

  -- general "str"

  local striywo  = ""  -- incoming parameter with lng code is the y-index word
  local strpara  = ""  -- incoming parameter with 4 digi, converted into 4 boo
  local strtmp   = ""  -- temp
  local strtpm   = ""  -- temp other
  local strsrcrw = ""  -- complete row from the source table via "mpiktbllki"
  local strret   = ""  -- big output string with the destination table
  local strbkn   = ""  -- HTML HEX color (6 digits)
  local strt3d   = ""  -- HTML "td" element concatenated from 3 parts
  local strtblc0 = ""  -- src column 0 (this is NOT the y-index word) (obliga)
  local strtblc1 = ""  -- src column 1 (nice to have)
  local strtblc2 = ""  -- src column 2 (nice to have) 1 digit
  local strtblc3 = ""  -- src column 3 (nice to have) 2 letters
  local strtblc4 = ""  -- src column 4 (nice to have) 3 letters
  local strtblc5 = ""
  local strtblc6 = ""
  local strtblc7 = ""  -- src column 7
  local strtblc8 = ""  -- src column 8
  local strtblc9 = ""  -- src column 9
  local strdeste = ""  -- destinat table element with both "td" HTML elements
  local strpurge = ""  -- purge quasi-external link complete with "[" and "]"

  -- general "num"

  local numoct    = 0    -- temp some char
  local numtamp   = 0    -- temp
  local numtump   = 0    -- temp
  local numlong   = 0    -- length of parameter from caller
  local numc6pedi = 0    -- ipedia code "0"..."2"
  local numc6tion = 0    -- tionary code "0"..."2"

  -- general "boo"

  local booerr     = false  -- fatal error flag (huge error, no table)
  local boonotfnd  = false  -- requested lang not found (lagom error in table)
  local boolocerr  = false  -- local error flag within a table element
  local boolokeer  = false  -- other local error flag within a table element
  local bootimp    = false  -- temp

  -- from arxourown "boo"

  local booaldsow  = false  -- f arxourown[2] do show appendix page in "d01"
  local bookapsow  = false  -- f arxourown[2] do show column d06 at all
  local boovorsow  = false  -- f arxourown[2] do show column d07 at all
  local booidxsow  = false  -- f arxourown[2] do show column d08 at all

  -- only for built-in function "optconcat"

  local isubtabbunch = {}     -- bunch strings here

  ---- BUILT-IN GOSUB-STYLE FUNCTION "OPTCONCAT" ----

  -- PURPOSE: workaround poor memory management in LUA during string
  --          concatenations, add incoming string to "strret"

  -- IN  : parameter "varincom" either string or type "nil"

  -- CHG : isubtabbunch (table), strret (string)

  -- NOTE: the thing needs to be initialized by <<local strret = "">>
  --       and <<local isubtabbunch = {}>>

  -- NOTE: if the "strret" string has to be changed directly (concatenation
  --       or replace), then "optconcat (nil)" or "isubtabbunch = {}"
  --       must be done before !!!

  local optconcat = function (varincom)
    if (type(varincom)=="string") then
      if (#isubtabbunch>20) then
        strret = strret .. table.concat (isubtabbunch) .. varincom
        isubtabbunch = {}
      else
        table.insert (isubtabbunch, varincom) -- ONE-based numbering
      end--if
    end--if
    if ((varincom==nil) and (#isubtabbunch>0)) then
      strret = strret .. table.concat (isubtabbunch)
      isubtabbunch = {}
    end--if
  end--function optconcat

  ---- SEIZE 2 OBLIGATORY PARAMETERS FROM CALLER ----

  -- in arxourown[1] expecting 2 or 3 lowercase letters,
  -- everythig else is criminal

  -- result in "striywo" will be later fed into "mpiktbllki" seizing
  -- "strsrcrw" but also displayed in right column in "d00" below title cell

  -- in arxourown[2] expecting 4 binary digits, "2" is NOT accepted here

  arxourown = arxframent.args -- "args" from our own "frame"

  if ((arxourown[1]==nil) or(arxourown[2]==nil) or (arxourown[3])) then
    booerr = true -- need two obligatory params, three are not appreciated
  else
    striywo = arxourown[1] -- y-index word (2 or 3 lowercase letters)
    if (not lfvalidatestr(striywo,nil,2,3,2,3)) then
      booerr = true -- faulty string
    end--if
    strpara = arxourown[2] -- 4 digits: ald 01 | kap 01 | vor 01 | idx 01
    numlong = string.len(strpara)
    if (numlong==4) then
      numoct = string.byte (strpara,1,1)
      numoct = lfdec1diglm (numoct,1) -- 255 if invalid
      if (numoct==255) then
        booerr = true -- invalid input
      end--if
      if (numoct==1) then
        booaldsow = true -- show link to appendix page in "d01"
      end--if
      numoct = string.byte (strpara,2,2)
      numoct = lfdec1diglm (numoct,1) -- 255 if invalid
      if (numoct==255) then
        booerr = true -- invalid input
      end--if
      if (numoct~=0) then
        bookapsow = true -- show kapvorta katego "d06"
      end--if
      numoct = string.byte (strpara,3,3)
      numoct = lfdec1diglm (numoct,1) -- 255 if invalid
      if (numoct==255) then
        booerr = true -- invalid input
      end--if
      if (numoct~=0) then
        boovorsow = true -- show vortara katego "d07"
      end--if
      numoct = string.byte (strpara,4,4)
      numoct = lfdec1diglm (numoct,1) -- 255 if invalid
      if (numoct==255) then
        booerr = true -- invalid input
      end--if
      if (numoct~=0) then
        booidxsow = true -- show index "d08"
      end--if
    else
      booerr = true -- invalid input
    end--if (numlong==4) else
  end--if

  ---- TRANSCODE EO IF NEEDED ----

  if (constrpriv=="eo") then
    constrd01qal  = lfkodeosg(constrd01qal)  -- "(aldona pagxo)"
    constrjlnkpu  = lfkodeosg(constrjlnkpu)  -- "gxisdatigo"
    contabd09d10  = lfkodeotb(contabd09d10)  -- 1,2 -- "fermita aux malplena"
    contabdestcol = lfkodeotb(contabdestcol) -- 0...12 -- table headings
  end--if

  ---- SEIZE THE PAGENAME (NEEDED FOR PURGE LINK) AND BREW THE PURGE LINK ----

  -- here we do NOT use the usual function "lfbrewurl" due to
  -- insurmountable differences in the link form

  -- we need "constrjlnkpu" with one word

  if (booerr==false) then

    strtpm = "Special:Recent changes" -- bad default

    vartmp = mw.title.getCurrentTitle().prefixedText -- with namespace prefix
    if (type(vartmp)=="string") then
      if (string.len(vartmp)~=0) then
        strtpm = vartmp -- pagename here (otherwise "Special:Recent changes")
      end--if
    end--if

    strtpm = lfspctound(strtpm) -- replace space by underscore in URL
    strtmp = 'http://' .. constrpriv .. '.wiktionary.org/wiki/' .. strtpm .. '?action=purge'

    strpurge = '[' .. strtmp .. ' ' .. constrjlnkpu .. ']' -- one word

  end--if

  ---- PEEK COMPLETE LINE VIA SUBMODULE ----

  -- note that "mpiktbllki" returns the complete table line including "cy"

  if (booerr==false) then
    strsrcrw = piktbllki.ek { args = { striywo , "+" } } -- complete line
    if (strsrcrw=="=") then
      strtmp = piktbllki.ek { args = { constrpriv , "-" } } -- tes own lng cod
      if (strtmp~="1") then
        booerr = true -- huge error (since our own code NOT found either)
      else
        boonotfnd = true -- lagom error (since at least our own code found)
      end--if
    end--if (strsrcrw=="=")
  end--if

  ---- TRIM OFF "CY" PART ----

  vartmp = string.find (strsrcrw, ' ', 1, true) -- plain -- separated by space
  if (vartmp~=nil) then
    strsrcrw = string.sub (strsrcrw, vartmp) -- from ONE-based "vartmp" to end
  end--if

  ---- BEGIN OUTPUT TABLE (1+13+1 ROWS) AND BREW TOP CELL "COLSPAN=2" ----

  -- using constants "constrtdcs" and "constrtden" for
  -- "<td"...">" (with <<colspan="2">>) and "</td>"

  -- table must use <<float:right;>> and different margins here

  -- here we start using "optconcat", the thing has been initialized
  -- by <<"local strret = "">> and <<local isubtabbunch = {}>>

  if (booerr==false) then
    optconcat ('<table style="' .. constrbord .. 'float:right;margin:0 0 1em 1em;border-collapse:collapse;">')
    optconcat ('<tr>' .. constrtdcs .. constrtop .. constrtden .. '</tr>')
  end--if

  ---- BOTHER WITH UNKNOWN LANGUAGE CODE ----

  -- using constants "constrtdcs" and "constrtden" for
  -- "<td"...">" (with <<colspan="2">>) and "</td>"

  if ((booerr==false) and (boonotfnd==true)) then
    optconcat ('<tr>' .. constrtdcs .. constrnekl .. constrtden .. '</tr>')
  end--if

  ---- MAIN BLOCK ----

  -- from above we receive "striywo" (from the caller) and "strsrcrw" (picked
  -- by "mpiktbllki" and having the "cy" part trimmed of)

  -- using function "lfbrewtitsel" for every table row "d00" ... "d12"

  -- this is NOT a loop since we just abuse "while"

  if ((booerr==false) and (boonotfnd==false)) then

    while (true) do -- fake loop

        optconcat ('<tr>') -- begin dest "d00" -- access code
        strtpm = constrtdbg .. lfbrewtitsel (0,false) .. constrtden
        optconcat (strtpm) -- "lfbrewtitsel" does not add "<td"...">" "</td>"
        strbkn = constrbkco -- color code without "#" cross
        if (striywo=="eo") then
          strbkn = '90FF90' -- green decoration
        end--if
        strt3d = constrtddf .. strbkn .. constrtdfd -- long "td" elem with clr
        optconcat (strt3d .. '<b>' .. striywo .. '</b>' .. constrtden)
        optconcat ('</tr>') -- done "d00"

        strtblc0 = piksubstrind.ek { args = { strsrcrw, "0" } } -- bg src "c0"
        strtblc0 = lfpreproeqmi (strtblc0) -- "="->"-" but no rl-enclos possib
        if (not lfvalidatestr(strtblc0,nil,2,connummaxc0c1nlen,0,0)) then
          booerr = true -- "c0" (name of lng in site lng) is faulty
          break -- to join mark -- no table and huge error
        end--if -- ultimately obligatory -- even "-" is bad here -- done "c0"

        optconcat ('<tr>') -- begin dest "d01" -- name of lng in our site lng
        strtpm = constrtdbg .. lfbrewtitsel (1,(not booaldsow)) .. constrtden
        optconcat (strtpm) -- "lfbrewtitsel" does not add "<td"...">" "</td>"
        strtpm = lfpresufkap(constrd01lem,strtblc0) -- augment and maybe uc
        strdeste = '[[' .. strtpm .. '|' .. strtblc0 .. ']]' -- wl to lem page
        if (booaldsow) then
          strtmp = lfpresufkap(constrd01d08,strtblc0) -- augme and maybe uc
          strtmp = constrapxp .. strtmp -- add the "Appendix:" prefix
          strdeste = strdeste .. '<br>[[' .. strtmp .. '|' .. constrd01qal .. ']]' -- wikili
        end--if
        strt3d = constrtddf .. constrbkco .. constrtdfd -- long "td" elem clr
        optconcat (strt3d .. strdeste .. constrtden) -- here "strdeste" used
        optconcat ('</tr>') -- done "d01"

        strtblc1 = piksubstrind.ek { args = { strsrcrw, "1" } } -- bg src "c1"
        strtblc1 = lfpreproeqmi (strtblc1) -- "="->"-" and rl-enclos possible
        strtblc1 = lfrlstrip(strtblc1) -- name of the lng in the lng itself
        if (not lfvalidatestr(strtblc1,"-",2,connummaxc0c1nlen,0,0)) then
          booerr = true -- "c1" (name of the lng in the lng itself) is faulty
          break -- to join mark -- no table and huge error
        end--if -- nice to have -- "-" is tolerable here -- done "c1"

        optconcat ('<tr>') -- begin dest "d02" -- name of the lang in the lang
        strtpm = constrtdbg .. lfbrewtitsel (2,false) .. constrtden
        optconcat (strtpm) -- "lfbrewtitsel" does not add "<td"...">" "</td>"
        strbkn = constrbkco -- color code without "#" cross
        if (strtblc1=="-") then -- nice to have, do not abort
          strbkn = 'FFD8D8' -- redish if no "lang in the lang"
        end--if
        strt3d = constrtddf .. strbkn .. constrtdfd -- long "td" elem with clr
        optconcat (strt3d .. strtblc1 .. constrtden) -- no "strdeste" here c1
        optconcat ('</tr>') -- done "d02"

        strtblc2 = piksubstrind.ek { args = { strsrcrw, "2" } } -- bg src "c2"
        strtblc2 = lfpreproeqmi (strtblc2) -- "="->"-" but no rl -- done "c2"

        optconcat ('<tr>') -- begin dest "d03"
        strtpm = constrtdbg .. lfbrewtitsel (3,false) .. constrtden
        optconcat (strtpm) -- "lfbrewtitsel" does not add "<td"...">" "</td>"
        strbkn = constrbkco -- default color code without "#" cross
        boolocerr = false
        if (strtblc2=="-") then -- nice to have, do not abort
          strbkn = 'FFD8D8' -- redish if no "constructed and antique status"
          strdeste = "-"
        else
          numtamp = string.len(strtblc2) -- length
          if (numtamp~=1) then
            boolocerr = true -- this will become "booerr = true"
          else
            numoct = string.byte (strtblc2,1,1) -- must be "0" ... "3"
            if ((numoct<48) or (numoct>51)) then
              boolocerr = true -- this will become "booerr = true"
            else
              if (numoct==49) then
                strbkn = 'D0FFD8' -- greenish
              end--if
              if (numoct==50) then
                strbkn = 'A0FFC0' -- more greenish (but not green)
              end--if
              if (numoct==51) then
                strbkn = 'D0D0D0' -- grey
              end--if
              strdeste = contabd03[numoct-47] -- "contabd03" is ONE-based
              strdeste = strdeste .. ' (' .. string.char(numoct) .. ')'
            end--if
          end--if (numtamp~=1) else
        end--if (strtblc2=="-") else
        if (boolocerr) then
          booerr = true -- "c2" is faulty
          break -- to join mark -- no table and huge error
        end--if
        strt3d = constrtddf .. strbkn .. constrtdfd -- long "td" elem with clr
        optconcat (strt3d .. strdeste .. constrtden) -- here "strdeste" used
        optconcat ('</tr>') -- done "d03"

        strtblc3 = piksubstrind.ek { args = { strsrcrw, "3" } } -- bg src "c3"
        strtblc3 = lfpreproeqmi (strtblc3) -- "="->"-" but no rl-enclos possib
        if (strtblc3=="--") then
          bootimp = false -- 2 valid alternative values "-" and "--" exist
        else
          bootimp = (not lfvalidatestr(strtblc3,"-",2,2,2,3))
        end--if
        if (bootimp) then
          booerr = true -- "c3" is faulty
          break -- to join mark -- no table and huge error
        end--if -- done "c3"

        optconcat ('<tr>') -- begin dest "d04"
        strtpm = constrtdbg .. lfbrewtitsel (4,false) .. constrtden
        optconcat (strtpm) -- "lfbrewtitsel" does not add "<td"...">" "</td>"
        strbkn = constrbkco -- color code without "#" cross
        if (strtblc3=="-") then -- nice to have ("-" is redish, "--" is NOT)
          strbkn = 'FFD8D8' -- redish if no ISO 639-1:2002 code
        end--if
        strt3d = constrtddf .. strbkn .. constrtdfd -- long "td" eleme
        optconcat (strt3d .. strtblc3 .. constrtden) -- no "strdeste" here c3
        optconcat ('</tr>') -- done "d04"

        strtblc4 = piksubstrind.ek { args = { strsrcrw, "4" } } -- bg src "c4"
        strtblc4 = lfpreproeqmi (strtblc4) -- "="->"-" but no rl-enclos possib
        if (strtblc4=="---") then
          bootimp = false -- 2 valid alternative values "-" and "---" exist
        else
          bootimp = (not lfvalidatestr(strtblc4,"-",3,3,2,3))
        end--if
        if (bootimp) then
          booerr = true -- "c4" is faulty
          break -- to join mark -- no table and huge error
        end--if -- done "c4"

        optconcat ('<tr>') -- begin dest "d05"
        strtpm = constrtdbg .. lfbrewtitsel (5,false) .. constrtden
        optconcat (strtpm) -- "lfbrewtitsel" does not add "<td"...">" "</td>"
        strbkn = constrbkco -- color code without "#" cross
        if (strtblc4=="-") then -- nice to have ("-" is redish, "---" is NOT)
          strbkn = 'FFD8D8' -- redish if no ISO 639-3:2007 code
        end--if
        strt3d = constrtddf .. strbkn .. constrtdfd -- long "td" eleme
        optconcat (strt3d .. strtblc4 .. constrtden) -- no "strdeste" here c4
        optconcat ('</tr>') -- done "d05"

        if (bookapsow) then -- column "d06" can be hidden !!!
          optconcat ('<tr>') -- begin dest "d06"
          strtpm = constrtdbg .. lfbrewtitsel (6,false) .. constrtden
          optconcat (strtpm) -- "lfbrewtitsel" does not add "<td"...">" "</td>"
          strbkn = constrbkco -- color code without "#" cross
          strtmp = lfpresufkap(constrd06km,strtblc0) -- augment and maybe uc
          strdeste = "[[:" .. constrkatp .. strtmp .. "|" .. constrkatp .. '<br>' .. strtmp .. "]]"
          bootimp,strtpm = lfquer2kat (arxframent,strtmp)
          strdeste = strdeste .. strtpm -- add 1 or 2 further lines
          if (bootimp) then
            strbkn = 'FFD8D8' -- redish if "kap" kat does not exist
          end--if
          strt3d = constrtddf .. strbkn .. constrtdfd -- long "td" eleme
          optconcat (strt3d .. strdeste .. constrtden) -- here "strdeste" used
          optconcat ('</tr>') -- done "d06"
        end--if (bookapsow) then

        if (boovorsow) then -- column "d07" can be hidden !!!
          optconcat ('<tr>') -- begin dest "d07"
          strtpm = constrtdbg .. lfbrewtitsel (7,false) .. constrtden
          optconcat (strtpm) -- "lfbrewtitsel" does not add "<td"...">" "</td>"
          strbkn = constrbkco -- color code without "#" cross
          strtmp = lfpresufkap(constrd07vm,strtblc0) -- augment and maybe uc
          strdeste = "[[:" .. constrkatp .. strtmp .. "|" .. constrkatp .. '<br>' .. strtmp .. "]]"
          bootimp,strtpm = lfquer2kat (arxframent,strtmp)
          strdeste = strdeste .. strtpm -- add 1 or 2 further lines
          if (bootimp) then
            strbkn = 'FFD8D8' -- redish if "vor" kat does not exist
          end--if
          strt3d = constrtddf .. strbkn .. constrtdfd -- long "td" eleme
          optconcat (strt3d .. strdeste .. constrtden) -- here "strdeste" used
          optconcat ('</tr>') -- done "d07"
        end--if (boovorsow) then

        if (booidxsow) then -- column "d08" can be hidden !!!
          optconcat ('<tr>') -- begin dest "d08"
          strtpm = constrtdbg .. lfbrewtitsel (8,false) .. constrtden
          optconcat (strtpm) -- "lfbrewtitsel" does not add "<td"...">" "</td>"
          strbkn = constrbkco -- color code without "#" cross
          strtmp = lfpresufkap(constrd01d08,strtblc0) -- augment and maybe uc
          strtmp = constrindp .. strtmp -- add the "Index:" prefix
          strdeste = '[[' .. strtmp .. ']]' -- brew the wikilink
          vartmp = arxframent:callParserFunction(('#ifexist:'..strtmp),'1','0')
          if (vartmp~='1') then
            strbkn = 'FFD8D8' -- redish if index page does not exist
            strdeste = strdeste .. '<br>(' .. constrbual .. ')'
          end--if
          strt3d = constrtddf .. strbkn .. constrtdfd -- long "td" eleme
          optconcat (strt3d .. strdeste .. constrtden) -- here "strdeste" used
          optconcat ('</tr>') -- done "d08"
        end--if (booidxsow) then

        strtblc5 = piksubstrind.ek { args = { strsrcrw, "5" } } -- bg src "c5"
        if (strtblc5=="=") then
          strtblc5 = "-" -- preprocess "=" to "-" but no rl-enclosement possib
        end--if
        numtamp = string.len(strtblc5) -- length
        if (strtblc5~="-") then -- nice to have
          numoct = string.byte(strtblc5,1,1) -- wiki access code
          if ((numtamp<2) or (numtamp>10) or (lftestlc(numoct)==false)) then
            booerr = true -- "c5" is faulty
            break -- to join mark -- no table and huge error
          end--if
        end--if -- done "c5" -- wiki access code

        strtblc6 = piksubstrind.ek { args = { strsrcrw, "6" } } -- bg src "c6"
        strtblc6 = lfpreproeqmi (strtblc6) -- "="->"-" but no rl-enclos possib
        numtamp = string.len(strtblc6) -- length
        if (strtblc6~="-") then -- nice to have
          if (numtamp==2) then
            numc6pedi = string.byte(strtblc6,1,1) -- availability code
            numc6tion = string.byte(strtblc6,2,2) -- availability code
            numc6pedi = lfdec1diglm (numc6pedi,2) -- 0...2 or 255 if invalid
            numc6tion = lfdec1diglm (numc6tion,2) -- 0...2 or 255 if invalid
            if ((numc6pedi==255) or (numc6tion==255)) then
              booerr = true -- "c6" is faulty
              break -- to join mark -- no table and huge error
            end--if
          else
            booerr = true -- "c6" is faulty
            break -- to join mark -- no table and huge error
          end--if
        end--if -- done "c6" -- wiki availability code

        optconcat ('<tr>') -- begin dest "d09"
        strtpm = constrtdbg .. lfbrewtitsel (9,false) .. constrtden
        optconcat (strtpm) -- "lfbrewtitsel" does not add "<td"...">" "</td>"
        strbkn = constrbkco -- color code without "#" cross
        strdeste = '-'
        if (strtblc5~="-") then
          strbkn = lfavailco(numc6pedi)
          strdeste = lfbrewurl (strtblc5,false,nil) -- other ipedia main page
          strdeste = strdeste .. lfavailnt(numc6pedi) -- <br>+notice or empty
        end--if
        strt3d = constrtddf .. strbkn .. constrtdfd -- long "td" eleme
        optconcat (strt3d .. strdeste .. constrtden) -- here "strdeste" used
        optconcat ('</tr>') -- done "d09"

        optconcat ('<tr>') -- begin dest "d10"
        strtpm = constrtdbg .. lfbrewtitsel (10,false) .. constrtden
        optconcat (strtpm) -- "lfbrewtitsel" does not add "<td"...">" "</td>"
        strbkn = constrbkco -- color code without "#" cross
        strdeste = '-'
        if (strtblc5~="-") then
          if (strtblc5==constrpriv) then
            strdeste = ':-)' -- only for "d10" cell "other tionary"
          else
            strbkn = lfavailco(numc6tion)
            strdeste = lfbrewurl (strtblc5,true,nil) -- other tionary main page
            strdeste = strdeste .. lfavailnt(numc6tion) -- <br>+notice or empt
          end--if
        end--if
        strt3d = constrtddf .. strbkn .. constrtdfd -- long "td" eleme
        optconcat (strt3d .. strdeste .. constrtden) -- here "strdeste" used
        optconcat ('</tr>') -- done "d10"

        strtblc7 = piksubstrind.ek { args = { strsrcrw, "7" } } -- bg src "c7"
        strtblc7 = lfpreproeqmi (strtblc7) -- "="->"-" but no rl-enclos possib
        if (not lfvalidatestr(strtblc7,"-",2,32,0,0)) then
          booerr = true -- "c7" (name of ipedia article) is faulty
          break -- to join mark -- no table and huge error
        end--if -- done "c7"

        optconcat ('<tr>') -- begin dest "d11"
        strtpm = constrtdbg .. lfbrewtitsel (11,false) .. constrtden
        optconcat (strtpm) -- "lfbrewtitsel" does not add "<td"...">" "</td>"
        strbkn = constrbkco -- color code without "#" cross
        strtmp = strtblc7 -- name of wp article, BEWARE: may contain space
        bootimp = false
        if (strtmp=="-") then
          bootimp = true -- this is semi-evil, we have to guess
          strtmp = lfpresufkap(constrd11wm,strtblc0) -- augment and maybe uc
        end--if
        strdeste = lfbrewurl (constrpriv,false,strtmp) -- own ipedia article
        if (bootimp) then
          strbkn = 'FFD8D8' -- redish if we had to guess
          strdeste = strdeste .. ' (??)'
        end--if
        strt3d = constrtddf .. strbkn .. constrtdfd -- long "td" eleme
        optconcat (strt3d .. strdeste .. constrtden) -- here "strdeste" used
        optconcat ('</tr>') -- done "d11"

        strtblc8 = piksubstrind.ek { args = { strsrcrw, "8" } } -- bg src "c8"
        if (strtblc8=="=") then
          strtblc8 = "-" -- preprocess "=" to "-" and rl-enclosement possible
        end--if
        strtblc8 = lfrlstrip(strtblc8) -- category link
        numtamp = string.len(strtblc8) -- length -- done "c8"

        strtblc9 = piksubstrind.ek { args = { strsrcrw, "9" } } -- bg src "c9"
        if (strtblc9=="=") then
          strtblc9 = "-" -- preprocess "=" to "-" but no rl-enclosement possib
        end--if
        numtump = string.len(strtblc9) -- length -- done "c9"

        optconcat ('<tr>') -- begin dest "d12"
        strtpm = constrtdbg .. lfbrewtitsel (12,false) .. constrtden
        optconcat (strtpm) -- "lfbrewtitsel" does not add "<td"...">" "</td>"
        strbkn = constrbkco -- color code without "#" cross
        boolocerr = false
        boolokeer = false
        if (strtblc8~="-") then -- do NOT evaluate evilness of "-" in "c8"
          if ((numtamp<8) or (numtamp>connummaxc8catlen)) then -- "c8" bad
            boolocerr = true -- length out of range
          else
            if (lfcountchr(strtblc8,58)~=1) then -- "c8" bad
              boolocerr = true -- bad amount of colons, ONE is required
            end--if
          end--if
        end--if
        if (strtblc9~="-") then -- do NOT evaluate evilness of "-" in "c9"
          if (numtump>8) then -- "c9" bad
            boolokeer = true -- length out of range (no minimum)
          else
            if (lfcountndg(strtblc9)~=0) then -- "c9" bad
              boolokeer = true -- faulty char:s, a number is expected
            end--if
          end--if
        end--if
        if (boolocerr or boolokeer) then
          booerr = true -- "c8" or "c9" is faulty
          break -- to join mark -- no table and huge error
        else
          if (strtblc8=='-') then
            strbkn = 'FFD8D8' -- redish if no category
            strdeste = '-'
          else
            strdeste = lfbrewurl (strtblc5,true,strtblc8) -- other tionary cat
            strdeste = strdeste .. '<br>'
            if (strtblc9=="-") then
              strdeste = strdeste .. lfamountinkat(nil) -- NOT count as error
            else
              numtump = tonumber(lfremovenondi(strtblc9)) -- apo:s tolerable
              strdeste = strdeste .. lfamountinkat(numtump) -- apo:s added
            end--if (strtblc9=='-') else
          end--if (strtblc8=='-') else
        end--if (boolocerr or boolokeer) else
        strt3d = constrtddf .. strbkn .. constrtdfd -- long "td" eleme
        optconcat (strt3d .. strdeste .. constrtden) -- here "strdeste" used
        optconcat ('</tr>') -- done "d12"

        break -- finally to join mark

    end--while -- fake loop -- join mark

  end--if ((booerr==false) and (boonotfnd==false)) then

  --- BREW THE BOTTOM CELL "COLSPAN=2" ----

  -- using constants "constrtdcs" and "constrtden" for
  -- "<td"...">" (with <<colspan="2">>) and "</td>"

  -- update/purge link (depends from pagename)
  -- link to source table (fixed) (template namespace)
  -- link to complete table (fixed) (appendix namespace)

  if (booerr==false) then
    optconcat ('<tr>' .. constrtdcs .. strpurge .. '<br>' .. constrjsumbr .. '<br>' .. constrjkompl .. constrtden .. '</tr>')
  end--if

  ---- CLOSE THE OUTPUT TABLE IF IT EXISTS AND WHINE IF NEEDED ----

  if (booerr==false) then
    optconcat ('</table>')
  else
    isubtabbunch = {} -- crucial
    strret = constrfate -- fatal error -- replace content of the string
  end--if

  ---- BREW THE FINAL HUGE STRING ----

  optconcat (nil) -- crucial, finalizes "strret"

  ---- RETURN THE JUNK STRING ----

  return strret

end--function

  ---- RETURN THE JUNK LUA TABLE ----

return sngtbllin