Modulo:Akuplu
Aspekto
[antaŭrigardi] [redakti] [historio] [renovigi]

- #T00 (no parameters, bad)
- parameters: ""
- expected result: " #E08 "
- actual result: " #E08 "
- #T01 (one anon parameter, still not enough, bad)
- parameters: "|jn"
- expected result: " #E08 "
- actual result: " #E08 "
- #T02 (3 anon parameters, too many, bad)
- parameters: "|j|n|jn"
- expected result: " #E08 "
- actual result: " #E08 "
- #T03 (two anon parameters, term empty, bad)
- parameters: "|jn|"
- expected result: "??"
- actual result: "??"
- #T04 (two anon parameters, invalid type "nj", bad)
- parameters: "|nj|lemniskato"
- expected result: "??"
- actual result: "??"
- #T10 (jn, faulty term "a", no change)
- parameters: "|jn|a"
- expected result: "a"
- actual result: "a"
- #T11 (n, faulty term "a kaj bo kaj co", no change)
- parameters: "|n|a kaj bo kaj co"
- expected result: "a kaj bo kaj co"
- actual result: "a kaj bo kaj co"
- #T12 (jn, faulty term "aa", gets suffixed)
- parameters: "|jn|aa"
- expected result: "aajn"
- actual result: "aajn"
- #T13 (n, non-Esperanto proper noun, gets suffixed, less useful)
- parameters: "|n|Albula"
- expected result: "Albulan"
- actual result: "Albulan"
- #T14 (n, gets suffixed except "kaj")
- parameters: "|n|buso kaj metroo"
- expected result: "buson kaj metroon"
- actual result: "buson kaj metroon"
- #T15 (jn, gets suffixed except 2 times "kaj", nouns derived from stop words)
- parameters: "|jn|buso kaj subo kaj kontrauxo"
- expected result: "busojn kaj subojn kaj kontrauxojn"
- actual result: "busojn kaj subojn kaj kontrauxojn"
- #T16 (n, gets suffixed except 2 times "nek", table words)
- parameters: "|n|nek cxio nek nenio"
- expected result: "nek cxion nek nenion"
- actual result: "nek cxion nek nenion"
- #T20 (j, gets suffixed except "KAJ", less useful)
- parameters: "|j|DEISMO KAJ ATEISMO"
- expected result: "DEISMOJ KAJ ATEISMOJ"
- actual result: "DEISMOJ KAJ ATEISMOJ"
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 "AKUPLU" (accusativizer pluralizer)
"eo.wikipedia.org/wiki/Modulo:Akuplu" <!--2025-Feb-14-->
------------------------------------------------------------------------
Purpose: accusativization and pluralization of Esperanto multiword terms
Utilo: akuzativigo kaj pluraligo de esperantaj plurvortaj esprimoj
Manfaat: pengakusatifan dan penjamakan istilah ...
Syfte: ackusativisering och pluralisering ...
Used by templates / Uzata far sxablonoj /
Digunakan oleh templat / Anvaend av mallar:
* "J" "N" "JN" (all NOT via "caller=true")
Required submodules / Bezonataj submoduloj /
Submodul yang diperlukan / Behoevda submoduler:
* none
Required templates:
* none
Required images:
* none
This module can accept parameters whether sent to itself (own frame) or
to the parent (parent's frame). If there is a parameter "caller=true"
on the own frame then that own frame is discarded in favor of the
parent's one.
------------------------------------------------------------------------
Incoming: * 2 anonymous and obligatory parameters
* type of inflection "j" "n" "jn"
* term in nominative singular form
Returned: * inflected form
------------------------------------------------------------------------
Features:
* accusativization and pluralization of Esperanto multiword terms
* works with single words too
* works for uppercase and lowercase
* automatically skips non-nouns and non-adjectives from inflection
* automatically skips non-Esperanto words such as "Brno" from inflection
* automatically skips all words after certain prepositions from inflection
* works for adjectivized numbers like "1-a" or "2a"
* recognizes common punctuation as word boundaries as opposed to
dash "-" that can be part of a word
Limitations:
* cannot pluralize existing accusative nor accusativize existing plural
* cannot accusativize personal pronouns (mi ... ri ...)
* does NOT support letter names (bo co ... gxo ... zo)
* does NOT support adjectivized Roman numbers (the practical consequence
is that for example "XI-a" gets inflected correctly whereas XX-a does not)
* supports only words and groups of words together belonging to word classes
noun or adjective, for other word classes the output is not generally
useful (for example "pasxado sur akvo" is a noun whereas "sub la ponto"
is an adverb)
* does NOT support terms of type "generic noun proper noun-a" or "generic
noun proper noun-o" like "montpasejo Albula" or "urbo Brno", on such
the output is not generally useful
* does NOT touch adverbs (not even those that can have "-n" for
whatever purpose)
* does NOT support "&", for terms like "nigra truo" or "bona&granda"
the output is not generally useful
* does NOT support brackets, for terms like "Fuzio (nuklea fiziko)" the
output is not generally useful
Notes:
* word must end with (a A o O) and have at least one vowel
(a e i o u A E I O U) or digit (0 1 2 3 4 5 6 7 8 9) somewhere
before to qualify for inflection
* no further validity checks, some invalid words like "aa" or "aaa" will pass
* spaces and common punctuation signs are considered as word boundaries
* redundant spaces or punctuation do not break the process and are preserved
Stop words and testcases (only add words that reasonably can appear
in an Esperanto multiword term that can be accusativized or pluralized):
* jn da -- cisterno da vino -> cisternojn da vino
* n de -- konkero de Konstantinopolo -> konkeron de Konstantinopolo
* j div -- metro div sekundo -> metroj div sekundo
* j dum -- metro dum sekundo -> metroj dum sekundo
* j en -- metro en sekundo -> metroj en sekundo
* n kontraux -- milito kontraux vandalismo -> militon kontraux vandalismo
* j per -- metro per sekundo -> metroj per sekundo
* j po -- metro po sekundo -> metroj po sekundo
* n por -- permesilo GNU por libera dokumento -> permesilon
GNU por libera dokumento
* j pro -- morto pro malsato -> mortoj pro malsato
* n sub -- Afriko sub kolonia regado -> Afrikon sub kolonia regado
* n sur -- pasxado sur akvo -> pasxadon sur akvo
* jn tra -- SALTO TRA MURO -> SALTOJN TRA MURO
Further testcases (some requests or results are not practically useful):
* jn a -> a
* n a kaj bo kaj co -> a kaj bo kaj co
* jn aa -> aajn
* n Albula -> Albulan
* n buso kaj metroo -> buson kaj metroon
* jn buso kaj subo kaj kontrauxo -> busojn kaj subojn kaj kontrauxojn
* n nek cxio nek nenio -> nek cxion nek nenion
* j DEISMO KAJ ATEISMO -> DEISMOJ KAJ ATEISMOJ
* n elemento por transmisio de rotacia movo -> elementon
por transmisio de rotacia movo
* n ekstere kaj intere -> ekstere kaj intere
* jn esperanto-parolanto, denaska -> esperanto-parolantojn, denaskajn
* n Granda flavkrura tringo -> Grandan flavkruran tringon
* n Gustavo la 1-a de Svedio -> Gustavon la 1-an de Svedio
* jn Inversa trigonometria funkcio -> Inversajn trigonometriajn funkciojn
* n Ivano la Terura -> Ivanon la Teruran
* jn kaptu la kato -> kaptu la katojn
* n kaptu la katoj -> kaptu la katoj
* j kaptu la katon -> kaptu la katon
* jn KARATEO kaj Kotavao -> KARATEOJN kaj Kotavaojn
* j kvazaux -> kvazaux
* n kvazaux bona -> kvazaux bonan
* n la 0a provo -> la 0an provon
* n la 99-a provo -> la 99-an provon
* n la Andoj -> la Andoj
* n la MMXC-a rango -> la MMXC-a rangon
* n la MMXCI-a rango -> la MMXCI-an rangon
* n la sveda -> la svedan
* jn MALHONESTA LUDO Per preparacxita jxetkubo -> MALHONESTAJN
LUDOJN Per preparacxita jxetkubo
* n MILITo aux pacO -> MILITon aux pacON
* n montpasejo Albula -> montpasejon Albulan
* n multe da monacxo -> multe da monacxo
* n nigra truo -> nigran truon
* n nigra truo -> nigra truon
* n Oslo kaj Brno -> Oslon kaj Brno
* j pasxo de musxo -> pasxoj de musxo
* n Permesilo de GNU por liberaj dokumentoj -> Permesilon de
GNU por liberaj dokumentoj
* jn POMO KAJ PIRO -> POMOJN KAJ PIROJN
* n por la kato -> por la kato
* jn rekte erara ekzemplo -> rekte erarajn ekzemplojn
* n Sankta Romia Imperio de Germana Nacio -> Sanktan
Romian Imperion de Germana Nacio
* n Sigismondo la 4-a Vasa de Litovio -> Sigismondon la 4-an Vasan de Litovio
* j sub la ponto -> sub la ponto
* n Tajloro kaj la regxo -> Tajloron kaj la regxon
* n Tajloro kaj vi -> Tajloron kaj vi
* n Universitato de Goettingen -> Universitaton de Goettingen
* n vorajxo por la kato -> vorajxon por la kato
------------------------------------------------------------------------
{{hr3}} <!-------------------------------->
* #T00 (no parameters, bad)
* parameters: ""
* expected result: " #E08 "
* actual result: "{{#invoke:Akuplu|ek}}"
::* #T01 (one anon parameter, still not enough, bad)
::* parameters: "|jn"
::* expected result: " #E08 "
::* actual result: "{{#invoke:Akuplu|ek|jn}}"
* #T02 (3 anon parameters, too many, bad)
* parameters: "|j|n|jn"
* expected result: " #E08 "
* actual result: "{{#invoke:Akuplu|ek|j|n|jn}}"
::* #T03 (two anon parameters, term empty, bad)
::* parameters: "|jn|"
::* expected result: "??"
::* actual result: "{{#invoke:Akuplu|ek|jn|}}"
* #T04 (two anon parameters, invalid type "nj", bad)
* parameters: "|nj|lemniskato"
* expected result: "??"
* actual result: "{{#invoke:Akuplu|ek|nj|lemniskato}}"
{{hr3}} <!-------------------------------->
* #T10 (jn, faulty term "a", no change)
* parameters: "|jn|a"
* expected result: "a"
* actual result: "{{#invoke:Akuplu|ek|jn|a}}"
::* #T11 (n, faulty term "a kaj bo kaj co", no change)
::* parameters: "|n|a kaj bo kaj co"
::* expected result: "a kaj bo kaj co"
::* actual result: "{{#invoke:Akuplu|ek|n|a kaj bo kaj co}}"
* #T12 (jn, faulty term "aa", gets suffixed)
* parameters: "|jn|aa"
* expected result: "aajn"
* actual result: "{{#invoke:Akuplu|ek|jn|aa}}"
::* #T13 (n, non-Esperanto proper noun, gets suffixed, less useful)
::* parameters: "|n|Albula"
::* expected result: "Albulan"
::* actual result: "{{#invoke:Akuplu|ek|n|Albula}}"
* #T14 (n, gets suffixed except "kaj")
* parameters: "|n|buso kaj metroo"
* expected result: "buson kaj metroon"
* actual result: "{{#invoke:Akuplu|ek|n|buso kaj metroo}}"
::* #T15 (jn, gets suffixed except 2 times "kaj", nouns derived from stop words)
::* parameters: "|jn|buso kaj subo kaj kontrauxo"
::* expected result: "busojn kaj subojn kaj kontrauxojn"
::* actual result: "{{#invoke:Akuplu|ek|jn|buso kaj subo kaj kontrauxo}}"
* #T16 (n, gets suffixed except 2 times "nek", table words)
* parameters: "|n|nek cxio nek nenio"
* expected result: "nek cxion nek nenion"
* actual result: "{{#invoke:Akuplu|ek|n|nek cxio nek nenio}}"
{{hr3}} <!-------------------------------->
* #T20 (j, gets suffixed except "KAJ", less useful)
* parameters: "|j|DEISMO KAJ ATEISMO"
* expected result: "DEISMOJ KAJ ATEISMOJ"
* actual result: "{{#invoke:Akuplu|ek|j|DEISMO KAJ ATEISMO}}"
{{hr3}} <!-------------------------------->
------------------------------------------------------------------------
]===]
local exporttable = {}
require('strict')
------------------------------------------------------------------------
---- CONSTANTS [O] ----
------------------------------------------------------------------------
-- stop words (only add words that reasonably can appear in an Esperanto
-- multiword term that can be accusativized or pluralized)
local contabstop = {'da','de','div','dum','en',('kontra'..string.char(197,173)),'per','po','por','pro','sub','sur','tra'}
------------------------------------------------------------------------
---- LOW LEVEL STRING PROCEDURES [G] ----
------------------------------------------------------------------------
-- test whether char is an ASCII digit "0"..."9", return boolean
local function lfgtestnum (numkaad)
local boodigit = false
boodigit = ((numkaad>=48) and (numkaad<=57))
return boodigit
end--function lfgtestnum
------------------------------------------------------------------------
-- Local function LFGTESTPUNCTURE
-- Test whether char is an ASCII punctuation sign, return type "boolean".
-- punctuation (5 char:s: ! , . ; ?) 21 33 | 2C 44 | 2E 46 | 3B 59 | 3F 63
-- dash "-" and apo "'" do NOT count as punctuation
-- here we do NOT include SPACE in the list
local function lfgtestpuncture (numcorde)
local boopunk = false
boopunk = ((numcorde==33) or (numcorde==44) or (numcorde==46) or (numcorde==59) or (numcorde==63))
return boopunk
end--function lfgtestpuncture
------------------------------------------------------------------------
-- Local function LFGTESTVOWEL
-- Test whether char is a vowel, return tristate, ZERO no
-- vowel, ONE (e i u), TWO (a o).
local function lfgtestvowel (numonechaar)
local numtrivowel = 0
if (numonechaar>=96) then
numonechaar = numonechaar - 32
end--if
if ((numonechaar==69) or (numonechaar==73) or (numonechaar==85)) then
numtrivowel = 1
end--if
if ((numonechaar==65) or (numonechaar==79)) then
numtrivowel = 2
end--if
return numtrivowel
end--function lfgtestvowel
------------------------------------------------------------------------
---- HIGH LEVEL STRING PROCEDURES [I] ----
------------------------------------------------------------------------
-- Local function LFIISSTOP
-- Depends on constants :
-- * table contabstop ONE-based
-- Called only from LFIAKUPLUEO.
local function lfiisstop (strmywordeo)
local var26tmp = 0
local numindeksego = 1 -- ONE-based
local booyesitis = false -- preASSume NOT found
while true do
var26tmp = contabstop[numindeksego]
if (type(var26tmp)~='string') then
break -- NOT found
end--if
if (var26tmp==strmywordeo) then
booyesitis = true -- found it
break
end--if
numindeksego = numindeksego + 1
end--while
return booyesitis
end--function lfiisstop
------------------------------------------------------------------------
-- Local function LFIAKUPLUEO
-- Accusativize or pluralize an Esperanto term (generous version: supports
-- stop words, supports punctuation, supports uppercase, has error checking).
-- Input : * strtypeinf -- type of inflection "j" "n" "jn" must be lowercase
-- * str27term -- term in nominative singular form
-- Depends on procedures :
-- [I] lfiisstop
-- [G] lfgtestnum lfgtestpuncture lfgtestvowel
-- Depends on constants :
-- * table contabstop ONE-based
local function lfiakuplueo (strtypeinf, str27term)
local strtypeucinf = '' -- "J" "N" "JN" but preASSume invalid
local str27outfo = '' -- we will rebuild it
local stroneword = '' -- lowercased
local num27lon = 0
local num27plindex = 0 -- ZERO-based
local nummychar = 0
local nummyches = 0
local boodontbother = false
local booendofword = false
local boovowdig = false -- preASSume not yet had a vowel or digit in a word
local boo27stop = false -- preASSume not yet stop in the term, never reset
while true do -- outer fake loop
if (strtypeinf=='j') then
strtypeucinf = 'J'
end--if
if (strtypeinf=='n') then
strtypeucinf = 'N'
end--if
if (strtypeinf=='jn') then
strtypeucinf = 'JN'
end--if
if ((strtypeucinf=='') or (str27term=='')) then
str27outfo = '??'
break -- botched
end--if
num27lon = string.len (str27term)
while true do -- inner genuine loop
if (num27plindex>=num27lon) then
break -- done whole term
end--if
nummychar = string.byte (str27term,(num27plindex+1),(num27plindex+1))
num27plindex = num27plindex + 1 -- ZERO-based
str27outfo = str27outfo .. string.char(nummychar) -- copy ch in any case
boodontbother = boo27stop or (nummychar==32) or lfgtestpuncture(nummychar)
if (not boodontbother) then
if (nummychar>=96) then -- must be stored lowercased
stroneword = stroneword .. string.char(nummychar)
else
stroneword = stroneword .. string.char(nummychar+32)
end--if
booendofword = (num27plindex==num27lon) -- end of term is end of word
if (not booendofword) then -- one more chance
nummyches = string.byte (str27term,(num27plindex+1),(num27plindex+1))
booendofword = (nummyches==32) or lfgtestpuncture(nummyches)
end--if
if (booendofword) then -- check for stop word, maybe add suffix soon
boo27stop = lfiisstop(stroneword)
stroneword = '' -- reset after having used it
if (boovowdig and (not boo27stop) and (lfgtestvowel(nummychar)==2)) then
if (nummychar>=96) then
str27outfo = str27outfo .. strtypeinf -- DO IT HERE
else
str27outfo = str27outfo .. strtypeucinf -- DO IT HERE
end--if
end--if
boovowdig = false -- reset after having used it
else
boovowdig = boovowdig or lfgtestnum(nummychar) or (lfgtestvowel(nummychar)~=0)
end--if (booendofword) else
end--if (not boodontbother) then
end--while -- inner genuine loop
break -- finally
end--while -- outer fake loop -- join mark
return str27outfo
end--function lfiakuplueo
------------------------------------------------------------------------
---- VARIABLES [R] ----
------------------------------------------------------------------------
function exporttable.ek (arxframent)
local arxsomons = 0 -- metaized "args" from our own or caller's "frame"
local strtajp = ''
local strgrundform = ''
local strret = ''
local numerr = 0
------------------------------------------------------------------------
---- 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['caller']=='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
---- GET TWO ANON PARAMS ----
if (numerr==0) then
strtajp = arxsomons[1]
strgrundform = arxsomons[2]
if ((type(strtajp)~='string') or (type(strgrundform)~='string') or (arxsomons[3]~=nil)) then
numerr = 8 -- #E08 number of anon params
end--if
end--if
---- DO THE HARD WORK ----
if (numerr==0) then
strret = lfiakuplueo (strtajp,strgrundform)
else
strret = ' #E0' .. tostring(numerr) .. ' ' -- max #E09
end--if
---- RETURN THE JUNK STRING ----
return strret
------------------------------------------------------------------------
end--function
---- RETURN THE JUNK LUA TABLE ----
return exporttable