This module implements Esperanto headword-line templates.
local export = {}
local pos_functions = {}
local concat = table.concat
local insert = table.insert
local umatch = mw.ustring.match
local PAGENAME = mw.title.getCurrentTitle().text
local lang = require("Module:languages").getByCode("eo")
local except = require("Module:eo-headword/exceptions")
-- Verb stem must have at least two letters.
local participle_pattern = "..(n?tj?n?)$"
local function monosyllabic(word)
return select(2, word:gsub("", "")) == 1
end
local function check(data, tracking_categories)
local catname = "Esperanto nouns with red links in their headword lines"
if data.pos_category == "adjectives" or data.pos_category == "determiners" or data.pos_category == "adjectival participles" then
catname = "Esperanto adjectives with red links in their headword lines"
end
for _, entry in ipairs(data.check) do
local t = mw.title.new(entry)
if t and not t.exists then
insert(tracking_categories, catname)
end
end
end
-- Determines which function in pos_functions should be used for a word in {{eo-head}}.
local function getPOS(word)
-- deal with some exceptions
if except then
return except
elseif word:sub(1, 1) == "-" then
return word:sub(-1) == "-" and "interfixes" or "prefixes"
elseif word:sub(-1) == "-" then
return "suffixes"
end
-- delete anything after "de"
word = word:gsub(" de .+$", "")
if word:find(" ", nil, true) then
if word:match("o%f") and word:match("a%f") then
return "nouns"
end
end
-- deal with letters
if word:match("^$") or umatch(word,"^o$") then
return "nouns"
end
-- deal with ordinals
if word:match("^%d+%-?a$") then
return "adjectives"
elseif word:match("^%d+%-?aj?n?$") then
return "adjective forms"
end
-- Words with only one vowel are always irregular
if monosyllabic(word) then
return nil
elseif umatch(word, participle_pattern) then -- detect this first
return "participles"
end
local ending = word:match("*$")
if ending == "a" then
return "adjectives"
elseif ending == "aj" or ending == "an" or ending == "ajn" then
return "adjective forms"
elseif ending == "e" or ending == "en" then
return "adverbs"
elseif ending == "o" then
return umatch(word, "^%u") and "proper nouns" or "nouns"
elseif ending == "oj" or ending == "on" or ending == "ojn" then
return umatch(word, "^%u") and "proper noun forms" or "noun forms"
elseif ending == "i" then
return "verbs"
elseif ending:match("^s$") or ending == "u" then
return "verb forms"
else
return nil
end
end
export.getPOS = getPOS
-- The main entry point
function export.show(frame)
local tracking_categories = {}
local parent_args = frame:getParent().args
local poscat = parent_args or frame.args or getPOS(PAGENAME)
if not poscat then
local namespace = mw.title.getCurrentTitle().namespace
if namespace == 10 or namespace == 828 then
poscat = "nouns"
else
error("Part of speech of \"" .. PAGENAME .. "\" cannot be automatically determined.")
end
else
if poscat == "plurale tantum" then
poscat = "pluralia tantum"
elseif not (poscat == "pluralia tantum" or poscat:find("s$")) then
poscat = poscat .. "s" -- Pluralize part of speech.
end
end
local params = {
= {list = true},
= {},
= {type = "boolean"},
}
if pos_functions then
for key, val in pairs(pos_functions.params) do
params = val
end
end
local args = require("Module:parameters").process(parent_args, params)
local data = {lang = lang, pos_category = poscat, categories = {}, heads = args, genders = {}, inflections = {}, check = {}}
if pos_functions then
pos_functions.func(args, data)
end
check(data, tracking_categories)
return require("Module:headword").full_headword(data) .. require("Module:utilities").format_categories(tracking_categories, lang)
end
pos_functions = {
params = {
},
func = function(args, data)
insert(data.inflections, {label = "accusative singular", accel = {form = "acc|s"}, PAGENAME .. "n"})
insert(data.inflections, {label = "plural", accel = {form = "p"}, PAGENAME .. "j"})
insert(data.inflections, {label = "accusative plural", accel = {form = "acc|p"}, PAGENAME .. "jn"})
insert(data.check, PAGENAME .. "n")
insert(data.check, PAGENAME .. "j")
insert(data.check, PAGENAME .. "jn")
end
}
pos_functions = {
params = {
},
func = function(args, data)
insert(data.inflections, {label = "accusative singular", accel = {form = "acc|s"}, PAGENAME .. "n"})
insert(data.inflections, {label = "plural", accel = {form = "p"}, PAGENAME .. "j"})
insert(data.inflections, {label = "accusative plural", accel = {form = "acc|p"}, PAGENAME .. "jn"})
insert(data.check, PAGENAME .. "n")
insert(data.check, PAGENAME .. "j")
insert(data.check, PAGENAME .. "jn")
end
}
pos_functions = {
params = {
= {list = true, allow_holes = true},
},
func = function(args, data)
-- Get the parameters
local inflected_words_specified = false
local inflected_words = {}
for i = 1, args.maxindex do
local word = args
if word == "+" or word == "-" then
word = nil
end
if word then
inflected_words = true
inflected_words_specified = true
end
end
local pl = {}
local acc = {}
local acc_pl = {}
-- Split multi-word terms
for word in mw.text.gsplit(PAGENAME, " ", true) do
local pos = getPOS(word)
-- Inflect each word separately
if (not inflected_words_specified or inflected_words) and (pos == "adjectives" or pos == "nouns" or pos == "proper nouns") then
local is_letter = ""
if word:match("^$") or umatch(word,"^o$")then
is_letter = "-o"
end
insert(acc, word .. is_letter .. "n")
insert(pl, word .. is_letter .. "j")
insert(acc_pl, word .. is_letter .. "jn")
else
insert(acc, word)
insert(pl, word)
insert(acc_pl, word)
end
end
-- Merge back together
acc = concat(acc, " ")
pl = concat(pl, " ")
acc_pl = concat(acc_pl, " ")
local acc2, pl2, acc_pl2
if PAGENAME == "sozo" then
acc2 = "sozo-on"
pl2 = "sozo-oj"
acc_pl2 = "sozo-ojn"
end
if args == "-" then
insert(data.inflections, {label = "uncountable"})
insert(data.inflections, {label = "accusative", accel = {form = "acc"}, acc})
insert(data.categories, lang:getCanonicalName() .. " uncountable nouns")
insert(data.check, acc)
else
insert(data.inflections, {label = "accusative singular", accel = {form = "acc|s"}, acc, acc2})
insert(data.inflections, {label = "plural", accel = {form = "p"}, pl, pl2})
insert(data.inflections, {label = "accusative plural", accel = {form = "acc|p"}, acc_pl, acc_pl2})
insert(data.check, acc)
insert(data.check, pl)
insert(data.check, acc_pl)
end
end
}
pos_functions = {
params = {
= {list = true, allow_holes = true},
},
func = function(args, data)
-- Get the parameters
local inflected_words_specified = false
local inflected_words = {}
for i = 1, args.maxindex do
local word = args
if word == "+" or word == "-" then
word = nil
end
if word then
inflected_words = true
inflected_words_specified = true
end
end
local acc = {}
local pl = {}
local acc_pl = {}
local de = false
-- Split multi-word terms
for word in mw.text.gsplit(PAGENAME, " ", true) do
local pos = getPOS(word)
if word == "de" then de = true end
-- Inflect each word separately
if (not inflected_words_specified or inflected_words) and (pos == "adjectives" or pos == "nouns" or pos == "proper nouns" or word:match("j$") and not monosyllabic(word)) and not de then
insert(acc, word .. "n")
insert(pl, word .. "j")
insert(acc_pl, word .. "jn")
else
insert(acc, word)
insert(pl, word)
insert(acc_pl, word)
end
end
-- Merge back together
acc = concat(acc, " ")
pl = concat(pl, " ")
acc_pl = concat(acc_pl, " ")
if args == "+" then
insert(data.inflections, {label = "accusative singular", accel = {form = "acc|s"}, acc})
insert(data.inflections, {label = "plural", accel = {form = "p"}, pl})
insert(data.inflections, {label = "accusative plural", accel = {form = "acc|p"}, acc_pl})
insert(data.check, acc)
insert(data.check, pl)
insert(data.check, acc_pl)
else
insert(data.inflections, {label = "accusative", accel = {form = "acc"}, acc})
insert(data.check, acc)
end
end
}
pos_functions = {
params = {
},
func = function(args, data)
local stem = PAGENAME:sub(1, -2)
insert(data.inflections, {label = "present", accel = {form = "pres"}, stem .. "as"})
insert(data.inflections, {label = "past", accel = {form = "past"}, stem .. "is"})
insert(data.inflections, {label = "future", accel = {form = "futr"}, stem .. "os"})
insert(data.inflections, {label = "conditional", accel = {form = "cond"}, stem .. "us"})
insert(data.inflections, {label = "volitive", accel = {form = "voli"}, stem .. "u"})
end
}
pos_functions = {
params = {
= {},
},
func = function(args, data)
if args == "p" or args == "p+" then
insert(data.genders, "p")
data.categories = {"Esperanto nouns", "Esperanto pluralia tantum"}
insert(data.inflections, {label = "accusative", accel = {form = "acc"}, PAGENAME .. "n"})
insert(data.check, PAGENAME .. "n")
if args == "p+" then
local singular = PAGENAME:gsub("j$", "")
insert(data.inflections, {label = "singular", singular})
insert(data.check, singular)
end
end
end
}
pos_functions = {
params = {
= {},
},
func = function(args, data)
data.pos_category = "nouns"
insert(data.categories, 1, "Esperanto pluralia tantum")
insert(data.inflections, {label = "accusative", accel = {form = "acc"}, PAGENAME .. "n"})
insert(data.check, PAGENAME .. "n")
if args == "+" then
local singular = PAGENAME:gsub("j$", "")
insert(data.inflections, {label = "singular", singular})
insert(data.check, singular)
end
end
}
pos_functions = {
params = {
= {}, = {}, --these will be phased out
},
func = function(args, data)
local ending = umatch(PAGENAME, participle_pattern)
if ending then
local vowel, consonant = ending:match("()(j?n?)$")
if consonant == "" then
if vowel == "a" or vowel == "o" then
insert(data.inflections, {label = "accusative singular", accel = {form = ending .. "n"}, PAGENAME .. "n"})
insert(data.inflections, {label = "plural", accel = {form = ending .. "j"}, PAGENAME .. "j"})
insert(data.inflections, {label = "accusative plural", accel = {form = ending .. "jn"}, PAGENAME .. "jn"})
insert(data.check, PAGENAME .. "n")
insert(data.check, PAGENAME .. "j")
insert(data.check, PAGENAME .. "jn")
elseif vowel == "e" then
data.categories = {"Esperanto adverbial participles"}
end
elseif vowel == "e" then
error("-e" .. consonant .. " is not a valid participle ending!")
end
if vowel == "a" then
data.categories = {"Esperanto adjectival participles"}
elseif vowel == "o" then
data.categories = {"Esperanto nominal participles"}
end
else
error("This term is not a participle!")
end
end
}
return export