This module is used for all Ukrainian and Belarusian headword-line templates. It provides a basic functionality common to all of them, but some of the templates have specific additional functionality to show genders or inflected forms.
All Ukrainian and Belarusian headword-line templates use the first parameter to provide the headword, with accented vowels where present. For example:
{{uk-noun|соба́ка|m-anml}}
The parameter supports all the special features that the |head=
parameter on {{head}}
does. So you can also use this parameter to link to individual words of a multi-word term. These words can be linked with accents still in place; the module will remove them from the page name before creating a link, just like {{l}}
does. If you need to specify accents in multiple alternative ways, use |head2=
, |head3=
and so on.
All Ukrainian and Belarusian words that have more than one syllable are expected to have accents specified. The module will check the parameter for the presence of accents, and (in the case of Ukrainian) throw an error if the accents are missing. If you really don't know the stress position, use |unknown_stress=1
to signal this. In this case, words without accents will be placed in a subcategory of Category:Requests for accents in Ukrainian entries or Category:Requests for accents in Belarusian entries.
local export = {}
local lang, langcode, langname
local com
local iut = require("Module:inflection utilities")
local m_links = require("Module:links")
local m_string_utilities = require("Module:string utilities")
local m_table = require("Module:table")
local rfind = mw.ustring.find
local pos_functions = {}
local function track(page)
require("Module:debug").track(langcode .. "-headword/" .. page)
return true
end
local function check_if_accents_needed(list, data)
for _, val in ipairs(list) do
val = m_links.remove_links(val)
if com.needs_accents(val) then
if langcode == "uk" and not data.unknown_stress then
error("Stress must be supplied using an acute accent: '" .. val .. "' (use unknown_stress=1 if stress is truly unknown)")
end
local pos = m_string_utilities.singularize(data.pos_category)
table.insert(data.categories, "Requests for accents in " .. langname .. " " .. pos .. " entries")
end
if com.is_multi_stressed(val) then
error("Multi-stressed form '" .. val .. "' not allowed")
end
end
end
-- The main entry point.
-- This is the only function that can be invoked from a template.
function export.show(frame)
local args = frame:getParent().args
local PAGENAME = mw.loadData("Module:headword/data").pagename
local iparams = {
= {required = true},
= {required = true},
}
local iargs = require("Module:parameters").process(frame.args, iparams)
local poscat = iargs
langcode = iargs.lang
if langcode ~= "uk" and langcode ~= "be" then
error("This module currently only works for lang=uk and lang=be")
end
lang = require("Module:languages").getByCode(langcode)
langname = langcode == "uk" and "Ukrainian" or "Belarusian"
com = langcode == "uk" and require("Module:uk-common") or require("Module:be-common")
local data = {lang = lang, pos_category = poscat, categories = {}, genders = {}, inflections = {}}
local params = {
= {list = "head"},
= {list = true, allow_holes = true},
= {type = "boolean"},
}
if pos_functions then
for key, val in pairs(pos_functions.params) do
params = val
end
end
local parargs = frame:getParent().args
local args = require("Module:parameters").process(parargs, params)
local heads = args
if #heads == 0 then
heads = {PAGENAME}
end
data.heads = heads
data.translits = args.tr
data.unknown_stress = args.unknown_stress
data.frame = frame
if args.unknown_stress then
table.insert(data.inflections, {label = "unknown stress"})
end
if pos_functions and not pos_functions.no_check_head_accents then
check_if_accents_needed(heads, data)
end
if pos_functions then
pos_functions.func(args, data)
end
return require("Module:headword").full_headword(data) .. (data.extra_text or "")
end
local function make_gloss_text(text)
return '<span class="gloss-brac">(</span>' ..
'<span class="gloss-content">' .. text ..
'</span><span class="gloss-brac">)</span>'
end
local function get_noun_pos(is_proper)
return {
params = {
= {alias_of = "g"},
= {list = "gen"},
= {list = "pl"},
= {list = "genpl"},
= {list = true},
= {list = true},
= {list = true},
= {list = true},
= {list = true},
= {list = true},
= {list = true},
= {list = true},
= {list = true},
= {list = true},
= {type = "boolean"},
= {type = "boolean"},
= {},
},
-- set this to avoid problems with cases like {{uk-noun|((ґандж<>,ґандж<F>))}},
-- which will otherwise throw an error
no_check_head_accents = true,
func = function(args, data)
local genitives, plurals, genitive_plurals
if rfind(data.heads, "<") then
local parargs = data.frame:getParent().args
local alternant_spec = require("Module:" .. langcode .. "-noun").do_generate_forms(parargs, nil, true)
args = alternant_spec.args
local footnote_obj
local function get_raw_forms(forms)
local raw_forms = {}
if forms then
for _, form in ipairs(forms) do
local text =
langcode == "uk" and com.remove_monosyllabic_stress(form.form) or
com.remove_monosyllabic_accents(form.form)
if form.footnotes then
if not footnote_obj then
footnote_obj = iut.create_footnote_obj()
end
local footnote_text = iut.get_footnote_text(form.footnotes, footnote_obj)
if rfind(text, "%[%[") then
text = text .. footnote_text
else
text = "]" .. footnote_text
end
end
table.insert(raw_forms, text)
end
end
if #raw_forms == 0 then
raw_forms = {"-"}
end
return raw_forms
end
if alternant_spec.number == "pl" then
data.heads = #args.lemma > 0 and args.lemma or get_raw_forms(alternant_spec.forms.nom_p_linked)
genitives = get_raw_forms(alternant_spec.forms.gen_p)
plurals = {"-"}
genitive_plurals = {"-"}
else
data.heads = #args.lemma > 0 and args.lemma or get_raw_forms(alternant_spec.forms.nom_s_linked)
genitives = get_raw_forms(alternant_spec.forms.gen_s)
if alternant_spec.number == "sg" then
plurals = {"-"}
genitive_plurals = {"-"}
else
plurals = get_raw_forms(alternant_spec.forms.nom_p)
genitive_plurals = get_raw_forms(alternant_spec.forms.gen_p)
end
end
if #args.g > 0 then
data.genders = args.g
else
data.genders = alternant_spec.genders
end
local notes_segments = {}
if footnote_obj then
for _, note in ipairs(footnote_obj.notes) do
table.insert(notes_segments, " " .. make_gloss_text(note))
end
end
data.extra_text = table.concat(notes_segments, "")
else
check_if_accents_needed(data.heads, data)
data.genders = args.g
if #data.genders == 0 then
if mw.title.getCurrentTitle().nsText ~= "Template" then
error("Gender must be specified")
else
table.insert(data.genders, "m-in")
end
end
genitives = args
plurals = args
genitive_plurals = args
if genitives ~= "-" then
-- don't track for indeclinables, which legitimately use the old-style syntax
track(langcode .. "-noun-old-style")
end
end
-- Process the genders
local singular_genders = {}
local plural_genders = {}
local allowed_genders = {"m", "f", "n", "mf", "mfbysense"}
if langcode == "be" or args.unknown_gender then
table.insert(allowed_genders, "?")
end
local allowed_animacies = {"pr", "anml", "in"}
if langcode == "be" or args.unknown_animacy then
table.insert(allowed_animacies, "?")
end
for _, gender in ipairs(allowed_genders) do
for _, animacy in ipairs(allowed_animacies) do
singular_genders = true
plural_genders = true
end
end
if langcode == "be" then
singular_genders = true
plural_genders = true
end
local seen_gender = nil
local seen_animacy = nil
for i, g in ipairs(data.genders) do
if not singular_genders and not plural_genders then
if g:match("%-an%-") or g:match("%-an$") then
error("Invalid animacy 'an'; use 'pr' for people, 'anml' for animals: " .. g)
end
error("Unrecognized gender: " .. g .. " (should be e.g. 'm-pr' for masculine personal, 'f-anml-p' for feminine animal plural, or 'n-in' for neuter inanimate)")
end
data.genders = g
end
-- Add the genitive forms
if genitives == "-" then
table.insert(data.inflections, {label = "]"})
table.insert(data.categories, langname .. " indeclinable nouns")
else
genitives.label = "genitive"
genitives.request = true
check_if_accents_needed(genitives, data)
table.insert(data.inflections, genitives)
end
-- Add the plural forms
-- If the noun is plural only, then ignore the 4th and 5th parameters altogether
if genitives == "-" then
-- do nothing
elseif plural_genders] then
table.insert(data.inflections, {label = "]"})
elseif plurals == "-" then
table.insert(data.inflections, {label = "]"})
table.insert(data.categories, langname .. " uncountable nouns")
else
plurals.label = "nominative plural"
plurals.request = true
check_if_accents_needed(plurals, data)
table.insert(data.inflections, plurals)
if #genitive_plurals > 0 then
-- allow the genitive plural to be unsupplied; formerly there
-- was no genitive plural param
if genitive_plurals == "-" then
-- handle case where there's no genitive plural (e.g. ага́)
table.insert(data.inflections, {label = "no genitive plural"})
else
genitive_plurals.label = "genitive plural"
check_if_accents_needed(genitive_plurals, data)
table.insert(data.inflections, genitive_plurals)
end
end
end
local function handle_infl(arg, label)
local vals = args
if #vals > 0 then
vals.label = label
check_if_accents_needed(vals, data)
table.insert(data.inflections, vals)
end
end
handle_infl("m", "masculine")
handle_infl("f", "feminine")
handle_infl("adj", "relational adjective")
handle_infl("dim", "diminutive")
handle_infl("aug", "augmentative")
handle_infl("pej", "pejorative")
handle_infl("dem", "demonym")
handle_infl("fdem", "female demonym")
data.id = args.id
end
}
end
pos_functions = get_noun_pos(true)
pos_functions = get_noun_pos(false)
pos_functions = {
params = {
= {default = "?"},
= {list = true},
= {list = true},
},
func = function(args, data)
-- Aspect
local aspect = args
if aspect == "both" then
aspect = "biasp"
elseif aspect ~= "pf" and aspect ~= "impf" and aspect ~= "biasp" and aspect ~= "?" then
error("Unrecognized aspect: '" .. aspect .. "'")
end
table.insert(data.genders, aspect)
-- Get the imperfective parameters
local imperfectives = args
-- Get the perfective parameters
local perfectives = args
check_if_accents_needed(imperfectives, data)
check_if_accents_needed(perfectives, data)
-- Add the imperfective forms
if #imperfectives > 0 then
if aspect == "impf" then
error("Can't specify imperfective counterparts for an imperfective verb")
end
imperfectives.label = "imperfective"
table.insert(data.inflections, imperfectives)
end
-- Add the perfective forms
if #perfectives > 0 then
if aspect == "pf" then
error("Can't specify perfective counterparts for a perfective verb")
end
perfectives.label = "perfective"
table.insert(data.inflections, perfectives)
end
end
}
pos_functions = {
params = {
= {list = "comp"},
= {list = "sup"},
= {list = true},
= {list = true},
= {list = true},
= {type = "boolean"},
},
func = function(args, data)
local comps = args
local sups = args
local adverbs = args
local abstract_nouns = args
local diminutives = args
if args.indecl then
table.insert(data.inflections, {label = "indeclinable"})
table.insert(data.categories, langname .. " indeclinable adjectives")
end
if #comps > 0 then
if comps == "-" then
table.insert(data.inflections, {label = "no comparative"})
else
check_if_accents_needed(comps, data)
comps.label = "comparative"
table.insert(data.inflections, comps)
end
end
if #sups > 0 then
check_if_accents_needed(sups, data)
sups.label = "superlative"
table.insert(data.inflections, sups)
end
if #adverbs > 0 then
check_if_accents_needed(adverbs, data)
adverbs.label = "adverb"
table.insert(data.inflections, adverbs)
end
if #abstract_nouns > 0 then
check_if_accents_needed(abstract_nouns, data)
abstract_nouns.label = "abstract noun"
table.insert(data.inflections, abstract_nouns)
end
if #diminutives > 0 then
check_if_accents_needed(diminutives, data)
diminutives.label = "diminutive"
table.insert(data.inflections, diminutives)
end
end
}
pos_functions = {
params = {
= {list = "comp"},
= {list = "sup"},
= {list = true},
},
func = function(args, data)
local comps = args
local sups = args
local diminutives = args
if #comps > 0 then
if comps == "-" then
table.insert(data.inflections, {label = "no comparative"})
else
check_if_accents_needed(comps, data)
comps.label = "comparative"
table.insert(data.inflections, comps)
end
end
if #sups > 0 then
check_if_accents_needed(sups, data)
sups.label = "superlative"
table.insert(data.inflections, sups)
end
if #diminutives > 0 then
check_if_accents_needed(diminutives, data)
diminutives.label = "diminutive"
table.insert(data.inflections, diminutives)
end
end
}
return export