Modulo:mensb

El Vikivortaro
Salti al navigilo Salti al serĉilo

Dokumentado por ĉi tiu modulo povas esti kreata ĉe Modulo:mensb/dokumentado

--[===[

MODULE "MENSB" (english substantivo)

"eo.wiktionary.org/wiki/Modulo:mensb" <!--2019-Mar-29-->
"id.wiktionary.org/wiki/Modul:mensb"

Purpose: generates declension table for an English noun,
         correctly guessing the plural form for 99.9 % of words

Utilo: generas deklinacian tabelon por angla substantivo,
       divenas gxuste pluralan formon por 99.9 % da vortoj

Manfaat: menghasilkan tabel deklinasi untuk nomina Inggris,
         membuat bentuk jamak dengan benar untuk 99.9 % kata

Used by templates / Uzata far sxablonoj /
Digunakan oleh templat / Anvaent av mallar:
- {{tf-en-sb}}

Incoming: - nothing (seized from caller's frame instead)

Returned: - one huge string containing the complete table

Parameters seized from the caller's frame:
          - 0 to 6 named parameters
            - "sa"  : alternative singular form
            - "pl"  : explicit plural form that replaces the
                      automatically generated one
            - "pa"  : alternative plural form
            - "paa" : alternative other plural form
            - "not" : notes
            - "pagenameoverridetestonly" : base form of the word, replaces
                                           peeking it from "pagename"

Following rules are applied (this works only with lowercase letters):
- consonant + "y" -> drop "y" add "ies" (try -> tries)
- consonant + "o" -> add "es" (hero -> heroes)
- ends with "s" "x" "z" "ch" "sh" -> add "es"
  (virus, fix, ??, reach, clutch, bush)
- otherwise -> add "s"

The base word must contain at least 2 letters.

DO NOT use this module for inherently uncountable
nouns like "news".

NE UZU cxi tiun modulon por kerne nenombreblaj
substantivoj kiel "news".

JANGAN menggunakan modul ini untuk nomina tidak
terhitung seperti "news".

This module is unbreakable (when called with correct module name
and function name).

Cxi tiu modulo estas nerompebla (kiam vokita kun gxustaj nomo de modulo
kaj nomo de funkcio).

Usage examples with results / Ekzemploj de uzo
kun rezultoj / Contoh penggunaan dengan hasil:

"{{#invoke:mensb|ek|computer}}"

-> "computers"

"{{#invoke:mensb|ek|try}}"

-> "tries"

"{{#invoke:mensb|ek|play}}"

-> "plays"

"{{#invoke:mensb|ek|hero}}"

-> "heroes"

"{{#invoke:mensb|ek|loo}}"

-> "loos"

"{{#invoke:mensb|ek|zero}}"

-> "zeroes" (ungrammatical, use "pl" override)

"{{#invoke:mensb|ek|thief}}"

-> "thiefs" (ungrammatical, use "pl" override)

"{{#invoke:mensb|ek|HERO}}"

-> "HEROs" (dubious)

"{{#invoke:mensb|ek|virus}}"

-> "viruses"

"{{#invoke:mensb|ek|fix}}"

-> "fixes"

"{{#invoke:mensb|ek|reach}}"

-> "reaches"

"{{#invoke:mensb|ek|bush}}"

-> "bushes"

"{{#invoke:mensb|ek|path}}"

-> "paths"

"{{#invoke:mensb|ek|news}}"

-> "newses" (ungrammatical, don't apply this module to uncountable nouns)

"{{#invoke:mensb|ek|ii}}"

-> "iis" (nonsense)

"{{#invoke:mensb|ek|i}}"

-> "bad usage"

]===]

local ensb = {}

---- 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  = '707070'  -- table frame color (grey)
  local constrbkti  = 'B0D0F0'  -- title cell background color (light grey/blue)
  local constrtdsty = '<td style="border:0.25em solid #' .. constrfrco .. ';padding:0.4em;'
  local constrtdbg2 = constrtdsty .. '">'                                                                -- NOT centered
  local constrtdbg4 = constrtdsty .. 'text-align:center;" colspan="2">'                                  -- centered & cs 2
  local constrtdbg6 = constrtdsty .. 'background:#' .. constrbkti .. ';text-align:center;" colspan="2">' -- centered & bk & cs 2

  local constrkros  = '&nbsp;#&nbsp;#&nbsp;'
  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 constrbadu = constrehubg .. 'Erara uzo de sxablono "tf-en-sb", legu gxian dokumentajxon' .. constrehuen   -- EO
  -- local constrbadu = constrehubg .. 'Penggunaan salah templat "tf-en-sb", bacalah dokumentasinya' .. constrehuen  -- ID

  local constrkate = '[[Kategorio:Erara uzo de tf-en-sb]]'     -- EO
  -- local constrkate = '[[Kategori:Penggunaan salah tf-en-sb]]'  -- ID

  local constrtit = 'Angla substantivo<br><small>English noun</small>'  -- EO
  -- local constrtit = 'Nomina Inggris<br><small>English noun</small>'     -- ID

  local constrsng = '[[singularo|Singularo]]'                -- EO
  -- local constrsng = '[[bentuk tunggal|Tunggal (singular)]]'  -- ID
  local constrplu = '[[pluralo|Pluralo]]'                    -- EO
  -- local constrplu = '[[bentuk jamak|Jamak (plural)]]'        -- ID

  local constralt = 'alternative'  -- EO
  -- local constralt = 'alternatif'   -- ID

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

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 lfnememlig (strmem,strtuff) -- prevents self-linking
  if (strmem~=strtuff) then
    strtuff = '[[' .. strtuff .. ']]'
  end--if
  return strtuff
end--function lfnememlig

---- MAIN EXPORTED FUNCTION ----

function ensb.ek (mwframent)

  -- general unknown type

  local vartmp = 0     -- variable without type multipurpose

  -- special type "args"

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

  -- general str

  local strsa   = ""  -- this MUST be DIFFERENT from "strbas" otherwise ERROR
  local strpl   = ""
  local strpa   = ""
  local strpaa  = ""
  local strnot  = ""
  local strbas  = ""  -- base form from "pagename" "pagenameoverridetestonly"
  local stralti = ""  -- "br" .. "small" .. alt .. "/small" .. "br"
  local strretu = ""  -- output string

  -- general num

  local numlength = 0  -- length of the input word
  local numlast = 0    -- last char
  local numbela = 0    -- char before the last one

  -- general boo

  local booerr = false  -- fatal error flag
  local boocon = true   -- char in "numbela" consonant flag (false if vowel)
  local boocut = false  -- cut off last letter flag
  local booiii = false  -- add "i" flag
  local booeee = false  -- add "e" flag

  ---- SEIZE 6 OPTIONAL NAMED PARAMS SUBMITTED TO THE CALLER ----

  arxcaller = mwframent:getParent().args -- "args" from caller's "frame"

  if ((arxcaller[1])~=nil) then
    booerr = true -- anonymous parameters NOT appreciated -> "bad usage"
  end--if

  if (booerr==false) then
    if (type(arxcaller["sa"])=="string") then
      strsa = arxcaller["sa"]
    end--if
    if (type(arxcaller["pl"])=="string") then
      strpl = arxcaller["pl"]
    end--if
    if (type(arxcaller["pa"])=="string") then
      strpa = arxcaller["pa"]
    end--if
    if (type(arxcaller["paa"])=="string") then
      strpaa = arxcaller["paa"]
    end--if
    if (type(arxcaller["not"])=="string") then
      strnot = arxcaller["not"]
    end--if
    if (type(arxcaller["pagenameoverridetestonly"])=="string") then
      strbas = arxcaller["pagenameoverridetestonly"]
    end--if
  end--if

  ---- SEIZE THE PAGENAME IF NEEDED ----

  if ((booerr==false) and (strbas=="")) then
    vartmp = mw.title.getCurrentTitle().text
    if (type(vartmp)=="string") then
      if (string.len(vartmp)~=0) then
        strbas = vartmp
      end--if
    end--if
    if (strbas=="") then
      booerr = true -- would result in "bad usage" but is hopefully impossible
    end--if
  end--if

  ---- CHECK WORD LENGTH (NO EN NOUN HAS ONLY 1 LETTER) AND MORE ----

  if (booerr==false) then
    numlength = string.len (strbas) -- length of the input word
    if ((numlength<2) or (strbas==strsa)) then
      booerr = true -- "bad usage"
    end--if
  end--if

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

  if (constrpriv=="eo") then
    constrbadu = lfkodeosg(constrbadu)
  end--if

  ---- BREW PLURAL FORM IF NEEDED ----

  if ((booerr==false) and (strpl=="")) then
      numlast = string.byte (strbas,numlength,numlength)
      numbela = string.byte (strbas,(numlength-1),(numlength-1))
      if ((numbela==97) or (numbela==101) or (numbela==105) or (numbela==111) or (numbela==117)) then
        boocon = false -- damn, it's a vowel
      end--if
      if (boocon==true) then
        if (numlast==121) then -- "y" -> "ies"
          boocut = true
          booiii = true
          booeee = true
        end--if
        if (numlast==111) then -- "o"
          booeee = true
        end--if
      end--if
      if ((numlast==115) or (numlast==120) or (numlast==122)) then
        booeee = true  -- "s" "x" "z"
      end--if
      if (numlast==104) then
        if ((numbela==99) or (numbela==115)) then
          booeee = true  -- "ch" "sh"
        end--if
      end--if
      if (boocut) then
        strpl = string.sub (strbas,1,(numlength-1)) -- omit last letter
      else
        strpl = strbas -- take it all
      end--if
      if (booiii==true) then
        strpl = strpl .. "i"
      end--if
      if (booeee==true) then
        strpl = strpl .. "e"
      end--if
      strpl = strpl .. "s" -- always add "s"
  end--if

  ---- BREW THE TABLE ----

  if (booerr==false) then
    stralti = '<br><small>' .. constralt .. '</small><br>'
    strretu = '<table style="float:right;margin:0 0 1em 1em;border:0.25em solid #'
    strretu = strretu .. constrfrco .. ';border-collapse:collapse;">'
    strretu = strretu .. '<tr>' .. constrtdbg6 .. constrtit .. '</td></tr>'
    strretu = strretu .. '<tr>' .. constrtdbg2 .. '<b>' ..constrsng .. '</b></td>'
    strretu = strretu .. constrtdbg2 .. '<b>' .. constrplu .. '</b></td></tr>'
    strretu = strretu .. '<tr>' .. constrtdbg2 .. strbas
    if (strsa~="") then -- lfnememlig NOT needed here
      strretu = strretu .. stralti .. '[[' .. strsa .. ']]'
    end--if
    strretu = strretu .. '</td>' .. constrtdbg2 .. lfnememlig(strbas,strpl)
    if (strpa~="") then
      strretu = strretu .. stralti .. lfnememlig(strbas,strpa)
    end--if
    if (strpaa~="") then
      strretu = strretu .. stralti .. lfnememlig(strbas,strpaa)
    end--if
    strretu = strretu .. '</td></tr>'
    if (strnot~="") then
      strretu = strretu .. '<tr>' .. constrtdbg4 .. '<small>' .. strnot .. '</small></td></tr>'
    end--if
    strretu = strretu .. '</table>'
  else
    strretu = constrbadu .. constrkate -- damn -- "bad usage" and pillory cate
  end--if

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

  return strretu

end--function

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

return ensb