Modulo:mwhineplendu

 MODULO
Memtesto ne disponeblas.

--[===[

MODULE "MWHINEPLENDU" (whine plendu)

"eo.wiktionary.org/wiki/Modulo:mwhineplendu" <!--2021-Jan-07-->
"id.wiktionary.org/wiki/Modul:mwhineplendu"

Purpose: whines about incorrect usage of a template by producing a
         red message and putting the page into 2 tracking categories

Utilo: plendas pri erara uzo de sxablono per eligo de rugxa
       mesagxo kaj almeto de la pagxo al 2 diagnozaj kategorioj

Manfaat: mengomel tentang penggunaan salah templat melalui buat pesan
         yang merah dan tambahkan halaman ke 2 kategori pelacak

Syfte: gnaeller kring fel anvaendning av en mall genom att producera ett
       roett meddelande och laegga sidan till 2 spaarningskategorier

Used by templates / Uzata far sxablonoj:
- bildodek gamkan deveno3 auxdo

Required submodules / Bezonataj submoduloj:
- none / neniuj

This module is special in that it takes parameters both those sent
to itself (own frame) and those sent to the caller (caller's frame).

This module is special in that it peeks caller's name (previous in chain)
rather than "pagename" or "fullpagename" (last in calling chain).

Incoming: - 1 anonymous optional parameter
            - whining details (5...52 octet:s, no ("[", "]", "{", "}"),
              ignored if invalid, default is "Legu gxian dokumentajxon",
              begin with uppercase, no dot at end)

Returned: - whining message and maybe category string, in some cases empty

Parameters seized from the caller's frame:
          - 1 named optional parameter
            - "nocat" (value "true" to suppress categorization,
              anything else is ignored)

To be called from template namespace only.

The caller's name is peeked via ":getParent():getTitle()".

For example for a template "SXablono:becool" calling this the EO message
will be "Erara uzo de sxablono {{becool}}. Legu gxian dokumentajxon."
with "{{becool}}" being a link to the template. The categories
will be [[Kategorio:Erara uzo de sxablono (becool)]]
and [[Kategorio:Erara uzo de sxablono]] without any sorting hint.

Note that we construct the link with just "<code>{{[[" ...
"]]}}</code>", NOT with "<code><nowiki>{{</nowiki>[[" ...
"]]<nowiki>}}</nowiki></code>", since string coming from a module is
subject to reduced parsing only, thus wiki links and external http links
and "<code>" still do work whereas template calls and "<nowiki>" do NOT.

We do nothing and return an empty string if any internal problem occurs,
for example caller's name is nil, empty or does not contain a colon.

Due to incomplete checking, inappropriate calling from for example
"Category:Physics" (NS=14) or "Help:TOC" (NS=12) will whine (thus
accept the namespace) whereas inappropriate calling from
"Physics" (NS=0) will fail silently and return empty.

]===]

local whineplendu = {}

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

---- 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 (error circumfixes)

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

  -- uncommentable EO vs ID constant strings (core site-related features)

  local constrpriv = "eo"                    -- EO (site language)
  -- local constrpriv = "id"                    -- ID (site language)
  local constrkatp = "Kategorio:"            -- EO
  -- local constrkatp = "Kategori:"             -- ID

  -- uncommentable EO vs ID constant strings (error messages)

  local constrwhi3 = 'Erara uzo de sxablono'        -- EO (no dots "." here)
  -- local constrwhi3 = 'Penggunaan salah templat'     -- ID (no dots "." here)

  local constrwhi4 = 'Legu gxian dokumentajxon'     -- EO (no dots "." here)
  -- local constrwhi4 = 'Bacalah dokumentasinya'       -- ID (no dots "." here)

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

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

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

-- Local function LFBANKRAMP

-- Check string for illegal stuff "[", "]", "{", "}" ie template
-- calls, wikilinks and external http links

-- Input  : * strqoq -- string (empty is useless but can't cause any harm)

-- Output : * booisbadkr -- true if the string is bad

local function lfbankramp (strqoq)
  local booisbadkr = false
  local numciiar = 0
  local numukurn = 0
  local numindeex = 0 -- ZERO-based
  numukurn = string.len (strqoq)
  while (true) do
    if (numindeex==numukurn) then
      break -- done -- ZERO iterations possible
    end--if
    numciiar = string.byte (strqoq,(numindeex+1),(numindeex+1))
    if ((numciiar==91) or (numciiar==93) or (numciiar==123) or (numciiar==125)) then
      booisbadkr = true
      break -- crime detected
    end--if
    numindeex = numindeex + 1
  end--while
  return booisbadkr
end--function lfbankramp

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

-- Local function LFKODEOSG

-- Transcode surrogates to cxapeloj in a string (EO only)

local function lfkodeosg (strsurr)
  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

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

---- MAIN EXPORTED FUNCTION ----

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

function whineplendu.ek (arxframent)

  -- general unknown type

  local vartmp = 0     -- variable without type

  -- special type "args" AKA "arx"

  local arxourown = 0  -- metaized "args" from our own "frame"
  local arxcaller = 0  -- metaized "args" from caller's "frame"

  -- general "str"

  local strtmp     = ""
  local strtpm     = ""
  local strdeta    = ""  -- optional whining details (5...52)
  local strpncalpr = ""  -- pagename namespace prefix including the colon ":"
  local strpncalco = ""  -- pagename core
  local strret     = ""  -- output string

  -- general "num"

  local numlong   = 0  -- length of parameter
  local numbull   = 0
  local numposcol = 0  -- ONE-based position of colon

  -- general "boo"

  local booerr    = false  -- fatal error flag (we fail silently)
  local boonocat  = false

  ---- GET THE ARX:ES ----

  arxourown = arxframent.args -- "args" from our own "frame"
  arxcaller = arxframent:getParent().args -- "args" from caller's "frame"

  ---- SEIZE 1 OPTIONAL ANONYMOUS PARAMETER SENT BY CALLER TO US ----

  -- leave "strdeta" empty on failure

  vartmp = arxourown[1] -- can be "nil"
  if (type(vartmp)=="string") then
    numlong = string.len (vartmp)
    if ((numlong>=5) and (numlong<=52)) then -- 5...52 octet:s
      if (lfbankramp(vartmp)==false) then -- no "[", "]", "{", "}"
        strdeta = vartmp
      end--if
    end--if ((numlong>=5) and (numlong<=52)) then
  end--if

  ---- SEIZE 1 OPTIONAL NAMED PARAMETER SENT BY SOMEONE TO CALLER ----

  vartmp = arxcaller["nocat"] -- can be "nil"
  if (type(vartmp)=="string") then
    if (vartmp=="true") then
      boonocat = true
    end--if
  end--if

  ---- SEIZE CALLER'S NAME INTO 2 STRING:S ----

  -- "strpncalpr" (pagename namespace prefix) at least one char + colon ":"
  -- "strpncalco" (pagename core) at least one char

  -- "numposcol" preset to ZERO (invalid)

  vartmp = arxframent:getParent():getTitle()

  if (type(vartmp)=="string") then
    strtmp = vartmp
    numbull = string.len (strtmp)
    if (numbull>2) then
      vartmp = string.find (strtmp, ':', 1, true) -- plain text search
      if (vartmp~=nil) then -- "not found" is NOT valid
        numposcol = vartmp -- ONE-based position
        if ((numposcol==1) or (numposcol==numbull)) then
          numposcol = 0 -- invalid position of colon
        end--if
      end--if
    end--if (numbull>2) then
  end--if

  if (numposcol==0) then
    booerr = true -- damn
  else
    strpncalpr = string.sub (strtmp,1,numposcol) -- includes the colon
    strpncalco = string.sub (strtmp,(numposcol+1),numbull) -- after colon
  end--if

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

  if (constrpriv=="eo") then
    constrwhi3 = lfkodeosg(constrwhi3)
    constrwhi4 = lfkodeosg(constrwhi4)
  end--if

  ---- CARRY OUT THE HARD WORK ----

  if (booerr==false) then

    -- prepare whining details

    if (strdeta=="") then
      strdeta = constrwhi4 -- take the default
    end--if

    -- brew 2 separate red bold parts

    strtmp = constrelabg .. constrwhi3 .. constrelaen -- before li
    strtpm = constrelabg .. ". " .. strdeta .. "." .. constrelaen -- after li

    -- brew the complaint with link in the middle, no "nowiki" here

    strret = constrkros .. strtmp .. " <code>{{[["
    strret = strret .. strpncalpr .. strpncalco .. "|" .. strpncalco
    strret = strret .. "]]}}</code>" .. strtpm .. constrkros

    -- brew 2 cat:s

    if (boonocat==false) then

      strret = strret .. "[[" .. constrkatp .. constrwhi3 .. " (" .. strpncalco .. ")]]"
      strret = strret .. "[[" .. constrkatp .. constrwhi3 .. "]]"

    end--if

  end--if

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

  return strret -- can be empty

end--function

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

return whineplendu