Modul:Katrintisan

--[===[

MODULE "KATRINTISAN" (kategori rintisan)

"id.wikipedia.org/ensiklopedia/Modul:Katrintisan" <!--2025-Aug-11-->

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

Purpose: provide cat insertion for stub category pages

Utilo: havigi ...

Manfaat: ...

Syfte: ...

Used by templates / Uzata far sxablonoj /
Digunakan oleh templat / Anvaend av mallar:
* only "StubCore"

Required submodules / Bezonataj submoduloj /
Submodul yang diperlukan / Behoevda submoduler: none

Required images: none

Required other pages: none

This module can accept parameters whether sent to itself (own frame) or
to the parent (parent's frame). If there is a parameter "parentframe=true"
on the own frame then that own frame is discarded in favor of the
parent's one.

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

Incoming: * ONE ordinary named and optional parameter
            * "category=" overrides autogeneration, does NOT override
              the structural checks though, no ns prefix, lowercase
              at begin, for example "golf"
          * TWO hidden named and optional parameters
            * "pagenameoverridetestonly=" can directly cause #E01
            * "nsnumberoverridetestonly=" can directly cause #E10

Returned: * one string, on success nothing visible and ca 3 cat insertions,
            on error red error string plus one ordinary and one tracking
            cat insertion

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

* Rintisan bertopik golf            -> Golf

There is a challenge with cat pages like:
* Rintisan biografi ilmuwan         -> Ilmuwan
* Rintisan biografi petinju Taiwan  -> Petinju Taiwan
* Rintisan biografi Ulama Nusantara -> Ulama Nusantara
vs
* Rintisan biografi Tibet           -> Tokoh Tibet
However, the letter case reveals whether the following text
is an occupation or a homeland (except for occupation "Ulama").

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

Following errors are possible:
* <<#E01 Internal error in "Module:Katrintisan">>
  Possible causes:
  * function "mw.title.getCurrentTitle().text" AKA "{{PAGENAME}}" failed
  * "pagenameoverridetestonly=" bad
  * "contabpatterns" is broken
* #E10 bad ns
* #E13 parameter "category=" bad
* #E14 bad pagename
* #E15 auto parent cat does not exist
* #E16 manual parent cat does not exist
Redundant parameter "category=" is NOT an error, causes a tracking cat
insertion though.

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

]===]

local exporttable = {}

require('strict')

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

local contaberaroj = {}
        contaberaroj[10] = 'Penggunaan salah %@, hanya bisa digunakan dalam ruang nama 14 (kategori)'
        contaberaroj[13] = 'Penggunaan salah %@, parameter "category=" tidak sah'
        contaberaroj[14] = 'Penggunaan salah %@, pola judul yang tidak dikenal'
        contaberaroj[15] = 'Penggunaan salah %@, halaman kategori atas otomatis "%~" tidak ada'
        contaberaroj[16] = 'Penggunaan salah %@, halaman kategori atas manual "%~" tidak ada'

local conhintkey = string.char(206,163) -- $CE,$A3 uppercase SIGMA

-- Patterns (this is the holy core):
-- * BEWARE no leading or trailing spaces anywhere here
-- * BEWARE longer detection strings must precede shorter ones
-- * 3 outer columns:
--   * outer left -- types of matches and bio status, 3 uppercase letters:
--     * inner left -- "Y" or "N" whether to accept equality
--     * inner middle -- "L" or "U" or "I" or "R" whether to accept substring:
--                       * "L" begin with lowercase
--                       * "U" begin with uppercase
--                       * "I" accept and case indifferent
--                       * "R" reject
--     * inner right -- "B" or "X" bio status
--   * outer middle -- detection string
--   * outer right -- replacement or action, can be empty unless
--                    for equality, do NOT uppercase here:
--     * empty "" -- drop the detection string plus separation space
--                   keeping the substring that follows
--     * star "*" -- do NOT brew any parent cat insertion automatically
--     * anything else:
--       * for substring replace the detection string plus separation
--         space by this string plus separation space
--       * for equality the whole new cat name

local contabpatterns = {}
contabpatterns [00] = {'YRX' , 'Rintisan kecamatan di Indonesia' , '*'}
contabpatterns [01] = {'YRX' , 'Rintisan nagari di Indonesia'    , '*'}
contabpatterns [02] = {'YRX' , 'Rintisan pekon di Indonesia'     , '*'}
contabpatterns [03] = {'YIB' , 'Rintisan biografi Ulama'         , 'Ulama'}
contabpatterns [04] = {'YRB' , 'Rintisan biografi pemain tenis'  , 'petenis'}
contabpatterns [05] = {'NUX' , 'Rintisan bertopik sepak bola'    , 'sepak bola di'}
contabpatterns [06] = {'NUB' , 'Rintisan biografi'               , 'tokoh'}
contabpatterns [07] = {'NLB' , 'Rintisan biografi'               , ''}
contabpatterns [08] = {'NIX' , 'Rintisan bertopik'               , ''}
contabpatterns [09] = {'YRB' , 'Semua rintisan biografi'         , '*'}
contabpatterns [10] = {'NIX' , 'Semua rintisan'                  , '*'}

local connumminlen = 20 -- length of "Rintisan biografi XX" or "Rintisan bertopik YY"

local contabflatcats = {}
contabflatcats.all = 'Semua kategori rintisan'
contabflatcats.bio = 'Semua kategori rintisan biografi'
contabflatcats.nob = 'Semua kategori rintisan selain dari biografi'

local contabtrako = {}
contabtrako['E10'] = 'Templat kategori rintisan digunakan di ruang nama salah'
contabtrako['E14'] = 'Templat kategori rintisan dengan pola judul yang tidak dikenal'
contabtrako['E15'] = 'Templat kategori rintisan dengan kategori atas otomatis yang tidak ada'
contabtrako['E16'] = 'Templat kategori rintisan dengan kategori atas manual yang tidak ada'
contabtrako.manual = 'Templat kategori rintisan dengan kategori atas melaui parameter'
contabtrako.redund = 'Templat kategori rintisan dengan kategori atas manual yang redundan'

local contabfel = {}
contabfel.mibg = '<span class="error">'     -- mini whining begin
contabfel.labg = '<b>' .. contabfel.mibg    -- lagom whining begin
contabfel.hubg = '<big>' .. contabfel.labg  -- huge whining begin
contabfel.mien = '</span>'                  -- mini whining end
contabfel.laen = contabfel.mien .. '</b>'   -- lagom whining end
contabfel.huen = contabfel.laen .. '</big>' -- huge whining end

-- *****************************
-- *    MATH PROCEDURES [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 PROCEDURES [N]    * --------------------------
-- ******************************************

local function prnnumto2digit (numzerotoninetynine)

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

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

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 prnnumto2digit

-- *****************************************
-- *    LOW LEVEL STRING PROCEDURES [G]    * ---------------------------
-- *****************************************

local function prgtestuc (numkode)
local booupperc = false
  booupperc = ((numkode>=65) and (numkode<=90))
return booupperc
end--function prgtestuc

local function prgtestlc (numcode)
local boolowerc = false
  boolowerc = ((numcode>=97) and (numcode<=122))
return boolowerc
end--function prgtestlc

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

local function prgstringrange (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 prgstringrange

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

local function prgpokestring (strinpokeout, numpokepoz, numpokeval)

-- Replace single octet in a string.

-- Input  : * strinpokeout -- empty legal
--          * numpokepoz   -- ZERO-based, out of range legal
--          * numpokeval   -- new value

-- This is inefficient by design of LUA. The caller is responsible to
-- minimize the number of invocations of this, in particular, not to
-- call if the new value is equal the existing one.

local numpokelen = 0

  numpokelen = string.len(strinpokeout)
  if ((numpokelen==1) and (numpokepoz==0)) then
    strinpokeout = string.char(numpokeval) -- totally replace
  end--if
  if (numpokelen>=2) then
    if (numpokepoz==0) then
      strinpokeout = string.char(numpokeval) .. string.sub (strinpokeout,2,numpokelen)
    end--if
    if ((numpokepoz>0) and (numpokepoz<(numpokelen-1))) then
      strinpokeout = string.sub (strinpokeout,1,numpokepoz) .. string.char(numpokeval) .. string.sub (strinpokeout,(numpokepoz+2),numpokelen)
    end--if
    if (numpokepoz==(numpokelen-1)) then
      strinpokeout = string.sub (strinpokeout,1,(numpokelen-1)) .. string.char(numpokeval)
    end--if
  end--if (numpokelen>=2) then

return strinpokeout

end--function prgpokestring

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

local function prgcmpbeg (strbig, strtiny, booalso6ekv)

-- Check whether a given substring can be found at begin of a longer
-- string (equality optionally valid).

-- Input  : * strbig, strtiny
--          * booalso6ekv -- allow equality

local numlen6big = 0
local numlen6tiny = 0
local boof6ound = false

  numlen6big = string.len (strbig)
  numlen6tiny = string.len (strtiny)
  if (numlen6tiny>0) then
    if ((numlen6tiny<numlen6big) or (booalso6ekv and (numlen6tiny==numlen6big))) then
      boof6ound = ( strtiny == (string.sub (strbig,1,numlen6tiny)) )
    end--if
  end--if

return boof6ound

end--function prgcmpbeg

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

local function prgfixcase (strinco2cs, boowup2cas, boodo2all)

-- Adjust letter case of ASCII letters in a string, either
-- only one char at begin, or all, other char:s untouched.

-- Input  : * strinco2cs -- string, empty tolerable
--          * boowup2cas -- "true" for uppercase and "false" for lowercase
--          * boodo2all -- "true" to adjust all letters, "false"
--                         only beginning letter

-- Output : * strinco2cs

-- Depends on procedures :
-- [G] prgtestuc prgtestlc prgpokestring

local numlong2den = 0
local numokt2index = 0 -- ZERO-based
local numcha2r = 0
local numdel2ta = 0

local boowan2tlowr = false

  boowup2cas = (boowup2cas==true)
  boodo2all = (boodo2all==true)
  boowan2tlowr = (not boowup2cas)
  numlong2den = string.len (strinco2cs)

  while true do
    if (numokt2index>=numlong2den) then
      break
    end--if
    numdel2ta = 0 -- preASSume on every iteration
    numcha2r = string.byte (strinco2cs,(numokt2index+1),(numokt2index+1))
    if (boodo2all or (numokt2index==0)) then
      if (prgtestuc(numcha2r) and boowan2tlowr) then
        numdel2ta = 32
      end--if
      if (prgtestlc(numcha2r) and boowup2cas) then
        numdel2ta = - 32
      end--if
    end--if
    if (numdel2ta~=0) then
      strinco2cs = prgpokestring (strinco2cs,numokt2index,(numcha2r+numdel2ta))
    end--if
    numokt2index = numokt2index + 1
  end--while

return strinco2cs

end--function prgfixcase

-- *******************************************
-- *    HIGH LEVEL STRING PROCEDURES [I7]    * -- placeholderism
-- *******************************************

local function pripl2altwre (strbeforfill, numaskikodo, varsupstitu)

-- Process all anon and fixed placeholders "%@" or "%~".

-- Input  : * strbeforfill -- request string with placeholders to be filled
--                            in, no placeholders or empty input is useless
--                            but cannot cause major harm
--          * numaskikodo  -- ASCII code of placeholder type, 64 for "%@" or
--                            126 for "%~"
--          * varsupstitu  -- substitute, either string (same content reused
--                            if multiple placeholders), or ZERO-based table
--                            (with one element per placeholder such as
--                            {[0]="none","neniu"}), length 1...80, further
--                            sanitization must be done elsewhere

-- Output : * strafterfill

-- Depends on procedures :
-- [G] prgstringrange

local varpfiller    = 0  -- risky picking
local strufiller    = '' -- final validated filler
local strafterfill  = ''
local numlenbigtext = 0  -- len of strbeforfill
local numsfrcindex  = 0  -- char index ZERO-based
local numinsrtinde  = 0  -- index in table ZERO-based
local numtecken0d   = 0
local numtecken1d   = 0

  numlenbigtext = string.len (strbeforfill)

  while true do
    if (numsfrcindex>=numlenbigtext) then
      break -- empty input is useless but cannot cause major harm
    end--if
    numtecken0d = string.byte(strbeforfill,(numsfrcindex+1),(numsfrcindex+1))
    numsfrcindex = numsfrcindex + 1 -- INC here
    numtecken1d = 0 -- preASSume none
    if (numsfrcindex<numlenbigtext) then -- pick but do NOT INC
      numtecken1d = string.byte(strbeforfill,(numsfrcindex+1),(numsfrcindex+1))
    end--if
    if ((numtecken0d==37) and (numtecken1d==numaskikodo)) then -- "%@" "%~"
      numsfrcindex = numsfrcindex + 1 -- INC more, now totally + 2
      varpfiller = 0 -- preASSume nothing available
      strufiller = '??' -- preASSume nothing available
      if (type(varsupstitu)=='string') then
        varpfiller = varsupstitu -- take it as-is (length check below)
      end--if
      if (type(varsupstitu)=='table') then
        varpfiller = varsupstitu [numinsrtinde] -- risk of type "nil"
        numinsrtinde = numinsrtinde + 1 -- INC tab index on every placeholder
      end--if
      if (prgstringrange(varpfiller,1,80)) then -- restrict
        strufiller = varpfiller -- now the substitute is finally accepted
      end--if
    else
      strufiller = string.char (numtecken0d) -- no placeholder -> copy octet
    end--if
    strafterfill = strafterfill .. strufiller -- add one of 4 possible cases
  end--while

return strafterfill

end--function pripl2altwre

-- ************************************                   error handling
-- *    HIGH LEVEL PROCEDURES [H4]    * --------------------------------
-- ************************************

local function prhconstructerar (numerar3code, boopeek3it)

-- Construct partial error message maybe peeking description.

-- Input  : * numerar3code -- 1 ... 98 or 2 ... 98 (resistant against
--                            invalid data type, giving "??" on such)
--          * boopeek3it   -- do peek description #E02...#E98 from table

-- Depends on procedures :
-- [N] prnnumto2digit
-- [E] mathisintrange mathdiv mathmod

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

-- To be called ONLY from PRHBREWERR4HUNP PRHBREWERR5HUPA
-- PRHBREWERR6SLNP PRHBREWERR7SLPA PRHBREWERR8SUBM PRHBREWERR9DETA.

local vardes3krip = 0
local numbottom3limit = 1
local stryt3sux = '#E'

  if (boopeek3it) then
    numbottom3limit = 2 -- #E01 is a valid code for submodule only
  end--if
  if (mathisintrange(numerar3code,numbottom3limit,98)) then
    stryt3sux = stryt3sux .. prnnumto2digit(numerar3code)
    if (boopeek3it) then
      vardes3krip = contaberaroj[numerar3code] -- risk of type "nil"
      if (type(vardes3krip)=='string') then
        stryt3sux = stryt3sux .. ' ' .. vardes3krip
      else
        stryt3sux = stryt3sux .. ' ??' -- no text found
      end--if
    end--if (boopeek3it) then
  else
    stryt3sux = stryt3sux .. '??' -- no valid error code
  end--if

return stryt3sux

end--function prhconstructerar

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

local function prhbrewerr9deta (numeror9code, strparent9nm, tabdeta9ils)

-- Brew error sev huge, one line, insertable parent & details.

-- Input  : * numeror9code -- TWO-based error code 2 ... 98 (resistant
--                            against invalid data type, giving "??" on such)
--          * strparent9nm -- name of parent (not used and should be type
--                            "nil" if message does NOT contain "%@")
--          * tabdeta9ils  -- ZERO-based table, for example
--                            {[0]="none","neniu"}, one element per
--                            placeholder "%~" located in description for
--                            error code in question (not used and should be
--                            type "nil" if message does NOT contain "%~")

-- Output : * stryt9sux -- message with HTML

-- Depends on procedures :
-- [H4] prhconstructerar
-- [I7] pripl2altwre
-- [G] prgstringrange
-- [N] prnnumto2digit
-- [E] mathisintrange mathdiv mathmod

-- Depends on constants :
-- * table contabfel with 2 elements .hubg .huen
-- * table contaberaroj TWO-based (holes permitted)

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

local stryt9sux = ''

  stryt9sux = contabfel.hubg .. pripl2altwre(pripl2altwre(prhconstructerar(numeror9code,true),126,tabdeta9ils),64,strparent9nm) .. contabfel.huen

return stryt9sux

end--function prhbrewerr9deta

-- **********************************************
-- *    MEDIAWIKI INTERACTION PROCEDURES [W]    * ----------------------
-- **********************************************

local function prwifexistrest (strpgnamsi)

-- Simple check whether a wiki page exists. The caller must use "pcall". Here
-- we can crash on the spot if we violate the limit of 500 expensive requests.

-- Input  : * strpgnamsi   -- fullpagename (default NS 0, not template NS 10)

-- Output : * boomemangada -- "true" on success

local boomemangada = false
local metaa = 0

  metaa = mw.title.new (strpgnamsi) -- one param
  boomemangada = metaa.exists -- expensive here

return boomemangada

end--function prwifexistrest

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

function exporttable.ek (arxframent)

-- misc unknown type

local vartymp = 0 -- variable without type multipurpose

-- special type "args" AKA "arx"

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

-- misc tab

local taberrdetail = {}

-- misc str

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

local strnamedparam = '' -- "category="

local strleftcol = '' -- &
local strmidlcol = '' -- & from contabpatterns
local strrajtcol = '' -- &

local stroeverka = '' -- also "" or "*"
local strcopiedx = ''
local strerrdeta = ''

local strinvkat = '' -- invisible category part on success
local strviserr = '' -- visible error message on error
local strtrakat = '' -- invisible tracking categories on success or error

-- misc num

local numerr = 0 -- 0 OK | 1 inter
local numtamp = 0
local numtemp = 0

-- misc boo

local bootakeql = false -- from strleftcol
local booisbio = false -- from strleftcol
local booredundant = false -- from comparison auto vs manual

local bootimp = false

-- peek

local strpikkatns = "Kategori" -- !!!FIXME!!! peek this
local strpikparent = "Templat:StubCore" -- !!!FIXME!!! peek this

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

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

  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['parentframe']=='true') then
    arxsomons = arxframent:getParent().args -- "args" from parent'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 INTO 2 STRING:S ----

  -- this may override "mw.title.getCurrentTitle().text" and
  -- stipulate content in "strpagenam", empty is NOT valid

  -- bad "pagenameoverridetestonly=" can give #E01
  -- no error is possible from other hidden parameters

  strpagenam = '' -- using vartymp here
  if (numerr==0) then -- get pagename (error if bad, silent if absent)
    vartymp = arxsomons['pagenameoverridetestonly']
    if (type(vartymp)=='string') then -- do NOT merge if:s
      if (prgstringrange(vartymp,1,240)) then
        strpagenam = vartymp
      else
        numerr = 1 -- #E01 internal
      end--if
    end--if
  end--if

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

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

  -- "pagenameoverridetestonly=" "nsnumberoverridetestonly=" processed above

  -- later reporting of #E01 must NOT depend on uncommentable
  -- or peekable stuff

  -- pagename must be 1...240 octet:s keep consistent with
  -- "pagenameoverridetestonly=", stricter checks only later

  if ((numerr==0) and (strpagenam=='')) then -- get pagename (error if bad)
    vartymp = mw.title.getCurrentTitle().text -- without namespace prefix
    if (prgstringrange(vartymp,1,240)) then
      strpagenam = vartymp -- cannot be left empty
    else
      numerr = 1 -- #E01 internal
    end--if
  end--if

  if ((numerr==0) and (strruangna=='')) then -- get namespace (silent if bad)
    vartymp = mw.title.getCurrentTitle().namespace -- type is "number"
    if (mathisintrange(vartymp,0,9999)) then -- negative NOT legal but silent
      strruangna = tostring(vartymp) -- can be left empty, check below required
    end--if
  end--if

  ---- CHECK NS AND PAGENAME IN THIS ORDER ----

  if ((numerr==0) and (strruangna~='14')) then -- must be "Category:"
    numerr = 10 -- #E10 called from wrong ns
  end--if
  if ((numerr==0) and (string.len(strpagenam)<connumminlen)) then
    numerr = 14 -- #E14 no chance later
  end--if

  ---- SEIZE NAMED PARAM ----

  strnamedparam = ''
  if (numerr==0) then
    vartymp = arxsomons['category']
    if (type(vartymp)=='string') then -- do NOT merge if:s
      if (prgstringrange(vartymp,1,240)) then
        strnamedparam = vartymp
      else
        numerr = 13 -- #E13
      end--if
    end--if
  end--if

  if ((numerr==0) and (string.find(strnamedparam,'*',1,true) or string.find(strnamedparam,'[',1,true) or string.find(strnamedparam,']',1,true))) then
    numerr = 13 -- #E13
  end--if

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

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

  -- do NOT use "PRHBREWERR" whatever, report our name, NOT of template, in EN

  if (numerr==1) then
    strviserr = contabfel.hubg .. '#E01 Internal error in "Module:Katrintisan".' .. contabfel.huen
  end--if

  ---- CHECK PAGENAME AND PICK PARENT CAT VIA TABLE WITH PATTERNS ----

  -- from above "strpagenam" has "connumminlen" to 240 octet:s

  if (numerr==0) then

    numtamp = 0
    while true do
      vartymp = contabpatterns[numtamp] -- nested table, outer ZERO-based
      if (type(vartymp)~='table') then
        numerr = 14 -- end of table, nothing found #E14
        break
      end--if
      if ((type(vartymp[1])~='string') or (type(vartymp[2])~='string') or (type(vartymp[3])~='string')) then
        numerr = 1 -- #E01 internal
        break
      end--if
      strleftcol = vartymp[1] -- 3 letters
      strmidlcol = vartymp[2] -- detection string
      strrajtcol = vartymp[3] -- replacement or action
      if ((string.len(strleftcol)~=3) or (strmidlcol=='')) then
        numerr = 1 -- #E01 internal
        break
      end--if
      bootakeql = (string.byte(strleftcol,1,1)==89) -- "Y" or nothing
      booisbio = (string.byte(strleftcol,3,3)==66) -- "B" or nothing
      strleftcol = string.sub(strleftcol,2,2) -- "L" or "U" or "I" or nothing
      if (bootakeql and (strrajtcol=='')) then
        numerr = 1 -- #E01 internal
        break
      end--if
      if (bootakeql and (strpagenam==strmidlcol)) then -- equality match here
        if (strrajtcol~='*') then
          stroeverka = strrajtcol -- else keep it empty, but abort in any case
        end--if
        break -- success
      end--if
      bootimp = false
      if ((strleftcol=='L') or (strleftcol=='U') or (strleftcol=='I')) then
        strmidlcol = strmidlcol .. ' ' -- add space
        if (prgcmpbeg(strpagenam,strmidlcol,false)) then -- equality NOT desired
          bootimp = true -- there is hope, but this is NOT final
          strcopiedx = string.sub(strpagenam,(string.len(strmidlcol)+1),-1) -- remaining stuff, at least ONE octet
          numtemp = string.byte(strcopiedx,1,1)
          if (prgtestuc(numtemp) and (strleftcol=='L')) then
            bootimp = false -- wrong letter case
          end--if
          if (prgtestlc(numtemp) and (strleftcol=='U')) then
            bootimp = false -- wrong letter case
          end--if
        end--if
      end--if
      if (bootimp) then -- substring match here
        stroeverka = strrajtcol -- can be empty or even "*" so far
        if (stroeverka=='*') then
          stroeverka = '' -- do NOT brew any parent cat automatically
        else
          if (stroeverka~='') then
            stroeverka = stroeverka .. ' ' -- add space unless empty
          end--if
          stroeverka = stroeverka .. strcopiedx -- no longer empty
        end--if
        break -- success
      end--if (bootimp) then
      numtamp = numtamp + 1
    end--while

  end--if (numerr==0) then

  -- the prey from this is numerr, stroeverka, and
  -- booisbio, the latter valid only on success

  ---- MANUAL OVERRIDE ----

  if ((numerr==0) and (strnamedparam~='')) then
    booredundant = (prgfixcase(strnamedparam,true,false)==prgfixcase(stroeverka,true,false))
    stroeverka = strnamedparam -- override, guaranteed to be non-empty
  end--if

  ---- PREPARE AND CHECK WHETHER THE PARENT CAT EXISTS ----

  if ((numerr==0) and (stroeverka~='')) then

    stroeverka = strpikkatns .. ':' .. prgfixcase(stroeverka,true,false) -- ucfirst and add ns prefix

    if (not prwifexistrest(stroeverka)) then
      if (strnamedparam~='') then
        numerr = 16 -- #E16 bad manual
      else
        numerr = 15 -- #E15 bad auto
      end--if
      strerrdeta = stroeverka
    end--if

  end--if

  ---- BREW ONE CAT INSERTION ALWAYS ----

  strinvkat = '[[' .. strpikkatns .. ':' .. contabflatcats.all .. ']]'

  ---- BREW ONE OR TWO CAT INSERTIONS ON SUCCESS ----

  -- from above "stroeverka" already has ns prefix

  if (numerr==0) then

    if (stroeverka~='') then
      strinvkat = strinvkat .. '[[' .. stroeverka .. '|' .. conhintkey .. ']]' -- with hint here
    end--if
    if (booisbio) then -- only on success, also with no parent cat
      strinvkat = strinvkat .. '[[' .. strpikkatns .. ':' .. contabflatcats.bio .. ']]'
    else
      strinvkat = strinvkat .. '[[' .. strpikkatns .. ':' .. contabflatcats.nob .. ']]'
    end--if

  end--if (numerr==0) then

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

  ---- WHINE IF YOU MUST #E02...#E98 WITH DETAILS ----

  -- reporting of errors #E02...#E98 depends on uncommentable strings

  -- some of them need "strerrdeta" via "taberrdetail"

  if ((numerr>=2) and (numerr<=98)) then -- NOT for #E01 #E99
    if ((numerr==15) or (numerr==16)) then
      taberrdetail = {[0]=strerrdeta} -- only #E15 #E16 have details
    end--if
    strviserr = prhbrewerr9deta (numerr,'"'..strpikparent..'"',taberrdetail)
  end--if

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

  ---- TRACKING CAT INSERTIONS #E02...#E98 ----

  -- up to 3 cat insertions from here

  if (numerr==10) then
    strtrakat = '[[' .. strpikkatns .. ':' .. contabtrako['E10'] .. ']]'
  end--if
  if (numerr==14) then
    strtrakat = '[[' .. strpikkatns .. ':' .. contabtrako['E14'] .. ']]'
  end--if
  if (numerr==15) then
    strtrakat = '[[' .. strpikkatns .. ':' .. contabtrako['E15'] .. ']]'
  end--if
  if (numerr==16) then
    strtrakat = '[[' .. strpikkatns .. ':' .. contabtrako['E16'] .. ']]'
  end--if

  if (numerr==0) then -- only on success
    if (strnamedparam~='') then
      strtrakat = strtrakat .. '[[' .. strpikkatns .. ':' .. contabtrako.manual .. ']]'
    end--if
    if (booredundant) then
      strtrakat = strtrakat .. '[[' .. strpikkatns .. ':' .. contabtrako.redund .. ']]'
    end--if
  end--if

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

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

  return strinvkat .. strviserr .. strtrakat

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

end--function exporttable.ek

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

return exporttable

Konten ini disalin dari wikipedia, mohon digunakan dengan bijak.

×
Advertisement