Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Saltu al enhavo

Modulo:Prisupre

El Vikipedio, la libera enciklopedio
Dokumentado Dokumentado

Uzata far Ŝablono:Prisupre, memtesto tie.


Se vi havas demandon pri ĉi tiu Lua-modulo, tiam vi povas demandi en la diskutejo pri Lua-moduloj. La Intervikiaj ligiloj estu metataj al Vikidatumoj. (Vidu Helpopaĝon pri tio.)
--[===[

MODULE "PRISUPRE" (pri supre)

"eo.wikipedia.org/wiki/Modulo:prisupre" <!--2024-Jul-23-->

Purpose: displays short disambiguation hint at the
         top of an article page at wikipedia

Utilo: montras mallongan apartigan konsilon cxe la
       supra parto de artikola pagxo cxe vikipedio

Manfaat: memperlihatkan petunjuk disambiguasi yang pendek di
         bagian atas halaman artikel wikipedia

Syfte: visar ett kort tips ang olika betydelser uppe
       paa en artikelsida hos wikipedia

Used by templates / Uzata far sxablonoj /
Digunakan oleh templat / Anvaent av mallar:
* prisupre

Required submodules / Bezonataj submoduloj / Submodul yang diperlukan:
* none

Required images:
* "Disambig-dark.svg" by Stephan Baum released under CC-BY-SA-3.0
  and CC-BY-SA-2.5, possibly ineligible for (C) due to trivial shape

Incoming: * 0,2,4,6 anonymous and optional parameters
            * 0,1,2,3 pairs of description + target page
          * 4 named and optional parameters
            * red= ali=
            * abo= pri=
            * dis= apa=
              * special value "#" means autoconstruct from pagename
              * special value "%" means autoconstruct
                from parameter "red=" "ali="
            * dit= apb=
              * no special values, legal only if dis= apa= is used too
          * 2 hidden named and optional parameters
            * "pagenameoverridetestonly=" can directly cause #E01
              and indirectly cause #E17
            * "nsnumberoverridetestonly=" can indirectly cause #E16

Returned: * HTML table with a small image on the left, and text
            in one potentially long line (that can get broken by
            the HTML parser) on the right

Languages:
--------------  --------  --------  -----------  ------
item            EN        EO        ID           SV
--------------  --------  --------  -----------  ------
name            abouttop  prisupre  tentangatas  omtopp
redirect        red=      ali=      ali=         odr=
about           abo=      pri=
disambiguation  dis=      apa=
disambig other  dit=      apb=
--------------  --------  --------  -----------  ------

Errors:
#E02 : missing parameters (at least one of (red=, abo=,
       dis=, anon) must be used)
#E03 : wrong length (must be 1...200 octet:s)
#E05 : number of anon params must be even and not too high
       (only 0,2,4,6 acceptable) and a parameter must NOT be empty
#E06 : special value "#" "%" only permitted in parameter "dis="
#E07 : special value "%" used in "dis=" but "red=" missing
#E15 : bad string content ( double space , double '' [[ ]] {{ }} )
#E16 : called from wrong ns (must be article ie ns ZERO)
#E17 : must NOT be used on disambig pages having " (disambiguation)"
#E18 : "dit= apb=" used but "dis= apa=" missing
#E20 : dis= vs dit= ie apa= vs apb= must be different
#E22 : target title invalid per MediaWiki (such as "Fault [geology]"),
       or unsafe (such as "File:Fault.png", "Category:Geology",
       "en:Fault (geology)"), or nonstandard (such as "Help:Index"
       on non-English wikipedia, or "Helpo  :  Indekso")

]===]

local exporttable = {}

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

---- CONSTANTS [O] ----

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

-- uncommentable constant strings (core site-related features)

    -- local constrdisa = '(disambiguation)'          -- EN (no space here)
      local constrdisa = '(apartigilo)'            -- EO (no space here)
        -- local constrdisa = '(disambiguasi)'        -- ID (no space here)
    -- local constrhelp = 'Help:Disambiguation'       -- EN
      local constrhelp = 'Helpo:Apartigiloj'       -- EO
        -- local constrhelp = 'Bantuan:Disambiguasi'  -- ID

-- uncommentable constant table (error messages)

-- #E02...#E99, holes permitted
-- note that #E00 and #E01 are NOT supposed to be included here
-- separate "strpikparent" needed for "\\@"

local contaberaroj = {}
  contaberaroj[ 2] = 'Erara uzo de \\@, mankas parametroj'                                        -- EO #E02
  contaberaroj[ 3] = 'Erara uzo de \\@, longo de signocxeno'                                      -- EO #E03
  contaberaroj[ 5] = 'Erara uzo de \\@, kvanto da anonimaj parametroj estu 0,2,4,6'               -- EO #E05 !!!FIXME!!! must be #E08
  contaberaroj[ 6] = 'Erara uzo de \\@, speciala valoro "#" "%" permesita nur en "apa="'          -- EO #E06
  contaberaroj[ 7] = 'Erara uzo de \\@, speciala valoro "%" uzata en "apa=" sed "ali=" forestas'  -- EO #E07
  contaberaroj[15] = 'Erara uzo de \\@, problemhava signaro, precipe [&#8296;[ ]&#8296;]'         -- EO #E15
  contaberaroj[16] = 'Eraro cxar \\@ uzeblas nur en artikola nomspaco'                            -- EO #E16 !!!FIXME!!! must be #E10
  contaberaroj[17] = 'Eraro cxar \\@ estas malpermesita sur apartigaj pagxoj'                     -- EO #E17
  contaberaroj[18] = 'Erara uzo de \\@, parametro "apb=" uzata sed "apa=" forestas'               -- EO #E18
  contaberaroj[20] = 'Erara uzo de \\@, parametroj "apa=" kaj "apb=" estu malsamaj'               -- EO #E20
  contaberaroj[22] = 'Erara uzo de \\@, cela titolo malbonas'                                     -- EO #E22

-- uncommentable constant table (other messages)

local contabmessa = {}
  contabmessa[ 0] = 'alidirektas cxi tien'        -- EO
  -- contabmessa[ 0] = 'mengalihkan ke sini'         -- ID
  contabmessa[ 1] = 'Cxi tiu artikolo temas pri'  -- EO
  -- contabmessa[ 1] = 'Artikel ini bertopik'        -- ID
  contabmessa[ 2] = 'Por'                         -- EO
  -- contabmessa[ 2] = 'Untuk'                       -- ID
  contabmessa[ 3] = 'rigardu la pagxon'           -- EO
  -- contabmessa[ 3] = 'lihatlah halaman'            -- ID
  contabmessa[ 4] = 'Por'
  contabmessa[ 5] = 'legu la artikolon'
  contabmessa[ 6] = 'Por'
  contabmessa[ 7] = 'disponeblas la pagxo'
  contabmessa[ 8] = 'Koncerne aliajn signifojn aliru la aparti'
  contabmessa[ 9] = 'gilon'   -- singular if only dis= apa= used
  contabmessa[10] = 'gilojn'  -- plural if dit= apb= used too
  contabmessa[11] = 'kaj'                         -- EO coordinator "and" AKA "&"
  -- contabmessa[11] = 'dan'                         -- ID coordinator "and" AKA "&"

  -- surrogate transcoding table (only needed for EO)

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

-- constant strings (error circumfixes)

local constrelabg = '<span class="error"><b>'  -- lagom whining begin
local constrelaen = '</b></span>'              -- lagom whining end
local constrlaxhu = '&nbsp;&#42;&#42;&nbsp;'   -- lagom -> huge circumfix " ** "

-- constant table (3 integers for preliminary parameter check)

  local contabparam = {}
  contabparam[0] = 0   -- minimal number of anon parameters
  contabparam[1] = 6   -- maximal number of anon parameters
  contabparam[2] = 200 -- maximal length of single para (min is hardcoded ONE)

-- uncommentable (override)

-- * name of table MUST always be defined, OTOH elements are usually NOT
-- * for testing only, values automatically peeked otherwise

local contabovrd = {}
  -- contabovrd['sitelang'] = 'eo'                                         -- "en"
  -- contabovrd['sitelang'] = 'id'
  -- contabovrd['katprefi'] = 'Kategorio'                                  -- "Category"
  -- contabovrd['katprefi'] = 'Kategori'
  -- contabovrd['parentfn'] = string.char(0xC5,0x9C) .. 'ablono:prisupre'  -- "Template:prisupre" (!!! no surr translation !!!)

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

---- SPECIAL STUFF OUTSIDE MAIN [B] ----

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

  -- SPECIAL VAR:S

require('strict')

local qbooguard = false  -- only for the guard test, pass to other var ASAP

  -- GUARD AGAINST INTERNAL ERROR

qbooguard = ((type(constrdisa)~='string') or (type(constrhelp)~='string'))

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

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

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

---- NUMBER CONVERSION FUNCTIONS [N] ----

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

-- Local function LFNUMTO2DIGIT

-- Convert integer 0...99 to decimal ASCII string always 2 digits "00"..."99".

-- Depends on functions :
-- [E] mathisintrange mathdiv mathmod

local function lfnumto2digit (numzerotoninetynine)
  local strtwodig = '??' -- always 2 digits
  if (mathisintrange(numzerotoninetynine,0,99)) then
    strtwodig = tostring(mathdiv(numzerotoninetynine,10)) .. tostring(mathmod(numzerotoninetynine,10))
  end--if
  return strtwodig
end--function lfnumto2digit

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

---- LOW LEVEL STRING FUNCTIONS [G] ----

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

-- Local function LFGSTRINGRANGE

local function lfgstringrange (varvictim, nummini, nummaxi)
  local nummylengthofstr = 0
  local booveryvalid = false -- preASSume guilt
  if (type(varvictim)=='string') then
    nummylengthofstr = string.len(varvictim)
    booveryvalid = ((nummylengthofstr>=nummini) and (nummylengthofstr<=nummaxi))
  end--if
  return booveryvalid
end--function lfgstringrange

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

-- Local function LFGCMPEND  !!!FIXME!!! prohibit equality

-- Check whether a given substring can be found at end of a longer string.

-- Input  : * strbig, strtiny

local function lfgcmpend (strbig, strtiny)
  local numlenbig = 0
  local numlentiny = 0
  local boof6ound = false
  numlenbig = string.len (strbig)
  numlentiny = string.len (strtiny)
  if ((numlentiny>0) and (numlentiny<=numlenbig)) then
    boof6ound = ( strtiny == (string.sub (strbig,(numlenbig-numlentiny+1),numlenbig)) )
  end--if
  return boof6ound
end--function lfgcmpend

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

---- HIGH LEVEL STRING FUNCTIONS [I] ----

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

-- Local function LFICHECKFORBAD  !!!FIXME!!! prohibit stript

-- Output : * booisbaad -- true if string is bad

local function lficheckforbad (streniro)
  local booisbaad = false
  booisbaad =              (string.find(streniro,"''",1,true)~=nil) -- dbl apo
  booisbaad = booisbaad or (string.find(streniro,"[[",1,true)~=nil)
  booisbaad = booisbaad or (string.find(streniro,"]]",1,true)~=nil)
  booisbaad = booisbaad or (string.find(streniro,"{{",1,true)~=nil)
  booisbaad = booisbaad or (string.find(streniro,"}}",1,true)~=nil)
  return booisbaad
end--function lficheckforbad

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

-- Local function LFIFILLNAME

-- Replace placeholder "\@" "\\@" by augmented name of the caller.

-- To be called ONLY from "lfhfillsurrstrtab".

-- The name of the caller is submitted to us as a parameter thus we
-- do NOT access any constants and do NOT have to peek it either.

local function lfifillname (strmessage, strcaller)

  local strhasill = ''
  local numstrloen = 0
  local numindfx = 1 -- ONE-based
  local numcjar = 0
  local numcjnext = 0

  numstrloen = string.len (strmessage)

  while true do
    if (numindfx>numstrloen) then
      break -- empty input is useless but cannot cause major harm
    end--if
    numcjar = string.byte (strmessage,numindfx,numindfx)
    numindfx = numindfx + 1
    numcjnext = 0 -- preASSume no char
    if (numindfx<=numstrloen) then
      numcjnext = string.byte (strmessage,numindfx,numindfx)
    end--if
    if ((numcjar==92) and (numcjnext==64)) then
      strhasill = strhasill .. strcaller -- invalid input is caller's risk
      numindfx = numindfx + 1 -- skip 2 octet:s of the placeholder
    else
      strhasill = strhasill .. string.char (numcjar)
    end--if
  end--while

  return strhasill

end--function lfifillname

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

-- Local function LFIKODEOSG

-- Transcode eo X-surrogates to cxapeloj in a single string (eo only).

-- Input  : * streosurr -- ANSI string (empty is useless but cannot
--                                      cause major harm)

-- Output : * strutf8eo -- UTF8 string

-- Depends on functions :
-- [E] mathdiv mathmod

-- Depends on constants :
-- * table "contabtransluteo" inherently holy

-- To be called ONLY from "lfhfillsurrstrtab".

-- * the "x" in a surr pair is case insensitive,
--   for example both "kacxo" and "kacXo" give same result
-- * avoid "\", thus for example "ka\cxo" would get converted but the "\" kept
-- * double "x" (both case insensitive) prevents conversion and becomes
--   reduced to single "x", for example "kacxxo" becomes "kacxo"

local function lfikodeosg (streosurr)

  local vareopeek = 0
  local strutf8eo = ''
  local numeoinplen = 0
  local numinpinx = 0 -- ZERO-based source index
  local numknar0k = 0 -- current char
  local numknaf1x = 0 -- next char (ZERO is NOT valid)
  local numknaf2x = 0 -- post next char (ZERO is NOT valid)
  local boonext1x = false
  local boonext2x = false
  local boosudahdone = false

  numeoinplen = string.len(streosurr)

  while true do

    if (numinpinx>=numeoinplen) then
      break
    end--if

    numknar0k = string.byte(streosurr,(numinpinx+1),(numinpinx+1))
    numknaf1x = 0 -- preASSume no char
    numknaf2x = 0 -- preASSume no char
    if ((numinpinx+1)<numeoinplen) then
      numknaf1x = string.byte(streosurr,(numinpinx+2),(numinpinx+2))
    end--if
    if ((numinpinx+2)<numeoinplen) then
      numknaf2x = string.byte(streosurr,(numinpinx+3),(numinpinx+3))
    end--if

    boonext1x = ((numknaf1x==88) or (numknaf1x==120)) -- case insensitive
    boonext2x = ((numknaf2x==88) or (numknaf2x==120)) -- case insensitive
    boosudahdone = false
    if (boonext1x and boonext2x) then -- got "xx"
      strutf8eo = strutf8eo .. string.char(numknar0k,numknaf1x) -- keep one "x" only
      numinpinx = numinpinx + 3 -- eaten 3 written 2
      boosudahdone = true
    end--if
    if (boonext1x and (not boonext2x)) then -- got yes-"x" and no-"x"
      vareopeek = contabtransluteo[numknar0k] -- UINT16 or type "nil"
      if (type(vareopeek)=='number') then
        strutf8eo = strutf8eo .. string.char(mathdiv(vareopeek,256),mathmod(vareopeek,256)) -- add UTF8 char
        numinpinx = numinpinx + 2 -- eaten 2 written 2
        boosudahdone = true
      end--if
    end--if
    if (not boosudahdone) then
      strutf8eo = strutf8eo .. string.char(numknar0k) -- copy char
      numinpinx = numinpinx + 1 -- eaten 1 written 1
    end--if

  end--while

  return strutf8eo

end--function lfikodeosg

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

---- HIGH LEVEL FUNCTIONS [H] ----

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

-- Local function LFHCONSTRUCTERAR

-- Input  : * numerar6code -- 1 ... 99 or 2 ... 99 (resistent against invalid
--                            data type, giving "??" on such)
--          * boopeek6it -- do peek description #E02...#E99 from table

-- Depends on functions :
-- [N] lfnumto2digit
-- [E] mathisintrange mathdiv mathmod

-- Depends on constants :
-- * maybe table contaberaroj TWO-based (holes permitted)

-- To be called ONLY from lfhbrewerror, lfhbrewerrsm,
-- lfhbrewerrsvr, lfhbrewerrinsi.

local function lfhconstructerar (numerar6code, boopeek6it)
  local vardes6krip = 0
  local numbottom6limit = 1
  local stryt6sux = '#E'
  if (boopeek6it) then
    numbottom6limit = 2 -- #E01 is a valid code for submodule only
  end--if
  if (mathisintrange(numerar6code,numbottom6limit,99)) then
    stryt6sux = stryt6sux .. lfnumto2digit(numerar6code)
    if (boopeek6it) then
      vardes6krip = contaberaroj[numerar6code] -- risk of type "nil"
      if (type(vardes6krip)=='string') then
        stryt6sux = stryt6sux .. ' ' .. vardes6krip
      else
        stryt6sux = stryt6sux .. ' ??' -- no text found
      end--if
    end--if (boopeek6it) then
  else
    stryt6sux = stryt6sux .. '??' -- no valid error code
  end--if
  return stryt6sux

end--function lfhconstructerar

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

-- Local function LFHBREWERROR

-- Input  : * numerar7code -- TWO-based error code 2 ... 99 (resistent
--                            against invalid data type, giving "??" on such)

-- Depends on functions :
-- [H] lfhconstructerar
-- [N] lfnumto2digit
-- [E] mathisintrange mathdiv mathmod

-- Depends on constants :
-- * 3 strings constrelabg constrelaen constrlaxhu
-- * table contaberaroj TWO-based (holes permitted)

-- #E02...#E99, note that #E00 and #E01 are NOT supposed to be included here.

local function lfhbrewerror (numerar7code)
  local stryt7sux = ''
  stryt7sux = constrlaxhu .. constrelabg .. lfhconstructerar (numerar7code,true) .. constrelaen .. constrlaxhu
  return stryt7sux
end--function lfhbrewerror

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

-- Local function LFHFILLSURRSTRTAB

-- Process (fill in, transcode surr) either a single string, or all string
-- items in a table (even nested) using any type of keys/indexes (such as
-- a holy number sequence and non-numeric ones). Items with a non-string
-- value are kept as-is. For filling in own name, and converting eo and
-- NOPE sv surrogates (via 3 separate sub:s).

-- Input  : * varinkommen -- type "string" or "table"
--          * varfyllo -- string, or type "nil" if no filling-in desired
--          * strlingkod -- "eo" or NOPE "sv" to convert surrogates, anything
--                          else (preferably type "nil") to skip this

-- Depends on functions :
-- [I] lfifillname (only if filling-in desired)
-- [I] lfikodeosg (only if converting of eo X-surrogates desired)
-- NOPE [I] lfikodsvsg (only if converting of sv blackslash-surrogates desired)
-- [E] mathdiv mathmod (via "lfikodeosg" and NOPE "lfikodsvsg")

-- Depends on constants :
-- * table "contabtransluteo" inherently holy (via "lfikodeosg")
-- NOPE * table "contabtranslutsv" inherently holy (via "lfikodsvsg")

local function lfhfillsurrstrtab (varinkommen, varfyllo, strlingkod)

  local varkey = 0 -- variable without type
  local varele = 0 -- variable without type
  local varutmatning = 0
  local boodone = false

  if (type(varinkommen)=='string') then
    if (type(varfyllo)=='string') then
      varinkommen = lfifillname (varinkommen,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
    varkey = next (varinkommen) -- try to pick 0:th (in no order) key/index
    while true do
      if (varkey==nil) then
        break -- empty table or end reached
      end--if
      varele = varinkommen[varkey] -- pick element of unknown type
      if ((type(varele)=='string') or (type(varele)=='table')) then
        varele = lfhfillsurrstrtab (varele, varfyllo, strlingkod) -- RECURSION
      end--if
      varutmatning[varkey] = varele -- write at same place in dest table
      varkey = next (varinkommen, varkey) -- try to pick next key/index
    end--while
    boodone = true
  end--if

  if (not boodone) then
    varutmatning = varinkommen -- copy as-is whatever it is
  end--if

  return varutmatning

end--function lfhfillsurrstrtab

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

---- MEDIAWIKI INTERACTION FUNCTIONS [W] ----

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

-- Local function LFWISTITLESAFE

-- Check whether title is safe (valid, not cat, not file,
-- no interwiki, standard form) returning a boolean.

-- Input  : * strsftitle

-- Output : * bootitlecxsafe -- true if safe (false also
--                              for non-string and invalid title)

-- Function "mw.title.new":
-- * returns type "nil" on invalid title string, and crashes if
--   input type is not string
-- * is NOT expensive (for our use) and works for non-existent titles too
-- * some useful fields:
--   * ".interwiki" is always a string, empty if no interwiki included
--   * ".namespace" is always a number, values <0 and 6 and 14
--     are unsafe ("Media:" gives -2)
--   * ".nsText" only bare ns prefix such as "Mall"
--   * ".prefixedText" {{FULLPAGENAME}} + maybe interwiki; veryfullpagename
--     including ns prefix and interwiki, a strictly standardized
--     form of title:
--     * adjusts letter case
--     * replaces underscores by spaces
--     * "Category:" becomes "Kategori:" in some languages
--     * removes extraneous spaces around colon ":"
--   * ".fullText" {{FULLPAGENAME}} + maybe interwiki + HTML section "#"

local function lfwistitlesafe (strsftitle)
  local tabtitleobject = {}
  local numnsoftheobject = 0
  local bootitlecxsafe = false -- preASSume guilt
  if (type(strsftitle)=='string') then
    tabtitleobject = mw.title.new(strsftitle) -- type "nil" for invalid
    if (type(tabtitleobject)=='table') then
      numnsoftheobject = tabtitleobject.namespace
      bootitlecxsafe = ((tabtitleobject.interwiki=='') and (numnsoftheobject>=0) and (numnsoftheobject~=6) and (numnsoftheobject~=14) and (tabtitleobject.prefixedText==strsftitle))
    end--if
  end--if
  return bootitlecxsafe
end--function lfwistitlesafe

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

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

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

---- VARIABLES [R] ----

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

function exporttable.ek (arxframent)

  -- general unknown type

  local vartmp = 0 -- variable without type multipurpose

  -- special type "args" AKA "arx"

  local arxsomons = 0 -- metaized "args" from our own or caller's "frame"

  -- peeked stuff

  local strpiklangcode = '' -- "en" privileged site language
  local strpikkatns    = '' -- "Category"
  local strpikparent   = '' -- "Template:nope" FULLPAGENAME
  local strpikpareuf   = '' -- "nope" PAGENAME unfull

  -- general str

  local strpagenam = '' -- from "{{PAGENAME}}" or "pagenameoverridetestonly="
  local strruangna = '' -- "{{NAMESPACENUMBER}}" or "nsnumberoverridetestonly"

  local strmyred  = ''
  local strmyabo  = ''
  local strmydis  = '' -- dis= apa= -- empty for # or % until autogenerated
  local strmydit  = '' -- dit= apb=

  local strdiswithspc = ''

  local strvisgud = '' -- visible good output
  local strviserr = '' -- visible error message
  local strtrakat = '' -- invisible tracking categories  !!!FIXME!!! not yet
  local strret    = '' -- final result string

  local strtymp   = ''

  -- general num

  local numerr    = 0  -- 1 inter 2 missing ...  !!!FIXME!!! move codes
  local numpindex = 0  -- number of anon params

  local numtamp   = 0
  local numtemp   = 0

  -- stuff from "args"

  local boohavered = false -- have red= AKA apa=
  local boohaveabo = false -- have abo= AKA pri=
  local boohavedis = false -- have apa= AKA dis= -- true also for # or %
  local boohavedinsp = false -- have non-special dis= -- false for # or %
  local boohvcross = false -- dis=#
  local boohvperce = false -- dis=%
  local boohavedit = false

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

---- MAIN [Z] ----

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

  ---- GUARD AGAINST INTERNAL ERROR AGAIN ----

  if (qbooguard) then
    numerr = 1 -- #E01 internal
  end--if

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

  ---- PEEK STUFF THAT IS NOT OVERRIDDEN GENEROUS ----

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

  -- full "strpikparent" is used for error messages
  -- unfull "strpikpareuf" is used for tracking cat:s

  if (numerr==0) then
    strpiklangcode = contabovrd['sitelang'] or mw.getContentLanguage():getCode() or 'en'                -- privileged site language
    strpikkatns    = contabovrd['katprefi'] or (mw.site.namespaces[ 14] or {})['name'] or 'Category'    -- standard namespace
    strpikparent   = contabovrd['parentfn'] or arxframent:getParent():getTitle() or 'Template:abouttop' -- fullpagename
    if ((type(strpiklangcode)~='string') or (type(strpikkatns)~='string') or (type(strpikparent)~='string')) then
      numerr = 1 -- #E01 internal
    end--if
    vartmp = string.find(strpikparent,':',1,true)
    if (mathisintrange(vartmp,2,(string.len(strpikparent)-1))) then
      strpikpareuf = string.sub(strpikparent,(vartmp+1),-1) -- make unfull
    else
      strpikpareuf = strpikparent -- dubi call from ns ZERO or misplaced ":"
    end--if
  end--if (numerr==0) then

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

  ---- PROCESS MESSAGES, FILL IN ALWAYS, SURR ONLY IF NEEDED ----

  -- needed for all errors except #E01

  -- placeholder "\@" "\\@" is replaced by name of the caller from
  -- "strpikparent" in any case, for example "SXablono:nope" or "Templat:nope"

  -- only for some languages the surr-transcoding is subsequently performed

  if (numerr==0) then
    contaberaroj = lfhfillsurrstrtab (contaberaroj, strpikparent, strpiklangcode)
    contabmessa  = lfhfillsurrstrtab (contabmessa, nil, strpiklangcode) -- no filling
  end--if

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

  ---- GET THE ARX (ONE OF TWO) ----

  -- must be seized independently on "numerr" even if we already suck

  -- give a f**k in possible params other than "caller=true"

  arxsomons = arxframent.args -- "args" from our own "frame"
  if (type(arxsomons)~='table') then
    arxsomons = {} -- guard against indexing error from our own
    numerr = 1 -- #E01 internal
  end--if
  if (arxsomons['caller']=='true') then
    arxsomons = arxframent:getParent().args -- "args" from caller's "frame"
  end--if
  if (type(arxsomons)~='table') then
    arxsomons = {} -- guard against indexing error again
    numerr = 1 -- #E01 internal
  end--if

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

  ---- PROCESS 2 HIDDEN NAMED PARAMS ----

  -- * this may override "mw.title.getCurrentTitle().text" and
  --   stipulate content in "strpagenam", empty or too long is NOT legal
  -- * bad "pagenameoverridetestonly=" can directly give #E01 whereas
  --   no error is possible here from other hidden parameters

  strpagenam = ''
  if (numerr==0) then -- get pagename (error if bad, silent if absent)
    vartmp = arxsomons['pagenameoverridetestonly']
    if (type(vartmp)=='string') then
      if (lfgstringrange(vartmp,1,200)) then -- empty or too long NOT legal
        strpagenam = vartmp
      else
        numerr = 1 -- #E01 internal
      end--if
    end--if
  end--if

  strruangna = ''
  if (numerr==0) then -- get namespace (silent if bad, silent if absent)
    vartmp = arxsomons['nsnumberoverridetestonly']
    if (lfgstringrange(vartmp,1,4)) then -- empty or too long NOT legal
      strruangna = vartmp -- empty is NOT legal
    end--if
  end--if

  ---- SEIZE PAGENAME AND NS FROM MW ----

  -- pagename must be 1...200 octet:s keep consistent
  -- with "pagenameoverridetestonly="

  if ((numerr==0) and (strpagenam=='')) then -- get pagename (error if bad)
    vartmp = mw.title.getCurrentTitle().text -- without namespace prefix
    if (lfgstringrange(vartmp,1,200)) then -- empty or too long NOT legal
      strpagenam = vartmp
    else
      numerr = 1 -- #E01 internal
    end--if
  end--if

  if ((numerr==0) and (strruangna=='')) then -- get namespace (silent if bad)
    vartmp = mw.title.getCurrentTitle().namespace -- type is "number"
    if (mathisintrange(vartmp,0,9999)) then -- negative NOT legal but silent
      strruangna = tostring(vartmp)
    end--if
  end--if

  ---- CHECK NS ----

  if ((numerr==0) and (strruangna~='0')) then
    numerr = 16 -- #E16 called from wrong ns
  end--if

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

  ---- WHINE IF YOU MUST #E01 ----

  -- reporting of this error #E01 must NOT depend on
  -- uncommentable stuff such as "strpikparent" and "contaberaroj"

  -- do NOT use sub "lfhbrewerror", report our name (NOT of template), in EN

  if (numerr==1) then
    strtymp = '#E01 Internal error in module "prisupre".'
    strviserr = constrlaxhu .. constrelabg .. strtymp .. constrelaen .. constrlaxhu
  end--if

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

  ---- PRELIMINARILY ANALYZE ANONYMOUS PARAMETERS ----

  -- this will catch holes, empty parameters, too long parameters,
  -- and wrong number of parameters

  -- below on exit var "numpindex" will contain number of
  -- prevalidated anonymous params

  -- this depends on 3 constants:
  -- * contabparam[0] minimal number
  -- * contabparam[1] maximal number
  -- * contabparam[2] maximal length

  if (numerr==0) then
    numpindex = 0 -- ZERO-based
    numtamp = contabparam[1] -- maximal number of anon params
    while true do
      vartmp = arxsomons [numpindex+1] -- can be "nil"
      if ((type(vartmp)~='string') or (numpindex>numtamp)) then
        break -- good or bad
      end--if
      numtemp = string.len (vartmp)
      if ((numtemp==0) or (numtemp>contabparam[2])) then
        numerr = 3 -- #E03 wrong length
        break -- only bad here
      end--if
      numpindex = numpindex + 1 -- on exit has number of valid parameters
    end--while
    if ((numpindex<contabparam[0]) or (numpindex>numtamp)) then
      numerr = 5 -- #E05 wrong number of anon params
    end--if
  end--if

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

  ---- SEIZE 4 NAMED PARAMETERS ----

  -- EN: red= abo= dis= dit= -- EO: ali= pri= apa= apb=

  if (numerr==0) then
    vartmp = arxsomons['ali'] -- 1...200 char:s
    if (type(vartmp)=='string') then
      numtamp = string.len (vartmp)
      if ((numtamp<1) or (numtamp>200)) then
        numerr = 3 -- #E03 wrong length
      else
        boohavered = true
        strmyred = vartmp
      end--if
    end--if
  end--if

  if (numerr==0) then
    vartmp = arxsomons['pri'] -- 1...200 char:s
    if (type(vartmp)=='string') then
      numtamp = string.len (vartmp)
      if ((numtamp<1) or (numtamp>200)) then
        numerr = 3 -- #E03 wrong length
      else
        boohaveabo = true
        strmyabo = vartmp
      end--if
    end--if
  end--if

  if (numerr==0) then
    vartmp = arxsomons['apa'] -- 1...200 char:s
    if (type(vartmp)=='string') then
      numtamp = string.len (vartmp)
      if ((numtamp<1) or (numtamp>200)) then
        numerr = 3 -- #E03 wrong length
      else
        boohavedis = true -- true also for # or %
        boohvcross = (vartmp=='#')
        boohvperce = (vartmp=='%')
        if (not (boohvcross or boohvperce)) then
          boohavedinsp = true -- false for # or % -- true for literal string
          strmydis = vartmp
        end--if
      end--if
    end--if
  end--if

  if (numerr==0) then
    vartmp = arxsomons['apb'] -- 1...200 char:s
    if (type(vartmp)=='string') then
      numtamp = string.len (vartmp)
      if ((numtamp<1) or (numtamp>200)) then
        numerr = 3 -- #E03 wrong length
      else
        boohavedit = true
        strmydit = vartmp
      end--if
    end--if
  end--if

  ---- ADD SPACE ----

  strdiswithspc = ' ' .. constrdisa -- disambiguation suffix

  ---- ANALYZE ----

  -- cross "#" is prohibited as pagename per MediaWiki, but percent "%"
  -- could appear in the parameter "red=" don't give #E06 then

  -- * all parameters are checked against "lficheckforbad" #E15
  --   empty string is OK there, special value # or % is OK there
  -- * only titles are further checked against "lfwistitlesafe" #E22
  --   we MUST NOT feed in empty string or # or % there

  -- shortest possible undesirable pagename is "X (disambiguation)" #E17

  while true do -- fake loop

    if (numerr~=0) then
      break -- bad from above
    end--if

    if ((not boohavered) and (not boohaveabo) and (numpindex==0) and (not boohavedis)) then
      numerr = 2 -- #E02 missing parameters -- above accept also # or %
      break
    end--if
    if ((numpindex~=0) and (numpindex~=2) and (numpindex~=4) and (numpindex~=6)) then
      numerr = 5 -- #E05 number of anon params
      break
    end--if
    if ((strmyabo=='#') or (strmyabo=='%') or (strmyred=='#') or (strmydit=='#') or (strmydit=='%')) then
      numerr = 6 -- #E06 special only permitted in param "dis=" (not "dit=")
      break
    end--if
    if (boohvperce and (not boohavered)) then
      numerr = 7 -- #E07 using special "%" in "dis=" but "red=" missing
      break
    end--if
    if (boohavedit and (not boohavedis)) then
      numerr = 18 -- #E18 "dit= vs "dis= -- above accept also # or %
      break
    end--if
    if (boohavedis and boohavedit and (strmydis==strmydit)) then
      numerr = 20 -- #E20 must NOT be same
      break
    end--if

    if (lficheckforbad(strmyred) or lficheckforbad(strmyabo) or lficheckforbad(strmydis) or lficheckforbad(strmydit)) then
      numerr = 15 -- #E15 bad string content
      break -- checked all 4 even if empty
    end--if
    if (boohavered and (not lfwistitlesafe(strmyred))) then
      numerr = 22 -- #E22
      break -- check only 3 of 4 (omit "abo=" not being a title)
    end--if
    if (boohavedinsp and (not lfwistitlesafe(strmydis))) then
      numerr = 22 -- #E22 -- above false for # or %
      break -- check only 3 of 4
    end--if
    if (boohavedit and (not lfwistitlesafe(strmydit))) then
      numerr = 22 -- #E22
      break -- check only 3 of 4
    end--if

    numtamp = 1
    while true do -- genuine loop
      if (numtamp>numpindex) then
        break -- no more params to check -- inner loop only
      end--if
      strtymp = arxsomons[numtamp]
      if (lficheckforbad(strtymp)) then -- check all
        numerr = 15 -- #E15 bad string content
        break -- inner loop only
      end--if
      if (mathmod(numtamp,2)==0) then -- check only ONE-based indexes 2,4,6
        if (not lfwistitlesafe(strtymp)) then
          numerr = 22 -- #E22
          break -- inner loop only
        end--if
      end--if (mathmod(numtamp,2)==0) then
      numtamp = numtamp + 1
    end--while

    if (numerr~=0) then
      break -- #E15 or #E22
    end--if

    if (lfgcmpend(strpagenam,strdiswithspc)) then
      numerr = 17 -- #E17 found on disambig
      break
    end--if

    break -- finally to join mark
  end--while -- fake loop -- join mark

  ---- BREW NAME OF DISAMBIGUATION PAGE AUTOMATICALLY ----

  if (numerr==0) then
    if (boohvcross) then
      strmydis = strpagenam .. strdiswithspc -- from pagename per "#"
    end--if
    if (boohvperce) then
      strmydis = strmyred .. strdiswithspc -- from "red=" valida above per "%"
    end--if
  end--if

  ---- PERFORM THE CORE WORK -- BREW THE LINE ----

  -- at least one of the conditions below will be true, thus
  -- empty between <i> and </i> via table is NOT possible

  -- for the "red=" parameter we link to page history

  if (numerr==0) then
    do -- scope

      local tabclaims = {}
      local strt8mp = ''

      if (boohavered) then
        table.insert(tabclaims,(lfwbrew3url(arxframent, strmyred, 'action=history', strmyred, true) .. ' ' .. contabmessa[0] .. '.'))
      end--if

      if (boohaveabo) then
        table.insert(tabclaims,(contabmessa[1] .. ' ' .. strmyabo .. '.'))
      end--if

      if (numpindex>=2) then
        table.insert(tabclaims,(contabmessa[2] .. ' ' .. arxsomons[1] .. ' ' .. contabmessa[3] .. ' [[' .. arxsomons[2] .. ']].'))
      end--if
      if (numpindex>=4) then
        table.insert(tabclaims,(contabmessa[4] .. ' ' .. arxsomons[3] .. ' ' .. contabmessa[5] .. ' [[' .. arxsomons[4] .. ']].'))
      end--if
      if (numpindex==6) then
        table.insert(tabclaims,(contabmessa[6] .. ' ' .. arxsomons[5] .. ' ' .. contabmessa[7] .. ' [[' .. arxsomons[6] .. ']].'))
      end--if

      if (boohavedis) then -- also for # or %
        if (boohavedit) then
          table.insert(tabclaims,(contabmessa[8] .. contabmessa[10] .. ' [[' .. strmydis .. ']] ' .. contabmessa[11] .. ' [[' .. strmydit .. ']].'))
        else
          table.insert(tabclaims,(contabmessa[8] .. contabmessa[9] .. ' [[' .. strmydis .. ']].'))
        end--if
      end--if

      strt8mp = '<i>' .. table.concat(tabclaims,' ') .. '</i>' -- not empty from table.concat
      strvisgud = '<table><tr><td style="padding:0.2em;">[[File:Disambig-dark.svg|25px|link=' .. constrhelp
      strvisgud = strvisgud .. ']]</td><td style="padding:0.2em;">' .. strt8mp .. '</td></tr></table>'

   end--do scope
  end--if

  ---- WHINE IF YOU MUST #E02...#E99 ----

  -- reporting of errors #E02...#E99 depends on uncommentable or peekable
  -- stuff and on name of the caller filled in from "strpikparent"

  if (numerr>1) then
    strviserr = lfhbrewerror(numerr)
  end--if

  ---- BREW TRACKING CAT:S ----

  -- "strpikkatns" "strpikpareuf" -> "strtrakat" not yet !!!FIXME!!!

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

  -- on #E02 and higher we risk partial results
  -- in "strvisgud" (no "strinvkat" here)

  if (numerr==0) then
    strret = strvisgud
  else
    strret = strviserr .. strtrakat
  end--if
  return strret

end--function exporttable.ek

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

return exporttable