Modulo:mensb
Salti al navigilo
Salti al serĉilo
|
Memtesto disponeblas sur la dokumentaĵa subpaĝo |
--[===[
MODULE "MENSB" (english substantivo)
"eo.wiktionary.org/wiki/Modulo:mensb" <!--2021-Jan-19-->
"id.wiktionary.org/wiki/Modul:mensb"
Purpose: generates declension table for an English noun,
correctly guessing the plural form for ca 99.9 % of words
Utilo: generas deklinacian tabelon por angla substantivo,
divenas gxuste pluralan formon por ca 99.9 % da vortoj
Manfaat: menghasilkan tabel deklinasi untuk nomina Inggris,
membuat bentuk jamak dengan benar untuk ca 99.9 % kata
Syfte: genererar en tabell foer ett engelskt substantiv,
gissar raett pluralformen foer ca 99.9 % av ord
Used by templates / Uzata far sxablonoj /
Digunakan oleh templat / Anvaent av mallar:
- {{tf-en-sb}}
This module can accept parameters whether sent to itself (own frame) or
to the caller (caller's frame). If there is a parameter "caller=true"
on the own frame then that own frame is discarded in favor of the
caller's one.
Parameters: - 0 to 6 optional 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"
Returned: - one big string containing the complete table
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:
* #T00 page "computer"
* expected result: "computers"
* actual result: "{{#invoke:mensb|ek|pagenameoverridetestonly=computer}}"
* {{nevideblafinodesekcio}}
::* #T01
::* expected result: "tries"
::* actual result: "{{#invoke:mensb|ek|pagenameoverridetestonly=try}}"
::* {{nevideblafinodesekcio}}
* #T02
* expected result: "plays"
* actual result: "{{#invoke:mensb|ek|pagenameoverridetestonly=play}}"
* {{nevideblafinodesekcio}}
::* #T03
::* expected result: "heroes"
::* actual result: "{{#invoke:mensb|ek|pagenameoverridetestonly=hero}}"
::* {{nevideblafinodesekcio}}
* #T04
* expected result: "loos"
* actual result: "{{#invoke:mensb|ek|pagenameoverridetestonly=loo}}"
* {{nevideblafinodesekcio}}
::* #T05
::* expected result: "zeroes" (ungrammatical, use "pl" to override)
::* actual result: "{{#invoke:mensb|ek|pagenameoverridetestonly=zero}}"
::* {{nevideblafinodesekcio}}
* #T06 "pl=zeros" override page "zero"
* expected result: "zeros"
* actual result: "{{#invoke:mensb|ek|pl=zeros|pagenameoverridetestonly=zero}}"
* {{nevideblafinodesekcio}}
::* #T07
::* expected result: "thiefs" (ungrammatical, use "pl" to override)
::* actual result: "{{#invoke:mensb|ek|pagenameoverridetestonly=thief}}"
::* {{nevideblafinodesekcio}}
: ---------------------------------------
* #T10
* expected result: "HEROs" (dubious)
* actual result: "{{#invoke:mensb|ek|pagenameoverridetestonly=HERO}}"
* {{nevideblafinodesekcio}}
* #T11
* expected result: "viruses"
* actual result: "{{#invoke:mensb|ek|pagenameoverridetestonly=virus}}"
* {{nevideblafinodesekcio}}
* #T12
* expected result: "fixes"
* actual result: "{{#invoke:mensb|ek|pagenameoverridetestonly=fix}}"
* {{nevideblafinodesekcio}}
* #T13
* expected result: "reaches"
* actual result: "{{#invoke:mensb|ek|pagenameoverridetestonly=reach}}"
* {{nevideblafinodesekcio}}
* #T14
* expected result: "bushes"
* actual result: "{{#invoke:mensb|ek|pagenameoverridetestonly=bush}}"
* {{nevideblafinodesekcio}}
* #T15
* expected result: "paths" (good although difficult to pronounce)
* actual result: "{{#invoke:mensb|ek|pagenameoverridetestonly=path}}"
* {{nevideblafinodesekcio}}
: ---------------------------------------
* #T20 page "news"
* expected result: "newses" (ungrammatical, don't apply this module to uncountable nouns)
* actual result: "{{#invoke:mensb|ek|pagenameoverridetestonly=news}}"
* {{nevideblafinodesekcio}}
* #T21 page "short story"
* expected result: "short stories" (multiword lemma)
* actual result: "{{#invoke:mensb|ek|pagenameoverridetestonly=short story}}"
* {{nevideblafinodesekcio}}
* #T22 page "ii"
* expected result: "iis" (nonsense)
* actual result: "{{#invoke:mensb|ek|pagenameoverridetestonly=ii}}"
* {{nevideblafinodesekcio}}
<pre>
* #T23 page "i"
* expected result: "bad usage"
* actual result: "{{#invoke:mensb|ek|pagenameoverridetestonly=i}}"
* {{nevideblafinodesekcio}}
* #T24 undesirable anonymous parameter
* expected result: "bad usage"
* actual result: "{{#invoke:mensb|ek|test|pagenameoverridetestonly=test}}"
* {{nevideblafinodesekcio}}
</pre>
: ---------------------------------------
* note that all tests depend on "nevideblafinodesekcio"
* note that tests #T23 #T24 cannot be reasonably executed on the docs subpage without help of "pate" or "debu"
]===]
local ensb = {}
---- CONSTANTS ----
-- uncommentable EO vs ID constant strings (core site-related features)
local constrpriv = "eo" -- EO (privileged site language)
-- local constrpriv = "id" -- ID (privileged site language)
-- constant table (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
-- constant strings (error circumfixes)
local constrkros = ' [] ' -- lagom -> huge " [] "
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
-- uncommentable EO vs ID constant strings (error messages, depends from above "error circumfixes" section)
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 constrkates = '[[Kategorio:Erara uzo de sxablono]]' -- EO
local constrkatel = '[[Kategorio:Erara uzo de sxablono (tf-en-sb)]]' -- EO
-- local constrkates = '[[Kategori:Penggunaan salah templat]]' -- ID
-- local constrkatel = '[[Kategori:Penggunaan salah templat (tf-en-sb)]]' -- ID
-- uncommentable EO vs ID constant strings (misc)
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 MATH FUNCTIONS ----
------------------------------------------------------------------------
local function mathdiv (xdividend, xdivisor)
local resultdiv = 0 -- DIV operator lacks in LUA :-(
resultdiv = math.floor (xdividend / xdivisor)
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
------------------------------------------------------------------------
---- ORDINARY LOCAL STRING FUNCTIONS ----
------------------------------------------------------------------------
local function lfnememlig (strmem,strtuff) -- prevents self-linking
if (strmem~=strtuff) then
strtuff = '[[' .. strtuff .. ']]'
end--if
return strtuff
end--function lfnememlig
------------------------------------------------------------------------
---- ORDINARY LOCAL HIGH LEVEL FUNCTIONS ----
------------------------------------------------------------------------
-- Local function LFKODEOSG
-- Transcode X-surrogates (without "\", thus for example "kacxo",
-- NOT "ka\cxo") to cxapeloj in a string (EO only)
-- Input : * strsurr -- string (empty is useless but can't cause major harm)
-- Output : * strcxapeloj
-- We need const table "contabtransiltable".
-- This sub depends on "MATH FUNCTIONS"\"mathdiv"
-- and "MATH FUNCTIONS"\"mathmod".
local function lfkodeosg (strsurr)
local varpeek = 0
local strcxapeloj = ''
local numinputl = 0
local numininx = 0 -- ZERO-based source index
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 = mathmod (varpeek,256)
numhaj = mathdiv (varpeek,256)
end--if
end--if
if (numhaj~=0) then
strcxapeloj = strcxapeloj .. string.char(numhaj,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 ensb.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"
-- param str
local strsa = "" -- this MUST be DIFFERENT from "strpgnm" otherwise ERROR
local strpl = ""
local strpa = ""
local strpaa = ""
local strnot = ""
-- general str
local strpgnm = "" -- base form from "pagename" "pagenameoverridetestonly"
local stralti = "" -- "br" .. "small" .. alt .. "/small" .. "br"
local strret = "" -- 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
---- GET THE ARX (ONE OF TWO) ----
if (booerr==false) then
arxsomons = arxframent.args -- "args" from our own "frame"
if (arxsomons['caller']=="true") then
arxsomons = arxframent:getParent().args -- "args" from caller's "frame"
end--if
end--if
---- SEIZE 6 OPTIONAL NAMED PARAMS ----
if ((arxsomons[1])~=nil) then
booerr = true -- anonymous parameters NOT appreciated -> "bad usage"
end--if
if (booerr==false) then
vartmp = arxsomons["sa"]
if (type(vartmp)=="string") then
strsa = vartmp
end--if
vartmp = arxsomons["pl"]
if (type(vartmp)=="string") then
strpl = vartmp
end--if
if (type(arxsomons["pa"])=="string") then
strpa = arxsomons["pa"]
end--if
if (type(arxsomons["paa"])=="string") then
strpaa = arxsomons["paa"]
end--if
if (type(arxsomons["not"])=="string") then
strnot = arxsomons["not"]
end--if
if (type(arxsomons["pagenameoverridetestonly"])=="string") then
strpgnm = arxsomons["pagenameoverridetestonly"]
end--if
end--if
---- SEIZE THE PAGENAME IF NEEDED ----
if ((booerr==false) and (strpgnm=="")) then
vartmp = mw.title.getCurrentTitle().text
if (type(vartmp)=="string") then
if (string.len(vartmp)~=0) then
strpgnm = vartmp
end--if
end--if
if (strpgnm=="") then
booerr = true -- would result in "bad usage" but is hopefully impossible
end--if
end--if
---- TRANSCODE EO IF NEEDED ----
if (constrpriv=="eo") then
constrbadu = lfkodeosg(constrbadu)
constrkates = lfkodeosg(constrkates)
constrkatel = lfkodeosg(constrkatel)
end--if
---- CHECK WORD LENGTH (NO EN NOUN HAS ONLY 1 LETTER) AND MORE ----
if (booerr==false) then
numlength = string.len (strpgnm) -- length of the input word
if ((numlength<2) or (strpgnm==strsa)) then
booerr = true -- "bad usage"
end--if
end--if
---- BREW PLURAL FORM IF NEEDED ----
if ((booerr==false) and (strpl=="")) then
numlast = string.byte (strpgnm,numlength,numlength)
numbela = string.byte (strpgnm,(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 (strpgnm,1,(numlength-1)) -- omit last letter
else
strpl = strpgnm -- 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>'
strret = '<table style="float:right;margin:0 0 1em 1em;border:0.25em solid #'
strret = strret .. constrfrco .. ';border-collapse:collapse;">'
strret = strret .. '<tr>' .. constrtdbg6 .. constrtit .. '</td></tr>'
strret = strret .. '<tr>' .. constrtdbg2 .. '<b>' ..constrsng .. '</b></td>'
strret = strret .. constrtdbg2 .. '<b>' .. constrplu .. '</b></td></tr>'
strret = strret .. '<tr>' .. constrtdbg2 .. strpgnm
if (strsa~="") then -- lfnememlig NOT needed here
strret = strret .. stralti .. '[[' .. strsa .. ']]'
end--if
strret = strret .. '</td>' .. constrtdbg2 .. lfnememlig(strpgnm,strpl)
if (strpa~="") then
strret = strret .. stralti .. lfnememlig(strpgnm,strpa)
end--if
if (strpaa~="") then
strret = strret .. stralti .. lfnememlig(strpgnm,strpaa)
end--if
strret = strret .. '</td></tr>'
if (strnot~="") then
strret = strret .. '<tr>' .. constrtdbg4 .. '<small>' .. strnot .. '</small></td></tr>'
end--if
strret = strret .. '</table>'
else
strret = constrbadu .. constrkates .. constrkatel -- "bad usage" and diag
end--if
---- RETURN THE JUNK STRING ----
return strret
end--function
---- RETURN THE JUNK TABLE ----
return ensb