ဝိက်ရှေန်နရဳ
mnwwiktionary
https://mnw.wiktionary.org/wiki/%E1%80%9D%E1%80%AD%E1%80%80%E1%80%BA%E1%80%9B%E1%80%BE%E1%80%B1%E1%80%94%E1%80%BA%E1%80%94%E1%80%9B%E1%80%B3:%E1%80%99%E1%80%AF%E1%80%80%E1%80%BA%E1%80%9C%E1%80%AD%E1%80%80%E1%80%BA%E1%80%90%E1%80%99%E1%80%BA
MediaWiki 1.47.0-wmf.15
case-sensitive
မဳဒဳယာ
တၟေင်
ဓရီုကျာ
ညးလွပ်
ညးလွပ် ဓရီုကျာ
ဝိက်ရှေန်နရဳ
ဝိက်ရှေန်နရဳ ဓရီုကျာ
ဝှာင်
ဝှာင် ဓရီုကျာ
မဳဒဳယာဝဳကဳ
မဳဒဳယာဝဳကဳ ဓရီုကျာ
ထာမ်ပလိက်
ထာမ်ပလိက် ဓရီုကျာ
ရီု
ရီု ဓရီုကျာ
ကဏ္ဍ
ကဏ္ဍ ဓရီုကျာ
အဆက်လက္ကရဴ
အဆက်လက္ကရဴ ဓရီုကျာ
ကာရန်
ကာရန် ဓရီုကျာ
အဘိဓာန်
အဘိဓာန် ဓရီုကျာ
ဗီုပြၚ်သိုၚ်တၟိ
ဗီုပြၚ်သိုၚ်တၟိ ဓရီုကျာ
TimedText
TimedText talk
မဝ်ဂျူ
မဝ်ဂျူ ဓရီုကျာ
Event
Event talk
မဝ်ဂျူ:cs-sk-headword
828
24346
401114
293888
2026-08-13T11:02:03Z
咽頭べさ
33
401114
Scribunto
text/plain
local export = {}
local pos_functions = {}
local force_cat = false -- for testing; if true, categories appear in non-mainspace pages
local rfind = mw.ustring.find
local require_when_needed = require("Module:require when needed")
local m_table = require("Module:table")
local en_utilities_module = "Module:en-utilities"
local headword_utilities_module = "Module:headword utilities"
local m_headword_utilities = require_when_needed(headword_utilities_module)
local m_string_utilities = require_when_needed("Module:string utilities")
local glossary_link = require_when_needed(headword_utilities_module, "glossary_link")
local insert = table.insert
local list_param = {list = true, disallow_holes = true}
-- Table of all valid genders by language, mapping user-specified gender specs to canonicalized versions.
local valid_gender_specs = {}
local valid_genders_with_animacy = {"mfbysense", "mf", "m"}
local valid_genders_without_animacy = {"f", "n", "?"}
local valid_two_way_animacies = {"an", "in"}
local valid_three_way_animacies = {"pr", "anml", "in"}
local valid_number_suffixes = {"", "-p"}
for _, lang in ipairs { "cs", "sk", "zlw-ocs", "zlw-osk" } do
valid_gender_specs[lang] = {}
local dest = valid_gender_specs[lang]
-- The following is correct; Old Czech has three-way animacy.
local animacy_src = lang == "cs" and valid_two_way_animacies or valid_three_way_animacies
for _, gender in ipairs(valid_genders_without_animacy) do
for _, number in ipairs(valid_number_suffixes) do
local spec = gender .. number
dest[spec] = spec
end
end
for _, gender in ipairs(valid_genders_with_animacy) do
for _, number in ipairs(valid_number_suffixes) do
for _, animacy in ipairs(animacy_src) do
local spec = gender .. "-" .. animacy .. number
dest[spec] = spec
end
end
end
end
-- Table of all valid aspects.
local valid_aspects = m_table.listToSet {
"impf", "pf", "both", "biasp", "?",
}
local allowed_sk_decl_patterns = m_table.listToSet {
"chlap", "dievča", "dub", "gazdiná", "hrdina", "kosť", "mesto", "srdce", "stroj", "ulica", "vysvedčenie", "žena",
-- In use but not in the Appendix
"dlaň", "idea", "kuli", "pani",
}
local function track(track_id)
require("Module:debug/track")("cs-sk-headword/" .. track_id)
return true
end
local function replace_hash_with_lemma(term, lemma)
-- If there is a % sign in the lemma, we have to replace it with %% so it doesn't get interpreted as a capture
-- replace expression.
lemma = m_string_utilities.replacement_escape(lemma)
return (term:gsub("#", lemma)) -- discard second retval
end
local function frob_term_with_hash(term, lemma)
if term:find("#") then
term = replace_hash_with_lemma(term, lemma)
end
return term
end
-- Parse and insert an inflection not requiring additional processing into `data.inflections`. The raw arguments come
-- from `args[field]`, which is parsed for inline modifiers. `label` is the label that the inflections are given;
-- sections enclosed in <<...>> are linked to the glossary. `accel` is the accelerator form, or nil.
local function parse_and_insert_inflection(data, args, field, label, accel, frob)
m_headword_utilities.parse_and_insert_inflection {
headdata = data,
forms = args[field],
paramname = field,
splitchar = ",",
label = label,
accel = accel and {form = accel} or nil,
frob = function(term)
term = frob_term_with_hash(term, data.pagename)
if frob then
term = frob(term)
end
return term
end,
}
end
-- Parse and return an inflection not requiring additional processing. The raw arguments come from `args[field]`, which
-- is parsed for inline modifiers.
local function parse_inflection(data, paramname, forms)
return m_headword_utilities.parse_term_list_with_modifiers {
paramname = paramname,
forms = forms,
splitchar = ",",
frob = function(term)
return frob_term_with_hash(term, data.pagename)
end,
}
end
-- Insert the parsed inflections in `terms` (as parsed by `parse_inflection`) into `data.inflections`, with label
-- `label` and optional accelerator spec `accel`.
local function insert_inflection(data, terms, label, accel, no_label)
m_headword_utilities.insert_inflection {
headdata = data,
terms = terms,
label = label,
no_label = no_label,
accel = accel and {form = accel} or nil,
}
end
-- The main entry point.
-- This is the only function that can be invoked from a template.
function export.show(frame)
local iparams = {
[1] = {required = true},
["lang"] = {required = true},
["def"] = {},
}
local iargs = require("Module:parameters").process(frame.args, iparams)
local args = frame:getParent().args
local poscat = iargs[1]
local langcode = iargs.lang
if langcode ~= "cs" and langcode ~= "sk" and langcode ~= "zlw-ocs" and langcode ~= "zlw-osk" then
error("This module currently only works for lang=cs, lang=sk, lang=zlw-ocs and lang=zlw-osk")
end
local lang = require("Module:languages").getByCode(langcode, true)
local langname = lang:getCanonicalName()
local def = iargs.def
local parargs = frame:getParent().args
local params = {
["head"] = list_param,
["id"] = {},
["sort"] = {},
["nolinkhead"] = {type = "boolean"},
["json"] = {type = "boolean"},
["pagename"] = {}, -- for testing
}
if pos_functions[poscat] then
local posparams = pos_functions[poscat].params
if type(posparams) == "function" then
posparams = posparams(lang)
end
for key, val in pairs(posparams) do
params[key] = val
end
end
local args = require("Module:parameters").process(parargs, params)
local pagename = args.pagename or mw.loadData("Module:headword/data").pagename
local data = {
lang = lang,
langname = langname,
pos_category = poscat,
categories = {},
heads = args.head,
genders = {},
inflections = {},
pagename = pagename,
id = args.id,
sort_key = args.sort,
force_cat_output = force_cat,
def = def,
is_suffix = false,
}
if pagename:find("^%-") and poscat ~= "ဗီုပြၚ်အဆက်လက္ကရဴ" then
data.is_suffix = true
data.pos_category = "အဆက်လက္ကရဴ"
-- local singular_poscat = require(en_utilities_module).singularize(poscat)
-- insert(data.categories, langname .. " " .. singular_poscat .. "-forming suffixes")
-- insert(data.inflections, {label = singular_poscat .. "-forming suffix"})
end
if pos_functions[poscat] then
pos_functions[poscat].func(args, data)
end
-- mw.ustring.toNFD performs decomposition, so letters that decompose
-- to an ASCII vowel and a diacritic, such as é, are counted as vowels and
-- do not need to be included in the pattern.
if not pagename:find("[ %-]") and not rfind(mw.ustring.lower(mw.ustring.toNFD(pagename)), "[aeiouyæœø]") then
-- insert(data.categories, langname .. " words spelled without vowels")
end
if args.json then
return require("Module:JSON").toJSON(data)
end
return require("Module:headword").full_headword(data)
end
local function get_noun_params(is_proper)
return function(lang)
params = {
[1] = {type = "genders", required = true, template_default = "?"},
["g"] = {list = true, disallow_holes = true, replaced_by = false,
instead = "use multiple comma-separated genders in |1="},
["g_qual"] = {list = "g\1_qual", allow_holes = true, replaced_by = false,
instead = "use inline modifiers on the gender(s) in |1="},
["indecl"] = {type = "boolean"},
["m"] = list_param,
["f"] = list_param,
["adj"] = list_param,
["pos"] = list_param,
["dim"] = list_param,
["aug"] = list_param,
["pej"] = list_param,
["dem"] = list_param,
["fdem"] = list_param,
["gen"] = list_param,
["pl"] = list_param,
["genpl"] = list_param,
}
if lang:getCode() == "sk" then
params["decl"] = list_param
end
return params
end
end
local function do_nouns(is_proper, args, data)
-- Validate and canonicalize genders.
local specs = valid_gender_specs[data.lang:getCode()]
for _, gspec in ipairs(args[1]) do
local g = gspec.spec
local canon_g = specs[g]
if canon_g then
g = canon_g
elseif g == "m" or g == "m-p" or g == "mf" or g == "mf-p" or g == "mfbysense" or g == "mfbysense-p" then
error("Invalid gender: '" .. g .. "'; must specify animacy along with masculine gender")
elseif data.lang:getCode() == "sk" and g:find("%-an") then
error("Invalid gender: '" .. g .. "'; instead of m-an, use m-pr for people and m-anml for animals")
else
error("Unrecognized gender: '" .. g .. "'")
end
track("gender-" .. g)
gspec.spec = g
insert(data.genders, gspec)
end
if args.indecl then
insert(data.inflections, {label = glossary_link("ပါ်ပါဲထောံဟွံမာန်")})
insert(data.categories, "နာမ်" .. data.langname .. "ပါ်ပါဲထောံဟွံဂွံဂမၠိုၚ်")
end
local decls
if data.lang:getCode() == "sk" then
-- Validate declension patterns and converto to Appendix links
decls = parse_inflection(data, "decl", args.decl)
for _, declobj in ipairs(decls) do
local decl = declobj.term
if not allowed_sk_decl_patterns[decl] then
error("Unrecognized " .. data.langname .. " declension pattern: " .. decl)
end
declobj.term = ("[[Appendix:%sမချူသ္ၜိုန်လဝ်ပရေၚ်လဟုတ်စှ်ေ%s|%s]]"):format(data.langname, decl, decl)
end
end
-- Parse and insert an inflection not requiring additional processing into `data.inflections`. The raw arguments
-- come from `args[field]`, which is parsed for inline modifiers. `label` is the label that the inflections are
-- given, which is linked to the glossary if preceded by * (which is removed).
local function handle_infl(field, label)
parse_and_insert_inflection(data, args, field, label)
end
handle_infl("gen", "<<ဗဳဇဂကူကိုန်ဨကဝုစ်>>")
handle_infl("pl", "<<မဒုၚ်ယၟုကိုန်ဗဟုဝစ်>>")
handle_infl("genpl", "<<ဗဳဇဂကူကိုန်ဗဟုဝစ်>>")
if decls and decls[1] then
decls.label = "မချူသ္ၜိုန်လဝ်ပရေၚ်လဟုတ်စှ်ေဆေၚ်စပ်ကဵု "
insert(data.inflections, decls)
end
handle_infl("m", "မညဳညတ်သၟတ်တးကဵုလိၚ်တြုံ")
handle_infl("f", "မညဳညတ်သၟတ်တးကဵုလိၚ်ဗြဴ")
handle_infl("adj", "<<relational adjective|နာမဝိသေသနဒၞာဲမဆက်စပ်>>")
handle_infl("pos", "<<possessive adjective|နာမဝိသေသနဓမံက်ထ္ၜးမဒှ်တၠဒြပ်>>")
handle_infl("dim", "<<လဟုတ်စှ်ေ>>")
handle_infl("aug", "<<ပရေၚ်မဗပေၚ်တိုန်>>")
handle_infl("pej", "<<စမ်ၜတ်ရံၚ်>>")
handle_infl("dem", "<<အပၠေံရုပ်ရာ>>")
handle_infl("fdem", "<<အပၠေံရုပ်ရာ>>ဣတ္တိလိၚ်")
end
pos_functions["နာမ်"] = {
params = get_noun_params(false),
func = function(args, data)
return do_nouns(false, args, data)
end,
}
pos_functions["နာမ်မကိတ်ညဳ"] = {
params = get_noun_params("နာမ်မကိတ်ညဳ"),
func = function(args, data)
return do_nouns("နာမ်မကိတ်ညဳ", args, data)
end,
}
pos_functions["ကြိယာ"] = {
params = {
["a"] = {default = "?"},
["pf"] = list_param,
["impf"] = list_param,
},
func = function(args, data)
if not valid_aspects[args.a] then
error("Unrecognized aspect: '" .. args.a .. "'")
end
data.genders = args.a == "both" and {"biasp"} or {args.a}
parse_and_insert_inflection(data, args, "pf", "ဗီုပြၚ်မက္ဍိုက်ပေၚ်")
parse_and_insert_inflection(data, args, "impf", "မက္ဍိုက်ပေၚ်")
end,
}
local function do_comparative_superlative(args, data, plpos)
if args[1][1] then
local comps = parse_inflection(data, {1, "comp"}, args[1])
if comps[1] and comps[1].term == "-" then
if comps[2] then
error("Can't specify comparatives along with '-' indicating an uncomparable adjective or adverb")
end
m_headword_utilities.insert_fixed_inflection {
headdata = data,
label = "<<ပတဝ်ပတုပ်ရံၚ်>>ဟွံမာန်",
originating_term = comps[1],
}
insert(data.categories, plpos .. data.langname .. "မဂၠာဲပတုပ်ရံၚ်ဟွံမာန်ဂမၠိုၚ်")
else
local sups = parse_inflection(data, {2, "sup"}, args[2])
if not sups[1] then
for _, comp in ipairs(comps) do
local sup = m_table.shallowCopy(comp)
-- Old Czech has naj-.
sup.term = (data.lang:getCode() == "cs" and "nej" or "naj") .. sup.term
insert(sups, sup)
end
end
insert_inflection(data, comps, "<<ပတဝ်ပတုပ်ရံၚ်>>", "comparative")
insert_inflection(data, sups, "<<သဒ္ဒာ>>", "superlative")
insert(data.categories, plpos .. data.langname .. "ပွမပတဝ်ပတုပ်ရံၚ်ဂမၠိုၚ်")
end
end
end
pos_functions["နာမဝိသေသန"] = {
params = function(lang)
local params = {
[1] = {list = "comp", disallow_holes = true},
[2] = {list = "sup", disallow_holes = true},
["adv"] = list_param,
["indecl"] = {type = "boolean"},
}
if lang:getCode() == "zlw-ocs" then
params.short = list_param
params.shortcomp = list_param
params.shortsup = list_param
end
return params
end,
func = function(args, data)
if args.indecl then
insert(data.inflections, {label = glossary_link("ပါ်ပါဲထောံဟွံမာန်")})
insert(data.categories, "နာမဝိသေသန" .. data.langname .. "မပါ်ပါဲထောံဟွံဂွံဂမၠိုၚ်")
end
parse_and_insert_inflection(data, args, "short", "ဗီုပြၚ်ဓမၠေံ")
do_comparative_superlative(args, data, "နာမဝိသေသန")
if data.lang:getCode() == "zlw-ocs" then
local shortcomps = parse_inflection(data, "shortcomp", args.shortcomp)
local shortsups = parse_inflection(data, "shortsup", args.shortsup)
if shortcomps[1] and not shortsups[1] then
for _, shortcomp in ipairs(shortcomps) do
local shortsup = m_table.shallowCopy(shortcomp)
-- Old Czech has naj-.
shortsup.term = "naj" .. shortsup.term
insert(shortsups, shortsup)
end
end
insert_inflection(data, shortcomps, "<<ပတဝ်ပတုပ်ရံၚ်>>ဓမၠေံ")
insert_inflection(data, shortsups, "<<သဒ္ဒာ>>ဓမၠေံ")
end
parse_and_insert_inflection(data, args, "adv", "ကြိယာဝိသေသန")
end,
}
pos_functions["ကြိယာဝိသေသန"] = {
params = {
[1] = {list = "တုဲဒှ်", disallow_holes = true},
[2] = {list = "ညိည", disallow_holes = true},
},
func = function(args, data)
do_comparative_superlative(args, data, "ကြိယာဝိသေသန")
end,
}
return export
6oongwi5lqsaooutylsdmwmw15i3dtx
ထာမ်ပလိက်:inflection-table-top
10
117454
401105
395065
2026-08-12T17:51:16Z
咽頭べさ
33
အကြောင်းအရာ "<includeonly>{{#invoke:inflection-table|top}}</includeonly><noinclude>{{documentation}}</noinclude>" ဖြင့် အစားထိုးခဲ့သည်
401105
wikitext
text/x-wiki
<includeonly>{{#invoke:inflection-table|top}}</includeonly><noinclude>{{documentation}}</noinclude>
60oviy8evqw0aty75k34bva8anzk38t
ထာမ်ပလိက်:inflection-box-bottom
10
117456
401103
396287
2026-08-12T17:48:22Z
咽頭べさ
33
401103
wikitext
text/x-wiki
{{#invoke:inflection-table|bottom}}<noinclude>{{documentation}}</noinclude>
l62gsdhaogqmws247rqfaxp6kz20yuy
မဝ်ဂျူ:inflection table
828
212425
401099
291990
2026-08-12T17:29:14Z
咽頭べさ
33
401099
Scribunto
text/plain
local export = {}
local M = require("Module:module loader").init({
require = {
parameters = "Module:parameters",
},
loadData = {
headword_data = "Module:headword/data",
},
})
local concat = table.concat
local insert = table.insert
local WRAPPER_CLASS = "inflection-table-wrapper"
local TABLE_CLASS = "inflection-table"
local TITLE_CLASS = "inflection-table-title"
local NO_TITLE_CLASS = "inflection-table-no-title"
local NOTES_CLASS = "inflection-table-notes"
local COLLAPSIBLE_CLASSES = "inflection-table-collapsible inflection-table-collapsed no-vc"
local VS_SWITCHER_CLASS = "vsSwitcher"
local VS_TOGGLE_CLASS = "vsToggleElement"
local BOX_CLASS = "inflection-box"
local BOX_CONTENT_CLASS = "inflection-box-content"
local BOX_NARROW_CLASS = "inflection-table-narrow"
local TR_ALONGSIDE_CLASS = "tr-alongside"
local FLOW_VERTICAL_CLASS = "flow-vertical"
local NO_TITLE_MARKER = "-"
local DEFAULT_PALETTE = "grey"
local DEFAULT_TOGGLE_CATEGORY = "inflection"
local DEFAULT_TITLE_FORMAT = "Inflection of ''%s''"
local VERTICAL_FLOW = "vertical"
local BASE_STYLE = "width: fit-content"
-- Palettes recognized by [[MediaWiki:Gadget-Palette.css]].
local PALETTES = {
red = true,
scarlet = true,
orange = true,
amber = true,
yellow = true,
lime = true,
green = true,
teal = true,
cyan = true,
blue = true,
indigo = true,
purple = true,
magenta = true,
rose = true,
grey = true,
brown = true,
}
local top_params = {
title = true,
tall = true,
class = true,
["min-width"] = true,
palette = true,
category = true,
lang = true,
["vs-category"] = true,
vsToggleElement = true,
}
local bottom_params = {
notes = true,
}
local box_top_params = {
title = true,
flow = true,
category = true,
}
local function nonempty(value)
return value ~= nil and value ~= "" and value or nil
end
-- Builds the opening <div> and the wikitable header. The markup is deliberately
-- unbalanced -- {{inflection-table-bottom}} closes both -- so this is assembled
-- as text rather than through mw.html, which cannot emit an unclosed node.
function export.make_top(args)
local palette = args.palette or DEFAULT_PALETTE
if not PALETTES[palette] then
error(("Unrecognized palette '%s'; see [[MediaWiki:Gadget-Palette.css]] for the recognized palettes.")
:format(palette))
end
local no_title = args.title == NO_TITLE_MARKER
local wrapper_classes = { WRAPPER_CLASS }
if no_title then
insert(wrapper_classes, NO_TITLE_CLASS)
end
if nonempty(args.tall) then
insert(wrapper_classes, COLLAPSIBLE_CLASSES)
end
if nonempty(args.class) then
insert(wrapper_classes, args.class)
end
local style = BASE_STYLE
local min_width = nonempty(args["min-width"])
if min_width then
style = ("%s; min-width: %s"):format(style, min_width)
end
local vs_category = nonempty(args["vs-category"])
local table_classes = { TABLE_CLASS }
if nonempty(args.lang) then
insert(table_classes, ("%s-%s"):format(TABLE_CLASS, args.lang))
end
if vs_category then
insert(table_classes, VS_SWITCHER_CLASS)
end
local lines = {
('<div class="%s" style="%s" data-wikt-palette-p="%s" data-toggle-category="%s">'):format(
concat(wrapper_classes, " "),
style,
palette,
args.category or DEFAULT_TOGGLE_CATEGORY
),
('{| class="%s"%s'):format(
concat(table_classes, " "),
vs_category and (' data-toggle-category="%s"'):format(vs_category) or ""
),
}
if not no_title then
insert(lines, ('|+ class="%s%s" | %s'):format(
TITLE_CLASS,
nonempty(args.vsToggleElement) and " " .. VS_TOGGLE_CLASS or "",
args.title or DEFAULT_TITLE_FORMAT:format(M.headword_data.pagename)
))
insert(lines, "|-")
end
return concat(lines, "\n") .. "\n"
end
-- Builds the opening markup for {{inflection-box-top}}, a wrapper holding
-- several complete inflection tables side by side. Boxes are always collapsible
-- and always place transliterations alongside, so those classes are fixed. No
-- palette is emitted: each table inside the box carries its own.
-- {{inflection-table-bottom}} closes this too.
function export.make_box_top(args)
local classes = {
WRAPPER_CLASS,
BOX_CLASS,
BOX_NARROW_CLASS,
COLLAPSIBLE_CLASSES,
TR_ALONGSIDE_CLASS,
}
if args.flow == VERTICAL_FLOW then
insert(classes, FLOW_VERTICAL_CLASS)
end
return concat({
('<div class="%s" style="%s" data-toggle-category="%s">'):format(
concat(classes, " "),
BASE_STYLE,
args.category or DEFAULT_TOGGLE_CATEGORY
),
('{| class="%s"'):format(BOX_CONTENT_CLASS),
('|+ class="%s" | %s'):format(
TITLE_CLASS,
args.title or DEFAULT_TITLE_FORMAT:format(M.headword_data.pagename)
),
"|-",
"|",
}, "\n") .. "\n"
end
-- Closes the wikitable and the wrapper opened by make_top, with the notes block
-- in between.
function export.make_bottom(args)
local notes = args and nonempty(args.notes)
if not notes then
-- The blank line is what the template emitted; kept so the parser sees
-- byte-identical wikitext.
return "|}\n\n</div>"
end
return ('|}\n<div class="%s">\n%s\n</div>\n</div>'):format(NOTES_CLASS, notes)
end
local function split_args(args)
local top_args, bottom_args = {}, {}
for k, v in pairs(args or {}) do
if bottom_params[k] then
bottom_args[k] = v
else
top_args[k] = v
end
end
return top_args, bottom_args
end
-- Builds a complete table around `contents`.
function export.make_table(args, contents)
local top_args, bottom_args = split_args(args)
return export.make_top(top_args) .. contents .. export.make_bottom(bottom_args)
end
-- As export.make_table, for boxes.
function export.make_box(args, contents)
local top_args, bottom_args = split_args(args)
return export.make_box_top(top_args) .. contents .. export.make_bottom(bottom_args)
end
-- Implementation of {{inflection-table-top}}. Other modules should call
-- make_top directly instead.
function export.top(frame)
local args = M.parameters.process(frame:getParent().args, top_params, nil, "inflection-table", "top")
return export.make_top(args)
end
-- Implementation of {{inflection-table-bottom}}. See the note on export.top.
function export.bottom(frame)
local args = M.parameters.process(frame:getParent().args, bottom_params, nil, "inflection-table", "bottom")
return export.make_bottom(args)
end
-- Implementation of {{inflection-box-top}}. See the note on export.top.
function export.box_top(frame)
local args = M.parameters.process(frame:getParent().args, box_top_params, nil, "inflection-table", "box_top")
return export.make_box_top(args)
end
-- Boxes close exactly like plain tables, so these are aliases rather than
-- separate implementations.
export.make_box_bottom = export.make_bottom
export.box_bottom = export.bottom
return export
6kiz9pqaah1j8t61f7zr7ltwi2gyzul
မဝ်ဂျူ:sk-noun
828
295618
401115
396480
2026-08-13T11:39:28Z
OctraBot
279
401115
Scribunto
text/plain
--[=[
This module contains functions for creating inflection tables for Slovak
nouns.
]=]--
local export = {}
-- Within this module, declensions are the functions that do the actual
-- declension by creating the forms of a basic noun.
-- They are defined further down.
--local lemma = "Bratislava"
local declensions = {}
local lang = require("Module:languages").getByCode("sk")
local m_table = require("Module:table")
local m_links = require("Module:links")
local m_adj = require("Module:sk-adjective")
local m_inflection_table = require("Module:inflection-table")
local allowed_genders = {
"m-pr", "m-anml", "m-in", "f", "n"
}
local allowed_genders_set = m_table.listToSet(allowed_genders)
local hard_consonants = {"d", "t", "n", "l", "h", "ch", "k", "g"}
local soft_consonants = {"ď", "ť", "ň", "ľ", "ž", "š", "č", "dž", "c", "dz", "j"}
local ambiguous_consonants = {"b", "m", "p", "r", "s", "v", "z", "f"}
local hard_consonants_set = m_table.listToSet(hard_consonants)
local soft_consonants_set = m_table.listToSet(soft_consonants)
local ambiguous_consonants_set = m_table.listToSet(ambiguous_consonants)
local consonants = m_table.append(hard_consonants, soft_consonants, ambiguous_consonants)
local consonants_set = m_table.listToSet(consonants)
local short_vowels = {"a", "e", "i", "o", "u", "y", "ä", "ö", "ü"}
local long_vowels = {"á", "é", "í", "ó", "ú", "ý", "ő", "ű"}
local diphthongs = {"ia", "ie", "iu", "ô"}
local short_vowels_set = m_table.listToSet(short_vowels)
local long_vowels_set = m_table.listToSet(long_vowels)
local diphthongs_set = m_table.listToSet(diphthongs)
local vowels = m_table.append(short_vowels, long_vowels)
local vowels_set = m_table.listToSet(vowels)
local obstruents = {"p", "t", "k", "b", "d", "g", "f", "s", "š", "ch", "z", "ž", "č", "dž"} --"v" removed??
local sonorants = {"m", "n", "l", "r", "ʋ", "v"} --"v" added??
local obstruents_set = m_table.listToSet(obstruents)
local sonorants_set = m_table.listToSet(sonorants)
local bigraphs = {"ch", "dz", "dž"}
local bigraphs_set = m_table.listToSet(bigraphs)
local prepositions = {"bez", "bezo", "cez", "cezo", "do", "k", "ku", "medzi",
"na", "nad", "nado", "o", "do", "okrem", "po", "pod", "podo", "pre", "pred",
"predo", "pri", "proti", "naproti", "oproti", "s", "so", "skrz", "u", "v",
"vo", "z", "zo", "za"} -- Add more prepositions as needed
local prepositions_set = m_table.listToSet(prepositions)
local conjunctions = {"a"} -- Add more conjunctions as needed
local conjunctions_set = m_table.listToSet(conjunctions)
-- 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
NAMESPACE = mw.title.getCurrentTitle().nsText
if NAMESPACE == "" then
PAGENAME = mw.loadData("Module:headword/data").pagename
else
if args["pagename"] then
PAGENAME = args["pagename"] -- TEST: lemma
else
error("Pagename not specified")
end
end
GENDER = check_gender(args[1])
NUMBER = args["n"]
TYPE = args["t"]
GEN_ENDING = args["g"]
PLURAL = args["pl"]
PLURAL2 = args["pl2"]
PRONUNCIATION = args["p"]
local genitive = args[2]
local category = ""
-- Check if PAGENAME is a multiword expression
if not mw.ustring.find(PAGENAME, " ") then
-- Single-word expression, handle as usual
PATTERN = determine_pattern(PAGENAME, genitive)
-- Category
if NAMESPACE == "" then
if PATTERN == "indeclinable" then
category = "[[ကဏ္ဍ:နာမ်သလဝ်ဝေန်နဳယျာနကဵုပါ်ပါဲထောံဟွံမာန်ဂမၠိုၚ်|" .. PAGENAME .. "]]"
elseif PATTERN == "irregular" then
category = "[[ကဏ္ဍ:နာမ်ကိုန်ဨကဝုစ်သလဝ်ဝေန်နဳယျာဂမၠိုၚ်|" .. PAGENAME .. "]]"
elseif PATTERN == "adjective" then
category = "[[ကဏ္ဍ:နာမ်မဆေၚ်စပ်ကဵုနာမဝိသေသနသလဝ်ဝေန်နဳယျာဂမၠိုၚ်|" .. PAGENAME .. "]]"
else
category = "[[ကဏ္ဍ:ဝေါဟာသလဝ်ဝေန်နဳယျာမၞုံကဵုဝေါဟာ " .. PATTERN .. " မလဟုတ်စှ်ေဂမၠိုၚ်|" .. PAGENAME .. "]]"
end
if GENDER == "m-anml" then
category = category .. "[[ကဏ္ဍ:ဝေါဟာသလဝ်ဝေန်နဳယျာမၞုံကဵုဝေါဟာ chlap မလဟုတ်စှ်ေဂမၠိုၚ်|" .. PAGENAME .. "]]"
end
if PAGENAME == "cól" then
category = category .. "[[ကဏ္ဍ:ဝေါဟာသလဝ်ဝေန်နဳယျာမၞုံကဵုဝေါဟာ dub မလဟုတ်စှ်ေဂမၠိုၚ်|" .. PAGENAME .. "]]"
end
end
local forms, title
-- Find out if there are more genitive stems and if so, process them
if genitive then
if mw.ustring.find(genitive, "/") then
forms, title = decline_with_more_stems(genitive)
else
forms, title = declensions[PATTERN](PAGENAME, genitive)
normalize_forms(forms)
end
else
forms, title = declensions[PATTERN](PAGENAME, genitive)
normalize_forms(forms)
end
specified_by_user(forms, args)
return make_table(forms, title) .. category
end
-- Multiword expressions
-- Category
if NAMESPACE == "" then
category = "[[ကဏ္ဍ:ဝေါဟာသလဝ်ဝေန်နဳယျာမဂၠိုၚ်ကဵုမအရေဝ်ဂမၠိုၚ်|" .. PAGENAME .. "]]"
end
-- Split into words
local units, gen_units = split_into_units(PAGENAME, genitive)
-- Process each unit to generate forms
local combined_forms = generate_combined_forms(units, gen_units)
-- Add forms specified by the user
specified_by_user(combined_forms, args)
-- Generate the final title and table
local title = "မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု ''" .. PAGENAME .. "'' (multiword term)"
return make_table(combined_forms, title) .. category
end
--[=[
Declension functions
]=]--
declensions["chlap"] = function(word, genitive)
local forms = {}
local syllable_count, syllables = split_into_syllables(word)
local mobile_removed = false -- Tracks if a mobile vowel was removed
local words_with_mobile = {"kmotor", "švagor", "svokor", "lotor",
"obor", "Uhor", "pochábeľ", "väzeň", "učeň",
"posol", "diabol", "blázon", "Turek", "fanúšek", "center",
"hypochonder", "Kafer", "neger", "gangster",
"kapor", "zubor", "bobor", "orol", "pes"
}
local surn_ech_always_declined = {"Čech", "Plech", "Pech", "Štech", "Vojtech"}
-- Determine the stem by removing mobile vowels if applicable
local stem = word
if (matches_any(word, words_with_mobile)
or ends_with_any(word, {"ec", "ček", "íček", "ok"}))
and not (TYPE == "surn"
and (ends_with_any(word, {"[aeiouyáéíóúýäöüőű]ček", "[aeiouyáéíóúýäöüőű]čok"})
or syllable_count == 1))
and not matches_any(word, {"otrok"})
then
stem = remove_mobile_vowel(word)
mobile_removed = true -- Mark mobile vowel as removed
end
-- Adjust specific stems based on predefined mappings
stem = ({["švec"] = "ševc", ["žnec"] = "ženc"})[word] or stem
-- Remove certain endings for words ending with "us", "os", "es" and "o"
if ends_with(word, "[uoea]s") then
stem = mw.ustring.sub(word, 1, -3)
end
if ends_with(word, "o") then
stem = remove_last_char(word)
end
-- Override if a specific argument is given
if genitive and NUMBER ~= "pl" then
stem = remove_last_char(genitive)
if mw.ustring.sub(word, 1, -3) .. get_last_char(word) == remove_last_char(genitive) then
mobile_removed = true
end
end
-- Title for the declension table
local title = "Declension of ''" .. word .. "'' <br>(pattern " .. pattern_link("chlap") .. ")"
if TYPE == "surn" then
if ends_with(word, "a[iy]") then
title = "မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု ''" .. word .. "'' <br>(pattern " .. pattern_link("chlap") .. " or " .. pattern_link("kuli") .. ")"
elseif ends_with_any(word, {"ých", "ech"}) and not matches_any(word, surn_ech_always_declined) then
title = "Declension of ''" .. word .. "'' <br>(pattern " .. pattern_link("chlap") .. " or indeclinable)"
end
end
-- Helper variables for analyzing the last and penultimate characters
local ultimate, penultimate = get_last_letters(stem)
local first = get_first_char(word)
-- Determine alternative dative and locative for some nouns
if matches_any(word, {"človek", "pán", "čert", "diabol", "vlk", "pes",
"Boh", "boh", "otec", "syn", "duch", "Kristus", "don", "šor"})
then
set_forms(forms, {"dat_sg2", "loc_sg2"}, {stem .. "u", stem .. "u"})
end
local nom_pl = "i"
if PLURAL then
if mw.ustring.find(PLURAL, "/") then
local endings = {}
for part in mw.ustring.gmatch(PLURAL, "[^/]+") do
table.insert(endings, part)
end
nom_pl = endings[1]
for i = 2, 4 do
if endings[i] then
set_forms(forms, {"nom_pl" .. i}, {append_ending(stem, endings[i])})
else
break
end
end
else
nom_pl = PLURAL
end
elseif (ends_with_any(word, {"fil", "fób", "graf", "nóm"})
and not matches_any(word, {"xylograf", "typograf"}))
or matches_any(word, {"cynik", "epik", "klasik", "stoik",
"Brit", "Búr", "Gal", "Ír", "Dór", "Italik", "Ión", "Nór",
"cár", "lodivod", "odkundes", "starík", "muž", "svat", "apoštol",
"augur", "bán", "bogomil", "buržuj", "don", "druid", "eféb",
"famulus", "héros", "man", "posol"
})
then
set_forms(forms, {"nom_pl2"}, {append_ending(stem, "ovia")})
elseif (ends_with_any(word, {"[^c]h", "g", "ček", "ek", "ik", "čik", "ok", "o", "duch"}) and word ~= "pes")
or matches_any(word, {"otec", "syn", "ujec", "strýc", "svák", "svokor", "tesť", "švagor",
"zať", "kmotor", "ded", "kmeť", "pobratim", "otčim", "zlosyn", "princ",
"Bask", "Frank", "Ind", "Ink", "Kurd", "Dák", "Čudo", "Fríz", "Azték",
"Asýr", "Etrusk", "Kazach", "Kašub", "odľud", "člen", "zved", "hňup", "cicerone"})
or (ends_with(word, "ch") and TYPE == "loan")
or (ends_with_any(word, {"us", "es"}) and genitive ~= word .. "a")
or matches_any(TYPE, {"comp-deverb", "surn", "name"})
or PLURAL == "ovia"
then
nom_pl = "ovia"
if TYPE == "surn" then
append_second_plural(forms, stem .. "ovci", stem .. "ovcov", stem .. "ovcom",
stem .. "ovcov", stem .. "ovcoch", stem .. "ovcami")
end
elseif ends_with(word, "teľ")
or (ends_with(word, "an") and is_capital(first))
or matches_any(word, {"občan", "dedinčan", "mešťan", "zeman", "ostrovan",
"krajan", "dolňan", "horňan", "južan", "severan", "rodič", "dedič", "brat", "hosť",
"manžel", "exmanžel", "sused", "žid", "Žid", "kresťan", "nekresťan", "pohan"})
then
nom_pl = "ia"
if word == "pohan" then
set_forms(forms, {"nom_pl2"}, {append_ending(stem, "i")})
end
end
-- Determine instrumental plural ending
local ins_pl = "mi" -- Default instrumental plural ending is "mi"
if ultimate == "m"
or mobile_removed
or ends_with_any(word, {"o", "ius"})
or matches_any(word, {"hosť", "tesť", "Kopt"}) --obstruents_set[penultimate] and obstruents_set[ultimate]
then
ins_pl = "ami"
end
-- Populate forms table with singular and plural endings
append_endings(forms, word, stem,
"a", "ovi", "a", "ovi", "om",
nom_pl, append_ending(stem, "ov"), "om", "ov", "och", ins_pl
)
-- Surnames ending with -ých, -ech, -ai, -ay
if TYPE == "surn" then
if ends_with_any(word, {"ých", "ech"}) and not matches_any(word, surn_ech_always_declined) then
append_alternative_singular(forms, word, word, word, word, word)
append_alternative_plural(forms, word, word, word, word, word, word)
elseif ends_with(word, "a[iy]") then
append_alternative_singular(forms, word .. "ho", word .. "mu", word .. "ho", word .. "m", word .. "m")
set_forms(forms, {"ins_pl2"}, {word .. "ami"})
end
end
-- Exceptions
if word == "človek" then
set_forms(forms,
{"nom_pl", "gen_pl", "dat_pl", "acc_pl", "loc_pl", "ins_pl"},
{"ľudia", "ľudí", "ľuďom", "ľudí", "ľuďoch", "ľuďmi"}
)
elseif word == "héros" then
set_forms(forms,
{"gen_sg", "dat_sg", "acc_sg", "loc_sg", "ins_sg",
"nom_pl", "gen_pl", "dat_pl", "acc_pl", "loc_pl", "ins_pl",
"gen_sg2", "dat_sg2", "acc_sg2", "loc_sg2", "ins_sg2",
"nom_pl2", "gen_pl2", "dat_pl2", "acc_pl2", "loc_pl2", "ins_pl2"},
{"hérosa", "hérosovi", "hérosa", "hérosovi", "hérosom",
"hérosi", "hérosov", "hérosom", "hérosov", "hérosoch", "hérosmi",
"héroa", "héroovi", "héroa", "héroovi", "héroom",
"héroovia", "héroov", "héroom", "héroov", "hérooch", "héroami"}
)
end
-- Vocative
if matches_any(word, {"syn", "sváko", "švagor", "kmotor", "brat", "synko",
"synáčik", "pán", "chlapec", "priateľ", "majster", "Boh", "boh", "Pán", "Syn",
"Duch", "Ježiš", "Ježiško", "Kristus", "Spasiteľ", "Vykupiteľ", "Stvoriteľ",
"Premožiteľ", "Kráľ", "Hospodin", "baránok", "Baránok", "tešiteľ", "Tešiteľ",
"hriešnik", "protivník", "kresťan", "otec", "Otec", "chlap", "človek"})
then
voc_stem = stem
if word == "synáčik" then voc_stem = "synáčk" end
if word == "pán" then voc_stem = "pan" end
if word == "Pán" then voc_stem = "Pan" end
if ends_with_any(word, {"teľ", "o"})
or matches_any(word, {"syn", "Syn", "Duch", "Ježiš", "Kráľ",
"hriešnik", "synáčik", "baránok", "Baránok"})
then
set_forms(forms, {"voc_sg"}, {append_ending(voc_stem, "u")})
else
if ends_with_any(voc_stem, {"k", "c"}) then
voc_stem = remove_last_char(voc_stem) .. "č"
elseif ends_with(voc_stem, "h") then
voc_stem = remove_last_char(voc_stem) .. "ž"
end
set_forms(forms, {"voc_sg"}, {append_ending(voc_stem, "e")})
end
if not matches_any(word, {"človek", "pán", "brat"}) then
set_forms(forms, {"voc_sg2"}, {word})
elseif word == "brat" then
set_forms(forms, {"voc_sg2", "voc_sg3"}, {"bratu", "brat"})
end
end
return forms, title -- Return forms table and title for declension
end
declensions["hrdina"] = function(word, genitive)
local forms = {}
local title = "မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု ''" .. word .. "'' <br>(pattern " .. pattern_link("hrdina") .. ")"
local stem = remove_suffix(word, "a")
if ends_with(word, "[oeě]") then
stem = remove_last_char(word)
if ends_with(word, "ě") and ends_with(stem, "[dtnl]") then
stem = soften_last_consonant(stem)
end
end
local nom_pl_ending = "ovia"
if ends_with_any(word, {"ista", "ita"})
or (ends_with(word, "ta") and TYPE == "loan") then
nom_pl_ending = "i"
end
local ins_pl_ending = "ami"
if ends_with(word, "[aeiouyáéíóúýäöüőű]ta") and TYPE == "loan" then
ins_pl_ending = "mi"
end
append_endings(forms, word, stem,
"u", "ovi", "u", "ovi", "om",
nom_pl_ending, stem .. "ov", "om", "ov", "och", ins_pl_ending
)
if TYPE == "surn" then
append_second_plural(forms, stem .. "ovci", stem .. "ovcov", stem .. "ovcom",
stem .. "ovcov", stem .. "ovcoch", stem .. "ovcami")
end
if word == "buržoa" then
set_forms(forms,
{"dat_sg", "loc_sg", "ins_sg",
"nom_pl", "gen_pl", "dat_pl", "acc_pl", "loc_pl"},
{"buržuovi", "buržuovi", "buržuom",
"buržuovia", "buržuov", "buržuom", "buržuov", "buržuoch"}
)
end
return forms, title
end
declensions["kuli"] = function(word, genitive)
local forms = {}
local stem = word
local title = "မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု ''" .. word .. "'' <br>(pattern " .. pattern_link("kuli") .. ")"
append_endings(forms, word, stem,
"ho", "mu", "ho", "m", "m",
"ovia", stem .. "ov", "om", "ov", "och", "ami"
)
if TYPE == "surn" then
append_second_plural(forms, stem .. "ovci", stem .. "ovcov", stem .. "ovcom",
stem .. "ovcov", stem .. "ovcoch", stem .. "ovcami")
end
return forms, title
end
declensions["dub"] = function(word, genitive)
local forms = {}
local mobile_removed = false -- Tracks if a mobile vowel was removed
local words_with_mobile = {"priemysel", "počet", "ocot", "bahor", "chrbát",
"ker", "cukor", "uhor", "vietor", "víchor", "vôdor", "kotol",
"kapor", "zubor", "bobor", "orol", "pes", "mozog", "uhol"}
local syllable_count, syllables = split_into_syllables(word)
-- Determine the stem by removing mobile vowels if applicable
local stem = word
if (matches_any(word, words_with_mobile)
or (ends_with_any(word, {"íček", "ýček", "ok"}) and syllable_count ~= 1))
and not matches_any(word, {"polrok", "nárok", "zákrok", "rozkrok"})
then
stem = remove_mobile_vowel(word)
mobile_removed = true -- Mark mobile vowel as removed
end
-- Adjust specific stems based on predefined mappings
stem = ({["mráz"] = "mraz", ["vietor"] = "vetr", ["kôl"] = "kol",
["stôl"] = "stol", ["vôl"] = "vol", ["chlieb"] = "chleb",
["ensemble"] = "ensembl"})[word] or stem
-- Remove certain endings for words ending with "us", "os", "es" and "o"
if (ends_with(word, "[uoe]s") and TYPE == "loan") or ends_with(word, "izmus") then
stem = mw.ustring.sub(word, 1, -3)
end
if ends_with(word, "o") then
stem = remove_last_char(word)
end
-- Pluralia tantum
if NUMBER == "pl" then
stem = remove_suffix(word, "y")
end
-- Override if a specific argument is given
if genitive and NUMBER ~= "pl" then
stem = remove_last_char(genitive)
if stem == remove_last_char(remove_last_char(word)) .. get_last_char(word) then
mobile_removed = true
elseif stem == word then
mobile_removed = false
end
end
-- Set "mobile_removed" if genitive was set by the user
if ends_with(word, "e[lr]") and ends_with(stem, "[^e][lr]") then
mobile_removed = true
end
-- Title for the declension table
local title = "မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု ''" .. word .. "'' <br>(pattern " .. pattern_link("dub") .. ")"
if GENDER == "m-anml" then
if matches_any(word, {"vták", "vlk", "pes"}) then
title = "မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု ''" .. word .. "'' <br>(patterns " .. pattern_link("chlap") .. " <small>(singular, plural 1)</small> and " .. pattern_link("dub") .. " <small>(plural 2)</small>)"
elseif PLURAL2 then
title = "မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု ''" .. word .. "'' <br>(patterns " .. pattern_link("chlap") .. " <small>(singular, plural 2)</small> and " .. pattern_link("dub") .. " <small>(plural 1)</small>)"
else
title = "မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု ''" .. word .. "'' <br>(patterns " .. pattern_link("chlap") .. " <small>(singular)</small> and " .. pattern_link("dub") .. " <small>(plural)</small>)"
end
end
-- Helper variables for analyzing the last and penultimate characters
local ultimate, penultimate = get_last_letters(stem)
local first = get_first_char(word)
-- Determine genitive singular ending
local gen_sg = "a"
if (matches_any(TYPE, {"abstr", "comp-deverb", "material", "collect", "loan"})
or matches_any(GEN_ENDING, {"u", "u/a"})
or ends_with_any(word, {"izmus", "x"})
or (ends_with(word, "m") and not is_capital(first))
or (ends_with(word, "z") and is_capital(first)))
and not matches_any(GEN_ENDING, {"a", "a/u"})
then
gen_sg = "u"
end
-- Override genitive singular ending if a specific argument is given
if genitive then
gen_sg = get_last_char(genitive)
end
-- Determine locative singular ending based on specific suffixes and patterns
local loc_sg = "e"
if ends_with_any(word, {"k", "g", "h", "ch"}) or (ends_with(word, "i[ue]s") and TYPE == "loan") then
loc_sg = "u"
elseif (ends_with(word, "ér")
or (ends_with(word, "ál") and not matches_any(word, {"bál", "paškál", "paušál", "šál", "škandál", "žurnál"}))
or matches_any(word, {"Alžír", "klavír", "apríl", "jún", "júl"}))
then
loc_sg = "i"
end
-- Determine genitive plural ending
local gen_pl = stem .. "ov" -- Default genitive plural ending is "ov"
-- Adjust genitive plural for specific place names and patterns
if is_capital(first) and (ends_with_any(word, {"any", "íky", "áky", "iaky"})
or matches_any(word, {"Krompachy", "Kubachy", "Veľbachy", "Spišské Vlachy",
"Žabokreky", "Čechy", "Brezolupy", "Bruty", "Rakoľuby",
"Rakúsy", "Prusy", "Veľaty", "Piešťany", "Bieščary"}))
then
local gen_stem = remove_last_char(word) -- Remove last character to get the base stem
local syllable_count, syllables = split_into_syllables(gen_stem)
local last_syllable = syllables[1]
local penultimate_syllable = syllables[2] or ""
-- Lengthen the vowel if the penultimate syllable is short, otherwise use unchanged stem
if is_long(penultimate_syllable) then
gen_pl = gen_stem
else
gen_pl = remove_suffix(gen_stem, last_syllable) .. lengthen_vowel(last_syllable)
end
end
-- Special cases for genitive plural of specific words
if word == "čas" then
gen_pl = "čias"
elseif word == "raz" then
gen_pl = "ráz"
end
-- Determine instrumental plural ending
local ins_pl = "mi" -- Default instrumental plural ending is "mi"
if ultimate == "m"
or mobile_removed
or ends_with_any(word, {"o", "ius", "eus"})
or (penultimate == "m" and consonants_set[ultimate])
then
ins_pl = "ami"
end
-- Doublets for instrumental plural
if matches_any(word, {"schod", "schody", "fúz", "fúzy", "roh", "rohy",
"paroh", "parohy", "čary", "orech"})
then
set_forms(forms, {"ins_pl2"}, {stem .. "ami"})
elseif matches_any(word, {"zub", "dol", "most", "prst", "piest", "necht"}) then
ins_pl = "ami"
set_forms(forms, {"ins_pl2"}, {stem .. "mi"})
end
-- Populate forms table with singular and plural endings
append_endings(forms, word, stem,
gen_sg, "u", nil, loc_sg, "om",
"y", gen_pl, "om", nil, "och", ins_pl
)
-- Alternative genitive ending
if GEN_ENDING == "a/u" then
set_forms(forms, {"gen_sg2"}, {stem .. "u"})
elseif GEN_ENDING == "u/a" then
set_forms(forms, {"gen_sg2"}, {stem .. "a"})
end
-- Exceptions
if matches_any(word, {"sen", "dol"}) then
set_forms(forms, {"loc_pl2"}, {stem .. "ách"})
elseif word == "čas" then
set_forms(forms, {"gen_pl2"}, {"časov"})
end
-- Animal nouns
if GENDER == "m-anml" then
append_animal_singular(forms, stem)
if matches_any(word, {"vták", "vlk", "pes"}) or PLURAL2 then
local forms2, title2 = declensions["chlap"](word, stem .. gen_sg)
append_second_plural(forms, forms2["nom_pl"], forms2["gen_pl"], forms2["dat_pl"],
forms2["acc_pl"], forms2["loc_pl"], forms2["ins_pl"])
if matches_any(word, {"vták", "vlk", "pes"}) then
switch_plural_forms(forms) --changes the prefered forms
-- Determine alternative dative and locative for some nouns
if matches_any(word, {"vlk", "pes"}) then
set_forms(forms, {"dat_sg2", "loc_sg2"}, {stem .. "u", stem .. "u"})
end
end
end
end
return forms, title -- Return forms table and title for declension
end
declensions["stroj"] = function(word, genitive)
local forms = {}
local mobile_removed = false -- Tracks if a mobile vowel was removed
local words_with_no_mobile = {"kúpeľ", "červeň", "kameň", "jačmeň", "koreň",
"prameň", "prsteň", "jeleň"}
local first = get_first_char(word)
-- Determine the stem by removing mobile vowels if applicable
local stem = word
if (ends_with_any(word, {"ec", "iec", "[^ti]eľ", "oľ", "[^i]eň", "eť", "[^i]er", "el"})
or (ends_with(word, "ac") and (is_capital(first) or word == "desaterac")))
and not matches_any(word, words_with_no_mobile)
then
stem = remove_mobile_vowel(word)
mobile_removed = true -- Mark mobile vowel as removed
end
-- Adjust specific stems based on predefined mappings
stem = ({["dážď"] = "dažď", ["kôš"] = "koš", ["nôž"] = "nož",
["kôň"] = "koň", ["timbre"] = "timbr"})[word] or stem
-- Pluralia tantum
if NUMBER == "pl" then
stem = remove_suffix(word, "e")
end
-- Override if a specific argument is given
if genitive and NUMBER ~= "pl" then
stem = remove_last_char(genitive)
if stem == remove_last_char(remove_last_char(word)) .. get_last_char(word) then
mobile_removed = true
elseif stem == word then
mobile_removed = false
end
end
-- Set "mobile_removed" if genitive was set by the user
if ends_with(word, "e[lr]") and ends_with(stem, "[^e][lr]") then
mobile_removed = true
end
-- Title for the declension table
local title = "မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု ''" .. word .. "'' <br>(pattern " .. pattern_link("stroj") .. ")"
if GENDER == "m-anml" then
if PLURAL2 then
title = "မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု ''" .. word .. "'' <br>(patterns " .. pattern_link("chlap") .. " <small>(singular, plural 2)</small> and " .. pattern_link("stroj") .. " <small>(plural 1)</small>)"
else
title = "မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု ''" .. word .. "'' <br>(patterns " .. pattern_link("chlap") .. " <small>(singular)</small> and " .. pattern_link("stroj") .. " <small>(plural)</small>)"
end
elseif word == "cól" then
title = "မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု ''" .. word .. "'' <br>(pattern " .. pattern_link("stroj") .. " or " .. pattern_link("dub") .. ")"
end
-- Helper variables for analyzing the last and penultimate characters
local ultimate, penultimate = get_last_letters(stem)
local first = get_first_char(word)
-- Determine genitive singular ending
local gen_sg = "a"
if ((matches_any(TYPE, {"abstr", "material"})
or matches_any(GEN_ENDING, {"u", "u/a"}))
and not matches_any(word, {"jačmeň", "kameň", "olej", "loj", "vývoj", "rozvoj"}))
and not matches_any(GEN_ENDING, {"a", "a/u"})
then
gen_sg = "u"
end
-- Override genitive singular ending if a specific argument is given
if genitive then
gen_sg = get_last_char(genitive)
end
-- Determine genitive plural ending
local gen_pl = stem .. "ov" -- Default genitive plural ending is "ov"
-- Adjust genitive plural for specific place names and patterns
if is_capital(first) and (ends_with_any(word, {"áre", "iare"})
or word == "Tlmače")
then
local gen_stem = remove_last_char(word) -- Remove last character to get the base stem
local syllable_count, syllables = split_into_syllables(gen_stem)
local last_syllable = syllables[1]
local penultimate_syllable = syllables[2] or ""
-- Lengthen the vowel if the penultimate syllable is short, otherwise use unchanged stem
if is_long(penultimate_syllable) then
gen_pl = gen_stem
else
gen_pl = remove_suffix(gen_stem, last_syllable) .. lengthen_vowel(last_syllable)
end
end
-- Special cases for genitive plural of specific words
if word == "Ladce" then
gen_pl = "Ladiec"
elseif word == "Vráble" then
gen_pl = "Vrábeľ"
elseif word == "peniaze" then
gen_pl = "peňazí"
elseif matches_any(word, {"deň", "kôň", "groš"}) then
gen_pl = append_ending(stem, "í")
end
-- Determine instrumental plural ending
local ins_pl = "mi" -- Default instrumental plural ending is "mi"
if mobile_removed
or (obstruents_set[penultimate] and obstruents_set[ultimate])
then
ins_pl = "ami"
end
-- Populate forms table with singular and plural endings
append_endings(forms, word, stem,
gen_sg, "u", nil, "i", "om",
"e", gen_pl, "om", nil, "och", ins_pl
)
-- Alternative genitive ending
if GEN_ENDING == "a/u" then
set_forms(forms, {"gen_sg2"}, {stem .. "u"})
elseif GEN_ENDING == "u/a" then
set_forms(forms, {"gen_sg2"}, {stem .. "a"})
end
-- Exceptions
if matches_any(word, {"deň", "poldeň"}) then
set_forms(forms,
{"nom_pl", "acc_pl", "loc_sg2"},
{append_ending(stem, "i"), append_ending(stem, "i"), append_ending(stem, "e")}
)
elseif word == "ďateľ" then
set_forms(forms,
{"gen_sg2", "dat_sg2", "loc_sg2", "ins_sg2",
"nom_pl2", "gen_pl2", "dat_pl2", "acc_pl2", "loc_pl2", "ins_pl2"},
{"ďatľa", "ďatľovi", "ďatľovi", "ďatľom",
"ďatle", "ďatľov", "ďatľom", "ďatle", "ďatľoch", "ďatľami"}
)
elseif word == "cól" then
set_forms(forms,
{"loc_sg2", "nom_pl2", "acc_pl2"},
{"cóle", "cóly", "cóly"}
)
end
-- Animal nouns
if GENDER == "m-anml" then
append_animal_singular(forms, stem)
if PLURAL2 then
local forms2, title2 = declensions["chlap"](word, stem .. gen_sg)
append_second_plural(forms, forms2["nom_pl"], forms2["gen_pl"], forms2["dat_pl"],
forms2["acc_pl"], forms2["loc_pl"], forms2["ins_pl"])
end
end
return forms, title -- Return forms table and title for declension
end
declensions["žena"] = function(word, genitive)
local forms = {}
local stem = remove_suffix(word, "a")
local title = "မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု ''" .. word .. "'' <br>(pattern " .. pattern_link("žena") .. ")"
if ends_with(word, "ea") then
title = "မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု ''" .. word .. "'' <br>(pattern " .. pattern_link("žena") .. ", loanword ending with ''-ea'')"
end
-- Pluralia tantum or genitive
if NUMBER == "pl" then
stem = remove_suffix(word, "y")
end
if genitive and NUMBER ~= "pl" then
stem = remove_suffix(genitive, "y")
end
-- Split into syllables
local gen_pl = ""
local syllable_count, syllables = split_into_syllables(stem)
local word_syllable_count, word_syllables = split_into_syllables(word)
-- Get the last and second-to-last syllables for rule checks
local last_syllable = syllables[1]
local penultimate_syllable = syllables[2] or ""
local word_penultimate_syllable = word_syllables[2] or ""
local ultimate, penultimate = get_last_letters(stem)
-- 1. Add a vowel between the last two consonants of a cluster at the end of the stem
if ends_with_consonant_cluster(last_syllable) or word_syllable_count == 1 then
if (ultimate == "k" and not matches_any(word, {"banka"}))
or (ultimate == "b" and (TYPE == "der" or not sonorants_set[penultimate]))
or sonorants_set[ultimate]
or matches_any(word, {"farba", "karta", "buchta", "astma"})
or (obstruents_set[penultimate] and ultimate == "v")
then
if penultimate ~= "j" and (word_syllable_count == 1 or is_short(word_penultimate_syllable)) then
gen_pl = harden_last_consonant(remove_suffix(stem, ultimate)) .. "ie" .. ultimate
if matches_any(word, {"handra", "perla", "metla", "slivka",
"tehla", "vidly", "karta", "kvapka", "stovka", "doska"})
then
gen_pl = remove_suffix(stem, ultimate) .. "á" .. ultimate
set_forms(forms, {"gen_pl2"}, {harden_last_consonant(remove_suffix(stem, ultimate)) .. "ie" .. ultimate})
end
if matches_any(word, {"jamka", "kvapka"}) then
set_forms(forms, {"gen_pl2"}, {remove_suffix(stem, ultimate) .. "ô" .. ultimate})
end
if matches_any(word, {"astma"}) then
set_forms(forms, {"gen_pl2"}, {stem .. "í"})
end
elseif obstruents_set[ultimate] and (is_long(word_penultimate_syllable) or penultimate == "j") then
gen_pl = remove_suffix(stem, ultimate) .. "o" .. ultimate
elseif (sonorants_set[ultimate] or ultimate == "v") and (is_long(word_penultimate_syllable) or penultimate == "j") then
gen_pl = remove_suffix(stem, ultimate) .. "e" .. ultimate
if penultimate ~= "j" then
set_forms(forms, {"gen_pl2"}, {remove_suffix(stem, ultimate) .. "ie" .. ultimate})
end
end
end
end
-- 2. Add "í" if stem ends with a vowel or a soft consonant
if gen_pl == "" and (vowels_set[ultimate]
or matches_any(word, {"medaila", "pera", "kanva", "panva", "skepsa", "nuansa"}))
then
gen_pl = stem .. "í"
if matches_any(word, {"nuansa"}) then
set_forms(forms, {"gen_pl2"}, {remove_suffix(stem, last_syllable) .. lengthen_vowel(last_syllable)})
end
end
-- 3. Return the stem with no change if conditions match
if gen_pl == "" and (is_long(penultimate_syllable)
or ends_with_any(stem, {"tvor", "ov"})
or mw.ustring.match(last_syllable, "[Jj][eo]")
or (TYPE == "loan" and matches_any(get_vowel(last_syllable), {"e", "o"}))) then
gen_pl = stem
end
-- 4. Logic to use the lengthened vowel if conditions match
if gen_pl == "" and (not (ends_with_consonant_cluster(last_syllable) or vowels_set[ultimate])
or (ends_with_consonant_cluster(last_syllable) and sonorants_set[penultimate] and obstruents_set[ultimate])
or (ends_with_consonant_cluster(last_syllable) and matches_any(penultimate, {"c", "s", "z", "š", "ž", "p"}) and matches_any(ultimate, {"t", "d"})))
and not matches_any(word, {"šachta", "mzda"}) then
gen_pl = remove_suffix(stem, last_syllable) .. lengthen_vowel(last_syllable)
if mw.ustring.find(stem, "au[bcčdďfghjklľmnňpqrsštťvwxzž]$") then
gen_pl = remove_suffix(stem, "a" .. last_syllable) .. "á" .. last_syllable
end
end
-- 5. long -á- instead of -ia- for some loanwords
if matches_any(word, {"pyžama", "šachta"}) then
gen_pl = (word == "pyžama") and "pyžám" or "šácht"
if word == "šachta" then
set_forms(forms, {"gen_pl2"}, {"šachiet"})
end
end
-- 6. Exceptions
if word == "mzda" then
gen_pl = "miezd"
end
if gen_pl == "" then gen_pl = stem end
local dat_pl, loc_pl
if is_long(word_penultimate_syllable) then
dat_pl, loc_pl = "am", "ach"
else
dat_pl, loc_pl = "ám", "ách"
end
local dat_sg, loc_sg
if ultimate == "e" then
dat_sg, loc_sg = "i", "i"
else
dat_sg, loc_sg = "e", "e"
end
append_endings(forms, word, stem,
"y", dat_sg, "u", loc_sg, "ou",
"y", gen_pl, dat_pl, nil, loc_pl, "ami"
)
if matches_any(word, {"zora", "žiara", "žiabra"}) then
set_forms(forms,
{"nom_pl", "acc_pl"},
{stem .. "e", stem .. "e"}
)
end
return forms, title
end
declensions["gazdiná"] = function(word, genitive)
local forms = {}
local stem = remove_suffix(word, "á")
local title = "မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု ''" .. word .. "'' <br>(pattern " .. pattern_link("gazdiná") .. ")"
local syllable_count, syllables = split_into_syllables(stem)
local last_syllable = syllables[1]
local gen_pl = ""
if ends_with_consonant_cluster(last_syllable) then
gen_pl = mw.ustring.sub(stem, 1, -2) .. "ien"
else
gen_pl = remove_suffix(stem, last_syllable) .. lengthen_vowel(last_syllable)
end
append_endings(forms, word, stem,
"ej", "ej", "ú", "ej", "ou",
"é", gen_pl, "ám", nil, "ách", "ami"
)
return forms, title
end
declensions["ulica"] = function(word, genitive)
local forms = {}
local stem = remove_suffix(word, "a")
local title = "မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု ''" .. word .. "'' <br>(pattern " .. pattern_link("ulica") .. ")"
-- Pluralia tantum
if NUMBER == "pl" then
stem = remove_suffix(word, "e")
if ends_with_any(stem, {"d", "t", "n", "l"}) then
stem = soften_last_consonant(stem)
end
end
-- Split into syllables
local gen_pl = ""
local syllable_count, syllables = split_into_syllables(stem)
local word_syllable_count, word_syllables = split_into_syllables(word)
-- Get the last and second-to-last syllables for rule checks
local last_syllable = syllables[1]
local penultimate_syllable = syllables[2] or ""
local word_penultimate_syllable = word_syllables[2] or ""
local ultimate, penultimate = get_last_letters(stem)
local first = get_first_char(word)
-- 1. Add a vowel between the last two consonants of a cluster at the end of the stem
if ends_with_consonant_cluster(last_syllable) then
if (is_capital(first) and ends_with(word, "ce"))
or matches_any(word, {"dverce", "ovca", "fakľa", "drumbľa", "husle", "jasle",
"kachle", "hrable", "šabľa", "mašľa", "žemľa", "ríbezľa", "čerešňa", "sukňa", "višňa"})
then
gen_pl = harden_last_consonant(remove_suffix(stem, ultimate)) .. "ie" .. ultimate
if matches_any(word, {"drumbľa", "husle", "jasle", "kachle", "hrable",
"šabľa", "mašľa", "žemľa", "ríbezľa", "čerešňa", "sukňa", "višňa"}) then
set_forms(forms, {"gen_pl2"}, {append_ending(stem, "í")})
end
end
end
-- 2. Add "í" if stem ends with a vowel or a soft consonant
if gen_pl == "" and (matches_any(ultimate, {"dz", "dž", "ž", "ť", "ď", "j", "i", "y"})
or ends_with_any(word, {"nca", "oľa", "ôľa", "aľa", "ša", "ča"})
or matches_any(word, {"liace", "pasca", "páľa", "trúbeľa", "mrľa", "konope", "večera", "rozopra"})
or (matches_any(ultimate, {"ľ"}) and consonants_set[penultimate])
or (matches_any(ultimate, {"ň"}) and penultimate ~= "y"))
and not matches_any(word, {"papuča", "priča", "hrča", "paprča",
"garniža", "fakľa", "skriňa", "sviňa", "abatiša", "čaša", "fľaša",
"Krkonoše", "ríša", "skrýša"})
then
gen_pl = append_ending(stem, "í")
end
-- 3. Logic to use the lengthened vowel if conditions match
if gen_pl == "" and not ends_with_consonant_cluster(last_syllable) and not vowels_set[ultimate]
and ((ends_with(word, "ca") and TYPE ~= "der")
or ends_with_any(word, {"yňa", "uľa"})
or matches_any(word, {"papuča", "priča", "hrča", "chvíľa", "míľa", "košeľa", "nedeľa",
"guľa", "hoľa", "homoľa", "skriňa", "sviňa", "abatiša", "čaša", "fľaša",
"Krkonoše", "ríša", "skrýša", "garniža", "Hybe", "dvere", "kuša", "moruša"}))
then
if is_long(penultimate_syllable) then
gen_pl = stem
else
gen_pl = remove_suffix(stem, last_syllable) .. lengthen_vowel(last_syllable)
if matches_any(word, {"homoľa", "kuša", "moruša", "hrča", "paprča",
"guľa", "hoľa"})
then
set_forms(forms, {"gen_pl2"}, {append_ending(stem, "í")})
end
end
end
if gen_pl == "" then gen_pl = stem end
local dat_pl, loc_pl
if ends_with_any(stem, {"i", "y"}) or word == "pizza" then
dat_pl, loc_pl = "ám", "ách"
elseif is_long(word_penultimate_syllable) or ends_with(stem, "j") then
dat_pl, loc_pl = "am", "ach"
else
dat_pl, loc_pl = "iam", "iach"
end
append_endings(forms, word, stem,
"e", "i", "u", "i", "ou",
"e", gen_pl, dat_pl, nil, loc_pl, "ami"
)
if word == "rozopra" then
set_forms(forms,
{"dat_pl2", "loc_pl2"},
{"rozoprám", "rozoprách"}
)
elseif word == "dvere" then
set_forms(forms,
{"dat_pl", "loc_pl", "gen_pl2", "ins_pl2"},
{"dverám", "dverách", "dverí", "dvermi"}
)
end
return forms, title
end
declensions["irregular"] = function(word, genitive)
local forms = {}
local title = "မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု ''" .. word .. "'' (irregular)"
if matches_any(word, {"mať", "mater", "mati"}) then
local stem = "mater"
append_endings(forms, word, stem,
"e", "i", "", "i", "ou",
"e", stem .. "í", "iam", "e", "iach", "ami"
)
local accusative = (word == "mater") and {"mater", "mať"} or {"mať", "mater"}
set_forms(forms, {"acc_sg", "acc_sg2"}, accusative)
elseif ends_with(word, "pani") then
local stem = remove_suffix(word, "ni") .. "ň"
append_endings(forms, word, stem,
"ej", "ej", "iu", "ej", "ou",
"ie", stem .. "í", "iam", nil, "iach", "iami"
)
end
return forms, title
end
declensions["dlaň"] = function(word, genitive)
local forms = {}
local words_with_mobile_vowel = {"faloš", "osuheľ", "siheľ", "myseľ"}
local stem
if genitive then
stem = remove_suffix(genitive, "e")
elseif matches_any(word, words_with_mobile_vowel) or ends_with(word, "eň") then
stem = remove_mobile_vowel(word)
else
stem = word
end
local title = "မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု ''" .. word .. "'' <br>(pattern " .. pattern_link("dlaň") .. ")"
local syllable_count, syllables = split_into_syllables(word)
local last_syllable = syllables[1]
local penultimate_syllable = syllables[2] or ""
local last_char = get_last_char(word)
local dat_pl, loc_pl
if is_long(penultimate_syllable) or last_char == "j" then
dat_pl, loc_pl = "am", "ach"
elseif word == "kader" then
dat_pl, loc_pl = "ám", "ách"
else
dat_pl, loc_pl = "iam", "iach"
end
append_endings(forms, word, stem,
"e", "i", nil, "i", "ou",
"e", append_ending(stem, "í"), dat_pl, nil, loc_pl, "ami"
)
if matches_any(word, {"myseľ", "tvár", "hneď", "raž"}) then
set_forms(forms, {"gen_sg2"}, {append_ending(stem, "i")})
end
return forms, title
end
declensions["kosť"] = function(word, genitive)
local forms = {}
local words_with_mobile_vowel = {"voš", "lož", "Ves", "ves", "cirkev", "reďkev"}
local stem = (matches_any(word, words_with_mobile_vowel))
and remove_mobile_vowel(word) or word
if word == "česť" then stem = "cť" end
local title = "မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု ''" .. word .. "'' <br>(pattern " .. pattern_link("kosť") .. ")"
append_endings(forms, word, stem,
"i", "i", nil, "i", "ou",
"i", append_ending(stem, "í"), "iam", nil, "iach", "ami"
)
if word == "hrsť" then
set_forms(forms,
{"nom_pl", "acc_pl"},
{"hrste", "hrste"}
)
elseif word == "lesť" then
append_alternative_singular(forms, "ľsti", "ľsti", nil, "ľsti", "ľsťou")
append_alternative_plural(forms, "ľsti", "ľstí", "ľstiam", nil, "ľstiach", "ľsťami")
elseif matches_any(word, {"cirkev", "reďkev"}) then
set_forms(forms,
{"dat_pl", "loc_pl"},
{stem .. "ám", stem .. "ách"}
)
end
return forms, title
end
declensions["mesto"] = function(word, genitive)
local forms = {}
local ultimate, penultimate = get_last_letters(word)
local special_type = ""
local stem = remove_suffix(word, "o")
if penultimate == "u" and ultimate == "m" then
stem = remove_suffix(word, "um")
special_type = ", of Latin origin ending with ''-um''"
elseif penultimate == "o" and ultimate == "n" then
stem = remove_suffix(word, "on")
special_type = ", of Greek origin ending with ''-on''"
elseif penultimate == "m" and ultimate == "ä" then
stem = remove_suffix(word, "ä") .. "en"
special_type = ", archaic type ending with ''-mä''"
end
-- Pluralia tantum
if NUMBER == "pl" then
stem = remove_suffix(word, ultimate)
end
local title = "မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု ''" .. word .. "'' <br>(pattern " .. pattern_link("mesto") .. special_type .. ")"
local stem_ultimate, stem_penultimate = get_last_letters(stem)
local loc_sg = "e"
if vowels_set[stem_ultimate] or matches_any(stem_ultimate, {"k", "g", "ch", "h"}) then
loc_sg = "u"
elseif matches_any(word, {"vnútro", "nebo"}) then
loc_sg = "i"
end
-- Split into syllables
local gen_pl = ""
local syllable_count, syllables = split_into_syllables(stem)
local word_syllable_count, word_syllables = split_into_syllables(word)
-- Get the last and second-to-last syllables for rule checks
local last_syllable = syllables[1]
local penultimate_syllable = syllables[2] or ""
local word_penultimate_syllable = word_syllables[2] or ""
-- 1. Add a vowel between the last two consonants of a cluster at the end of the stem
if ends_with_consonant_cluster(last_syllable) then
if matches_any(word, {"jedlo", "predjedlo", "jutro", "vrecko", "brvno"}) then
if matches_any(word, {"jedlo", "predjedlo", "jutro"}) then
gen_pl = remove_suffix(stem, stem_ultimate) .. "á" .. stem_ultimate
else
gen_pl = remove_suffix(stem, stem_ultimate) .. "ie" .. stem_ultimate
set_forms(forms, {"gen_pl2"}, {remove_suffix(stem, stem_ultimate) .. "á" .. stem_ultimate})
end
elseif sonorants_set[stem_ultimate] or ends_with_any(last_syllable, {"stv", "ctv", "íčk", "ečk", "očk"}) or TYPE == "dim" then
if stem_penultimate ~= "j" and (word_syllable_count == 1 or ends_with_any(last_syllable, {"stv", "ctv"}) or is_short(word_penultimate_syllable)) then
gen_pl = remove_suffix(stem, stem_ultimate) .. "ie" .. stem_ultimate
elseif obstruents_set[stem_ultimate] and (is_long(word_penultimate_syllable) or stem_penultimate == "j") then
gen_pl = remove_suffix(stem, stem_ultimate) .. "o" .. stem_ultimate
elseif sonorants_set[stem_ultimate] and (is_long(word_penultimate_syllable) or stem_penultimate == "j") then
gen_pl = remove_suffix(stem, stem_ultimate) .. "e" .. stem_ultimate
if stem_penultimate ~= "j" then
set_forms(forms, {"gen_pl2"}, {remove_suffix(stem, stem_ultimate) .. "ie" .. stem_ultimate})
end
end
end
end
-- 2. Add "í" if stem ends with a vowel or a soft consonant
if gen_pl == "" and (vowels_set[stem_ultimate] or soft_consonants_set[stem_ultimate]) then
gen_pl = stem .. "í"
end
-- 3. Return the stem with no change if conditions match
if gen_pl == "" and (is_long(penultimate_syllable)
or ends_with_any(stem, {"vojsk", "ov"})
or (TYPE == "loan" and matches_any(get_vowel(last_syllable), {"e", "o"}))) then
gen_pl = stem
end
-- 4. Logic to use the lengthened vowel if conditions match
if gen_pl == "" and (not (ends_with_consonant_cluster(last_syllable) or vowels_set[stem_ultimate])
or (ends_with_consonant_cluster(last_syllable) and obstruents_set[stem_ultimate])) then
gen_pl = remove_suffix(stem, last_syllable) .. lengthen_vowel(last_syllable)
end
local nom_pl = "á"
if NUMBER == "pl" then
nom_pl = ultimate
end
if gen_pl == "" then gen_pl = stem end
if (is_long(word_penultimate_syllable) or word == "jojo") and not ends_with(word, "ium") then
append_endings(forms, word, stem,
"a", "u", nil, loc_sg, "om",
"a", gen_pl, "am", nil, "ach", "ami"
)
else
append_endings(forms, word, stem,
"a", "u", nil, loc_sg, "om",
nom_pl, gen_pl, "ám", nil, "ách", "ami"
)
end
if matches_any(word, {"oko", "ucho"}) then
local pl_stem = (word == "oko") and "oč" or "uš"
append_second_plural(forms, pl_stem .. "i", pl_stem .. "í", pl_stem .. "iam",
nil, pl_stem .. "iach", pl_stem .. "ami")
switch_plural_forms(forms) --changes the prefered forms
set_forms(forms,
{"gen_pl2"},
{pl_stem .. "ú"}
)
elseif word == "nebo" then
set_forms(forms,
{"nom_pl", "nom_pl2", "gen_pl", "dat_pl", "dat_pl2", "acc_pl",
"acc_pl2", "loc_pl", "loc_pl2", "ins_pl"},
{"nebesá", "nebesia", "nebies", "nebesám", "nebesiam", "nebesá",
"nebesia", "nebesách", "nebesiach", "nebesami"}
)
end
return forms, title
end
declensions["srdce"] = function(word, genitive)
local forms = {}
local stem = remove_suffix(word, "e")
if ends_with(word, "ě") then
stem = remove_suffix(word, "ě")
end
local title = "မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု ''" .. word .. "'' <br>(pattern " .. pattern_link("srdce") .. ")"
if NUMBER == "pl" then
if ends_with(word, "ia") then
stem = remove_suffix(word, "ia")
else
stem = remove_suffix(word, "a")
end
end
if ends_with(stem, "[dtnl]") then
stem = soften_last_consonant(stem)
end
-- Split into syllables
local gen_pl = ""
local syllable_count, syllables = split_into_syllables(stem)
local word_syllable_count, word_syllables = split_into_syllables(word)
-- Get the last and second-to-last syllables for rule checks
local last_syllable = syllables[1]
local penultimate_syllable = syllables[2] or ""
local word_penultimate_syllable = word_syllables[2] or ""
local last_char = get_last_char(stem)
local stem_ultimate, stem_penultimate = get_last_letters(stem)
-- 1 & 2. Lengthen the last syllable's vowel if conditions apply,
-- otherwise leave the stem unchanged if penultimate syllable is long
if not ends_with_consonant_cluster(last_syllable)
or (ends_with(word, "ce") and matches_any(get_vowel(word_penultimate_syllable), {"r", "l"}) and TYPE ~= "dim")
or ends_with(word, "ište") then
if is_long(penultimate_syllable) then
gen_pl = stem -- If penultimate syllable of the stem is long, use the stem unchanged
else
-- Otherwise, lengthen the last syllable's vowel
gen_pl = remove_suffix(stem, last_syllable) .. lengthen_vowel(last_syllable)
end
end
-- 3. Add a vowel between the last two consonants if the conditions apply
if gen_pl == "" and (word == "citoslovce" or word == "vajce"
or ends_with(word, "ce")) then
if stem_penultimate ~= "j" and is_short(word_penultimate_syllable) then
gen_pl = remove_suffix(stem, stem_ultimate) .. "ie" .. stem_ultimate
elseif is_long(word_penultimate_syllable) or stem_penultimate == "j" then
gen_pl = remove_suffix(stem, stem_ultimate) .. "e" .. stem_ultimate
end
end
-- 4. Add "í" to the stem for specific words
if matches_any(word, {"more", "oje", "pole", "lože"}) then
gen_pl = harden_last_consonant(stem) .. "í"
end
-- Fallback: if none of the rules apply, return the original stem
if gen_pl == "" then gen_pl = stem end
if is_long(word_penultimate_syllable) or ends_with(stem, "j") then
append_endings(forms, word, stem,
"a", "u", nil, "i", "om",
"a", gen_pl, "am", nil, "ach", "ami"
)
else
append_endings(forms, word, stem,
"a", "u", nil, "i", "om",
"ia", gen_pl, "iam", nil, "iach", "ami"
)
end
return forms, title
end
declensions["vysvedčenie"] = function(word, genitive)
local forms = {}
local stem = remove_suffix(word, "ie")
if ends_with(word, "í") then
stem = remove_suffix(word, "í")
end
local title = "မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု ''" .. word .. "'' <br>(pattern " .. pattern_link("vysvedčenie") .. ")"
append_endings(forms, word, stem,
"ia", "iu", nil, "í", "ím",
"ia", stem .. "í", "iam", nil, "iach", "iami"
)
if word == "storočie" then
append_second_plural(forms, "stáročia", "stáročí", "stáročiam",
nil, "stáročiach", "stáročiami")
end
return forms, title
end
declensions["dievča"] = function(word, genitive)
local forms = {}
local stem = remove_suffix(word, "a")
if ends_with(word, "ä") then
stem = remove_suffix(word, "ä")
end
local ending = get_last_char(word)
local title = "မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု ''" .. word .. "'' <br>(pattern " .. pattern_link("dievča") .. ")"
local gen_pl = ""
local syllable_count, syllables = split_into_syllables(word)
local last_syllable = syllables[1]
local penultimate_syllable = syllables[2] or ""
if is_long(penultimate_syllable) then
gen_pl = stem .. ending .. "t"
else
gen_pl = append_ending(stem, "iat")
end
append_endings(forms, word, stem,
ending .. "ťa", ending .. "ťu", nil, ending .. "ti", ending .. "ťom",
ending .. "tá", gen_pl, ending .. "tám", nil, ending .. "tách", ending .. "tami"
)
local pl_stem = harden_last_consonant(stem)
append_second_plural(forms, pl_stem .. "ence", pl_stem .. "eniec", pl_stem .. "encom",
nil, pl_stem .. "encoch", pl_stem .. "encami")
if matches_any(word, {"kura", "strídža", "drumblence", "gajdence", "deťúrence"}) then
switch_plural_forms(forms) --changes the prefered forms
unset_alt_forms(forms)
elseif matches_any(word, {"páža", "knieža", "kurča", "plánča", "pôrča",
"zviera", "pachoľa", "mláďa", "dúpä", "chlápä", "žieňa", "nemluvňa"}) then
unset_alt_forms(forms)
elseif matches_any(word, {"prasa", "teľa", "šteňa"}) then
local pl_stem = (word == "šteňa") and "šten" or stem
append_second_plural(forms, pl_stem .. "ce", append_ending(pl_stem, "iec"),
pl_stem .. "com", nil, pl_stem .. "coch", pl_stem .. "cami")
switch_plural_forms(forms) --changes the prefered forms
elseif word == "dieťa" then
set_forms(forms,
{"nom_pl", "gen_pl", "dat_pl", "acc_pl", "loc_pl", "ins_pl"},
{"deti", "detí", "deťom", "deti", "deťoch", "deťmi"}
)
unset_alt_forms(forms)
end
return forms, title
end
declensions["နာမဝိသေသန"] = function(word, genitive)
local forms = {}
local title = "မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု ''" .. word .. "'' (adjective declension)"
local ultimate, penultimate = get_last_letters(word)
local lemma_form = word
if NUMBER == "pl" then
if ends_with(word, "é") then
lemma_form = remove_suffix(word, "é") .. "ý"
elseif ends_with(word, "ie") then
lemma_form = remove_suffix(word, "ie") .. "í"
elseif ends_with_any(word, {"ove", "ine"}) then
lemma_form = remove_suffix(word, "e")
elseif ends_with(word, "e") then
lemma_form = remove_suffix(word, "e") .. "y"
elseif ends_with(word, "í") and not soft_consonants_set[penultimate] then
lemma_form = remove_suffix(word, "í") .. "ý"
elseif ends_with(word, "i") and not soft_consonants_set[penultimate] then
lemma_form = remove_suffix(word, "i") .. "y"
end
else
if GENDER == "f" or GENDER == "n" then
if ends_with_any(word, {"á", "é"}) then
lemma_form = remove_last_char(word) .. "ý"
elseif ends_with_any(word, {"ia", "ie"}) then
lemma_form = remove_suffix(remove_last_char(word), "i") .. "í"
elseif ends_with_any(word, {"ova", "ovo", "ina", "ino"}) then
lemma_form = remove_last_char(word)
elseif ends_with_any(word, {"a", "e"}) then
lemma_form = remove_last_char(word) .. "y"
end
end
end
local forms_raw = m_adj.do_generate_forms({pagename=lemma_form}, "adjective").forms
set_forms(forms,
{"nom_sg"},
{forms_raw["nom_" .. get_first_char(GENDER)][1].form}
)
-- Singular
if GENDER == "f" then
set_forms(forms,
{"gen_sg", "dat_sg", "loc_sg", "ins_sg"},
{
forms_raw["gen_f"][1].form, forms_raw["dat_f"][1].form,
forms_raw["loc_f"][1].form, forms_raw["ins_f"][1].form
}
)
else
set_forms(forms,
{"gen_sg", "dat_sg", "loc_sg", "ins_sg"},
{
forms_raw["gen_mn"][1].form, forms_raw["dat_mn"][1].form,
forms_raw["loc_mn"][1].form, forms_raw["ins_mn"][1].form
}
)
end
-- special accusative singular
if GENDER == "m-pr" or GENDER == "m-anml" then
set_forms(forms,
{"acc_sg"},
{forms_raw["acc_m_an"][1].form}
)
elseif GENDER == "m-in" then
set_forms(forms,
{"acc_sg"},
{forms_raw["acc_m_in"][1].form}
)
else
set_forms(forms,
{"acc_sg"},
{forms_raw["acc_" .. get_first_char(GENDER)][1].form}
)
end
-- Plural
set_forms(forms,
{"gen_pl", "dat_pl", "loc_pl", "ins_pl"},
{
forms_raw["gen_p"][1].form, forms_raw["dat_p"][1].form,
forms_raw["loc_p"][1].form, forms_raw["ins_p"][1].form
}
)
if GENDER == "m-pr" then
set_forms(forms,
{"nom_pl", "acc_sg", "acc_pl"},
{forms_raw["nom_mp_an"][1].form, forms_raw["acc_m_an"][1].form, forms_raw["acc_mp_an"][1].form}
)
else
set_forms(forms,
{"nom_pl", "acc_pl"},
{forms_raw["nom_fnp"][1].form, forms_raw["acc_fnp"][1].form}
)
end
return forms, title
end
declensions["indeclinable"] = function(word, genitive)
local forms = {}
local title = "မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု ''" .. word .. "'' (indeclinable)"
local cases = {"nom", "gen", "dat", "acc", "loc", "ins"} -- List of cases
local numbers = {"sg", "pl"}
for _, case in ipairs(cases) do
for _, number in ipairs(numbers) do
local form_key = case .. "_" .. number
forms[form_key] = word
end
end
-- Surnames ending with -ů, -eje, -oje and -ovie
if TYPE == "surn" and ends_with_any(word, {"ů", "eje", "e", "oje", "ovie"}) then
append_second_plural(forms, word .. "ovci", word .. "ovcov", word .. "ovcom",
word .. "ovcov", word .. "ovcoch", word .. "ovcami")
end
return forms, title
end
--[=[
Partial declination functions
]=]--
function check_gender(gender)
if gender == nil then
return error("No gender entered. Please pass one of these values as parameter 1: m-pr, m-anml, m-in, f, n.")
elseif allowed_genders_set[gender] then
return gender
else
return error("Unknown gender. Please pass one of these values as parameter 1: m-pr, m-anml, m-in, f, n.")
end
end
function determine_pattern(word, genitive)
local pattern
local phon_word = (PRONUNCIATION) and PRONUNCIATION or word
local ultimate, penultimate = get_last_letters(phon_word)
local first = get_first_char(phon_word)
local dlan_endings = m_table.listToSet({"ň", "č", "ž", "ľ", "ď", "j", "š", "m", "z", "dz", "x"})
local dlan_exceptions_neg = m_table.listToSet({"reč", "seč", "lož", "beľ", "soľ", "mlaď", "meď", "myš", "voš"})
local dlan_exceptions_pos = m_table.listToSet({"obec", "pec", "čelusť", "kysť", "päsť", "Provence"})
local dlan_end_with_r_t = m_table.listToSet({"kader", "neter", "šír", "tvár",
"činovať", "drobäť", "droboť", "hať", "hrochoť", "Hrochoť", "hrsť", "inovať", "labuť",
"niť", "obeť", "paruť", "pažiť", "pečať", "perepúť", "perleť", "peruť", "pípeť", "plť",
"postať", "prť", "púť", "sieť", "sihoť", "stať", "štvrť", "trať", "úvrať", "vňať",
"violeť", "záhať", "žlť"})
local stroj_exceptions_pos = {"timbre", "cól", "gáfor", "hámor", "kôpor",
"kufor", "Pôtor", "šiator", "pedál", "sandál", "kanál", "peniaz", "daniel"}
local stroj_exceptions_neg = {"nesvár", "nešvár", "pár", "suchopár", "svár", "ker"}
if matches_any(ultimate, {"r", "l"}) and penultimate == "e" and not ends_with(phon_word, "ier") and genitive == nil then
genitive = phon_word .. "a"
end
if mw.ustring.find(phon_word, " ") or word == genitive then
return "indeclinable"
end
if NUMBER == "pl" then
if matches_any(ultimate, {"é", "i", "í"}) or (ultimate == "e" and ends_with(genitive, "ch")) then
pattern = "adjective"
elseif GENDER == "m-in" then
if ultimate == "y" then
pattern = "dub"
else
pattern = "stroj"
end
elseif GENDER == "f" then
if ultimate == "y" then
pattern = "žena"
else
pattern = "ulica"
end
elseif GENDER == "n" then
if ultimate == "á" then
pattern = "mesto"
elseif penultimate == "i" and ultimate == "a" then
pattern = "srdce"
else
if soft_consonants_set[penultimate] then
pattern = "srdce"
else
pattern = "mesto"
end
end
end
else
if GENDER == "m-pr" then
if (matches_any(ultimate, {"y", "ý", "i", "í"}) and not ends_with_any(genitive, {"[yií]ho", "a"})
and not (TYPE == "surn" and matches_any(penultimate .. ultimate, {"ay", "ai"})))
or (matches_any(penultimate .. ultimate, {"ov", "in"}) and ends_with_any(genitive, {"ovho", "inho"}))
then
pattern = "နာမဝိသေသန"
elseif ultimate == "a"
or (TYPE == "surn" and matches_any(ultimate, {"e", "ě"}) and (penultimate .. ultimate == "ně" or ends_with(genitive, "u")))
then
pattern = "hrdina"
elseif (matches_any(ultimate, {"i", "í", "y", "e", "é", "ä"})
or (TYPE == "name" and matches_any(ultimate, {"ü", "ö", "ő"}))
or matches_any(phon_word, {"Hrabě", "Poupě"}))
and not (TYPE == "surn" and (ends_with_any(phon_word, {"ay", "ai", "eje", "oje", "ovie"}) or ends_with(genitive, "a")))
then
pattern = "kuli"
elseif TYPE == "surn" and ends_with_any(phon_word, {"ů", "eje", "oje", "ovie"}) then
pattern = "indeclinable"
else
pattern = "chlap"
end
elseif GENDER == "m-in" or GENDER == "m-anml" then
if matches_any(ultimate, {"y", "ý", "i", "í"})
or (matches_any(penultimate .. ultimate, {"ov", "in"}) and ends_with(genitive, "ho"))
then
pattern = "နာမဝိသေသန"
elseif (soft_consonants_set[ultimate]
or (matches_any(ultimate, {"r", "l"}) and penultimate == "e"
and (ends_with(genitive, "[^e][rl]a")))
or ends_with_any(phon_word, {"ár", "iar", "ier"})
or matches_any(phon_word, stroj_exceptions_pos))
and not matches_any(phon_word, stroj_exceptions_neg)
then
pattern = "stroj"
else
pattern = "dub"
end
elseif GENDER == "f" then
if matches_any(phon_word, {"gazdiná", "švagriná", "testiná", "ujčiná", "stryná",
"kňažná", "kráľovná", "cisárovná", "cárovná", "šľachtičná", "princezná"
}) then
pattern = "gazdiná"
elseif ultimate == "a" and not ends_with(genitive, "ej") then
if soft_consonants_set[penultimate] or matches_any(penultimate, {"i", "y"}) or matches_any(phon_word, {"rozopra", "konopa", "večera"}) then
pattern = "ulica"
else
pattern = "žena"
end
elseif matches_any(ultimate, {"a", "á"})
or (ends_with_any(phon_word, {"ova", "ina"}) and ends_with(genitive, "ej"))
then
pattern = "adjective"
elseif ends_with(phon_word, "pani") or matches_any(phon_word, {"Mať", "mať", "mater", "mati"}) then
pattern = "irregular"
else
if not dlan_exceptions_neg[phon_word]
and (dlan_endings[ultimate] or dlan_exceptions_pos[phon_word]
or dlan_end_with_r_t[phon_word] or (penultimate == "š" and ultimate == "ť" and not is_capital(first)))
then
pattern = "dlaň"
else
pattern = "kosť"
end
end
if genitive then
local g_ultimate = get_last_char(genitive)
if g_ultimate == "y" then
pattern = "žena"
elseif g_ultimate == "i" then
pattern = "kosť"
end
end
elseif GENDER == "n" then
if (ultimate == "o" or (penultimate == "u" and ultimate == "m")
or (penultimate == "o" and ultimate == "n")
or (penultimate == "m" and ultimate == "ä"))
and not ends_with(genitive, "ho")
then
pattern = "mesto"
elseif (penultimate == "i" and ultimate == "e")
or ultimate == "í"
then
pattern = "vysvedčenie"
elseif (ultimate == "e" or ultimate == "ě")
and not ends_with(genitive, "ho")
then
pattern = "srdce"
elseif matches_any(ultimate, {"a", "ä"}) then
pattern = "dievča"
elseif matches_any(ultimate, {"e", "é"})
or ends_with_any(phon_word, {"ovo", "ino"})
then
pattern = "နာမဝိသေသန"
else
pattern = "indeclinable"
end
end
end
return pattern
end
function append_ending(stem1, ending)
if matches_any(get_first_char(ending), {"e", "i", "é", "í"}) then
return harden_last_consonant(stem1) .. ending
else
return stem1 .. ending
end
end
function append_endings(forms, word, stem, end2, end3, end4, end5, end6, end7, gen_pl, end9, end10, end11, end12)
forms["nom_sg"] = word
forms["gen_sg"] = append_ending(stem, end2)
forms["dat_sg"] = append_ending(stem, end3)
if GENDER == "m-pr"
or (GENDER == "f"
and (ends_with_any(word, {"pani", "a", "á"})
or matches_any(word, {"Mať", "mať", "mater", "mati"})))
then
forms["acc_sg"] = append_ending(stem, end4)
else
forms["acc_sg"] = word
end
forms["loc_sg"] = append_ending(stem, end5)
forms["ins_sg"] = append_ending(stem, end6)
local nom_pl = stem
if ends_with_any(stem, {"k", "ch"}) and matches_any(GENDER, {"m-pr", "m-anml"}) and end7 == "i" then
if ends_with(stem, "k") then
nom_pl = remove_suffix(stem, "k") .. "c"
else
nom_pl = remove_suffix(stem, "ch") .. "s"
end
end
forms["nom_pl"] = append_ending(nom_pl, end7)
forms["gen_pl"] = gen_pl
forms["dat_pl"] = append_ending(stem, end9)
if GENDER == "m-pr"
or end10
or (GENDER == "f"
and (ends_with_any(word, {"pani"})
or matches_any(word, {"Mať", "mať", "mater", "mati"})))
then
forms["acc_pl"] = append_ending(stem, end10)
else
forms["acc_pl"] = forms["nom_pl"]
end
forms["loc_pl"] = append_ending(stem, end11)
forms["ins_pl"] = append_ending(stem, end12)
end
function set_forms(forms, indices, values)
for i = 1, #indices do
forms[indices[i]] = values[i]
end
end
function switch_plural_forms(forms)
local indices = {"nom_pl", "gen_pl", "dat_pl", "acc_pl", "loc_pl", "ins_pl"}
for _, index in ipairs(indices) do
forms[index], forms[index .. "_alt"] = forms[index .. "_alt"], forms[index]
end
end
function unset_alt_forms(forms)
for key in pairs(forms) do
if mw.ustring.find(key, "_alt$") then
forms[key] = nil
end
end
end
function append_alternative_singular(forms, form2, form3, form4, form5, form6)
forms["gen_sg2"] = (forms["gen_sg"] ~= form2) and form2
forms["dat_sg2"] = (forms["dat_sg"] ~= form3) and form3
if matches_any(GENDER, {"m-pr", "m-anml"})
or (GENDER == "f"
and (ends_with_any(word, {"pani", "a", "á"})
or matches_any(word, {"Mať", "mať", "mater", "mati"})))
then
forms["acc_sg2"] = (forms["acc_sg"] ~= form4) and form4
end
forms["loc_sg2"] = (forms["loc_sg"] ~= form5) and form5
forms["ins_sg2"] = (forms["ins_sg"] ~= form6) and form6
end
function append_alternative_plural(forms, form1, form2, form3, form4, form5, form6)
forms["nom_pl2"] = (forms["nom_pl"] ~= form2) and form1
forms["gen_pl2"] = (forms["gen_pl"] ~= form2) and form2
forms["dat_pl2"] = (forms["dat_pl"] ~= form2) and form3
if form4 ~= nil and forms["acc_pl"] ~= form4 then
forms["acc_pl2"] = form4
elseif forms["acc_pl"] ~= form1 then
forms["acc_pl2"] = form1
end
forms["loc_pl2"] = (forms["loc_pl"] ~= form2) and form5
forms["ins_pl2"] = (forms["ins_pl"] ~= form2) and form6
end
function append_second_plural(forms, form1, form2, form3, form4, form5, form6)
forms["nom_pl_alt"] = form1
forms["gen_pl_alt"] = form2
forms["dat_pl_alt"] = form3
if form4 ~= nil then
forms["acc_pl_alt"] = form4
else
forms["acc_pl_alt"] = forms["nom_pl_alt"]
end
forms["loc_pl_alt"] = form5
forms["ins_pl_alt"] = form6
end
function append_animal_singular(forms, stem)
set_forms(forms,
{"gen_sg", "dat_sg", "acc_sg", "loc_sg"},
{
append_ending(stem, "a"),
append_ending(stem, "ovi"),
append_ending(stem, "a"),
append_ending(stem, "ovi")
}
)
end
function get_last_char(str)
local last = mw.ustring.sub(str, -1, -1)
return last
end
function get_first_char(str)
local first = mw.ustring.sub(str, 1, 1)
return first
end
function remove_last_char(str)
local stem = mw.ustring.sub(str, 1, -2)
return stem
end
function is_capital(str)
return mw.ustring.find(str, "[A-Z]")
end
function get_last_letters(word)
local ultimate = get_last_char(word)
local penultimate = get_last_char(remove_last_char(word))
local antepenultimate = get_last_char(remove_last_char(remove_last_char(word)))
if (penultimate == "c" and ultimate == "h")
or (penultimate == "d" and (ultimate == "z" or ultimate == "ž"))
then
ultimate = penultimate .. ultimate
penultimate = antepenultimate
antepenultimate = get_last_char(remove_last_char(remove_last_char(remove_last_char(word))))
end
if (antepenultimate == "c" and penultimate == "h")
or (antepenultimate == "d" and (penultimate == "z" or penultimate == "ž"))
then
penultimate = antepenultimate .. penultimate
end
if penultimate == "v" and consonants_set[ultimate] and not matches_any(ultimate, {"r", "l", "ŕ", "ĺ"}) then
penultimate = "ʋ"
end
return ultimate, penultimate
end
function ends_with(word, suffix)
-- Check if suffix matches the end of word
word = (word ~= nil) and word or ""
return mw.ustring.find(word, suffix .. "$") ~= nil
end
function ends_with_any(word, suffixes)
for _, suffix in ipairs(suffixes) do
if ends_with(word, suffix) then
return true -- Return true if any suffix matches
end
end
return false -- Return false if no suffix matches
end
function matches_any(value, list)
for _, item in ipairs(list) do
if value == item then
return true
end
end
return false
end
function get_vowel(syllable)
-- Define patterns for diphthongs and vowels
local diphthong_pattern = "ia|ie|iu|ô"
local vowel_pattern = "[aeiouyáéíóúýäöőüű]"
local syllabic_consonant_pattern = "[rl]"
-- Check for a diphthong first
local diphthong = mw.ustring.match(syllable, diphthong_pattern)
if diphthong then
return diphthong
end
-- Check for a single vowel
local vowel = mw.ustring.match(syllable, vowel_pattern)
if vowel then
return vowel
end
-- Check for a syllabic consonant if no vowel is found
local syllabic_consonant = mw.ustring.match(syllable, syllabic_consonant_pattern)
if syllabic_consonant then
return syllabic_consonant
end
return nil -- Return nil if no vowel or syllabic consonant is found
end
-- Function to split a word into characters and bigraphs
function split_into_letter_units(word)
local units = {}
local i_word = 1
local i_pron = 1
local word_len = mw.ustring.len(word)
local pron_len = PRONUNCIATION and mw.ustring.len(PRONUNCIATION) or 0
while i_word <= word_len do
local two_char = mw.ustring.sub(word, i_word, i_word + 1)
-- Check if PRONUNCIATION forbids combining here
local combine_forbidden = false
if PRONUNCIATION then
-- Advance pronunciation pointer to skip slashes until it aligns with actual letters
-- We only block combination if the *next* character in PRON is a slash
while i_pron <= pron_len and mw.ustring.sub(PRONUNCIATION, i_pron, i_pron) == "/" do
i_pron = i_pron + 1
end
-- Look ahead: is the *next* pronunciation char a slash?
if i_pron < pron_len then
local next_ch = mw.ustring.sub(PRONUNCIATION, i_pron + 1, i_pron + 1)
if next_ch == "/" then
combine_forbidden = true
end
end
end
-- Normal combination if allowed
if not combine_forbidden and (bigraphs_set[two_char] or diphthongs_set[two_char]) then
table.insert(units, two_char)
i_word = i_word + 2
i_pron = i_pron + 2 -- move pronunciation index along with it
else
-- Fallback: single character
local char = mw.ustring.sub(word, i_word, i_word)
table.insert(units, char)
i_word = i_word + 1
i_pron = i_pron + 1
end
end
return units
end
-- check if a unit is a vowel or syllabic element
function is_vowel(unit, prev_unit, next_unit)
if diphthongs_set[unit] then return true end
if vowels_set[unit] then return true end
-- Check if 'r' or 'l' are syllabic (preceded and followed by consonants)
if matches_any(unit, {"r", "ŕ", "l", "ĺ"})
and prev_unit and next_unit
and not (vowels_set[prev_unit] or vowels_set[next_unit]
or diphthongs_set[prev_unit] or diphthongs_set[next_unit])
then
return true
end
return false
end
-- Function to split a word into syllables according to Slovak rules
function split_into_syllables(word)
local units = split_into_letter_units(word)
local syllables = {}
local current_syllable = ""
local i = 1
local length = #units
local first_vowel_found = false -- Flag to indicate when the first vowel has been encountered
-- Iterate over the units in the word
while i <= length do
local unit = units[i]
local next_unit = i < length and units[i + 1] or nil
local previous_unit = i > 1 and units[i - 1] or nil
local is_current_vowel = is_vowel(unit, previous_unit, next_unit)
-- If we haven't encountered the first vowel, keep adding to the first syllable
if not first_vowel_found then
current_syllable = current_syllable .. unit
if is_current_vowel then
first_vowel_found = true -- Mark that the first vowel has been found
end
else
if is_current_vowel then
-- If a vowel is encountered after the first vowel has been found, finalize the current syllable
if current_syllable ~= "" and is_vowel(previous_unit, nil, nil) then
table.insert(syllables, current_syllable)
current_syllable = ""
end
current_syllable = current_syllable .. unit
else
-- Handling consonants between vowels
local consonant_cluster = unit
-- Collect any consecutive consonants into a cluster
local j = i + 1
while j <= length and not is_vowel(units[j], units[j - 1], units[j + 1]) do
consonant_cluster = consonant_cluster .. units[j]
j = j + 1
end
local consonant_count = mw.ustring.len(consonant_cluster)
if next_unit and is_vowel(next_unit, unit, units[j]) then
-- Apply syllable rules based on the number of consonants in the cluster
if consonant_count == 1 then
-- Rule 3: Single consonant goes to the next syllable
table.insert(syllables, current_syllable) -- End the current syllable without the consonant
current_syllable = consonant_cluster -- Start the next syllable with the consonant
elseif consonant_count == 2 then
-- Rule 4: Two consonants split between syllables
current_syllable = current_syllable .. mw.ustring.sub(consonant_cluster, 1, 1)
table.insert(syllables, current_syllable)
current_syllable = mw.ustring.sub(consonant_cluster, 2, 2)
else
-- Rule 5: Three or more consonants - first goes with current syllable, rest with next
current_syllable = current_syllable .. mw.ustring.sub(consonant_cluster, 1, 1)
table.insert(syllables, current_syllable)
current_syllable = mw.ustring.sub(consonant_cluster, 2)
end
i = j - 1 -- Adjust the index to skip the processed consonants
else
current_syllable = current_syllable .. unit
end
end
end
i = i + 1
end
-- Add any remaining characters as the final syllable
if #current_syllable > 0 then
table.insert(syllables, current_syllable)
end
-- Reverse the syllables array for the requested output order
local reversed_syllables = {}
for j = #syllables, 1, -1 do
reversed_syllables[#reversed_syllables + 1] = syllables[j]
end
-- Return the count of syllables and the reversed syllable array
return #syllables, reversed_syllables
end
function is_long(syllable)
return mw.ustring.find(syllable, "[áéíóúýôĺŕ]") ~= nil or mw.ustring.find(syllable, "i[aeu]") ~= nil
end
function is_short(syllable)
return not is_long(syllable)
end
local function get_last_consonant_before_vowel(syllable)
local vowel = get_vowel(syllable)
-- If there is no vowel in the syllable, return false
if not vowel then
return false
end
-- Find the position of the vowel in the syllable
local vowel_pos = mw.ustring.find(syllable, vowel)
-- Loop backwards from the position of the vowel to find the last consonant
for i = vowel_pos - 1, 1, -1 do
local char = mw.ustring.sub(syllable, i, i)
if not mw.ustring.find(char, "[aeiouáéíóúýôä]") then
return char -- Return the last consonant before the vowel
end
end
return false -- Return false if no consonant is found before the vowel
end
-- Function to lengthen the last vowel in a syllable if it’s not already long
function lengthen_vowel(syllable)
if is_long(syllable) then
return syllable -- Return as-is if the syllable is already long
end
local lengthening_map = {
["a"] = "á", ["i"] = "í", ["y"] = "ý", ["u"] = "ú",
["ä"] = "ia", ["e"] = "ie", ["o"] = "ô"
}
local cons_map = {
["ď"] = "d", ["ť"] = "t", ["ň"] = "n", ["ľ"] = "l"
}
-- Check for regular vowels first and replace if found
for vowel, long_vowel in pairs(lengthening_map) do
if mw.ustring.find(syllable, vowel) then
-- if there is a soft consonant before "a", it becomes "ia" instead of "á"
local last_cons = get_last_consonant_before_vowel(syllable) or ""
if soft_consonants_set[last_cons] and last_cons ~= "j" and vowel == "a" then
long_vowel = "ia"
end
-- if a or ä changes into "ia", the previous consonant should be written as hard
if matches_any(vowel, {"ä", "a"}) and matches_any(last_cons, {"ď", "ť", "ň", "ľ"}) then
syllable = mw.ustring.gsub(syllable, last_cons .. vowel, cons_map[last_cons] .. vowel, 1)
end
syllable = mw.ustring.gsub(syllable, vowel, long_vowel, 1)
return syllable -- Return immediately after replacing a regular vowel
end
end
-- Only replace "r" and "l" if no other vowels were found
if not mw.ustring.find(syllable, "[aeiouyáéíóúýôä]") then
syllable = mw.ustring.gsub(syllable, "r", "ŕ")
syllable = mw.ustring.gsub(syllable, "l", "ĺ")
end
return syllable
end
-- Helper function to determine if the syllable ends with a consonant cluster
function ends_with_consonant_cluster(last_syllable)
local last_char = get_last_char(last_syllable)
local second_last_char = mw.ustring.sub(last_syllable, -2, -2)
local third_last_char = mw.ustring.sub(last_syllable, -3, -3)
local last_two_chars = mw.ustring.sub(last_syllable, -2)
-- Check if the syllable contains any regular vowels
local has_vowel = mw.ustring.find(last_syllable, "[aeiouyáéíóúýôä]")
if has_vowel then
-- If the last two characters form a digraph, check the third-last character for a cluster
if bigraphs_set[last_two_chars] then
return not vowels_set[third_last_char]
else
-- If no digraph, just check the last two characters
return not (vowels_set[last_char] or vowels_set[second_last_char]
or diphthongs_set[last_char] or diphthongs_set[second_last_char])
end
else
-- No regular vowel; treat `r` or `l` as syllabic if either is in the last two characters
if matches_any(last_char, {'ŕ', 'ĺ'}) or matches_any(second_last_char, {'ŕ', 'ĺ'}) then
return false
elseif mw.ustring.find(last_syllable, "[bcčdďfghjkľmnňpqsštťvwxzž][rl][bcčdďfghjkľmnňpqysštťvwxzž][rl]$") then
return true
else
-- No syllabic `r` or `l`, so both characters are treated as consonants
return not vowels_set[last_char] and not vowels_set[second_last_char]
end
end
end
function remove_mobile_vowel(word)
local units = split_into_letter_units(word) -- Split word into units
for i = #units, 1, -1 do
local unit = units[i]
if matches_any(unit, {"e", "ie", "o", "i", "á"}) then
-- Remove the mobile vowel unit and reassemble the word
table.remove(units, i)
return table.concat(units)
end
end
return word -- Return the original word if no mobile vowel is found
end
function soften_last_consonant(str)
local consonants_t = { ["c"] = "č", ["d"] = "ď", ["l"] = "ľ", ["n"] = "ň",
["s"] = "š", ["t"] = "ť", ["z"] = "ž" }
local last_char = get_last_char(str)
-- Check if the last character is in consonants_t and replace if needed
return consonants_t[last_char] and remove_last_char(str) .. consonants_t[last_char] or str
end
function harden_last_consonant(str)
local soft_to_hard = { ["ď"] = "d", ["ť"] = "t", ["ň"] = "n", ["ľ"] = "l" }
local last_char = get_last_char(str)
-- Check if the last character is a soft consonant and replace if needed
return soft_to_hard[last_char] and remove_last_char(str) .. soft_to_hard[last_char] or str
end
function remove_suffix(form, suffix)
if mw.ustring.find(form, suffix .. "$") then
local length = mw.ustring.len(suffix)
return mw.ustring.sub(form, 1, -length-1)
end
return form
end
function pattern_link(pattern)
return "''[[Appendix:Slovak declension pattern " .. pattern .. "|" .. pattern .. "]]''"
end
function decline_with_more_stems(genitive)
local genitives = {}
for part in mw.ustring.gmatch(genitive, "[^/]+") do
table.insert(genitives, part)
end
local forms, title = declensions[PATTERN](PAGENAME, genitives[1])
normalize_forms(forms)
local forms2, title2 = declensions[PATTERN](PAGENAME, genitives[2])
normalize_forms(forms2)
append_alternative_singular(forms, forms2["gen_sg"], forms2["dat_sg"], forms2["acc_sg"],
forms2["loc_sg"], forms2["ins_sg"])
append_alternative_plural(forms, forms2["nom_pl"], forms2["gen_pl"], forms2["dat_pl"],
forms2["acc_pl"], forms2["loc_pl"], forms2["ins_pl"])
return forms, title
end
function split_into_units(expression, genitive)
-- Split the original expression into words
local words = {}
for word in mw.ustring.gmatch(expression, "%S+") do
table.insert(words, word)
end
-- Split the genitive phrase into words, if provided
local gen_words = {}
if genitive then
for word in mw.ustring.gmatch(genitive, "%S+") do
table.insert(gen_words, word)
end
-- Check if the genitive phrase has the same structure as the original
if #gen_words ~= #words then
error("Genitive phrase must have the same number of words as the original expression.")
end
end
-- Combine words into units, grouping prepositional phrases for both expressions
local units = {}
local gen_units = {}
local i = 1
while i <= #words do
if prepositions_set[words[i]] and words[i + 1] then
-- Combine preposition with the following words as one unit
local phrase = words[i]
local gen_phrase = genitive and gen_words[i] or nil
i = i + 1
while i <= #words do
phrase = phrase .. " " .. words[i]
if genitive then
gen_phrase = gen_phrase .. " " .. gen_words[i]
end
if i == #words then
table.insert(units, phrase)
if genitive then table.insert(gen_units, gen_phrase) end
end
i = i + 1
end
else
-- Add standalone word as a unit
table.insert(units, words[i])
if genitive then
table.insert(gen_units, gen_words[i])
end
i = i + 1
end
end
-- Return both units and genitive units
return units, gen_units
end
function generate_combined_forms(units, gen_units)
-- Process each unit to generate forms
local all_forms = {}
local patterns = ""
for i = 1, #units do
local unit = units[i]
local gen_unit = gen_units[i]
if conjunctions_set[unit] or unit == gen_unit then
-- Conjunctions are indeclinable
local forms = declensions["indeclinable"](unit, gen_unit)
table.insert(all_forms, forms)
else
-- Decline each unit using determine_pattern and declensions
local pattern = determine_pattern(unit, gen_unit)
local forms, title = declensions[pattern](unit, gen_unit)
normalize_forms(forms)
table.insert(all_forms, forms)
end
end
-- Combine forms into a single forms table
local combined_forms = {}
local cases = {"nom", "gen", "dat", "acc", "loc", "ins"}
local numbers = {"sg", "pl"}
-- check if vocative and plural 2 forms are necessary
for _, forms in ipairs(all_forms) do
if forms["voc_sg"] and #cases == 6 then
table.insert(cases, "voc")
end
if forms["nom_pl_alt"] and #numbers == 2 then
table.insert(numbers, "pl_alt")
end
end
for _, case in ipairs(cases) do
for _, number in ipairs(numbers) do
local form_key = case .. "_" .. number
local combined_form, highest_index = {}, 1
-- Gather primary and numbered alternative forms (e.g., gen_sg2, gen_sg3)
for _, forms in ipairs(all_forms) do
local primary_form = forms[form_key] or forms["nom_" .. number] or forms[case .. "_pl"]
table.insert(combined_form, primary_form)
-- Check the highest alternative index
for alt_index = 2, 4 do
local alt_key = form_key .. alt_index
if forms[alt_key] then
highest_index = alt_index
end
end
end
-- Combine primary forms
combined_forms[form_key] = mw.ustring.gsub(table.concat(combined_form, " "), "^%s+", "")
-- Combine alternative forms if present
if highest_index > 1 then
for alt_index = 2, highest_index do
-- Check and add numbered alternative forms
local alt_key = form_key .. alt_index
alt_form = {}
for _, forms in ipairs(all_forms) do
local primary_form = forms[form_key] or forms["nom_" .. number]
if forms[alt_key] then
table.insert(alt_form, forms[alt_key])
else
table.insert(alt_form, primary_form)
end
end
combined_forms[alt_key] = mw.ustring.gsub(table.concat(alt_form, " "), "^%s+", "")
end
end
end
end
return combined_forms
end
function normalize_forms(forms)
-- Step 1: Remove forms based on NUMBER
if NUMBER == "sg" then
for key in pairs(forms) do
if mw.ustring.find(key, "_pl") then
forms[key] = nil -- Remove plural forms if "n" is "sg"
end
end
elseif NUMBER == "pl" then
for key in pairs(forms) do
if mw.ustring.find(key, "_sg") then
forms[key] = nil -- Remove singular forms if "n" is "pl"
end
end
end
-- Step 2: Ensure all mandatory indices are set
local cases = {"nom", "gen", "dat", "acc", "loc", "ins"}
local numbers = {"sg", "pl"}
for _, case in ipairs(cases) do
for _, number in ipairs(numbers) do
local form_key = case .. "_" .. number
if not forms[form_key] then
forms[form_key] = "—" -- Set missing forms to —
end
end
end
-- Step 3: Create missing _pl_alt indices if at least one exists
local has_alt_plural = false
for key in pairs(forms) do
if mw.ustring.find(key, "_pl_alt") then
has_alt_plural = true
break
end
end
if has_alt_plural then
for _, case in ipairs(cases) do
local form_key_alt = case .. "_pl_alt"
if not forms[form_key_alt] then
forms[form_key_alt] = "—" -- Create missing _pl_alt forms
end
end
end
-- Step 4: Create vocative plural forms if voc_sg exists
if forms["voc_sg"] then
forms["voc_pl"] = forms["nom_pl"] -- Set voc_pl to nom_pl
if has_alt_plural then
forms["voc_pl_alt"] = forms["nom_pl_alt"] -- Set voc_pl_alt to nom_pl_alt if it exists
end
end
end
function specified_by_user(forms, args)
local cases = {nom = true, gen = true, dat = true, acc = true, voc = true, loc = true, ins = true}
local numbers = {sg = true, pl = true}
for key, value in pairs(args) do
-- Match the pattern "<case>_<number><optional digit>" using mw.ustring.match
local case, number, optional_digit = mw.ustring.match(key, "^(%a%a%a)_(%a%a)(%d?)$")
-- Check if it matches the cases and numbers you want
if case and cases[case] and number and numbers[number] then
forms[key] = make_link(value, case .. "|" .. get_first_char(number))
end
end
end
function make_link(link, accel_form)
local new_link = link
-- If link is not empty, valid, and not "—", create the full link
if link ~= "" and link and link ~= "—" then
new_link = m_links.full_link({lang = lang, term = link, accel = {form = accel_form}})
end
return new_link
end
function make_table_header(title)
return m_inflection_table.make_top{
title = title,
palette = 'blue',
tall = 'yes'
}
end
function make_simple_row(forms, case)
local case_code = mw.ustring.sub(case, 1, 3)
local row = "<tr><th>" .. case .. "</th>"
-- Singular
if NUMBER ~= "pl" then
row = row .. "<td><span lang=\"sk\">" .. make_link(forms[case_code .. "_sg"], case_code .. "|s") .. "</span>"
-- Loop to check and display secondary singular forms in the same cell
for i = 2, 4 do
local form_key = case_code .. "_sg" .. i
if not forms[form_key] then
break -- Exit loop if form doesn't exist
end
row = row .. ",<br /><span lang=\"sk\">" .. make_link(forms[form_key], case_code .. "|s") .. "</span>"
end
row = row .. "</td>"
end
-- Plural
if NUMBER ~= "sg" then
-- Primary plural form
row = row .. "<td><span lang=\"sk\">" .. make_link(forms[case_code .. "_pl"], case_code .. "|p") .. "</span>"
-- Loop to check and display secondary plural forms in the same cell
for i = 2, 4 do
local form_key = case_code .. "_pl" .. i
if not forms[form_key] then
break -- Exit loop if form doesn't exist
end
row = row .. ",<br /><span lang=\"sk\">" .. make_link(forms[form_key], case_code .. "|p") .. "</span>"
end
row = row .. "</td>"
-- Check for alternative plural and add it in a separate cell
if forms[case_code .. "_pl_alt"] then
row = row .. "<td><span lang=\"sk\">" .. make_link(forms[case_code .. "_pl_alt"], case_code .. "|p") .. "</span></td>"
end
end
row = row .. "</tr>"
return row
end
function make_table_header2(forms)
local tr_open = "<tr><th></th>"
local singular = "<th>singular</th>"
local plural = "<th>plural</th>"
local plural1 = "<th>plural 1</th>"
local plural2 = "<th>plural 2</th>"
local tr_close = "</tr>"
local alt_plural = false
if forms["nom_pl_alt"] or forms["gen_pl_alt"] or forms["dat_pl_alt"]
or forms["acc_pl_alt"] or forms["loc_pl_alt"] or forms["ins_pl_alt"]
then
alt_plural = true
end
local header
if NUMBER == "sg" then
header = tr_open .. singular .. tr_close
elseif NUMBER == "pl" then
if alt_plural then
header = tr_open .. plural1 .. plural2 .. tr_close
else
header = tr_open .. plural .. tr_close
end
elseif alt_plural then
header = tr_open .. singular .. plural1 .. plural2 .. tr_close
else
header = tr_open .. singular .. plural .. tr_close
end
return header
end
function make_table_footer()
return '\n' .. m_inflection_table.make_bottom{}
end
-- Make the table
function make_table(forms, title)
for key, form in pairs(forms) do
-- check for empty strings and nil's
if form == "" or not form then
forms[key] = "—"
end
end
local final = make_table_header(title)
final = final .. make_table_header2(forms)
final = final .. make_simple_row(forms, "မဒုၚ်ယၟု")
final = final .. make_simple_row(forms, "ဗဳဇဂကူ")
final = final .. make_simple_row(forms, "ပြကမ္မကာရက")
final = final .. make_simple_row(forms, "ကမ္မကာရက")
if forms["voc_sg"] then
final = final .. make_simple_row(forms, "ပရေၚ်ဂယိုၚ်လမျီု")
end
final = final .. make_simple_row(forms, "ခၞံဗဒှ်ဌာန်မတန်တဴ")
final = final .. make_simple_row(forms, "တိၚ်တိုက်ကပေါတ်ကွိၚ်ကွိုက်")
final = final .. make_table_footer()
return final
end
return export
lzzq7uu57dn1blx3ha8i9ea8xfds5b1
401116
401115
2026-08-13T11:44:29Z
OctraBot
279
401116
Scribunto
text/plain
--[=[
This module contains functions for creating inflection tables for Slovak
nouns.
]=]--
local export = {}
-- Within this module, declensions are the functions that do the actual
-- declension by creating the forms of a basic noun.
-- They are defined further down.
--local lemma = "Bratislava"
local declensions = {}
local lang = require("Module:languages").getByCode("sk")
local m_table = require("Module:table")
local m_links = require("Module:links")
local m_adj = require("Module:sk-adjective")
local m_inflection_table = require("Module:inflection-table")
local allowed_genders = {
"m-pr", "m-anml", "m-in", "f", "n"
}
local allowed_genders_set = m_table.listToSet(allowed_genders)
local hard_consonants = {"d", "t", "n", "l", "h", "ch", "k", "g"}
local soft_consonants = {"ď", "ť", "ň", "ľ", "ž", "š", "č", "dž", "c", "dz", "j"}
local ambiguous_consonants = {"b", "m", "p", "r", "s", "v", "z", "f"}
local hard_consonants_set = m_table.listToSet(hard_consonants)
local soft_consonants_set = m_table.listToSet(soft_consonants)
local ambiguous_consonants_set = m_table.listToSet(ambiguous_consonants)
local consonants = m_table.append(hard_consonants, soft_consonants, ambiguous_consonants)
local consonants_set = m_table.listToSet(consonants)
local short_vowels = {"a", "e", "i", "o", "u", "y", "ä", "ö", "ü"}
local long_vowels = {"á", "é", "í", "ó", "ú", "ý", "ő", "ű"}
local diphthongs = {"ia", "ie", "iu", "ô"}
local short_vowels_set = m_table.listToSet(short_vowels)
local long_vowels_set = m_table.listToSet(long_vowels)
local diphthongs_set = m_table.listToSet(diphthongs)
local vowels = m_table.append(short_vowels, long_vowels)
local vowels_set = m_table.listToSet(vowels)
local obstruents = {"p", "t", "k", "b", "d", "g", "f", "s", "š", "ch", "z", "ž", "č", "dž"} --"v" removed??
local sonorants = {"m", "n", "l", "r", "ʋ", "v"} --"v" added??
local obstruents_set = m_table.listToSet(obstruents)
local sonorants_set = m_table.listToSet(sonorants)
local bigraphs = {"ch", "dz", "dž"}
local bigraphs_set = m_table.listToSet(bigraphs)
local prepositions = {"bez", "bezo", "cez", "cezo", "do", "k", "ku", "medzi",
"na", "nad", "nado", "o", "do", "okrem", "po", "pod", "podo", "pre", "pred",
"predo", "pri", "proti", "naproti", "oproti", "s", "so", "skrz", "u", "v",
"vo", "z", "zo", "za"} -- Add more prepositions as needed
local prepositions_set = m_table.listToSet(prepositions)
local conjunctions = {"a"} -- Add more conjunctions as needed
local conjunctions_set = m_table.listToSet(conjunctions)
-- 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
NAMESPACE = mw.title.getCurrentTitle().nsText
if NAMESPACE == "" then
PAGENAME = mw.loadData("Module:headword/data").pagename
else
if args["pagename"] then
PAGENAME = args["pagename"] -- TEST: lemma
else
error("Pagename not specified")
end
end
GENDER = check_gender(args[1])
NUMBER = args["n"]
TYPE = args["t"]
GEN_ENDING = args["g"]
PLURAL = args["pl"]
PLURAL2 = args["pl2"]
PRONUNCIATION = args["p"]
local genitive = args[2]
local category = ""
-- Check if PAGENAME is a multiword expression
if not mw.ustring.find(PAGENAME, " ") then
-- Single-word expression, handle as usual
PATTERN = determine_pattern(PAGENAME, genitive)
-- Category
if NAMESPACE == "" then
if PATTERN == "indeclinable" then
category = "[[ကဏ္ဍ:နာမ်သလဝ်ဝေန်နဳယျာနကဵုပါ်ပါဲထောံဟွံမာန်ဂမၠိုၚ်|" .. PAGENAME .. "]]"
elseif PATTERN == "irregular" then
category = "[[ကဏ္ဍ:နာမ်ကိုန်ဨကဝုစ်သလဝ်ဝေန်နဳယျာဂမၠိုၚ်|" .. PAGENAME .. "]]"
elseif PATTERN == "adjective" then
category = "[[ကဏ္ဍ:နာမ်မဆေၚ်စပ်ကဵုနာမဝိသေသနသလဝ်ဝေန်နဳယျာဂမၠိုၚ်|" .. PAGENAME .. "]]"
else
category = "[[ကဏ္ဍ:ဝေါဟာသလဝ်ဝေန်နဳယျာမၞုံကဵုဝေါဟာ " .. PATTERN .. " မလဟုတ်စှ်ေဂမၠိုၚ်|" .. PAGENAME .. "]]"
end
if GENDER == "m-anml" then
category = category .. "[[ကဏ္ဍ:ဝေါဟာသလဝ်ဝေန်နဳယျာမၞုံကဵုဝေါဟာ chlap မလဟုတ်စှ်ေဂမၠိုၚ်|" .. PAGENAME .. "]]"
end
if PAGENAME == "cól" then
category = category .. "[[ကဏ္ဍ:ဝေါဟာသလဝ်ဝေန်နဳယျာမၞုံကဵုဝေါဟာ dub မလဟုတ်စှ်ေဂမၠိုၚ်|" .. PAGENAME .. "]]"
end
end
local forms, title
-- Find out if there are more genitive stems and if so, process them
if genitive then
if mw.ustring.find(genitive, "/") then
forms, title = decline_with_more_stems(genitive)
else
forms, title = declensions[PATTERN](PAGENAME, genitive)
normalize_forms(forms)
end
else
forms, title = declensions[PATTERN](PAGENAME, genitive)
normalize_forms(forms)
end
specified_by_user(forms, args)
return make_table(forms, title) .. category
end
-- Multiword expressions
-- Category
if NAMESPACE == "" then
category = "[[ကဏ္ဍ:ဝေါဟာသလဝ်ဝေန်နဳယျာမဂၠိုၚ်ကဵုမအရေဝ်ဂမၠိုၚ်|" .. PAGENAME .. "]]"
end
-- Split into words
local units, gen_units = split_into_units(PAGENAME, genitive)
-- Process each unit to generate forms
local combined_forms = generate_combined_forms(units, gen_units)
-- Add forms specified by the user
specified_by_user(combined_forms, args)
-- Generate the final title and table
local title = "မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု ''" .. PAGENAME .. "'' (multiword term)"
return make_table(combined_forms, title) .. category
end
--[=[
Declension functions
]=]--
declensions["chlap"] = function(word, genitive)
local forms = {}
local syllable_count, syllables = split_into_syllables(word)
local mobile_removed = false -- Tracks if a mobile vowel was removed
local words_with_mobile = {"kmotor", "švagor", "svokor", "lotor",
"obor", "Uhor", "pochábeľ", "väzeň", "učeň",
"posol", "diabol", "blázon", "Turek", "fanúšek", "center",
"hypochonder", "Kafer", "neger", "gangster",
"kapor", "zubor", "bobor", "orol", "pes"
}
local surn_ech_always_declined = {"Čech", "Plech", "Pech", "Štech", "Vojtech"}
-- Determine the stem by removing mobile vowels if applicable
local stem = word
if (matches_any(word, words_with_mobile)
or ends_with_any(word, {"ec", "ček", "íček", "ok"}))
and not (TYPE == "surn"
and (ends_with_any(word, {"[aeiouyáéíóúýäöüőű]ček", "[aeiouyáéíóúýäöüőű]čok"})
or syllable_count == 1))
and not matches_any(word, {"otrok"})
then
stem = remove_mobile_vowel(word)
mobile_removed = true -- Mark mobile vowel as removed
end
-- Adjust specific stems based on predefined mappings
stem = ({["švec"] = "ševc", ["žnec"] = "ženc"})[word] or stem
-- Remove certain endings for words ending with "us", "os", "es" and "o"
if ends_with(word, "[uoea]s") then
stem = mw.ustring.sub(word, 1, -3)
end
if ends_with(word, "o") then
stem = remove_last_char(word)
end
-- Override if a specific argument is given
if genitive and NUMBER ~= "pl" then
stem = remove_last_char(genitive)
if mw.ustring.sub(word, 1, -3) .. get_last_char(word) == remove_last_char(genitive) then
mobile_removed = true
end
end
-- Title for the declension table
local title = "Declension of ''" .. word .. "'' <br>(pattern " .. pattern_link("chlap") .. ")"
if TYPE == "surn" then
if ends_with(word, "a[iy]") then
title = "မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု ''" .. word .. "'' <br>(pattern " .. pattern_link("chlap") .. " or " .. pattern_link("kuli") .. ")"
elseif ends_with_any(word, {"ých", "ech"}) and not matches_any(word, surn_ech_always_declined) then
title = "Declension of ''" .. word .. "'' <br>(pattern " .. pattern_link("chlap") .. " or indeclinable)"
end
end
-- Helper variables for analyzing the last and penultimate characters
local ultimate, penultimate = get_last_letters(stem)
local first = get_first_char(word)
-- Determine alternative dative and locative for some nouns
if matches_any(word, {"človek", "pán", "čert", "diabol", "vlk", "pes",
"Boh", "boh", "otec", "syn", "duch", "Kristus", "don", "šor"})
then
set_forms(forms, {"dat_sg2", "loc_sg2"}, {stem .. "u", stem .. "u"})
end
local nom_pl = "i"
if PLURAL then
if mw.ustring.find(PLURAL, "/") then
local endings = {}
for part in mw.ustring.gmatch(PLURAL, "[^/]+") do
table.insert(endings, part)
end
nom_pl = endings[1]
for i = 2, 4 do
if endings[i] then
set_forms(forms, {"nom_pl" .. i}, {append_ending(stem, endings[i])})
else
break
end
end
else
nom_pl = PLURAL
end
elseif (ends_with_any(word, {"fil", "fób", "graf", "nóm"})
and not matches_any(word, {"xylograf", "typograf"}))
or matches_any(word, {"cynik", "epik", "klasik", "stoik",
"Brit", "Búr", "Gal", "Ír", "Dór", "Italik", "Ión", "Nór",
"cár", "lodivod", "odkundes", "starík", "muž", "svat", "apoštol",
"augur", "bán", "bogomil", "buržuj", "don", "druid", "eféb",
"famulus", "héros", "man", "posol"
})
then
set_forms(forms, {"nom_pl2"}, {append_ending(stem, "ovia")})
elseif (ends_with_any(word, {"[^c]h", "g", "ček", "ek", "ik", "čik", "ok", "o", "duch"}) and word ~= "pes")
or matches_any(word, {"otec", "syn", "ujec", "strýc", "svák", "svokor", "tesť", "švagor",
"zať", "kmotor", "ded", "kmeť", "pobratim", "otčim", "zlosyn", "princ",
"Bask", "Frank", "Ind", "Ink", "Kurd", "Dák", "Čudo", "Fríz", "Azték",
"Asýr", "Etrusk", "Kazach", "Kašub", "odľud", "člen", "zved", "hňup", "cicerone"})
or (ends_with(word, "ch") and TYPE == "loan")
or (ends_with_any(word, {"us", "es"}) and genitive ~= word .. "a")
or matches_any(TYPE, {"comp-deverb", "surn", "name"})
or PLURAL == "ovia"
then
nom_pl = "ovia"
if TYPE == "surn" then
append_second_plural(forms, stem .. "ovci", stem .. "ovcov", stem .. "ovcom",
stem .. "ovcov", stem .. "ovcoch", stem .. "ovcami")
end
elseif ends_with(word, "teľ")
or (ends_with(word, "an") and is_capital(first))
or matches_any(word, {"občan", "dedinčan", "mešťan", "zeman", "ostrovan",
"krajan", "dolňan", "horňan", "južan", "severan", "rodič", "dedič", "brat", "hosť",
"manžel", "exmanžel", "sused", "žid", "Žid", "kresťan", "nekresťan", "pohan"})
then
nom_pl = "ia"
if word == "pohan" then
set_forms(forms, {"nom_pl2"}, {append_ending(stem, "i")})
end
end
-- Determine instrumental plural ending
local ins_pl = "mi" -- Default instrumental plural ending is "mi"
if ultimate == "m"
or mobile_removed
or ends_with_any(word, {"o", "ius"})
or matches_any(word, {"hosť", "tesť", "Kopt"}) --obstruents_set[penultimate] and obstruents_set[ultimate]
then
ins_pl = "ami"
end
-- Populate forms table with singular and plural endings
append_endings(forms, word, stem,
"a", "ovi", "a", "ovi", "om",
nom_pl, append_ending(stem, "ov"), "om", "ov", "och", ins_pl
)
-- Surnames ending with -ých, -ech, -ai, -ay
if TYPE == "surn" then
if ends_with_any(word, {"ých", "ech"}) and not matches_any(word, surn_ech_always_declined) then
append_alternative_singular(forms, word, word, word, word, word)
append_alternative_plural(forms, word, word, word, word, word, word)
elseif ends_with(word, "a[iy]") then
append_alternative_singular(forms, word .. "ho", word .. "mu", word .. "ho", word .. "m", word .. "m")
set_forms(forms, {"ins_pl2"}, {word .. "ami"})
end
end
-- Exceptions
if word == "človek" then
set_forms(forms,
{"nom_pl", "gen_pl", "dat_pl", "acc_pl", "loc_pl", "ins_pl"},
{"ľudia", "ľudí", "ľuďom", "ľudí", "ľuďoch", "ľuďmi"}
)
elseif word == "héros" then
set_forms(forms,
{"gen_sg", "dat_sg", "acc_sg", "loc_sg", "ins_sg",
"nom_pl", "gen_pl", "dat_pl", "acc_pl", "loc_pl", "ins_pl",
"gen_sg2", "dat_sg2", "acc_sg2", "loc_sg2", "ins_sg2",
"nom_pl2", "gen_pl2", "dat_pl2", "acc_pl2", "loc_pl2", "ins_pl2"},
{"hérosa", "hérosovi", "hérosa", "hérosovi", "hérosom",
"hérosi", "hérosov", "hérosom", "hérosov", "hérosoch", "hérosmi",
"héroa", "héroovi", "héroa", "héroovi", "héroom",
"héroovia", "héroov", "héroom", "héroov", "hérooch", "héroami"}
)
end
-- Vocative
if matches_any(word, {"syn", "sváko", "švagor", "kmotor", "brat", "synko",
"synáčik", "pán", "chlapec", "priateľ", "majster", "Boh", "boh", "Pán", "Syn",
"Duch", "Ježiš", "Ježiško", "Kristus", "Spasiteľ", "Vykupiteľ", "Stvoriteľ",
"Premožiteľ", "Kráľ", "Hospodin", "baránok", "Baránok", "tešiteľ", "Tešiteľ",
"hriešnik", "protivník", "kresťan", "otec", "Otec", "chlap", "človek"})
then
voc_stem = stem
if word == "synáčik" then voc_stem = "synáčk" end
if word == "pán" then voc_stem = "pan" end
if word == "Pán" then voc_stem = "Pan" end
if ends_with_any(word, {"teľ", "o"})
or matches_any(word, {"syn", "Syn", "Duch", "Ježiš", "Kráľ",
"hriešnik", "synáčik", "baránok", "Baránok"})
then
set_forms(forms, {"voc_sg"}, {append_ending(voc_stem, "u")})
else
if ends_with_any(voc_stem, {"k", "c"}) then
voc_stem = remove_last_char(voc_stem) .. "č"
elseif ends_with(voc_stem, "h") then
voc_stem = remove_last_char(voc_stem) .. "ž"
end
set_forms(forms, {"voc_sg"}, {append_ending(voc_stem, "e")})
end
if not matches_any(word, {"človek", "pán", "brat"}) then
set_forms(forms, {"voc_sg2"}, {word})
elseif word == "brat" then
set_forms(forms, {"voc_sg2", "voc_sg3"}, {"bratu", "brat"})
end
end
return forms, title -- Return forms table and title for declension
end
declensions["hrdina"] = function(word, genitive)
local forms = {}
local title = "မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု ''" .. word .. "'' <br>(pattern " .. pattern_link("hrdina") .. ")"
local stem = remove_suffix(word, "a")
if ends_with(word, "[oeě]") then
stem = remove_last_char(word)
if ends_with(word, "ě") and ends_with(stem, "[dtnl]") then
stem = soften_last_consonant(stem)
end
end
local nom_pl_ending = "ovia"
if ends_with_any(word, {"ista", "ita"})
or (ends_with(word, "ta") and TYPE == "loan") then
nom_pl_ending = "i"
end
local ins_pl_ending = "ami"
if ends_with(word, "[aeiouyáéíóúýäöüőű]ta") and TYPE == "loan" then
ins_pl_ending = "mi"
end
append_endings(forms, word, stem,
"u", "ovi", "u", "ovi", "om",
nom_pl_ending, stem .. "ov", "om", "ov", "och", ins_pl_ending
)
if TYPE == "surn" then
append_second_plural(forms, stem .. "ovci", stem .. "ovcov", stem .. "ovcom",
stem .. "ovcov", stem .. "ovcoch", stem .. "ovcami")
end
if word == "buržoa" then
set_forms(forms,
{"dat_sg", "loc_sg", "ins_sg",
"nom_pl", "gen_pl", "dat_pl", "acc_pl", "loc_pl"},
{"buržuovi", "buržuovi", "buržuom",
"buržuovia", "buržuov", "buržuom", "buržuov", "buržuoch"}
)
end
return forms, title
end
declensions["kuli"] = function(word, genitive)
local forms = {}
local stem = word
local title = "မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု ''" .. word .. "'' <br>(pattern " .. pattern_link("kuli") .. ")"
append_endings(forms, word, stem,
"ho", "mu", "ho", "m", "m",
"ovia", stem .. "ov", "om", "ov", "och", "ami"
)
if TYPE == "surn" then
append_second_plural(forms, stem .. "ovci", stem .. "ovcov", stem .. "ovcom",
stem .. "ovcov", stem .. "ovcoch", stem .. "ovcami")
end
return forms, title
end
declensions["dub"] = function(word, genitive)
local forms = {}
local mobile_removed = false -- Tracks if a mobile vowel was removed
local words_with_mobile = {"priemysel", "počet", "ocot", "bahor", "chrbát",
"ker", "cukor", "uhor", "vietor", "víchor", "vôdor", "kotol",
"kapor", "zubor", "bobor", "orol", "pes", "mozog", "uhol"}
local syllable_count, syllables = split_into_syllables(word)
-- Determine the stem by removing mobile vowels if applicable
local stem = word
if (matches_any(word, words_with_mobile)
or (ends_with_any(word, {"íček", "ýček", "ok"}) and syllable_count ~= 1))
and not matches_any(word, {"polrok", "nárok", "zákrok", "rozkrok"})
then
stem = remove_mobile_vowel(word)
mobile_removed = true -- Mark mobile vowel as removed
end
-- Adjust specific stems based on predefined mappings
stem = ({["mráz"] = "mraz", ["vietor"] = "vetr", ["kôl"] = "kol",
["stôl"] = "stol", ["vôl"] = "vol", ["chlieb"] = "chleb",
["ensemble"] = "ensembl"})[word] or stem
-- Remove certain endings for words ending with "us", "os", "es" and "o"
if (ends_with(word, "[uoe]s") and TYPE == "loan") or ends_with(word, "izmus") then
stem = mw.ustring.sub(word, 1, -3)
end
if ends_with(word, "o") then
stem = remove_last_char(word)
end
-- Pluralia tantum
if NUMBER == "pl" then
stem = remove_suffix(word, "y")
end
-- Override if a specific argument is given
if genitive and NUMBER ~= "pl" then
stem = remove_last_char(genitive)
if stem == remove_last_char(remove_last_char(word)) .. get_last_char(word) then
mobile_removed = true
elseif stem == word then
mobile_removed = false
end
end
-- Set "mobile_removed" if genitive was set by the user
if ends_with(word, "e[lr]") and ends_with(stem, "[^e][lr]") then
mobile_removed = true
end
-- Title for the declension table
local title = "မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု ''" .. word .. "'' <br>(pattern " .. pattern_link("dub") .. ")"
if GENDER == "m-anml" then
if matches_any(word, {"vták", "vlk", "pes"}) then
title = "မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု ''" .. word .. "'' <br>(patterns " .. pattern_link("chlap") .. " <small>(singular, plural 1)</small> and " .. pattern_link("dub") .. " <small>(plural 2)</small>)"
elseif PLURAL2 then
title = "မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု ''" .. word .. "'' <br>(patterns " .. pattern_link("chlap") .. " <small>(singular, plural 2)</small> and " .. pattern_link("dub") .. " <small>(plural 1)</small>)"
else
title = "မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု ''" .. word .. "'' <br>(patterns " .. pattern_link("chlap") .. " <small>(singular)</small> and " .. pattern_link("dub") .. " <small>(plural)</small>)"
end
end
-- Helper variables for analyzing the last and penultimate characters
local ultimate, penultimate = get_last_letters(stem)
local first = get_first_char(word)
-- Determine genitive singular ending
local gen_sg = "a"
if (matches_any(TYPE, {"abstr", "comp-deverb", "material", "collect", "loan"})
or matches_any(GEN_ENDING, {"u", "u/a"})
or ends_with_any(word, {"izmus", "x"})
or (ends_with(word, "m") and not is_capital(first))
or (ends_with(word, "z") and is_capital(first)))
and not matches_any(GEN_ENDING, {"a", "a/u"})
then
gen_sg = "u"
end
-- Override genitive singular ending if a specific argument is given
if genitive then
gen_sg = get_last_char(genitive)
end
-- Determine locative singular ending based on specific suffixes and patterns
local loc_sg = "e"
if ends_with_any(word, {"k", "g", "h", "ch"}) or (ends_with(word, "i[ue]s") and TYPE == "loan") then
loc_sg = "u"
elseif (ends_with(word, "ér")
or (ends_with(word, "ál") and not matches_any(word, {"bál", "paškál", "paušál", "šál", "škandál", "žurnál"}))
or matches_any(word, {"Alžír", "klavír", "apríl", "jún", "júl"}))
then
loc_sg = "i"
end
-- Determine genitive plural ending
local gen_pl = stem .. "ov" -- Default genitive plural ending is "ov"
-- Adjust genitive plural for specific place names and patterns
if is_capital(first) and (ends_with_any(word, {"any", "íky", "áky", "iaky"})
or matches_any(word, {"Krompachy", "Kubachy", "Veľbachy", "Spišské Vlachy",
"Žabokreky", "Čechy", "Brezolupy", "Bruty", "Rakoľuby",
"Rakúsy", "Prusy", "Veľaty", "Piešťany", "Bieščary"}))
then
local gen_stem = remove_last_char(word) -- Remove last character to get the base stem
local syllable_count, syllables = split_into_syllables(gen_stem)
local last_syllable = syllables[1]
local penultimate_syllable = syllables[2] or ""
-- Lengthen the vowel if the penultimate syllable is short, otherwise use unchanged stem
if is_long(penultimate_syllable) then
gen_pl = gen_stem
else
gen_pl = remove_suffix(gen_stem, last_syllable) .. lengthen_vowel(last_syllable)
end
end
-- Special cases for genitive plural of specific words
if word == "čas" then
gen_pl = "čias"
elseif word == "raz" then
gen_pl = "ráz"
end
-- Determine instrumental plural ending
local ins_pl = "mi" -- Default instrumental plural ending is "mi"
if ultimate == "m"
or mobile_removed
or ends_with_any(word, {"o", "ius", "eus"})
or (penultimate == "m" and consonants_set[ultimate])
then
ins_pl = "ami"
end
-- Doublets for instrumental plural
if matches_any(word, {"schod", "schody", "fúz", "fúzy", "roh", "rohy",
"paroh", "parohy", "čary", "orech"})
then
set_forms(forms, {"ins_pl2"}, {stem .. "ami"})
elseif matches_any(word, {"zub", "dol", "most", "prst", "piest", "necht"}) then
ins_pl = "ami"
set_forms(forms, {"ins_pl2"}, {stem .. "mi"})
end
-- Populate forms table with singular and plural endings
append_endings(forms, word, stem,
gen_sg, "u", nil, loc_sg, "om",
"y", gen_pl, "om", nil, "och", ins_pl
)
-- Alternative genitive ending
if GEN_ENDING == "a/u" then
set_forms(forms, {"gen_sg2"}, {stem .. "u"})
elseif GEN_ENDING == "u/a" then
set_forms(forms, {"gen_sg2"}, {stem .. "a"})
end
-- Exceptions
if matches_any(word, {"sen", "dol"}) then
set_forms(forms, {"loc_pl2"}, {stem .. "ách"})
elseif word == "čas" then
set_forms(forms, {"gen_pl2"}, {"časov"})
end
-- Animal nouns
if GENDER == "m-anml" then
append_animal_singular(forms, stem)
if matches_any(word, {"vták", "vlk", "pes"}) or PLURAL2 then
local forms2, title2 = declensions["chlap"](word, stem .. gen_sg)
append_second_plural(forms, forms2["nom_pl"], forms2["gen_pl"], forms2["dat_pl"],
forms2["acc_pl"], forms2["loc_pl"], forms2["ins_pl"])
if matches_any(word, {"vták", "vlk", "pes"}) then
switch_plural_forms(forms) --changes the prefered forms
-- Determine alternative dative and locative for some nouns
if matches_any(word, {"vlk", "pes"}) then
set_forms(forms, {"dat_sg2", "loc_sg2"}, {stem .. "u", stem .. "u"})
end
end
end
end
return forms, title -- Return forms table and title for declension
end
declensions["stroj"] = function(word, genitive)
local forms = {}
local mobile_removed = false -- Tracks if a mobile vowel was removed
local words_with_no_mobile = {"kúpeľ", "červeň", "kameň", "jačmeň", "koreň",
"prameň", "prsteň", "jeleň"}
local first = get_first_char(word)
-- Determine the stem by removing mobile vowels if applicable
local stem = word
if (ends_with_any(word, {"ec", "iec", "[^ti]eľ", "oľ", "[^i]eň", "eť", "[^i]er", "el"})
or (ends_with(word, "ac") and (is_capital(first) or word == "desaterac")))
and not matches_any(word, words_with_no_mobile)
then
stem = remove_mobile_vowel(word)
mobile_removed = true -- Mark mobile vowel as removed
end
-- Adjust specific stems based on predefined mappings
stem = ({["dážď"] = "dažď", ["kôš"] = "koš", ["nôž"] = "nož",
["kôň"] = "koň", ["timbre"] = "timbr"})[word] or stem
-- Pluralia tantum
if NUMBER == "pl" then
stem = remove_suffix(word, "e")
end
-- Override if a specific argument is given
if genitive and NUMBER ~= "pl" then
stem = remove_last_char(genitive)
if stem == remove_last_char(remove_last_char(word)) .. get_last_char(word) then
mobile_removed = true
elseif stem == word then
mobile_removed = false
end
end
-- Set "mobile_removed" if genitive was set by the user
if ends_with(word, "e[lr]") and ends_with(stem, "[^e][lr]") then
mobile_removed = true
end
-- Title for the declension table
local title = "မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု ''" .. word .. "'' <br>(pattern " .. pattern_link("stroj") .. ")"
if GENDER == "m-anml" then
if PLURAL2 then
title = "မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု ''" .. word .. "'' <br>(patterns " .. pattern_link("chlap") .. " <small>(singular, plural 2)</small> and " .. pattern_link("stroj") .. " <small>(plural 1)</small>)"
else
title = "မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု ''" .. word .. "'' <br>(patterns " .. pattern_link("chlap") .. " <small>(singular)</small> and " .. pattern_link("stroj") .. " <small>(plural)</small>)"
end
elseif word == "cól" then
title = "မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု ''" .. word .. "'' <br>(pattern " .. pattern_link("stroj") .. " or " .. pattern_link("dub") .. ")"
end
-- Helper variables for analyzing the last and penultimate characters
local ultimate, penultimate = get_last_letters(stem)
local first = get_first_char(word)
-- Determine genitive singular ending
local gen_sg = "a"
if ((matches_any(TYPE, {"abstr", "material"})
or matches_any(GEN_ENDING, {"u", "u/a"}))
and not matches_any(word, {"jačmeň", "kameň", "olej", "loj", "vývoj", "rozvoj"}))
and not matches_any(GEN_ENDING, {"a", "a/u"})
then
gen_sg = "u"
end
-- Override genitive singular ending if a specific argument is given
if genitive then
gen_sg = get_last_char(genitive)
end
-- Determine genitive plural ending
local gen_pl = stem .. "ov" -- Default genitive plural ending is "ov"
-- Adjust genitive plural for specific place names and patterns
if is_capital(first) and (ends_with_any(word, {"áre", "iare"})
or word == "Tlmače")
then
local gen_stem = remove_last_char(word) -- Remove last character to get the base stem
local syllable_count, syllables = split_into_syllables(gen_stem)
local last_syllable = syllables[1]
local penultimate_syllable = syllables[2] or ""
-- Lengthen the vowel if the penultimate syllable is short, otherwise use unchanged stem
if is_long(penultimate_syllable) then
gen_pl = gen_stem
else
gen_pl = remove_suffix(gen_stem, last_syllable) .. lengthen_vowel(last_syllable)
end
end
-- Special cases for genitive plural of specific words
if word == "Ladce" then
gen_pl = "Ladiec"
elseif word == "Vráble" then
gen_pl = "Vrábeľ"
elseif word == "peniaze" then
gen_pl = "peňazí"
elseif matches_any(word, {"deň", "kôň", "groš"}) then
gen_pl = append_ending(stem, "í")
end
-- Determine instrumental plural ending
local ins_pl = "mi" -- Default instrumental plural ending is "mi"
if mobile_removed
or (obstruents_set[penultimate] and obstruents_set[ultimate])
then
ins_pl = "ami"
end
-- Populate forms table with singular and plural endings
append_endings(forms, word, stem,
gen_sg, "u", nil, "i", "om",
"e", gen_pl, "om", nil, "och", ins_pl
)
-- Alternative genitive ending
if GEN_ENDING == "a/u" then
set_forms(forms, {"gen_sg2"}, {stem .. "u"})
elseif GEN_ENDING == "u/a" then
set_forms(forms, {"gen_sg2"}, {stem .. "a"})
end
-- Exceptions
if matches_any(word, {"deň", "poldeň"}) then
set_forms(forms,
{"nom_pl", "acc_pl", "loc_sg2"},
{append_ending(stem, "i"), append_ending(stem, "i"), append_ending(stem, "e")}
)
elseif word == "ďateľ" then
set_forms(forms,
{"gen_sg2", "dat_sg2", "loc_sg2", "ins_sg2",
"nom_pl2", "gen_pl2", "dat_pl2", "acc_pl2", "loc_pl2", "ins_pl2"},
{"ďatľa", "ďatľovi", "ďatľovi", "ďatľom",
"ďatle", "ďatľov", "ďatľom", "ďatle", "ďatľoch", "ďatľami"}
)
elseif word == "cól" then
set_forms(forms,
{"loc_sg2", "nom_pl2", "acc_pl2"},
{"cóle", "cóly", "cóly"}
)
end
-- Animal nouns
if GENDER == "m-anml" then
append_animal_singular(forms, stem)
if PLURAL2 then
local forms2, title2 = declensions["chlap"](word, stem .. gen_sg)
append_second_plural(forms, forms2["nom_pl"], forms2["gen_pl"], forms2["dat_pl"],
forms2["acc_pl"], forms2["loc_pl"], forms2["ins_pl"])
end
end
return forms, title -- Return forms table and title for declension
end
declensions["žena"] = function(word, genitive)
local forms = {}
local stem = remove_suffix(word, "a")
local title = "မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု ''" .. word .. "'' <br>(pattern " .. pattern_link("žena") .. ")"
if ends_with(word, "ea") then
title = "မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု ''" .. word .. "'' <br>(pattern " .. pattern_link("žena") .. ", loanword ending with ''-ea'')"
end
-- Pluralia tantum or genitive
if NUMBER == "pl" then
stem = remove_suffix(word, "y")
end
if genitive and NUMBER ~= "pl" then
stem = remove_suffix(genitive, "y")
end
-- Split into syllables
local gen_pl = ""
local syllable_count, syllables = split_into_syllables(stem)
local word_syllable_count, word_syllables = split_into_syllables(word)
-- Get the last and second-to-last syllables for rule checks
local last_syllable = syllables[1]
local penultimate_syllable = syllables[2] or ""
local word_penultimate_syllable = word_syllables[2] or ""
local ultimate, penultimate = get_last_letters(stem)
-- 1. Add a vowel between the last two consonants of a cluster at the end of the stem
if ends_with_consonant_cluster(last_syllable) or word_syllable_count == 1 then
if (ultimate == "k" and not matches_any(word, {"banka"}))
or (ultimate == "b" and (TYPE == "der" or not sonorants_set[penultimate]))
or sonorants_set[ultimate]
or matches_any(word, {"farba", "karta", "buchta", "astma"})
or (obstruents_set[penultimate] and ultimate == "v")
then
if penultimate ~= "j" and (word_syllable_count == 1 or is_short(word_penultimate_syllable)) then
gen_pl = harden_last_consonant(remove_suffix(stem, ultimate)) .. "ie" .. ultimate
if matches_any(word, {"handra", "perla", "metla", "slivka",
"tehla", "vidly", "karta", "kvapka", "stovka", "doska"})
then
gen_pl = remove_suffix(stem, ultimate) .. "á" .. ultimate
set_forms(forms, {"gen_pl2"}, {harden_last_consonant(remove_suffix(stem, ultimate)) .. "ie" .. ultimate})
end
if matches_any(word, {"jamka", "kvapka"}) then
set_forms(forms, {"gen_pl2"}, {remove_suffix(stem, ultimate) .. "ô" .. ultimate})
end
if matches_any(word, {"astma"}) then
set_forms(forms, {"gen_pl2"}, {stem .. "í"})
end
elseif obstruents_set[ultimate] and (is_long(word_penultimate_syllable) or penultimate == "j") then
gen_pl = remove_suffix(stem, ultimate) .. "o" .. ultimate
elseif (sonorants_set[ultimate] or ultimate == "v") and (is_long(word_penultimate_syllable) or penultimate == "j") then
gen_pl = remove_suffix(stem, ultimate) .. "e" .. ultimate
if penultimate ~= "j" then
set_forms(forms, {"gen_pl2"}, {remove_suffix(stem, ultimate) .. "ie" .. ultimate})
end
end
end
end
-- 2. Add "í" if stem ends with a vowel or a soft consonant
if gen_pl == "" and (vowels_set[ultimate]
or matches_any(word, {"medaila", "pera", "kanva", "panva", "skepsa", "nuansa"}))
then
gen_pl = stem .. "í"
if matches_any(word, {"nuansa"}) then
set_forms(forms, {"gen_pl2"}, {remove_suffix(stem, last_syllable) .. lengthen_vowel(last_syllable)})
end
end
-- 3. Return the stem with no change if conditions match
if gen_pl == "" and (is_long(penultimate_syllable)
or ends_with_any(stem, {"tvor", "ov"})
or mw.ustring.match(last_syllable, "[Jj][eo]")
or (TYPE == "loan" and matches_any(get_vowel(last_syllable), {"e", "o"}))) then
gen_pl = stem
end
-- 4. Logic to use the lengthened vowel if conditions match
if gen_pl == "" and (not (ends_with_consonant_cluster(last_syllable) or vowels_set[ultimate])
or (ends_with_consonant_cluster(last_syllable) and sonorants_set[penultimate] and obstruents_set[ultimate])
or (ends_with_consonant_cluster(last_syllable) and matches_any(penultimate, {"c", "s", "z", "š", "ž", "p"}) and matches_any(ultimate, {"t", "d"})))
and not matches_any(word, {"šachta", "mzda"}) then
gen_pl = remove_suffix(stem, last_syllable) .. lengthen_vowel(last_syllable)
if mw.ustring.find(stem, "au[bcčdďfghjklľmnňpqrsštťvwxzž]$") then
gen_pl = remove_suffix(stem, "a" .. last_syllable) .. "á" .. last_syllable
end
end
-- 5. long -á- instead of -ia- for some loanwords
if matches_any(word, {"pyžama", "šachta"}) then
gen_pl = (word == "pyžama") and "pyžám" or "šácht"
if word == "šachta" then
set_forms(forms, {"gen_pl2"}, {"šachiet"})
end
end
-- 6. Exceptions
if word == "mzda" then
gen_pl = "miezd"
end
if gen_pl == "" then gen_pl = stem end
local dat_pl, loc_pl
if is_long(word_penultimate_syllable) then
dat_pl, loc_pl = "am", "ach"
else
dat_pl, loc_pl = "ám", "ách"
end
local dat_sg, loc_sg
if ultimate == "e" then
dat_sg, loc_sg = "i", "i"
else
dat_sg, loc_sg = "e", "e"
end
append_endings(forms, word, stem,
"y", dat_sg, "u", loc_sg, "ou",
"y", gen_pl, dat_pl, nil, loc_pl, "ami"
)
if matches_any(word, {"zora", "žiara", "žiabra"}) then
set_forms(forms,
{"nom_pl", "acc_pl"},
{stem .. "e", stem .. "e"}
)
end
return forms, title
end
declensions["gazdiná"] = function(word, genitive)
local forms = {}
local stem = remove_suffix(word, "á")
local title = "မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု ''" .. word .. "'' <br>(pattern " .. pattern_link("gazdiná") .. ")"
local syllable_count, syllables = split_into_syllables(stem)
local last_syllable = syllables[1]
local gen_pl = ""
if ends_with_consonant_cluster(last_syllable) then
gen_pl = mw.ustring.sub(stem, 1, -2) .. "ien"
else
gen_pl = remove_suffix(stem, last_syllable) .. lengthen_vowel(last_syllable)
end
append_endings(forms, word, stem,
"ej", "ej", "ú", "ej", "ou",
"é", gen_pl, "ám", nil, "ách", "ami"
)
return forms, title
end
declensions["ulica"] = function(word, genitive)
local forms = {}
local stem = remove_suffix(word, "a")
local title = "မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု ''" .. word .. "'' <br>(pattern " .. pattern_link("ulica") .. ")"
-- Pluralia tantum
if NUMBER == "pl" then
stem = remove_suffix(word, "e")
if ends_with_any(stem, {"d", "t", "n", "l"}) then
stem = soften_last_consonant(stem)
end
end
-- Split into syllables
local gen_pl = ""
local syllable_count, syllables = split_into_syllables(stem)
local word_syllable_count, word_syllables = split_into_syllables(word)
-- Get the last and second-to-last syllables for rule checks
local last_syllable = syllables[1]
local penultimate_syllable = syllables[2] or ""
local word_penultimate_syllable = word_syllables[2] or ""
local ultimate, penultimate = get_last_letters(stem)
local first = get_first_char(word)
-- 1. Add a vowel between the last two consonants of a cluster at the end of the stem
if ends_with_consonant_cluster(last_syllable) then
if (is_capital(first) and ends_with(word, "ce"))
or matches_any(word, {"dverce", "ovca", "fakľa", "drumbľa", "husle", "jasle",
"kachle", "hrable", "šabľa", "mašľa", "žemľa", "ríbezľa", "čerešňa", "sukňa", "višňa"})
then
gen_pl = harden_last_consonant(remove_suffix(stem, ultimate)) .. "ie" .. ultimate
if matches_any(word, {"drumbľa", "husle", "jasle", "kachle", "hrable",
"šabľa", "mašľa", "žemľa", "ríbezľa", "čerešňa", "sukňa", "višňa"}) then
set_forms(forms, {"gen_pl2"}, {append_ending(stem, "í")})
end
end
end
-- 2. Add "í" if stem ends with a vowel or a soft consonant
if gen_pl == "" and (matches_any(ultimate, {"dz", "dž", "ž", "ť", "ď", "j", "i", "y"})
or ends_with_any(word, {"nca", "oľa", "ôľa", "aľa", "ša", "ča"})
or matches_any(word, {"liace", "pasca", "páľa", "trúbeľa", "mrľa", "konope", "večera", "rozopra"})
or (matches_any(ultimate, {"ľ"}) and consonants_set[penultimate])
or (matches_any(ultimate, {"ň"}) and penultimate ~= "y"))
and not matches_any(word, {"papuča", "priča", "hrča", "paprča",
"garniža", "fakľa", "skriňa", "sviňa", "abatiša", "čaša", "fľaša",
"Krkonoše", "ríša", "skrýša"})
then
gen_pl = append_ending(stem, "í")
end
-- 3. Logic to use the lengthened vowel if conditions match
if gen_pl == "" and not ends_with_consonant_cluster(last_syllable) and not vowels_set[ultimate]
and ((ends_with(word, "ca") and TYPE ~= "der")
or ends_with_any(word, {"yňa", "uľa"})
or matches_any(word, {"papuča", "priča", "hrča", "chvíľa", "míľa", "košeľa", "nedeľa",
"guľa", "hoľa", "homoľa", "skriňa", "sviňa", "abatiša", "čaša", "fľaša",
"Krkonoše", "ríša", "skrýša", "garniža", "Hybe", "dvere", "kuša", "moruša"}))
then
if is_long(penultimate_syllable) then
gen_pl = stem
else
gen_pl = remove_suffix(stem, last_syllable) .. lengthen_vowel(last_syllable)
if matches_any(word, {"homoľa", "kuša", "moruša", "hrča", "paprča",
"guľa", "hoľa"})
then
set_forms(forms, {"gen_pl2"}, {append_ending(stem, "í")})
end
end
end
if gen_pl == "" then gen_pl = stem end
local dat_pl, loc_pl
if ends_with_any(stem, {"i", "y"}) or word == "pizza" then
dat_pl, loc_pl = "ám", "ách"
elseif is_long(word_penultimate_syllable) or ends_with(stem, "j") then
dat_pl, loc_pl = "am", "ach"
else
dat_pl, loc_pl = "iam", "iach"
end
append_endings(forms, word, stem,
"e", "i", "u", "i", "ou",
"e", gen_pl, dat_pl, nil, loc_pl, "ami"
)
if word == "rozopra" then
set_forms(forms,
{"dat_pl2", "loc_pl2"},
{"rozoprám", "rozoprách"}
)
elseif word == "dvere" then
set_forms(forms,
{"dat_pl", "loc_pl", "gen_pl2", "ins_pl2"},
{"dverám", "dverách", "dverí", "dvermi"}
)
end
return forms, title
end
declensions["irregular"] = function(word, genitive)
local forms = {}
local title = "မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု ''" .. word .. "'' (irregular)"
if matches_any(word, {"mať", "mater", "mati"}) then
local stem = "mater"
append_endings(forms, word, stem,
"e", "i", "", "i", "ou",
"e", stem .. "í", "iam", "e", "iach", "ami"
)
local accusative = (word == "mater") and {"mater", "mať"} or {"mať", "mater"}
set_forms(forms, {"acc_sg", "acc_sg2"}, accusative)
elseif ends_with(word, "pani") then
local stem = remove_suffix(word, "ni") .. "ň"
append_endings(forms, word, stem,
"ej", "ej", "iu", "ej", "ou",
"ie", stem .. "í", "iam", nil, "iach", "iami"
)
end
return forms, title
end
declensions["dlaň"] = function(word, genitive)
local forms = {}
local words_with_mobile_vowel = {"faloš", "osuheľ", "siheľ", "myseľ"}
local stem
if genitive then
stem = remove_suffix(genitive, "e")
elseif matches_any(word, words_with_mobile_vowel) or ends_with(word, "eň") then
stem = remove_mobile_vowel(word)
else
stem = word
end
local title = "မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု ''" .. word .. "'' <br>(pattern " .. pattern_link("dlaň") .. ")"
local syllable_count, syllables = split_into_syllables(word)
local last_syllable = syllables[1]
local penultimate_syllable = syllables[2] or ""
local last_char = get_last_char(word)
local dat_pl, loc_pl
if is_long(penultimate_syllable) or last_char == "j" then
dat_pl, loc_pl = "am", "ach"
elseif word == "kader" then
dat_pl, loc_pl = "ám", "ách"
else
dat_pl, loc_pl = "iam", "iach"
end
append_endings(forms, word, stem,
"e", "i", nil, "i", "ou",
"e", append_ending(stem, "í"), dat_pl, nil, loc_pl, "ami"
)
if matches_any(word, {"myseľ", "tvár", "hneď", "raž"}) then
set_forms(forms, {"gen_sg2"}, {append_ending(stem, "i")})
end
return forms, title
end
declensions["kosť"] = function(word, genitive)
local forms = {}
local words_with_mobile_vowel = {"voš", "lož", "Ves", "ves", "cirkev", "reďkev"}
local stem = (matches_any(word, words_with_mobile_vowel))
and remove_mobile_vowel(word) or word
if word == "česť" then stem = "cť" end
local title = "မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု ''" .. word .. "'' <br>(pattern " .. pattern_link("kosť") .. ")"
append_endings(forms, word, stem,
"i", "i", nil, "i", "ou",
"i", append_ending(stem, "í"), "iam", nil, "iach", "ami"
)
if word == "hrsť" then
set_forms(forms,
{"nom_pl", "acc_pl"},
{"hrste", "hrste"}
)
elseif word == "lesť" then
append_alternative_singular(forms, "ľsti", "ľsti", nil, "ľsti", "ľsťou")
append_alternative_plural(forms, "ľsti", "ľstí", "ľstiam", nil, "ľstiach", "ľsťami")
elseif matches_any(word, {"cirkev", "reďkev"}) then
set_forms(forms,
{"dat_pl", "loc_pl"},
{stem .. "ám", stem .. "ách"}
)
end
return forms, title
end
declensions["mesto"] = function(word, genitive)
local forms = {}
local ultimate, penultimate = get_last_letters(word)
local special_type = ""
local stem = remove_suffix(word, "o")
if penultimate == "u" and ultimate == "m" then
stem = remove_suffix(word, "um")
special_type = ", of Latin origin ending with ''-um''"
elseif penultimate == "o" and ultimate == "n" then
stem = remove_suffix(word, "on")
special_type = ", of Greek origin ending with ''-on''"
elseif penultimate == "m" and ultimate == "ä" then
stem = remove_suffix(word, "ä") .. "en"
special_type = ", archaic type ending with ''-mä''"
end
-- Pluralia tantum
if NUMBER == "pl" then
stem = remove_suffix(word, ultimate)
end
local title = "မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု ''" .. word .. "'' <br>(pattern " .. pattern_link("mesto") .. special_type .. ")"
local stem_ultimate, stem_penultimate = get_last_letters(stem)
local loc_sg = "e"
if vowels_set[stem_ultimate] or matches_any(stem_ultimate, {"k", "g", "ch", "h"}) then
loc_sg = "u"
elseif matches_any(word, {"vnútro", "nebo"}) then
loc_sg = "i"
end
-- Split into syllables
local gen_pl = ""
local syllable_count, syllables = split_into_syllables(stem)
local word_syllable_count, word_syllables = split_into_syllables(word)
-- Get the last and second-to-last syllables for rule checks
local last_syllable = syllables[1]
local penultimate_syllable = syllables[2] or ""
local word_penultimate_syllable = word_syllables[2] or ""
-- 1. Add a vowel between the last two consonants of a cluster at the end of the stem
if ends_with_consonant_cluster(last_syllable) then
if matches_any(word, {"jedlo", "predjedlo", "jutro", "vrecko", "brvno"}) then
if matches_any(word, {"jedlo", "predjedlo", "jutro"}) then
gen_pl = remove_suffix(stem, stem_ultimate) .. "á" .. stem_ultimate
else
gen_pl = remove_suffix(stem, stem_ultimate) .. "ie" .. stem_ultimate
set_forms(forms, {"gen_pl2"}, {remove_suffix(stem, stem_ultimate) .. "á" .. stem_ultimate})
end
elseif sonorants_set[stem_ultimate] or ends_with_any(last_syllable, {"stv", "ctv", "íčk", "ečk", "očk"}) or TYPE == "dim" then
if stem_penultimate ~= "j" and (word_syllable_count == 1 or ends_with_any(last_syllable, {"stv", "ctv"}) or is_short(word_penultimate_syllable)) then
gen_pl = remove_suffix(stem, stem_ultimate) .. "ie" .. stem_ultimate
elseif obstruents_set[stem_ultimate] and (is_long(word_penultimate_syllable) or stem_penultimate == "j") then
gen_pl = remove_suffix(stem, stem_ultimate) .. "o" .. stem_ultimate
elseif sonorants_set[stem_ultimate] and (is_long(word_penultimate_syllable) or stem_penultimate == "j") then
gen_pl = remove_suffix(stem, stem_ultimate) .. "e" .. stem_ultimate
if stem_penultimate ~= "j" then
set_forms(forms, {"gen_pl2"}, {remove_suffix(stem, stem_ultimate) .. "ie" .. stem_ultimate})
end
end
end
end
-- 2. Add "í" if stem ends with a vowel or a soft consonant
if gen_pl == "" and (vowels_set[stem_ultimate] or soft_consonants_set[stem_ultimate]) then
gen_pl = stem .. "í"
end
-- 3. Return the stem with no change if conditions match
if gen_pl == "" and (is_long(penultimate_syllable)
or ends_with_any(stem, {"vojsk", "ov"})
or (TYPE == "loan" and matches_any(get_vowel(last_syllable), {"e", "o"}))) then
gen_pl = stem
end
-- 4. Logic to use the lengthened vowel if conditions match
if gen_pl == "" and (not (ends_with_consonant_cluster(last_syllable) or vowels_set[stem_ultimate])
or (ends_with_consonant_cluster(last_syllable) and obstruents_set[stem_ultimate])) then
gen_pl = remove_suffix(stem, last_syllable) .. lengthen_vowel(last_syllable)
end
local nom_pl = "á"
if NUMBER == "pl" then
nom_pl = ultimate
end
if gen_pl == "" then gen_pl = stem end
if (is_long(word_penultimate_syllable) or word == "jojo") and not ends_with(word, "ium") then
append_endings(forms, word, stem,
"a", "u", nil, loc_sg, "om",
"a", gen_pl, "am", nil, "ach", "ami"
)
else
append_endings(forms, word, stem,
"a", "u", nil, loc_sg, "om",
nom_pl, gen_pl, "ám", nil, "ách", "ami"
)
end
if matches_any(word, {"oko", "ucho"}) then
local pl_stem = (word == "oko") and "oč" or "uš"
append_second_plural(forms, pl_stem .. "i", pl_stem .. "í", pl_stem .. "iam",
nil, pl_stem .. "iach", pl_stem .. "ami")
switch_plural_forms(forms) --changes the prefered forms
set_forms(forms,
{"gen_pl2"},
{pl_stem .. "ú"}
)
elseif word == "nebo" then
set_forms(forms,
{"nom_pl", "nom_pl2", "gen_pl", "dat_pl", "dat_pl2", "acc_pl",
"acc_pl2", "loc_pl", "loc_pl2", "ins_pl"},
{"nebesá", "nebesia", "nebies", "nebesám", "nebesiam", "nebesá",
"nebesia", "nebesách", "nebesiach", "nebesami"}
)
end
return forms, title
end
declensions["srdce"] = function(word, genitive)
local forms = {}
local stem = remove_suffix(word, "e")
if ends_with(word, "ě") then
stem = remove_suffix(word, "ě")
end
local title = "မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု ''" .. word .. "'' <br>(pattern " .. pattern_link("srdce") .. ")"
if NUMBER == "pl" then
if ends_with(word, "ia") then
stem = remove_suffix(word, "ia")
else
stem = remove_suffix(word, "a")
end
end
if ends_with(stem, "[dtnl]") then
stem = soften_last_consonant(stem)
end
-- Split into syllables
local gen_pl = ""
local syllable_count, syllables = split_into_syllables(stem)
local word_syllable_count, word_syllables = split_into_syllables(word)
-- Get the last and second-to-last syllables for rule checks
local last_syllable = syllables[1]
local penultimate_syllable = syllables[2] or ""
local word_penultimate_syllable = word_syllables[2] or ""
local last_char = get_last_char(stem)
local stem_ultimate, stem_penultimate = get_last_letters(stem)
-- 1 & 2. Lengthen the last syllable's vowel if conditions apply,
-- otherwise leave the stem unchanged if penultimate syllable is long
if not ends_with_consonant_cluster(last_syllable)
or (ends_with(word, "ce") and matches_any(get_vowel(word_penultimate_syllable), {"r", "l"}) and TYPE ~= "dim")
or ends_with(word, "ište") then
if is_long(penultimate_syllable) then
gen_pl = stem -- If penultimate syllable of the stem is long, use the stem unchanged
else
-- Otherwise, lengthen the last syllable's vowel
gen_pl = remove_suffix(stem, last_syllable) .. lengthen_vowel(last_syllable)
end
end
-- 3. Add a vowel between the last two consonants if the conditions apply
if gen_pl == "" and (word == "citoslovce" or word == "vajce"
or ends_with(word, "ce")) then
if stem_penultimate ~= "j" and is_short(word_penultimate_syllable) then
gen_pl = remove_suffix(stem, stem_ultimate) .. "ie" .. stem_ultimate
elseif is_long(word_penultimate_syllable) or stem_penultimate == "j" then
gen_pl = remove_suffix(stem, stem_ultimate) .. "e" .. stem_ultimate
end
end
-- 4. Add "í" to the stem for specific words
if matches_any(word, {"more", "oje", "pole", "lože"}) then
gen_pl = harden_last_consonant(stem) .. "í"
end
-- Fallback: if none of the rules apply, return the original stem
if gen_pl == "" then gen_pl = stem end
if is_long(word_penultimate_syllable) or ends_with(stem, "j") then
append_endings(forms, word, stem,
"a", "u", nil, "i", "om",
"a", gen_pl, "am", nil, "ach", "ami"
)
else
append_endings(forms, word, stem,
"a", "u", nil, "i", "om",
"ia", gen_pl, "iam", nil, "iach", "ami"
)
end
return forms, title
end
declensions["vysvedčenie"] = function(word, genitive)
local forms = {}
local stem = remove_suffix(word, "ie")
if ends_with(word, "í") then
stem = remove_suffix(word, "í")
end
local title = "မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု ''" .. word .. "'' <br>(pattern " .. pattern_link("vysvedčenie") .. ")"
append_endings(forms, word, stem,
"ia", "iu", nil, "í", "ím",
"ia", stem .. "í", "iam", nil, "iach", "iami"
)
if word == "storočie" then
append_second_plural(forms, "stáročia", "stáročí", "stáročiam",
nil, "stáročiach", "stáročiami")
end
return forms, title
end
declensions["dievča"] = function(word, genitive)
local forms = {}
local stem = remove_suffix(word, "a")
if ends_with(word, "ä") then
stem = remove_suffix(word, "ä")
end
local ending = get_last_char(word)
local title = "မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု ''" .. word .. "'' <br>(pattern " .. pattern_link("dievča") .. ")"
local gen_pl = ""
local syllable_count, syllables = split_into_syllables(word)
local last_syllable = syllables[1]
local penultimate_syllable = syllables[2] or ""
if is_long(penultimate_syllable) then
gen_pl = stem .. ending .. "t"
else
gen_pl = append_ending(stem, "iat")
end
append_endings(forms, word, stem,
ending .. "ťa", ending .. "ťu", nil, ending .. "ti", ending .. "ťom",
ending .. "tá", gen_pl, ending .. "tám", nil, ending .. "tách", ending .. "tami"
)
local pl_stem = harden_last_consonant(stem)
append_second_plural(forms, pl_stem .. "ence", pl_stem .. "eniec", pl_stem .. "encom",
nil, pl_stem .. "encoch", pl_stem .. "encami")
if matches_any(word, {"kura", "strídža", "drumblence", "gajdence", "deťúrence"}) then
switch_plural_forms(forms) --changes the prefered forms
unset_alt_forms(forms)
elseif matches_any(word, {"páža", "knieža", "kurča", "plánča", "pôrča",
"zviera", "pachoľa", "mláďa", "dúpä", "chlápä", "žieňa", "nemluvňa"}) then
unset_alt_forms(forms)
elseif matches_any(word, {"prasa", "teľa", "šteňa"}) then
local pl_stem = (word == "šteňa") and "šten" or stem
append_second_plural(forms, pl_stem .. "ce", append_ending(pl_stem, "iec"),
pl_stem .. "com", nil, pl_stem .. "coch", pl_stem .. "cami")
switch_plural_forms(forms) --changes the prefered forms
elseif word == "dieťa" then
set_forms(forms,
{"nom_pl", "gen_pl", "dat_pl", "acc_pl", "loc_pl", "ins_pl"},
{"deti", "detí", "deťom", "deti", "deťoch", "deťmi"}
)
unset_alt_forms(forms)
end
return forms, title
end
declensions["နာမဝိသေသန"] = function(word, genitive)
local forms = {}
local title = "မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု ''" .. word .. "'' (adjective declension)"
local ultimate, penultimate = get_last_letters(word)
local lemma_form = word
if NUMBER == "pl" then
if ends_with(word, "é") then
lemma_form = remove_suffix(word, "é") .. "ý"
elseif ends_with(word, "ie") then
lemma_form = remove_suffix(word, "ie") .. "í"
elseif ends_with_any(word, {"ove", "ine"}) then
lemma_form = remove_suffix(word, "e")
elseif ends_with(word, "e") then
lemma_form = remove_suffix(word, "e") .. "y"
elseif ends_with(word, "í") and not soft_consonants_set[penultimate] then
lemma_form = remove_suffix(word, "í") .. "ý"
elseif ends_with(word, "i") and not soft_consonants_set[penultimate] then
lemma_form = remove_suffix(word, "i") .. "y"
end
else
if GENDER == "f" or GENDER == "n" then
if ends_with_any(word, {"á", "é"}) then
lemma_form = remove_last_char(word) .. "ý"
elseif ends_with_any(word, {"ia", "ie"}) then
lemma_form = remove_suffix(remove_last_char(word), "i") .. "í"
elseif ends_with_any(word, {"ova", "ovo", "ina", "ino"}) then
lemma_form = remove_last_char(word)
elseif ends_with_any(word, {"a", "e"}) then
lemma_form = remove_last_char(word) .. "y"
end
end
end
local forms_raw = m_adj.do_generate_forms({pagename=lemma_form}, "adjective").forms
set_forms(forms,
{"nom_sg"},
{forms_raw["nom_" .. get_first_char(GENDER)][1].form}
)
-- Singular
if GENDER == "f" then
set_forms(forms,
{"gen_sg", "dat_sg", "loc_sg", "ins_sg"},
{
forms_raw["gen_f"][1].form, forms_raw["dat_f"][1].form,
forms_raw["loc_f"][1].form, forms_raw["ins_f"][1].form
}
)
else
set_forms(forms,
{"gen_sg", "dat_sg", "loc_sg", "ins_sg"},
{
forms_raw["gen_mn"][1].form, forms_raw["dat_mn"][1].form,
forms_raw["loc_mn"][1].form, forms_raw["ins_mn"][1].form
}
)
end
-- special accusative singular
if GENDER == "m-pr" or GENDER == "m-anml" then
set_forms(forms,
{"acc_sg"},
{forms_raw["acc_m_an"][1].form}
)
elseif GENDER == "m-in" then
set_forms(forms,
{"acc_sg"},
{forms_raw["acc_m_in"][1].form}
)
else
set_forms(forms,
{"acc_sg"},
{forms_raw["acc_" .. get_first_char(GENDER)][1].form}
)
end
-- Plural
set_forms(forms,
{"gen_pl", "dat_pl", "loc_pl", "ins_pl"},
{
forms_raw["gen_p"][1].form, forms_raw["dat_p"][1].form,
forms_raw["loc_p"][1].form, forms_raw["ins_p"][1].form
}
)
if GENDER == "m-pr" then
set_forms(forms,
{"nom_pl", "acc_sg", "acc_pl"},
{forms_raw["nom_mp_an"][1].form, forms_raw["acc_m_an"][1].form, forms_raw["acc_mp_an"][1].form}
)
else
set_forms(forms,
{"nom_pl", "acc_pl"},
{forms_raw["nom_fnp"][1].form, forms_raw["acc_fnp"][1].form}
)
end
return forms, title
end
declensions["indeclinable"] = function(word, genitive)
local forms = {}
local title = "မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု ''" .. word .. "'' (indeclinable)"
local cases = {"nom", "gen", "dat", "acc", "loc", "ins"} -- List of cases
local numbers = {"sg", "pl"}
for _, case in ipairs(cases) do
for _, number in ipairs(numbers) do
local form_key = case .. "_" .. number
forms[form_key] = word
end
end
-- Surnames ending with -ů, -eje, -oje and -ovie
if TYPE == "surn" and ends_with_any(word, {"ů", "eje", "e", "oje", "ovie"}) then
append_second_plural(forms, word .. "ovci", word .. "ovcov", word .. "ovcom",
word .. "ovcov", word .. "ovcoch", word .. "ovcami")
end
return forms, title
end
--[=[
Partial declination functions
]=]--
function check_gender(gender)
if gender == nil then
return error("No gender entered. Please pass one of these values as parameter 1: m-pr, m-anml, m-in, f, n.")
elseif allowed_genders_set[gender] then
return gender
else
return error("Unknown gender. Please pass one of these values as parameter 1: m-pr, m-anml, m-in, f, n.")
end
end
function determine_pattern(word, genitive)
local pattern
local phon_word = (PRONUNCIATION) and PRONUNCIATION or word
local ultimate, penultimate = get_last_letters(phon_word)
local first = get_first_char(phon_word)
local dlan_endings = m_table.listToSet({"ň", "č", "ž", "ľ", "ď", "j", "š", "m", "z", "dz", "x"})
local dlan_exceptions_neg = m_table.listToSet({"reč", "seč", "lož", "beľ", "soľ", "mlaď", "meď", "myš", "voš"})
local dlan_exceptions_pos = m_table.listToSet({"obec", "pec", "čelusť", "kysť", "päsť", "Provence"})
local dlan_end_with_r_t = m_table.listToSet({"kader", "neter", "šír", "tvár",
"činovať", "drobäť", "droboť", "hať", "hrochoť", "Hrochoť", "hrsť", "inovať", "labuť",
"niť", "obeť", "paruť", "pažiť", "pečať", "perepúť", "perleť", "peruť", "pípeť", "plť",
"postať", "prť", "púť", "sieť", "sihoť", "stať", "štvrť", "trať", "úvrať", "vňať",
"violeť", "záhať", "žlť"})
local stroj_exceptions_pos = {"timbre", "cól", "gáfor", "hámor", "kôpor",
"kufor", "Pôtor", "šiator", "pedál", "sandál", "kanál", "peniaz", "daniel"}
local stroj_exceptions_neg = {"nesvár", "nešvár", "pár", "suchopár", "svár", "ker"}
if matches_any(ultimate, {"r", "l"}) and penultimate == "e" and not ends_with(phon_word, "ier") and genitive == nil then
genitive = phon_word .. "a"
end
if mw.ustring.find(phon_word, " ") or word == genitive then
return "indeclinable"
end
if NUMBER == "pl" then
if matches_any(ultimate, {"é", "i", "í"}) or (ultimate == "e" and ends_with(genitive, "ch")) then
pattern = "adjective"
elseif GENDER == "m-in" then
if ultimate == "y" then
pattern = "dub"
else
pattern = "stroj"
end
elseif GENDER == "f" then
if ultimate == "y" then
pattern = "žena"
else
pattern = "ulica"
end
elseif GENDER == "n" then
if ultimate == "á" then
pattern = "mesto"
elseif penultimate == "i" and ultimate == "a" then
pattern = "srdce"
else
if soft_consonants_set[penultimate] then
pattern = "srdce"
else
pattern = "mesto"
end
end
end
else
if GENDER == "m-pr" then
if (matches_any(ultimate, {"y", "ý", "i", "í"}) and not ends_with_any(genitive, {"[yií]ho", "a"})
and not (TYPE == "surn" and matches_any(penultimate .. ultimate, {"ay", "ai"})))
or (matches_any(penultimate .. ultimate, {"ov", "in"}) and ends_with_any(genitive, {"ovho", "inho"}))
then
pattern = "နာမဝိသေသန"
elseif ultimate == "a"
or (TYPE == "surn" and matches_any(ultimate, {"e", "ě"}) and (penultimate .. ultimate == "ně" or ends_with(genitive, "u")))
then
pattern = "hrdina"
elseif (matches_any(ultimate, {"i", "í", "y", "e", "é", "ä"})
or (TYPE == "name" and matches_any(ultimate, {"ü", "ö", "ő"}))
or matches_any(phon_word, {"Hrabě", "Poupě"}))
and not (TYPE == "surn" and (ends_with_any(phon_word, {"ay", "ai", "eje", "oje", "ovie"}) or ends_with(genitive, "a")))
then
pattern = "kuli"
elseif TYPE == "surn" and ends_with_any(phon_word, {"ů", "eje", "oje", "ovie"}) then
pattern = "indeclinable"
else
pattern = "chlap"
end
elseif GENDER == "m-in" or GENDER == "m-anml" then
if matches_any(ultimate, {"y", "ý", "i", "í"})
or (matches_any(penultimate .. ultimate, {"ov", "in"}) and ends_with(genitive, "ho"))
then
pattern = "နာမဝိသေသန"
elseif (soft_consonants_set[ultimate]
or (matches_any(ultimate, {"r", "l"}) and penultimate == "e"
and (ends_with(genitive, "[^e][rl]a")))
or ends_with_any(phon_word, {"ár", "iar", "ier"})
or matches_any(phon_word, stroj_exceptions_pos))
and not matches_any(phon_word, stroj_exceptions_neg)
then
pattern = "stroj"
else
pattern = "dub"
end
elseif GENDER == "f" then
if matches_any(phon_word, {"gazdiná", "švagriná", "testiná", "ujčiná", "stryná",
"kňažná", "kráľovná", "cisárovná", "cárovná", "šľachtičná", "princezná"
}) then
pattern = "gazdiná"
elseif ultimate == "a" and not ends_with(genitive, "ej") then
if soft_consonants_set[penultimate] or matches_any(penultimate, {"i", "y"}) or matches_any(phon_word, {"rozopra", "konopa", "večera"}) then
pattern = "ulica"
else
pattern = "žena"
end
elseif matches_any(ultimate, {"a", "á"})
or (ends_with_any(phon_word, {"ova", "ina"}) and ends_with(genitive, "ej"))
then
pattern = "adjective"
elseif ends_with(phon_word, "pani") or matches_any(phon_word, {"Mať", "mať", "mater", "mati"}) then
pattern = "irregular"
else
if not dlan_exceptions_neg[phon_word]
and (dlan_endings[ultimate] or dlan_exceptions_pos[phon_word]
or dlan_end_with_r_t[phon_word] or (penultimate == "š" and ultimate == "ť" and not is_capital(first)))
then
pattern = "dlaň"
else
pattern = "kosť"
end
end
if genitive then
local g_ultimate = get_last_char(genitive)
if g_ultimate == "y" then
pattern = "žena"
elseif g_ultimate == "i" then
pattern = "kosť"
end
end
elseif GENDER == "n" then
if (ultimate == "o" or (penultimate == "u" and ultimate == "m")
or (penultimate == "o" and ultimate == "n")
or (penultimate == "m" and ultimate == "ä"))
and not ends_with(genitive, "ho")
then
pattern = "mesto"
elseif (penultimate == "i" and ultimate == "e")
or ultimate == "í"
then
pattern = "vysvedčenie"
elseif (ultimate == "e" or ultimate == "ě")
and not ends_with(genitive, "ho")
then
pattern = "srdce"
elseif matches_any(ultimate, {"a", "ä"}) then
pattern = "dievča"
elseif matches_any(ultimate, {"e", "é"})
or ends_with_any(phon_word, {"ovo", "ino"})
then
pattern = "နာမဝိသေသန"
else
pattern = "indeclinable"
end
end
end
return pattern
end
function append_ending(stem1, ending)
if matches_any(get_first_char(ending), {"e", "i", "é", "í"}) then
return harden_last_consonant(stem1) .. ending
else
return stem1 .. ending
end
end
function append_endings(forms, word, stem, end2, end3, end4, end5, end6, end7, gen_pl, end9, end10, end11, end12)
forms["nom_sg"] = word
forms["gen_sg"] = append_ending(stem, end2)
forms["dat_sg"] = append_ending(stem, end3)
if GENDER == "m-pr"
or (GENDER == "f"
and (ends_with_any(word, {"pani", "a", "á"})
or matches_any(word, {"Mať", "mať", "mater", "mati"})))
then
forms["acc_sg"] = append_ending(stem, end4)
else
forms["acc_sg"] = word
end
forms["loc_sg"] = append_ending(stem, end5)
forms["ins_sg"] = append_ending(stem, end6)
local nom_pl = stem
if ends_with_any(stem, {"k", "ch"}) and matches_any(GENDER, {"m-pr", "m-anml"}) and end7 == "i" then
if ends_with(stem, "k") then
nom_pl = remove_suffix(stem, "k") .. "c"
else
nom_pl = remove_suffix(stem, "ch") .. "s"
end
end
forms["nom_pl"] = append_ending(nom_pl, end7)
forms["gen_pl"] = gen_pl
forms["dat_pl"] = append_ending(stem, end9)
if GENDER == "m-pr"
or end10
or (GENDER == "f"
and (ends_with_any(word, {"pani"})
or matches_any(word, {"Mať", "mať", "mater", "mati"})))
then
forms["acc_pl"] = append_ending(stem, end10)
else
forms["acc_pl"] = forms["nom_pl"]
end
forms["loc_pl"] = append_ending(stem, end11)
forms["ins_pl"] = append_ending(stem, end12)
end
function set_forms(forms, indices, values)
for i = 1, #indices do
forms[indices[i]] = values[i]
end
end
function switch_plural_forms(forms)
local indices = {"nom_pl", "gen_pl", "dat_pl", "acc_pl", "loc_pl", "ins_pl"}
for _, index in ipairs(indices) do
forms[index], forms[index .. "_alt"] = forms[index .. "_alt"], forms[index]
end
end
function unset_alt_forms(forms)
for key in pairs(forms) do
if mw.ustring.find(key, "_alt$") then
forms[key] = nil
end
end
end
function append_alternative_singular(forms, form2, form3, form4, form5, form6)
forms["gen_sg2"] = (forms["gen_sg"] ~= form2) and form2
forms["dat_sg2"] = (forms["dat_sg"] ~= form3) and form3
if matches_any(GENDER, {"m-pr", "m-anml"})
or (GENDER == "f"
and (ends_with_any(word, {"pani", "a", "á"})
or matches_any(word, {"Mať", "mať", "mater", "mati"})))
then
forms["acc_sg2"] = (forms["acc_sg"] ~= form4) and form4
end
forms["loc_sg2"] = (forms["loc_sg"] ~= form5) and form5
forms["ins_sg2"] = (forms["ins_sg"] ~= form6) and form6
end
function append_alternative_plural(forms, form1, form2, form3, form4, form5, form6)
forms["nom_pl2"] = (forms["nom_pl"] ~= form2) and form1
forms["gen_pl2"] = (forms["gen_pl"] ~= form2) and form2
forms["dat_pl2"] = (forms["dat_pl"] ~= form2) and form3
if form4 ~= nil and forms["acc_pl"] ~= form4 then
forms["acc_pl2"] = form4
elseif forms["acc_pl"] ~= form1 then
forms["acc_pl2"] = form1
end
forms["loc_pl2"] = (forms["loc_pl"] ~= form2) and form5
forms["ins_pl2"] = (forms["ins_pl"] ~= form2) and form6
end
function append_second_plural(forms, form1, form2, form3, form4, form5, form6)
forms["nom_pl_alt"] = form1
forms["gen_pl_alt"] = form2
forms["dat_pl_alt"] = form3
if form4 ~= nil then
forms["acc_pl_alt"] = form4
else
forms["acc_pl_alt"] = forms["nom_pl_alt"]
end
forms["loc_pl_alt"] = form5
forms["ins_pl_alt"] = form6
end
function append_animal_singular(forms, stem)
set_forms(forms,
{"gen_sg", "dat_sg", "acc_sg", "loc_sg"},
{
append_ending(stem, "a"),
append_ending(stem, "ovi"),
append_ending(stem, "a"),
append_ending(stem, "ovi")
}
)
end
function get_last_char(str)
local last = mw.ustring.sub(str, -1, -1)
return last
end
function get_first_char(str)
local first = mw.ustring.sub(str, 1, 1)
return first
end
function remove_last_char(str)
local stem = mw.ustring.sub(str, 1, -2)
return stem
end
function is_capital(str)
return mw.ustring.find(str, "[A-Z]")
end
function get_last_letters(word)
local ultimate = get_last_char(word)
local penultimate = get_last_char(remove_last_char(word))
local antepenultimate = get_last_char(remove_last_char(remove_last_char(word)))
if (penultimate == "c" and ultimate == "h")
or (penultimate == "d" and (ultimate == "z" or ultimate == "ž"))
then
ultimate = penultimate .. ultimate
penultimate = antepenultimate
antepenultimate = get_last_char(remove_last_char(remove_last_char(remove_last_char(word))))
end
if (antepenultimate == "c" and penultimate == "h")
or (antepenultimate == "d" and (penultimate == "z" or penultimate == "ž"))
then
penultimate = antepenultimate .. penultimate
end
if penultimate == "v" and consonants_set[ultimate] and not matches_any(ultimate, {"r", "l", "ŕ", "ĺ"}) then
penultimate = "ʋ"
end
return ultimate, penultimate
end
function ends_with(word, suffix)
-- Check if suffix matches the end of word
word = (word ~= nil) and word or ""
return mw.ustring.find(word, suffix .. "$") ~= nil
end
function ends_with_any(word, suffixes)
for _, suffix in ipairs(suffixes) do
if ends_with(word, suffix) then
return true -- Return true if any suffix matches
end
end
return false -- Return false if no suffix matches
end
function matches_any(value, list)
for _, item in ipairs(list) do
if value == item then
return true
end
end
return false
end
function get_vowel(syllable)
-- Define patterns for diphthongs and vowels
local diphthong_pattern = "ia|ie|iu|ô"
local vowel_pattern = "[aeiouyáéíóúýäöőüű]"
local syllabic_consonant_pattern = "[rl]"
-- Check for a diphthong first
local diphthong = mw.ustring.match(syllable, diphthong_pattern)
if diphthong then
return diphthong
end
-- Check for a single vowel
local vowel = mw.ustring.match(syllable, vowel_pattern)
if vowel then
return vowel
end
-- Check for a syllabic consonant if no vowel is found
local syllabic_consonant = mw.ustring.match(syllable, syllabic_consonant_pattern)
if syllabic_consonant then
return syllabic_consonant
end
return nil -- Return nil if no vowel or syllabic consonant is found
end
-- Function to split a word into characters and bigraphs
function split_into_letter_units(word)
local units = {}
local i_word = 1
local i_pron = 1
local word_len = mw.ustring.len(word)
local pron_len = PRONUNCIATION and mw.ustring.len(PRONUNCIATION) or 0
while i_word <= word_len do
local two_char = mw.ustring.sub(word, i_word, i_word + 1)
-- Check if PRONUNCIATION forbids combining here
local combine_forbidden = false
if PRONUNCIATION then
-- Advance pronunciation pointer to skip slashes until it aligns with actual letters
-- We only block combination if the *next* character in PRON is a slash
while i_pron <= pron_len and mw.ustring.sub(PRONUNCIATION, i_pron, i_pron) == "/" do
i_pron = i_pron + 1
end
-- Look ahead: is the *next* pronunciation char a slash?
if i_pron < pron_len then
local next_ch = mw.ustring.sub(PRONUNCIATION, i_pron + 1, i_pron + 1)
if next_ch == "/" then
combine_forbidden = true
end
end
end
-- Normal combination if allowed
if not combine_forbidden and (bigraphs_set[two_char] or diphthongs_set[two_char]) then
table.insert(units, two_char)
i_word = i_word + 2
i_pron = i_pron + 2 -- move pronunciation index along with it
else
-- Fallback: single character
local char = mw.ustring.sub(word, i_word, i_word)
table.insert(units, char)
i_word = i_word + 1
i_pron = i_pron + 1
end
end
return units
end
-- check if a unit is a vowel or syllabic element
function is_vowel(unit, prev_unit, next_unit)
if diphthongs_set[unit] then return true end
if vowels_set[unit] then return true end
-- Check if 'r' or 'l' are syllabic (preceded and followed by consonants)
if matches_any(unit, {"r", "ŕ", "l", "ĺ"})
and prev_unit and next_unit
and not (vowels_set[prev_unit] or vowels_set[next_unit]
or diphthongs_set[prev_unit] or diphthongs_set[next_unit])
then
return true
end
return false
end
-- Function to split a word into syllables according to Slovak rules
function split_into_syllables(word)
local units = split_into_letter_units(word)
local syllables = {}
local current_syllable = ""
local i = 1
local length = #units
local first_vowel_found = false -- Flag to indicate when the first vowel has been encountered
-- Iterate over the units in the word
while i <= length do
local unit = units[i]
local next_unit = i < length and units[i + 1] or nil
local previous_unit = i > 1 and units[i - 1] or nil
local is_current_vowel = is_vowel(unit, previous_unit, next_unit)
-- If we haven't encountered the first vowel, keep adding to the first syllable
if not first_vowel_found then
current_syllable = current_syllable .. unit
if is_current_vowel then
first_vowel_found = true -- Mark that the first vowel has been found
end
else
if is_current_vowel then
-- If a vowel is encountered after the first vowel has been found, finalize the current syllable
if current_syllable ~= "" and is_vowel(previous_unit, nil, nil) then
table.insert(syllables, current_syllable)
current_syllable = ""
end
current_syllable = current_syllable .. unit
else
-- Handling consonants between vowels
local consonant_cluster = unit
-- Collect any consecutive consonants into a cluster
local j = i + 1
while j <= length and not is_vowel(units[j], units[j - 1], units[j + 1]) do
consonant_cluster = consonant_cluster .. units[j]
j = j + 1
end
local consonant_count = mw.ustring.len(consonant_cluster)
if next_unit and is_vowel(next_unit, unit, units[j]) then
-- Apply syllable rules based on the number of consonants in the cluster
if consonant_count == 1 then
-- Rule 3: Single consonant goes to the next syllable
table.insert(syllables, current_syllable) -- End the current syllable without the consonant
current_syllable = consonant_cluster -- Start the next syllable with the consonant
elseif consonant_count == 2 then
-- Rule 4: Two consonants split between syllables
current_syllable = current_syllable .. mw.ustring.sub(consonant_cluster, 1, 1)
table.insert(syllables, current_syllable)
current_syllable = mw.ustring.sub(consonant_cluster, 2, 2)
else
-- Rule 5: Three or more consonants - first goes with current syllable, rest with next
current_syllable = current_syllable .. mw.ustring.sub(consonant_cluster, 1, 1)
table.insert(syllables, current_syllable)
current_syllable = mw.ustring.sub(consonant_cluster, 2)
end
i = j - 1 -- Adjust the index to skip the processed consonants
else
current_syllable = current_syllable .. unit
end
end
end
i = i + 1
end
-- Add any remaining characters as the final syllable
if #current_syllable > 0 then
table.insert(syllables, current_syllable)
end
-- Reverse the syllables array for the requested output order
local reversed_syllables = {}
for j = #syllables, 1, -1 do
reversed_syllables[#reversed_syllables + 1] = syllables[j]
end
-- Return the count of syllables and the reversed syllable array
return #syllables, reversed_syllables
end
function is_long(syllable)
return mw.ustring.find(syllable, "[áéíóúýôĺŕ]") ~= nil or mw.ustring.find(syllable, "i[aeu]") ~= nil
end
function is_short(syllable)
return not is_long(syllable)
end
local function get_last_consonant_before_vowel(syllable)
local vowel = get_vowel(syllable)
-- If there is no vowel in the syllable, return false
if not vowel then
return false
end
-- Find the position of the vowel in the syllable
local vowel_pos = mw.ustring.find(syllable, vowel)
-- Loop backwards from the position of the vowel to find the last consonant
for i = vowel_pos - 1, 1, -1 do
local char = mw.ustring.sub(syllable, i, i)
if not mw.ustring.find(char, "[aeiouáéíóúýôä]") then
return char -- Return the last consonant before the vowel
end
end
return false -- Return false if no consonant is found before the vowel
end
-- Function to lengthen the last vowel in a syllable if it’s not already long
function lengthen_vowel(syllable)
if is_long(syllable) then
return syllable -- Return as-is if the syllable is already long
end
local lengthening_map = {
["a"] = "á", ["i"] = "í", ["y"] = "ý", ["u"] = "ú",
["ä"] = "ia", ["e"] = "ie", ["o"] = "ô"
}
local cons_map = {
["ď"] = "d", ["ť"] = "t", ["ň"] = "n", ["ľ"] = "l"
}
-- Check for regular vowels first and replace if found
for vowel, long_vowel in pairs(lengthening_map) do
if mw.ustring.find(syllable, vowel) then
-- if there is a soft consonant before "a", it becomes "ia" instead of "á"
local last_cons = get_last_consonant_before_vowel(syllable) or ""
if soft_consonants_set[last_cons] and last_cons ~= "j" and vowel == "a" then
long_vowel = "ia"
end
-- if a or ä changes into "ia", the previous consonant should be written as hard
if matches_any(vowel, {"ä", "a"}) and matches_any(last_cons, {"ď", "ť", "ň", "ľ"}) then
syllable = mw.ustring.gsub(syllable, last_cons .. vowel, cons_map[last_cons] .. vowel, 1)
end
syllable = mw.ustring.gsub(syllable, vowel, long_vowel, 1)
return syllable -- Return immediately after replacing a regular vowel
end
end
-- Only replace "r" and "l" if no other vowels were found
if not mw.ustring.find(syllable, "[aeiouyáéíóúýôä]") then
syllable = mw.ustring.gsub(syllable, "r", "ŕ")
syllable = mw.ustring.gsub(syllable, "l", "ĺ")
end
return syllable
end
-- Helper function to determine if the syllable ends with a consonant cluster
function ends_with_consonant_cluster(last_syllable)
local last_char = get_last_char(last_syllable)
local second_last_char = mw.ustring.sub(last_syllable, -2, -2)
local third_last_char = mw.ustring.sub(last_syllable, -3, -3)
local last_two_chars = mw.ustring.sub(last_syllable, -2)
-- Check if the syllable contains any regular vowels
local has_vowel = mw.ustring.find(last_syllable, "[aeiouyáéíóúýôä]")
if has_vowel then
-- If the last two characters form a digraph, check the third-last character for a cluster
if bigraphs_set[last_two_chars] then
return not vowels_set[third_last_char]
else
-- If no digraph, just check the last two characters
return not (vowels_set[last_char] or vowels_set[second_last_char]
or diphthongs_set[last_char] or diphthongs_set[second_last_char])
end
else
-- No regular vowel; treat `r` or `l` as syllabic if either is in the last two characters
if matches_any(last_char, {'ŕ', 'ĺ'}) or matches_any(second_last_char, {'ŕ', 'ĺ'}) then
return false
elseif mw.ustring.find(last_syllable, "[bcčdďfghjkľmnňpqsštťvwxzž][rl][bcčdďfghjkľmnňpqysštťvwxzž][rl]$") then
return true
else
-- No syllabic `r` or `l`, so both characters are treated as consonants
return not vowels_set[last_char] and not vowels_set[second_last_char]
end
end
end
function remove_mobile_vowel(word)
local units = split_into_letter_units(word) -- Split word into units
for i = #units, 1, -1 do
local unit = units[i]
if matches_any(unit, {"e", "ie", "o", "i", "á"}) then
-- Remove the mobile vowel unit and reassemble the word
table.remove(units, i)
return table.concat(units)
end
end
return word -- Return the original word if no mobile vowel is found
end
function soften_last_consonant(str)
local consonants_t = { ["c"] = "č", ["d"] = "ď", ["l"] = "ľ", ["n"] = "ň",
["s"] = "š", ["t"] = "ť", ["z"] = "ž" }
local last_char = get_last_char(str)
-- Check if the last character is in consonants_t and replace if needed
return consonants_t[last_char] and remove_last_char(str) .. consonants_t[last_char] or str
end
function harden_last_consonant(str)
local soft_to_hard = { ["ď"] = "d", ["ť"] = "t", ["ň"] = "n", ["ľ"] = "l" }
local last_char = get_last_char(str)
-- Check if the last character is a soft consonant and replace if needed
return soft_to_hard[last_char] and remove_last_char(str) .. soft_to_hard[last_char] or str
end
function remove_suffix(form, suffix)
if mw.ustring.find(form, suffix .. "$") then
local length = mw.ustring.len(suffix)
return mw.ustring.sub(form, 1, -length-1)
end
return form
end
function pattern_link(pattern)
return "''[[Appendix:Slovak declension pattern " .. pattern .. "|" .. pattern .. "]]''"
end
function decline_with_more_stems(genitive)
local genitives = {}
for part in mw.ustring.gmatch(genitive, "[^/]+") do
table.insert(genitives, part)
end
local forms, title = declensions[PATTERN](PAGENAME, genitives[1])
normalize_forms(forms)
local forms2, title2 = declensions[PATTERN](PAGENAME, genitives[2])
normalize_forms(forms2)
append_alternative_singular(forms, forms2["gen_sg"], forms2["dat_sg"], forms2["acc_sg"],
forms2["loc_sg"], forms2["ins_sg"])
append_alternative_plural(forms, forms2["nom_pl"], forms2["gen_pl"], forms2["dat_pl"],
forms2["acc_pl"], forms2["loc_pl"], forms2["ins_pl"])
return forms, title
end
function split_into_units(expression, genitive)
-- Split the original expression into words
local words = {}
for word in mw.ustring.gmatch(expression, "%S+") do
table.insert(words, word)
end
-- Split the genitive phrase into words, if provided
local gen_words = {}
if genitive then
for word in mw.ustring.gmatch(genitive, "%S+") do
table.insert(gen_words, word)
end
-- Check if the genitive phrase has the same structure as the original
if #gen_words ~= #words then
error("Genitive phrase must have the same number of words as the original expression.")
end
end
-- Combine words into units, grouping prepositional phrases for both expressions
local units = {}
local gen_units = {}
local i = 1
while i <= #words do
if prepositions_set[words[i]] and words[i + 1] then
-- Combine preposition with the following words as one unit
local phrase = words[i]
local gen_phrase = genitive and gen_words[i] or nil
i = i + 1
while i <= #words do
phrase = phrase .. " " .. words[i]
if genitive then
gen_phrase = gen_phrase .. " " .. gen_words[i]
end
if i == #words then
table.insert(units, phrase)
if genitive then table.insert(gen_units, gen_phrase) end
end
i = i + 1
end
else
-- Add standalone word as a unit
table.insert(units, words[i])
if genitive then
table.insert(gen_units, gen_words[i])
end
i = i + 1
end
end
-- Return both units and genitive units
return units, gen_units
end
function generate_combined_forms(units, gen_units)
-- Process each unit to generate forms
local all_forms = {}
local patterns = ""
for i = 1, #units do
local unit = units[i]
local gen_unit = gen_units[i]
if conjunctions_set[unit] or unit == gen_unit then
-- Conjunctions are indeclinable
local forms = declensions["indeclinable"](unit, gen_unit)
table.insert(all_forms, forms)
else
-- Decline each unit using determine_pattern and declensions
local pattern = determine_pattern(unit, gen_unit)
local forms, title = declensions[pattern](unit, gen_unit)
normalize_forms(forms)
table.insert(all_forms, forms)
end
end
-- Combine forms into a single forms table
local combined_forms = {}
local cases = {"nom", "gen", "dat", "acc", "loc", "ins"}
local numbers = {"sg", "pl"}
-- check if vocative and plural 2 forms are necessary
for _, forms in ipairs(all_forms) do
if forms["voc_sg"] and #cases == 6 then
table.insert(cases, "voc")
end
if forms["nom_pl_alt"] and #numbers == 2 then
table.insert(numbers, "pl_alt")
end
end
for _, case in ipairs(cases) do
for _, number in ipairs(numbers) do
local form_key = case .. "_" .. number
local combined_form, highest_index = {}, 1
-- Gather primary and numbered alternative forms (e.g., gen_sg2, gen_sg3)
for _, forms in ipairs(all_forms) do
local primary_form = forms[form_key] or forms["nom_" .. number] or forms[case .. "_pl"]
table.insert(combined_form, primary_form)
-- Check the highest alternative index
for alt_index = 2, 4 do
local alt_key = form_key .. alt_index
if forms[alt_key] then
highest_index = alt_index
end
end
end
-- Combine primary forms
combined_forms[form_key] = mw.ustring.gsub(table.concat(combined_form, " "), "^%s+", "")
-- Combine alternative forms if present
if highest_index > 1 then
for alt_index = 2, highest_index do
-- Check and add numbered alternative forms
local alt_key = form_key .. alt_index
alt_form = {}
for _, forms in ipairs(all_forms) do
local primary_form = forms[form_key] or forms["nom_" .. number]
if forms[alt_key] then
table.insert(alt_form, forms[alt_key])
else
table.insert(alt_form, primary_form)
end
end
combined_forms[alt_key] = mw.ustring.gsub(table.concat(alt_form, " "), "^%s+", "")
end
end
end
end
return combined_forms
end
function normalize_forms(forms)
-- Step 1: Remove forms based on NUMBER
if NUMBER == "sg" then
for key in pairs(forms) do
if mw.ustring.find(key, "_pl") then
forms[key] = nil -- Remove plural forms if "n" is "sg"
end
end
elseif NUMBER == "pl" then
for key in pairs(forms) do
if mw.ustring.find(key, "_sg") then
forms[key] = nil -- Remove singular forms if "n" is "pl"
end
end
end
-- Step 2: Ensure all mandatory indices are set
local cases = {"nom", "gen", "dat", "acc", "loc", "ins"}
local numbers = {"sg", "pl"}
for _, case in ipairs(cases) do
for _, number in ipairs(numbers) do
local form_key = case .. "_" .. number
if not forms[form_key] then
forms[form_key] = "—" -- Set missing forms to —
end
end
end
-- Step 3: Create missing _pl_alt indices if at least one exists
local has_alt_plural = false
for key in pairs(forms) do
if mw.ustring.find(key, "_pl_alt") then
has_alt_plural = true
break
end
end
if has_alt_plural then
for _, case in ipairs(cases) do
local form_key_alt = case .. "_pl_alt"
if not forms[form_key_alt] then
forms[form_key_alt] = "—" -- Create missing _pl_alt forms
end
end
end
-- Step 4: Create vocative plural forms if voc_sg exists
if forms["voc_sg"] then
forms["voc_pl"] = forms["nom_pl"] -- Set voc_pl to nom_pl
if has_alt_plural then
forms["voc_pl_alt"] = forms["nom_pl_alt"] -- Set voc_pl_alt to nom_pl_alt if it exists
end
end
end
function specified_by_user(forms, args)
local cases = {nom = true, gen = true, dat = true, acc = true, voc = true, loc = true, ins = true}
local numbers = {sg = true, pl = true}
for key, value in pairs(args) do
-- Match the pattern "<case>_<number><optional digit>" using mw.ustring.match
local case, number, optional_digit = mw.ustring.match(key, "^(%a%a%a)_(%a%a)(%d?)$")
-- Check if it matches the cases and numbers you want
if case and cases[case] and number and numbers[number] then
forms[key] = make_link(value, case .. "|" .. get_first_char(number))
end
end
end
function make_link(link, accel_form)
local new_link = link
-- If link is not empty, valid, and not "—", create the full link
if link ~= "" and link and link ~= "—" then
new_link = m_links.full_link({lang = lang, term = link, accel = {form = accel_form}})
end
return new_link
end
function make_table_header(title)
return m_inflection_table.make_top{
title = title,
palette = 'blue',
tall = 'yes'
}
end
function make_simple_row(forms, case, mnw_case)
local case_code = mw.ustring.sub(case, 1, 3)
local row = "<tr><th>" .. mnw_case .. "</th>"
-- Singular
if NUMBER ~= "pl" then
row = row .. "<td><span lang=\"sk\">" .. make_link(forms[case_code .. "_sg"], case_code .. "|s") .. "</span>"
-- Loop to check and display secondary singular forms in the same cell
for i = 2, 4 do
local form_key = case_code .. "_sg" .. i
if not forms[form_key] then
break -- Exit loop if form doesn't exist
end
row = row .. ",<br /><span lang=\"sk\">" .. make_link(forms[form_key], case_code .. "|s") .. "</span>"
end
row = row .. "</td>"
end
-- Plural
if NUMBER ~= "sg" then
-- Primary plural form
row = row .. "<td><span lang=\"sk\">" .. make_link(forms[case_code .. "_pl"], case_code .. "|p") .. "</span>"
-- Loop to check and display secondary plural forms in the same cell
for i = 2, 4 do
local form_key = case_code .. "_pl" .. i
if not forms[form_key] then
break -- Exit loop if form doesn't exist
end
row = row .. ",<br /><span lang=\"sk\">" .. make_link(forms[form_key], case_code .. "|p") .. "</span>"
end
row = row .. "</td>"
-- Check for alternative plural and add it in a separate cell
if forms[case_code .. "_pl_alt"] then
row = row .. "<td><span lang=\"sk\">" .. make_link(forms[case_code .. "_pl_alt"], case_code .. "|p") .. "</span></td>"
end
end
row = row .. "</tr>"
return row
end
function make_table_header2(forms)
local tr_open = "<tr><th></th>"
local singular = "<th>singular</th>"
local plural = "<th>plural</th>"
local plural1 = "<th>plural 1</th>"
local plural2 = "<th>plural 2</th>"
local tr_close = "</tr>"
local alt_plural = false
if forms["nom_pl_alt"] or forms["gen_pl_alt"] or forms["dat_pl_alt"]
or forms["acc_pl_alt"] or forms["loc_pl_alt"] or forms["ins_pl_alt"]
then
alt_plural = true
end
local header
if NUMBER == "sg" then
header = tr_open .. singular .. tr_close
elseif NUMBER == "pl" then
if alt_plural then
header = tr_open .. plural1 .. plural2 .. tr_close
else
header = tr_open .. plural .. tr_close
end
elseif alt_plural then
header = tr_open .. singular .. plural1 .. plural2 .. tr_close
else
header = tr_open .. singular .. plural .. tr_close
end
return header
end
function make_table_footer()
return '\n' .. m_inflection_table.make_bottom{}
end
-- Make the table
function make_table(forms, title)
for key, form in pairs(forms) do
-- check for empty strings and nil's
if form == "" or not form then
forms[key] = "—"
end
end
local final = make_table_header(title)
final = final .. make_table_header2(forms)
final = final .. make_simple_row(forms, "nominative", "မဒုၚ်ယၟု")
final = final .. make_simple_row(forms, "genitive", "ဗဳဇဂကူ")
final = final .. make_simple_row(forms, "dative", "ပြကမ္မကာရက")
final = final .. make_simple_row(forms, "accusative", "ကမ္မကာရက")
if forms["voc_sg"] then
final = final .. make_simple_row(forms, "vocative", "ပရေၚ်ဂယိုၚ်လမျီု")
end
final = final .. make_simple_row(forms, "locative", "ခၞံဗဒှ်ဌာန်မတန်တဴ")
final = final .. make_simple_row(forms, "instrumental", "တိၚ်တိုက်ကပေါတ်ကွိၚ်ကွိုက်")
final = final .. make_table_footer()
return final
end
return export
hj5c2gn5g16hu47beb3u7khyk9rq2hv
ᜋᜆᜒᜋᜆᜒᜃ
0
298491
401087
2026-08-12T16:53:28Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "==တာဂါလံက်== ===နာမ်=== {{head|tl|နာမ်}} # သၚ်္ချာ။"
401087
wikitext
text/x-wiki
==တာဂါလံက်==
===နာမ်===
{{head|tl|နာမ်}}
# သၚ်္ချာ။
7dmz6mgdirou8gtrceu5adwiv7szcyz
matematický
0
298492
401088
2026-08-12T16:57:28Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "{{also|matematicky|matematičky}} ==ချက်ခ်== ===ဗွဟ်ရမ္သာၚ်=== * {{cs-IPA|[ty]}} ===နာမဝိသေသန=== {{cs-adj|adv=matematicky}} # မဆေၚ်စပ်ကဵုသၚ်္ချာ။ #: {{coi|cs|[[matematická logika]]|[[mathematical logic]]}} ====လဟုတ်စှ်ေ==== {{cs-adecl}}"
401088
wikitext
text/x-wiki
{{also|matematicky|matematičky}}
==ချက်ခ်==
===ဗွဟ်ရမ္သာၚ်===
* {{cs-IPA|[ty]}}
===နာမဝိသေသန===
{{cs-adj|adv=matematicky}}
# မဆေၚ်စပ်ကဵုသၚ်္ချာ။
#: {{coi|cs|[[matematická logika]]|[[mathematical logic]]}}
====လဟုတ်စှ်ေ====
{{cs-adecl}}
a1ve4rih3q5s664s0pu1sg028rny30r
ထာမ်ပလိက်:cs-adecl
10
298493
401089
2026-08-12T16:58:23Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "{{#invoke:cs-adjective|show}}<noinclude> {{documentation}} </noinclude>"
401089
wikitext
text/x-wiki
{{#invoke:cs-adjective|show}}<noinclude>
{{documentation}}
</noinclude>
cmhigwpsk87bv8d76fn56yrgnvxiiuf
မဝ်ဂျူ:cs-adjective
828
298494
401090
2026-08-12T17:13:50Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "local export = {} --[=[ Authorship: Ben Wing <benwing2> ]=] --[=[ TERMINOLOGY: -- "slot" = A particular combination of case/gender/number. Example slot names for adjectives are "gen_f" (genitive feminine singular) and "nom_mp_an" (animate nominative masculine plural). Each slot is filled with zero or more forms. -- "form" = The declined Czech form representing the value of a given slot. -- "lemma" = The d..."
401090
Scribunto
text/plain
local export = {}
--[=[
Authorship: Ben Wing <benwing2>
]=]
--[=[
TERMINOLOGY:
-- "slot" = A particular combination of case/gender/number.
Example slot names for adjectives are "gen_f" (genitive feminine singular) and
"nom_mp_an" (animate nominative masculine plural). Each slot is filled with zero or more forms.
-- "form" = The declined Czech form representing the value of a given slot.
-- "lemma" = The dictionary form of a given Czech term. Generally the nominative
masculine singular, but may occasionally be another form if the nominative
masculine singular is missing.
]=]
local lang = require("Module:languages").getByCode("cs")
local m_links = require("Module:links")
local m_table = require("Module:table")
local m_string_utilities = require("Module:string utilities")
local iut = require("Module:inflection utilities")
local put = require("Module:parse utilities")
local com = require("Module:cs-common")
local en_utilities_module = "Module:en-utilities"
local m_inflection_table = require("Module:inflection-table")
local u = mw.ustring.char
local rsplit = mw.text.split
local rfind = mw.ustring.find
local rmatch = mw.ustring.match
local rgmatch = mw.ustring.gmatch
local rsubn = mw.ustring.gsub
local ulen = mw.ustring.len
local uupper = mw.ustring.upper
-- version of rsubn() that discards all but the first return value
local function rsub(term, foo, bar)
local retval = rsubn(term, foo, bar)
return retval
end
-- version of rsubn() that returns a 2nd argument boolean indicating whether
-- a substitution was made.
local function rsubb(term, foo, bar)
local retval, nsubs = rsubn(term, foo, bar)
return retval, nsubs > 0
end
-- All slots that are used by any of the different tables. The key is the slot and the value is a list of the tables
-- that use the slot. "" = regular, "plonly" = special=plonly in {{cs-adecl-manual}}, "dva" = special=dva in
-- {{cs-adecl-manual}}.
local input_adjective_slots = {
nom_m = {""},
nom_f = {""},
nom_n = {""},
nom_mp_an = {"", "plonly"},
nom_fp = {"", "plonly"},
nom_np = {"", "plonly"},
nom_mp = {"dva"},
nom_fnp = {"dva"},
gen_mn = {""},
gen_f = {""},
gen_p = {"", "plonly", "dva"},
dat_mn = {""},
dat_f = {""},
dat_p = {"", "plonly", "dva"},
acc_m_an = {""},
acc_m_in = {""},
acc_f = {""},
acc_n = {""},
acc_mfp = {"", "plonly"},
acc_np = {"", "plonly"},
acc_mp = {"dva"},
acc_fnp = {"dva"},
ins_mn = {""},
ins_f = {""},
ins_p = {"", "plonly", "dva"},
ins_d = {"", "plonly"},
loc_mn = {""},
loc_f = {""},
loc_p = {"", "plonly", "dva"},
short_m = {""},
short_f = {""},
short_n = {""},
short_mp_an = {""},
short_fp = {""},
short_np = {""},
}
local output_adjective_slots = {
nom_m = "nom|m|s",
nom_m_linked = "nom|m|s", -- used in [[Module:cs-noun]]?
nom_f = "nom|f|s",
nom_n = "nom|n|s",
nom_mp_an = "an|nom|m|p",
nom_fp = "in|nom|m|p|;|nom|f|p",
nom_np = "nom|n|p",
nom_mp = "nom|m|p",
nom_fnp = "nom|f//n|p",
gen_mn = "gen|m//n|s",
gen_f = "gen|f|s",
gen_p = "gen|p",
dat_mn = "dat|m//n|s",
dat_f = "dat|f|s",
dat_p = "dat|p",
acc_m_an = "an|acc|m|s",
acc_m_in = "in|acc|m|s",
acc_f = "acc|f|s",
acc_n = "acc|n|s",
acc_mfp = "acc|m//f|p",
acc_np = "acc|n|p",
acc_mp = "acc|m|p",
acc_fnp = "acc|f//n|p",
ins_mn = "ins|m//n|s",
ins_f = "ins|f|s",
ins_p = "ins|p",
ins_d = "ins|d",
loc_mn = "loc|m//n|s",
loc_f = "loc|f|s",
loc_p = "loc|p",
short_m = "short|m|s",
short_f = "short|f|s",
short_n = "short|n|s",
short_mp_an = "short|an|m|p",
short_fp = "short|in|m|p|;|short|f|p",
short_np = "short|n|p",
}
local function get_output_adjective_slots(alternant_multiword_spec)
return output_adjective_slots
end
local function combine_stem_ending(stem, ending)
if stem == "?" then
return "?"
else
return stem .. ending
end
end
local function add(base, slot, stems, endings, footnote)
if stems then
stems = iut.combine_form_and_footnotes(stems, footnote)
end
iut.add_forms(base.forms, slot, stems, endings, combine_stem_ending)
end
local function add_normal_decl(base, stems,
nom_m, nom_f, nom_n, nom_mp_an, nom_fp, nom_np,
gen_mn, gen_f, gen_p,
dat_mn, dat_f, dat_p,
acc_f,
loc_mn, loc_f, loc_p,
ins_mn, ins_f, ins_p, ins_d,
footnote)
if stems then
stems = iut.combine_form_and_footnotes(stems, footnote)
end
add(base, "nom_m", stems, nom_m)
add(base, "nom_f", stems, nom_f)
add(base, "nom_n", stems, nom_n)
add(base, "nom_mp_an", stems, nom_mp_an)
add(base, "nom_fp", stems, nom_fp)
add(base, "nom_np", stems, nom_np)
add(base, "gen_mn", stems, gen_mn)
add(base, "gen_f", stems, gen_f)
add(base, "gen_p", stems, gen_p)
add(base, "dat_mn", stems, dat_mn)
add(base, "dat_f", stems, dat_f)
add(base, "dat_p", stems, dat_p)
add(base, "acc_f", stems, acc_f)
add(base, "loc_mn", stems, loc_mn)
add(base, "loc_f", stems, loc_f)
add(base, "loc_p", stems, loc_p)
add(base, "ins_mn", stems, ins_mn)
add(base, "ins_f", stems, ins_f)
add(base, "ins_p", stems, ins_p)
add(base, "ins_d", stems, ins_d)
end
local function add_short_decl(base, stems, m, f, n, mp_an, fp, np, footnote)
if stems then
stems = iut.combine_form_and_footnotes(stems, footnote)
end
add(base, "short_m", stems, m)
add(base, "short_f", stems, f)
add(base, "short_n", stems, n)
add(base, "short_mp_an", stems, mp_an)
add(base, "short_fp", stems, fp)
add(base, "short_np", stems, np)
end
local decls = {}
decls["normal"] = function(base)
local stem, suffix
local dual_footnote = "this form is used when describing dual nouns, e.g. {{m|cs|[[očima]]}}, {{m|cs|rukama}}"
dual_footnote = "[" .. mw.getCurrentFrame():preprocess(dual_footnote) .. "]"
-- hard in -ý
stem, suffix = rmatch(base.lemma, "^(.*)(ý)$")
if stem then
add_normal_decl(base, stem,
"ý", "á", "é", {}, "é", "á",
"ého", "é", "ých",
"ému", "é", "ým",
"ou",
"ém", "é", "ých",
"ým", "ou", "ými"
)
add_normal_decl(base, stem,
nil, nil, nil, nil, nil, nil,
nil, nil, nil,
nil, nil, nil,
nil,
nil, nil, nil,
nil, nil, nil, "ýma",
dual_footnote
)
-- Do the nominative masculine animate plural separately since it may have a different stem (with the second
-- palatalization applied).
add_normal_decl(base, com.apply_second_palatalization(stem, "is adj"), nil, nil, nil, "í")
if base.short then
-- Examples of short adjectives:
-- bledý "pale" -> bled
-- bosý "barefoot" -> bos
-- pilný "hardworking, diligent" -> pilen (reducible)
-- veselý "funny, jolly" -> vesel
-- jistý "certain, sure" -> jist
-- vinný "guilty" -> vinen (reducible)
-- živý "alive, living" -> živ
-- tichý "quiet" -> tich; mp_an = tiši
-- vědomý "conscious, aware" -> vědom
-- rád "glad" (short only)
-- chudý "poor" -> chud
-- nevinný "innocent" -> nevinen (reducible)
-- silný "strong" -> silen (reducible)
-- známý "known" -> znám
-- mladý "young" -> mlád (note length); other forms have mlád- or mlad-
-- starý "old" -> stár (note length); other forms have stár- or star-; mp_an = stáři, staři
-- slabý "weak" -> sláb (note length); other forms only have sláb- (FIXME: check against a grammar)
-- zdravý "healthy" -> zdráv (note length); other forms only have zdráv- (FIXME: check against a grammar)
-- nemocný "ill" -> nemocen (reducible)
-- plný "full" -> pln
-- schopný "able, capable" -> schopen (reducible)
-- vděčný "grateful" -> vděčen (reducible)
-- věrný "faithful" -> věren (reducible)
-- šťastný "happy" -> šťasten (reducible)
-- křepký "strong" -> křepek (reducible); mp_an = křepci
-- hotový "ready, finished" -> hotov
-- němý "mute" -> něma
-- smutný "sad" -> smuten (reducible)
-- samotný "lonely" -> samoten (reducible)
-- bohatý "rich" -> bohat
-- chladný "cold" -> chladen (reducible)
-- dlužný "necessary?" -> dlužen (reducible)
-- povinný "mandatory" -> povinen (reducible)
-- zodpovědný "responsible" -> zodpověden (reducible)
-- udatný "brave" -> udaten (reducible)
-- náchylný "susceptible" -> náchylen (reducible)
for _, short_stem_obj in ipairs(base.short) do
add_short_decl(base, short_stem_obj.base, "")
add_short_decl(base, short_stem_obj.stem, nil, "a", "o", nil, "y", "a")
add_short_decl(base, com.apply_second_palatalization(short_stem_obj.stem.form, "is adj"), nil, nil, nil, "i",
short_stem_obj.stem.footnotes)
end
end
return
end
-- soft in -í
stem, suffix = rmatch(base.lemma, "^(.*)(í)$")
if stem then
add_normal_decl(base, stem,
"í", "í", "í", "í", "í", "í",
"ího", "í", "ích",
"ímu", "í", "ím",
"í",
"ím", "í", "ích",
"ím", "í", "ími"
)
add_normal_decl(base, stem,
nil, nil, nil, nil, nil, nil,
nil, nil, nil,
nil, nil, nil,
nil,
nil, nil, nil,
nil, nil, nil, "íma",
dual_footnote
)
return
end
-- possessive in -ův
stem, suffix = rmatch(base.lemma, "^(.*)(ův)$")
if stem then
add_normal_decl(base, stem,
"ův", "ova", "ovo", "ovi", "ovy", "ova",
"ova", "ovy", "ových",
"ovu", "ově", "ovým",
"ovu",
{"ově", "ovu"}, "ově", "ových",
"ovým", "ovou", "ovými"
)
add_normal_decl(base, stem,
nil, nil, nil, nil, nil, nil,
nil, nil, nil,
nil, nil, nil,
nil,
nil, nil, nil,
nil, nil, nil, "ovýma",
dual_footnote
)
return
end
-- possessive in -in
stem, suffix = rmatch(base.lemma, "^(.*)(in)$")
if stem then
add_normal_decl(base, stem,
"in", "ina", "ino", "ini", "iny", "ina",
"ina", "iny", "iných",
"inu", "ině", "iným",
"inu",
{"ině", "inu"}, "ině", "iných",
"iným", "inou", "inými"
)
add_normal_decl(base, stem,
nil, nil, nil, nil, nil, nil,
nil, nil, nil,
nil, nil, nil,
nil,
nil, nil, nil,
nil, nil, nil, "inýma",
dual_footnote
)
return
end
error("Unrecognized adjective lemma, should end in '-ý', '-í', '-ův' or '-in': '" .. base.lemma .. "'")
end
decls["irreg"] = function(base)
local stem, suffix
local dual_footnote = "this form is used when describing dual nouns, e.g. {{m|cs|[[očima]]}}, {{m|cs|rukama}}"
dual_footnote = "[" .. mw.getCurrentFrame():preprocess(dual_footnote) .. "]"
-- determiner like můj
stem, suffix = rmatch(base.lemma, "^(.*)(ůj)$")
if stem then
add_normal_decl(base, stem,
"ůj", {"á", "oje"}, {"é", "oje"}, {"í", "oji"}, {"é", "oje"}, {"á", "oje"},
"ého", {"é", "ojí"}, "ých",
"ému", {"é", "ojí"}, "ým",
{"ou", "oji"},
"ém", {"é", "ojí"}, "ých",
"ým", {"ou", "ojí"}, "ými"
)
add_normal_decl(base, stem,
nil, nil, nil, nil, nil, nil,
nil, nil, nil,
nil, nil, nil,
nil,
nil, nil, nil,
nil, nil, nil, "ýma",
dual_footnote
)
return
end
-- determiner like dvoje
stem, suffix = rmatch(base.lemma, "^(.*)(oje)$")
if stem then
add_normal_decl(base, stem,
"ůj", "oje", "oje", "oji", "oje", "oje",
"ojího", "ojí", "ojích",
"ojímu", "ojí", "ojím",
"oji",
"ojím", "ojí", "ojích",
"ojím", "ojí", "ojími"
)
add_normal_decl(base, stem,
nil, nil, nil, nil, nil, nil,
nil, nil, nil,
nil, nil, nil,
nil,
nil, nil, nil,
nil, nil, nil, "ojíma",
dual_footnote
)
return
end
-- determiner like čtvery
stem, suffix = rmatch(base.lemma, "^(.*)(ery)$")
if stem then
add_normal_decl(base, stem,
"er", "era", "ero", "eři", "ery", "era",
"erého", "eré", "erých",
"erému", "eré", "erým",
"erou",
"erém", "eré", "erých",
"erým", "erou", "erými"
)
add_normal_decl(base, stem,
nil, nil, nil, nil, nil, nil,
nil, nil, nil,
nil, nil, nil,
nil,
nil, nil, nil,
nil, nil, nil, "erýma",
dual_footnote
)
return
end
if base.lemma == "všechen" then
add_normal_decl(base, "",
"všechen", "všechna", {"všechno", "vše"}, "všichni", "všechny", "všechna",
"všeho", "vší", "všech",
"všemu", "vší", "všem",
{"všechnu", "vši"},
"všem", "vší", "všech",
"vším", "vší", "všemi"
)
add_normal_decl(base, "",
nil, nil, nil, nil, nil, nil,
nil, nil, nil,
nil, nil, nil,
nil,
nil, nil, nil,
nil, nil, nil, "všema",
dual_footnote
)
return
end
if base.lemma == "všecek" then
add_normal_decl(base, "",
"všecek", "všecka", {"všecko", "vše"}, "všicci", "všecky", "všecka",
"všeho", "vší", "všech",
"všemu", "vší", "všem",
{"všecku", "vši"},
"všem", "vší", "všech",
"vším", "vší", "všemi"
)
add_normal_decl(base, "",
nil, nil, nil, nil, nil, nil,
nil, nil, nil,
nil, nil, nil,
nil,
nil, nil, nil,
nil, nil, nil, "všema",
dual_footnote
)
return
end
if base.lemma == "všecken" then
add_normal_decl(base, "",
"všecken", "všeckna", {"všeckno", "vše"}, "všickni", "všeckny", "všeckna",
"všeho", "vší", "všech",
"všemu", "vší", "všem",
{"všecknu", "vši"},
"všem", "vší", "všech",
"vším", "vší", "všemi"
)
add_normal_decl(base, "",
nil, nil, nil, nil, nil, nil,
nil, nil, nil,
nil, nil, nil,
nil,
nil, nil, nil,
nil, nil, nil, "všema",
dual_footnote
)
return
end
-- determiner like [[ten]], [[tamten]], [[tamhleten]], [[tuten]], [[jeden]], [[onen]]
-- [[tento]] uses 'ten<irreg>to'
-- [[tenhle]] uses 'ten<irreg>hle'
-- [[tenhleten]] uses 'ten<irreg>hleten<irreg>'
stem, suffix = rmatch(base.lemma, "^(.*)(en)$")
if stem then
local nom_stem = stem .. suffix
if nom_stem == "jeden" then
stem = "jedn"
end
add_normal_decl(base, nom_stem, "")
add_normal_decl(base, stem,
nil, "a", "o", "i", "y", "a",
"oho", "é", "ěch",
"omu", "é", "ěm",
"u",
"om", "é", "ěch",
"ím", "ou", "ěmi"
)
add_normal_decl(base, stem,
nil, nil, nil, nil, nil, nil,
nil, nil, nil,
nil, nil, nil,
nil,
nil, nil, nil,
nil, nil, nil, "ěma",
dual_footnote
)
return
end
-- [[náš]], [[váš]]
stem, suffix = rmatch(base.lemma, "^(.*)(áš)$")
if stem then
local nom_stem = stem .. suffix
stem = stem .. "aš"
add_normal_decl(base, nom_stem, "")
add_normal_decl(base, stem,
nil, "e", "e", "i", "e", "e",
"eho", "í", "ich",
"emu", "í", "im",
"i",
"em", "í", "ich",
"ím", "í", "imi"
)
add_normal_decl(base, stem,
nil, nil, nil, nil, nil, nil,
nil, nil, nil,
nil, nil, nil,
nil,
nil, nil, nil,
nil, nil, nil, "ima",
dual_footnote
)
return
end
if base.lemma == "jenž" then
local preposition_footnote = "the leading letter ''j-'' is changed to ''n-'' when the pronoun is preceded by a preposition, e.g. {{m|cs|[[s]] [[nímž]]}}, {{m|cs|[[k]] [[němuž]]}}, {{m|cs|[[bez]] [[níž]]}}"
preposition_footnote = "[" .. mw.getCurrentFrame():preprocess(preposition_footnote) .. "]"
-- Add the non-prepositional forms.
add_normal_decl(base, "",
"jenž", "jež", "jež", "již", "jež", "jež",
{"jehož", "jejž"}, "jíž", "jichž",
"jemuž", "jíž", "jimž",
"již",
nil, nil, nil,
"jímž", "jíž", "jimiž"
)
-- Add the prepositional forms. (FIXME: Maybe should go in a separate column in a special table.)
add_normal_decl(base, "",
nil, nil, nil, nil, nil, nil,
{"něhož", "nějž"}, "níž", "nichž",
"němuž", "níž", "nimž",
"niž",
"němž", "níž", "nichž",
"nímž", "níž", "nimiž",
preposition_footnote
)
add_normal_decl(base, "",
nil, nil, nil, nil, nil, nil,
nil, nil, nil,
nil, nil, nil,
nil,
nil, nil, nil,
nil, nil, {"jimaž", "nimaž"},
dual_footnote
)
-- Unusually, the accusative masculine animate singular is not the same as the genitive masculine singular,
-- and the accusative masculine inanimate singular is not the same as the nominative masculine singular.
add(base, "acc_m_an", "", {"jejž", "jehož"})
add(base, "acc_m_an", "", {"nějž", "něhož"}, preposition_footnote)
add(base, "acc_m_in", "", "jejž")
add(base, "acc_m_in", "", "nějž", preposition_footnote)
return
end
if base.lemma == "tentýž" then
add_normal_decl(base, "",
"tentýž", "tatáž", "totéž", "titíž", "tytéž", "tatáž",
"téhož", "téže", "týchž",
{"témuž", "tomutéž"}, "téže", "týmž",
"tutéž",
"tomtéž", "téže", "týchž",
"tímtéž", "toutéž", "týmiž"
)
add_normal_decl(base, "",
nil, nil, nil, nil, nil, nil,
nil, nil, nil,
nil, nil, nil,
nil,
nil, nil, nil,
nil, nil, "týmaž",
dual_footnote
)
return
end
if base.lemma == "týž" then
add_normal_decl(base, "",
"týž", "táž", nil, "tíž", nil, "tatáž",
"téhož", "téže", "týchž",
"témuž", "téže", "týmž",
"touž",
"témž", "téže", "týchž",
"týmž", "touž", "týmiž"
)
add_normal_decl(base, "",
nil, nil, nil, nil, nil, nil,
nil, nil, nil,
nil, nil, nil,
nil,
nil, nil, nil,
nil, nil, "týmaž",
dual_footnote
)
return
end
if base.lemma == "sám" then
-- This mixes long and short endings.
add_normal_decl(base, "sám", "")
add_normal_decl(base, "sam",
nil, "a", "o", "i", "y", "a",
"ého", "é", "ých",
"ému", "é", "ým",
"u",
"ém", "é", "ých",
"ým", "ou", "ými"
)
add_normal_decl(base, "sam",
nil, nil, nil, nil, nil, nil,
nil, nil, nil,
nil, nil, nil,
nil,
nil, nil, nil,
nil, nil, nil, "ýma",
dual_footnote
)
-- Unusually, the accusative masculine animate singular is not the same as the genitive masculine singular.
add(base, "acc_m_an", "sam", {"a", "ého"})
return
end
if base.lemma == "jejíž" then
add_normal_decl(base, "jej",
"íž", "íž", "íž", "íž", "íž", "íž",
"íhož", "íž", "íchž",
"ímuž", "íž", "ímž",
"íž",
"ímž", "íž", "íchž",
"ímž", "íž", "ímiž"
)
add_normal_decl(base, "jej",
nil, nil, nil, nil, nil, nil,
nil, nil, nil,
nil, nil, nil,
nil,
nil, nil, nil,
nil, nil, "ímaž",
dual_footnote
)
return
end
error("Unrecognized irregular lemma '" .. base.lemma .. "'")
end
local function fetch_footnotes(separated_group)
local footnotes
for j = 2, #separated_group - 1, 2 do
if separated_group[j + 1] ~= "" then
error("Extraneous text after bracketed footnotes: '" .. table.concat(separated_group) .. "'")
end
if not footnotes then
footnotes = {}
end
table.insert(footnotes, separated_group[j])
end
return footnotes
end
local function parse_indicator_spec(angle_bracket_spec)
local inside = rmatch(angle_bracket_spec, "^<(.*)>$")
assert(inside)
local base = {forms = {}}
if inside ~= "" then
local parts = rsplit(inside, ".", true)
for _, part in ipairs(parts) do
if part == "irreg" then
base.irreg = true
elseif part == "short" then
base.short = {{
base = {
form = "+",
},
stem = {
form = "+",
}
}}
elseif rfind(part, "^short:") then
part = rsub(part, "^short:%s*", "")
base.short = {}
local segments = put.parse_balanced_segment_run(part, "[", "]")
local comma_separated_groups = put.split_alternating_runs(segments, "%s*,%s*")
for _, comma_separated_group in ipairs(comma_separated_groups) do
if comma_separated_group[1] == "*" then
-- reducible
table.insert(base.short, {
base = {
form = "*",
footnotes = fetch_footnotes(comma_separated_group),
},
stem = {
form = "*",
footnotes = fetch_footnotes(comma_separated_group),
}
})
else
local slash_separated_groups = put.split_alternating_runs(comma_separated_group, "%s*/%s*")
if #slash_separated_groups > 2 then
error("Too many slash-separated stems: '" .. inside .. "'")
end
local short_base = slash_separated_groups[1]
local short_stem = slash_separated_groups[2]
local short_base_obj = {
form = short_base[1],
footnotes = fetch_footnotes(short_base),
}
local short_stem_obj
if short_stem then
short_stem_obj = {
form = short_stem[1],
footnotes = fetch_footnotes(short_stem),
}
end
table.insert(base.short, {
base = short_base_obj,
stem = short_stem_obj,
})
end
iut.insert_form(forms, slot, formobj)
end
else
error("Unrecognized indicator '" .. part .. "': '" .. inside .. "'")
end
end
end
return base
end
local function normalize_all_lemmas(alternant_multiword_spec, pagename)
iut.map_word_specs(alternant_multiword_spec, function(base)
if base.lemma == "" then
base.lemma = pagename
end
base.orig_lemma = base.lemma
base.orig_lemma_no_links = m_links.remove_links(base.lemma)
base.lemma = base.orig_lemma_no_links
end)
end
local function detect_indicator_spec(base)
if base.short then
if not base.lemma:find("ý$") then
error("Short forms can only be specified for lemmas ending in -ý, but saw '" .. base.lemma .. "'")
end
local stem = rmatch(base.lemma, "^(.*)ý$")
for _, short_spec in ipairs(base.short) do
if short_spec.base.form == "+" then
short_spec.base.form = stem
elseif short_spec.base.form == "*" then
short_spec.base.form = com.dereduce(base, stem)
if not short_spec.base.form then
error("Unable to construct non-reduced variant of stem '" .. stem .. "'")
end
end
if not short_spec.stem then
short_spec.stem = {
form = short_spec.base.form,
footnotes = short_spec.base.footnotes
}
end
if short_spec.stem.form == "+" or short_spec.stem.form == "*" then
short_spec.stem.form = stem
end
end
end
if base.irreg then
base.decl = "irreg"
else
base.decl = "normal"
end
end
local function detect_all_indicator_specs(alternant_multiword_spec)
iut.map_word_specs(alternant_multiword_spec, function(base)
detect_indicator_spec(base)
end)
end
local function decline_adjective(base)
if not decls[base.decl] then
error("Internal error: Unrecognized declension type '" .. base.decl .. "'")
end
decls[base.decl](base)
-- handle_derived_slots_and_overrides(base)
end
-- Process override for the arguments in `args`, storing the results into `forms`. If `do_acc`, only do accusative
-- slots; otherwise, don't do accusative slots.
local function process_overrides(forms, args, do_acc)
for slot, _ in pairs(input_adjective_slots) do
if args[slot] and not not do_acc == not not slot:find("^acc") then
forms[slot] = nil
if args[slot] ~= "-" and args[slot] ~= "—" then
local segments = put.parse_balanced_segment_run(args[slot], "[", "]")
local comma_separated_groups = put.split_alternating_runs(segments, "%s*,%s*")
for _, comma_separated_group in ipairs(comma_separated_groups) do
local formobj = {
form = comma_separated_group[1],
footnotes = fetch_footnotes(comma_separated_group),
}
iut.insert_form(forms, slot, formobj)
end
end
end
end
end
local function check_allowed_overrides(alternant_multiword_spec, args)
local special = alternant_multiword_spec.special or alternant_multiword_spec.surname and "surname" or ""
for slot, types in pairs(input_adjective_slots) do
if args[slot] then
local allowed = false
for _, typ in ipairs(types) do
if typ == special then
allowed = true
break
end
end
if not allowed then
error(("Override %s= not allowed for %s"):format(slot, special == "" and "regular declension" or
"special=" .. special))
end
end
end
end
local function set_accusative(alternant_multiword_spec)
local forms = alternant_multiword_spec.forms
local function copy_if(from_slot, to_slot)
if not forms[to_slot] then
iut.insert_forms(forms, to_slot, forms[from_slot])
end
end
copy_if("nom_n", "acc_n")
copy_if("gen_mn", "acc_m_an")
copy_if("nom_m", "acc_m_in")
copy_if("nom_fp", "acc_mfp")
copy_if("nom_np", "acc_np")
end
local function add_categories(alternant_multiword_spec)
local cats = {}
local plpos = require(en_utilities_module).pluralize(alternant_multiword_spec.pos or "adjective")
local function insert(cattype)
-- m_table.insertIfNot(cats, "Czech " .. cattype .. " " .. plpos)
end
if not alternant_multiword_spec.manual then
iut.map_word_specs(alternant_multiword_spec, function(base)
if base.decl == "irreg" then
insert("irregular")
elseif rfind(base.lemma, "ý$") then
insert("hard")
elseif rfind(base.lemma, "í$") then
insert("soft")
else
insert("possessive")
end
if base.short then
-- table.insert(cats, "Czech " .. plpos .. " with short forms")
end
end)
end
alternant_multiword_spec.categories = cats
end
local function show_forms(alternant_multiword_spec)
local lemmas = {}
local lemmaform = alternant_multiword_spec.forms.nom_m or alternant_multiword_spec.forms.nom_mp or
alternant_multiword_spec.forms.nom_mp_an
if lemmaform then
for _, form in ipairs(lemmaform) do
table.insert(lemmas, form.form)
end
end
local props = {
lemmas = lemmas,
slot_table = get_output_adjective_slots(alternant_multiword_spec),
lang = lang,
}
iut.show_forms(alternant_multiword_spec.forms, props)
end
local function make_table(alternant_multiword_spec)
local forms = alternant_multiword_spec.forms
local function template_prelude()
return m_inflection_table.make_top{
title = '{title}{annotation}',
palette = 'blue',
tall = 'yes',
}
end
local function template_postlude()
return m_inflection_table.make_bottom{
notes = '{notes_clause}' or nil
}
end
local table_spec_sg = [=[
! colspan=5 class="outer" | ကိုန်ဨကဝုစ်
|-
! rowspan="2" |
! colspan="2" | ပုလ္လိၚ်
! rowspan="2" | ဣတ္တိလိၚ်
! rowspan="2" | နပုလ္လိၚ်
|-
! class="secondary" | လမျီုလုပ်ကၠုၚ်
! class="secondary" | မသက္ကုဟၟဲကဵုလမျီု
|-
! မဒုၚ်ယၟု
| colspan=2 | {nom_m}
| {nom_f}
| {nom_n}
|-
! ဗဳဇဂကူ
| colspan=2 | {gen_mn}
| {gen_f}
| {gen_mn}
|-
! ပြကမ္မကာရက
| colspan=2 | {dat_mn}
| {dat_f}
| {dat_mn}
|-
! ကမ္မကာရက
| {acc_m_an}
| {acc_m_in}
| {acc_f}
| {acc_n}
|-
! ခၞံဗဒှ်ဌာန်မတန်တဴ
| colspan=2 | {loc_mn}
| {loc_f}
| {loc_mn}
|-
! တိၚ်တိုက်ကပေါတ်ကွိၚ်ကွိုက်
| colspan=2 | {ins_mn}
| {ins_f}
| {ins_mn}{short_sg_clause}
]=]
local table_spec_pl = [=[
! colspan=5 class="outer" | ကိုန်ဗဟုဝစ်
|-
! rowspan="2" |
! colspan="2" | ပုလ္လိၚ်
! rowspan="2" | ဣတ္တိလိၚ်
! rowspan="2" | နပုလ္လိၚ်
|-
! class="secondary" | လမျီုလုပ်ကၠုၚ်
! class="secondary" | မသက္ကုဟၟဲကဵုလမျီု
|-
! မဒုၚ်ယၟု
| {nom_mp_an}
| colspan=2 | {nom_fp}
| {nom_np}
|-
! ဗဳဇဂကူ
| colspan=4 | {gen_p}
|-
! ပြကမ္မကာရက
| colspan=4 | {dat_p}
|-
! ကမ္မကာရက
| colspan=3 | {acc_mfp}
| {acc_np}
|-
! ခၞံဗဒှ်ဌာန်မတန်တဴ
| colspan=4 | {loc_p}
|-
! တိၚ်တိုက်ကပေါတ်ကွိၚ်ကွိုက်
| colspan=4 | {ins_p}, {ins_d}{short_pl_clause}
]=]
local table_spec = template_prelude("55") .. table_spec_sg .. "|-\n" .. table_spec_pl .. template_postlude()
local table_spec_plonly = template_prelude("55") .. table_spec_pl .. template_postlude()
local table_spec_dva = template_prelude("40") .. [=[
! colspan=5 class="outer" | ကိုန်ဗဟုဝစ်
|-
! colspan="2" |
! ပုလ္လိၚ်
! ဣတ္တိလိၚ်/နပုလ္လိၚ်
|-
! colspan="2" | မဒုၚ်ယၟု
| {nom_mp}
| {nom_fnp}
|-
! colspan="2" | ဗဳဇဂကူ
| colspan="2" | {gen_p}
|-
! colspan="2" | ပြကမ္မကာရက
| colspan="2" | {dat_p}
|-
! colspan="2" | ကမ္မကာရက
| {acc_mp}
| {acc_fnp}
|-
! colspan="2" | ခၞံဗဒှ်ဌာန်မတန်တဴ
| colspan="2" | {loc_p}
|-
! colspan="2" | တိၚ်တိုက်ကပေါတ်ကွိၚ်ကွိုက်
| colspan="2" | {ins_p}
]=] .. template_postlude()
local short_sg_template = [=[
|-
! ဓမၠေံ
| colspan=2 | {short_m}
| {short_f}
| {short_n}
]=]
local short_pl_template = [=[
|-
! ဓမၠေံ
| {short_mp_an}
| colspan=2 | {short_fp}
| {short_np}]=]
if alternant_multiword_spec.title then
forms.title = alternant_multiword_spec.title
else
forms.title = 'မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု <i lang="cs">' .. forms.lemma .. '</i>'
end
if alternant_multiword_spec.manual then
forms.annotation = ""
else
local ann_parts = {}
local decls = {}
iut.map_word_specs(alternant_multiword_spec, function(base)
if base.decl == "irreg" then
m_table.insertIfNot(decls, "irregular")
elseif rfind(base.lemma, "ý$") then
m_table.insertIfNot(decls, "hard")
elseif rfind(base.lemma, "í$") then
m_table.insertIfNot(decls, "soft")
else
m_table.insertIfNot(decls, "possessive")
end
end)
table.insert(ann_parts, table.concat(decls, " // "))
forms.annotation = " (" .. table.concat(ann_parts, ", ") .. ")"
end
forms.notes_clause = forms.footnote ~= "" and forms.footnote or ""
forms.short_sg_clause = forms.short_m and forms.short_m ~= "—" and
m_string_utilities.format(short_sg_template, forms) or ""
forms.short_pl_clause = forms.short_mp_an and forms.short_mp_an ~= "—" and
m_string_utilities.format(short_pl_template, forms) or ""
return m_string_utilities.format(
alternant_multiword_spec.special == "plonly" and table_spec_plonly or
alternant_multiword_spec.special == "dva" and table_spec_dva or
table_spec, forms
)
end
-- Externally callable function to parse and decline an adjective given
-- user-specified arguments. Return value is WORD_SPEC, an object where the
-- declined forms are in `WORD_SPEC.forms` for each slot. If there are no values
-- for a slot, the slot key will be missing. The value for a given slot is a
-- list of objects {form=FORM, footnotes=FOOTNOTES}.
function export.do_generate_forms(parent_args, pos, from_headword, def)
local params = {
[1] = {template_default = "křepký<short:*>"},
pos = true,
json = {type = "boolean"}, -- for use with bots
title = true,
pagename = true,
}
for slot, _ in pairs(input_adjective_slots) do
params[slot] = true
end
-- Only default param 1 when displaying the template.
local args = require("Module:parameters").process(parent_args, params)
local pagename = args.pagename or mw.loadData("Module:headword/data").pagename
local args1 = args[1] or pagename
local parse_props = {
parse_indicator_spec = parse_indicator_spec,
allow_default_indicator = true,
allow_blank_lemma = true,
}
local alternant_multiword_spec = iut.parse_inflected_text(args1, parse_props)
alternant_multiword_spec.pos = args.pos
alternant_multiword_spec.title = args.title
alternant_multiword_spec.forms = {}
normalize_all_lemmas(alternant_multiword_spec, pagename)
detect_all_indicator_specs(alternant_multiword_spec)
check_allowed_overrides(alternant_multiword_spec, args)
local inflect_props = {
slot_table = get_output_adjective_slots(alternant_multiword_spec),
inflect_word_spec = decline_adjective,
}
iut.inflect_multiword_or_alternant_multiword_spec(alternant_multiword_spec, inflect_props)
-- Do non-accusative overrides so they get copied to the accusative forms appropriately.
process_overrides(alternant_multiword_spec.forms, args)
set_accusative(alternant_multiword_spec)
-- Do accusative overrides after copying the accusative forms.
process_overrides(alternant_multiword_spec.forms, args, "do acc")
add_categories(alternant_multiword_spec)
if args.json and not from_headword then
return require("Module:JSON").toJSON(alternant_multiword_spec)
end
return alternant_multiword_spec
end
-- Externally callable function to parse and decline an adjective where all
-- forms are given manually. Return value is WORD_SPEC, an object where the
-- declined forms are in `WORD_SPEC.forms` for each slot. If there are no values
-- for a slot, the slot key will be missing. The value for a given slot is a
-- list of objects {form=FORM, footnotes=FOOTNOTES}.
function export.do_generate_forms_manual(parent_args, pos, from_headword, def)
local params = {
pos = true,
special = true,
json = {type = "boolean"}, -- for use with bots
title = true,
}
for slot, _ in pairs(input_adjective_slots) do
params[slot] = true
end
local args = require("Module:parameters").process(parent_args, params)
local alternant_multiword_spec = {
pos = args.pos,
special = args.special,
title = args.title,
forms = {},
manual = true,
}
check_allowed_overrides(alternant_multiword_spec, args)
-- Do non-accusative overrides so they get copied to the accusative forms appropriately.
process_overrides(alternant_multiword_spec.forms, args)
set_accusative(alternant_multiword_spec)
-- Do accusative overrides after copying the accusative forms.
process_overrides(alternant_multiword_spec.forms, args, "do acc")
add_categories(alternant_multiword_spec)
if args.json and not from_headword then
return require("Module:JSON").toJSON(alternant_multiword_spec)
end
return alternant_multiword_spec
end
-- Entry point for {{cs-adecl}}. Template-callable function to parse and decline
-- an adjective given user-specified arguments and generate a displayable table
-- of the declined forms.
function export.show(frame)
local parent_args = frame:getParent().args
local alternant_multiword_spec = export.do_generate_forms(parent_args)
show_forms(alternant_multiword_spec)
return make_table(alternant_multiword_spec) .. require("Module:utilities").format_categories(alternant_multiword_spec.categories, lang)
end
-- Entry point for {{cs-adecl-manual}}. Template-callable function to parse and
-- decline an adjective given manually-specified inflections and generate a
-- displayable table of the declined forms.
function export.show_manual(frame)
local parent_args = frame:getParent().args
local alternant_multiword_spec = export.do_generate_forms_manual(parent_args)
show_forms(alternant_multiword_spec)
return make_table(alternant_multiword_spec) .. require("Module:utilities").format_categories(alternant_multiword_spec.categories, lang)
end
return export
at5mbs99zxnwiugqx2vf0lb0kx2bytt
မဝ်ဂျူ:cs-common/documentation
828
298495
401091
2026-08-12T17:17:56Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "{{documentation needed}}<!-- Replace this with a short description of the purpose of the module, and how to use it. --> <includeonly> {{module cat|cs}} </includeonly>"
401091
wikitext
text/x-wiki
{{documentation needed}}<!-- Replace this with a short description of the purpose of the module, and how to use it. -->
<includeonly>
{{module cat|cs}}
</includeonly>
9jmn9kvfo1n7rvkpn6ldjr198vyuk65
401092
401091
2026-08-12T17:18:12Z
咽頭べさ
33
咽頭べさ ပြံင်ပဆုဲလဝ် မုက်လိက် [[မဝ်ဂျူ:cs-common/doc]] ဇရေင် [[မဝ်ဂျူ:cs-common/documentation]] သီုကဵု ဟွံဂွံ ဂိုင်စွံလဝ် မကလေင်ပညုင်
401091
wikitext
text/x-wiki
{{documentation needed}}<!-- Replace this with a short description of the purpose of the module, and how to use it. -->
<includeonly>
{{module cat|cs}}
</includeonly>
9jmn9kvfo1n7rvkpn6ldjr198vyuk65
ကဏ္ဍ:မဝ်ဂျူချက်ခ်ဂမၠိုၚ်
14
298496
401093
2026-08-12T17:20:33Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "[[:ကဏ္ဍ:ဒၞာဲလုပ်အဝေါၚ်ကဵုပၟိက်|ဒၞာဲလုပ်အဝေါၚ်ကဵုပၟိက်]] » [[:ကဏ္ဍ:အရေဝ်ဘာသာအိုတ်သီုဂမၠိုၚ်|အရေဝ်ဘာသာအိုတ်သီုဂမၠိုၚ်]] » [[:ကဏ္ဍ:ဘာသာချက်ခ်|ချက်ခ်]] » '''မဝ်ဂျူဂမ..."
401093
wikitext
text/x-wiki
[[:ကဏ္ဍ:ဒၞာဲလုပ်အဝေါၚ်ကဵုပၟိက်|ဒၞာဲလုပ်အဝေါၚ်ကဵုပၟိက်]] » [[:ကဏ္ဍ:အရေဝ်ဘာသာအိုတ်သီုဂမၠိုၚ်|အရေဝ်ဘာသာအိုတ်သီုဂမၠိုၚ်]] » [[:ကဏ္ဍ:ဘာသာချက်ခ်|ချက်ခ်]] » '''မဝ်ဂျူဂမၠိုၚ်'''
:[[:ကဏ္ဍ:မဝ်ဂျူဂမၠိုၚ်|မဝ်ဂျူ]]ဘာသာချက်ခ်၊ မနွံကဵုလုပ်အဝေါၚ်ကုဒ် Lua နကဵုမကၠောန်ဗဒှ် ကဵု မစဳရေၚ်ယဵုဒုၚ်သ္ပမာန်ဂမၠိုၚ်။
[[ကဏ္ဍ:ဘာသာချက်ခ်]][[ကဏ္ဍ:မဝ်ဂျူဗက်အလိုက်အရေဝ်ဘာသာဂမၠိုၚ်|ခ]]
3jvigtpfhz6vpjgk51muujz8rnt2j2c
မဝ်ဂျူ:cs-adjective/documentation
828
298497
401094
2026-08-12T17:22:57Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "{{documentation needed}}<!-- Replace this with a short description of the purpose of the module, and how to use it. --> <includeonly> {{module cat|cs}} </includeonly>"
401094
wikitext
text/x-wiki
{{documentation needed}}<!-- Replace this with a short description of the purpose of the module, and how to use it. -->
<includeonly>
{{module cat|cs}}
</includeonly>
9jmn9kvfo1n7rvkpn6ldjr198vyuk65
401095
401094
2026-08-12T17:23:16Z
咽頭べさ
33
咽頭べさ ပြံင်ပဆုဲလဝ် မုက်လိက် [[မဝ်ဂျူ:cs-adjective/doc]] ဇရေင် [[မဝ်ဂျူ:cs-adjective/documentation]] သီုကဵု ဟွံဂွံ ဂိုင်စွံလဝ် မကလေင်ပညုင်
401094
wikitext
text/x-wiki
{{documentation needed}}<!-- Replace this with a short description of the purpose of the module, and how to use it. -->
<includeonly>
{{module cat|cs}}
</includeonly>
9jmn9kvfo1n7rvkpn6ldjr198vyuk65
ကဏ္ဍ:မဝ်ဂျူပွမပြံၚ်လှာဲချက်ခ်ဂမၠိုၚ်
14
298498
401096
2026-08-12T17:25:10Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "[[ကဏ္ဍ:မဝ်ဂျူချက်ခ်ဂမၠိုၚ်]][[ကဏ္ဍ:ထာမ်ပလိက်ချက်ခ်အပြံၚ်အလှာဲပ္တဝ်ထ္ၜးပမာဏဂမၠိုၚ်]][[ကဏ္ဍ:မဝ်ဂျူဗီုအပြံၚ်အလှာဲဝေါဟာဗက်အလိုက်အရေဝ်ဘာသာဂမၠိုၚ်|ခ]]"
401096
wikitext
text/x-wiki
[[ကဏ္ဍ:မဝ်ဂျူချက်ခ်ဂမၠိုၚ်]][[ကဏ္ဍ:ထာမ်ပလိက်ချက်ခ်အပြံၚ်အလှာဲပ္တဝ်ထ္ၜးပမာဏဂမၠိုၚ်]][[ကဏ္ဍ:မဝ်ဂျူဗီုအပြံၚ်အလှာဲဝေါဟာဗက်အလိုက်အရေဝ်ဘာသာဂမၠိုၚ်|ခ]]
o5lhndvs5nqbto6x0l6zkr0rrmc0au2
မဝ်ဂျူ:cs-noun/documentation
828
298499
401097
2026-08-12T17:26:43Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "{{documentation needed}}<!-- Replace this with a short description of the purpose of the module, and how to use it. --> <includeonly> {{module cat|cs}} </includeonly>"
401097
wikitext
text/x-wiki
{{documentation needed}}<!-- Replace this with a short description of the purpose of the module, and how to use it. -->
<includeonly>
{{module cat|cs}}
</includeonly>
tfhgtlgf8kd5o8b9raoqq6m37fy0etm
401098
401097
2026-08-12T17:26:59Z
咽頭べさ
33
咽頭べさ ပြံင်ပဆုဲလဝ် မုက်လိက် [[မဝ်ဂျူ:cs-noun/doc]] ဇရေင် [[မဝ်ဂျူ:cs-noun/documentation]] သီုကဵု ဟွံဂွံ ဂိုင်စွံလဝ် မကလေင်ပညုင်
401097
wikitext
text/x-wiki
{{documentation needed}}<!-- Replace this with a short description of the purpose of the module, and how to use it. -->
<includeonly>
{{module cat|cs}}
</includeonly>
tfhgtlgf8kd5o8b9raoqq6m37fy0etm
မဳဒဳယာဝဳကဳ:Gadget-Palette.css/documentation
8
298500
401100
2026-08-12T17:31:29Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "{{documentation subpage}} Contains CSS variables for common colors to be used by templates. See [[Wiktionary:Palette]] for more information. New colors, when added, are expected to meet contrast requirements. Colors can be previewed in [[MediaWiki:Gadget-Palette/table]]. <includeonly> [[ကဏ္ဍ:ဂေက်ဂျေက်ဝိတ်ရှေန်နရဳဂမၠိုၚ်]] </includeonly>"
401100
wikitext
text/x-wiki
{{documentation subpage}}
Contains CSS variables for common colors to be used by templates. See [[Wiktionary:Palette]] for more information.
New colors, when added, are expected to meet contrast requirements.
Colors can be previewed in [[MediaWiki:Gadget-Palette/table]].
<includeonly>
[[ကဏ္ဍ:ဂေက်ဂျေက်ဝိတ်ရှေန်နရဳဂမၠိုၚ်]]
</includeonly>
7x3d519bjawr8v7yg54w1doo908t95e
မဳဒဳယာဝဳကဳ:Gadget-Palette
8
298501
401101
2026-08-12T17:42:40Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "နဲကၠောန်ဒမၠုမစှ်ေကဵုဗီုပြၚ် CSS ဂၞန်ကၠာဲသွက်အရံၚ်မရပ်စပ်မာန်အပ္ဍဲထာမ်ပလိက်ဂမၠိုၚ်။ ဗဵုရံၚ်မဆေၚ်စပ်ကဵု[[MediaWiki:Gadget-Palette/table|လဗံက်]]။ {{gadget tag|လ္တူနူမစကၠောန်၊ မတၟာတ..."
401101
wikitext
text/x-wiki
နဲကၠောန်ဒမၠုမစှ်ေကဵုဗီုပြၚ် CSS ဂၞန်ကၠာဲသွက်အရံၚ်မရပ်စပ်မာန်အပ္ဍဲထာမ်ပလိက်ဂမၠိုၚ်။ ဗဵုရံၚ်မဆေၚ်စပ်ကဵု[[MediaWiki:Gadget-Palette/table|လဗံက်]]။ {{gadget tag|လ္တူနူမစကၠောန်၊ မတၟာတ်ထောံပရေၚ်အန္တရာဲဇကု}}
qsug58e9ikg9llc1zy1g820sbsbrwet
ထာမ်ပလိက်:cs-adecl/documentation
10
298502
401102
2026-08-12T17:47:10Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "{{documentation subpage}} {{documentation needed}}<!-- Replace this with a short description of the purpose of the template, and how to use it. --> <includeonly> [[ကဏ္ဍ:ထာမ်ပလိက်ချက်ခ်အပြံၚ်အလှာဲပ္တဝ်ထ္ၜးပမာဏနာမဝိသေသနဂမၠိုၚ်]] </includeonly>"
401102
wikitext
text/x-wiki
{{documentation subpage}}
{{documentation needed}}<!-- Replace this with a short description of the purpose of the template, and how to use it. -->
<includeonly>
[[ကဏ္ဍ:ထာမ်ပလိက်ချက်ခ်အပြံၚ်အလှာဲပ္တဝ်ထ္ၜးပမာဏနာမဝိသေသနဂမၠိုၚ်]]
</includeonly>
iau130oobgngvo2ztplgj7iarqpp3c5
မဝ်ဂျူ:inflection-table
828
298503
401104
2026-08-12T17:49:45Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "local export = {} local M = require("Module:module loader").init({ require = { parameters = "Module:parameters", }, loadData = { headword_data = "Module:headword/data", }, }) local concat = table.concat local insert = table.insert local WRAPPER_CLASS = "inflection-table-wrapper" local TABLE_CLASS = "inflection-table" local TITLE_CLASS = "inflection-table-title" local NO_TITLE_CLASS = "inflection-table-no-ti..."
401104
Scribunto
text/plain
local export = {}
local M = require("Module:module loader").init({
require = {
parameters = "Module:parameters",
},
loadData = {
headword_data = "Module:headword/data",
},
})
local concat = table.concat
local insert = table.insert
local WRAPPER_CLASS = "inflection-table-wrapper"
local TABLE_CLASS = "inflection-table"
local TITLE_CLASS = "inflection-table-title"
local NO_TITLE_CLASS = "inflection-table-no-title"
local NOTES_CLASS = "inflection-table-notes"
local COLLAPSIBLE_CLASSES = "inflection-table-collapsible inflection-table-collapsed no-vc"
local VS_SWITCHER_CLASS = "vsSwitcher"
local VS_TOGGLE_CLASS = "vsToggleElement"
local BOX_CLASS = "inflection-box"
local BOX_CONTENT_CLASS = "inflection-box-content"
local BOX_NARROW_CLASS = "inflection-table-narrow"
local TR_ALONGSIDE_CLASS = "tr-alongside"
local FLOW_VERTICAL_CLASS = "flow-vertical"
local NO_TITLE_MARKER = "-"
local DEFAULT_PALETTE = "grey"
local DEFAULT_TOGGLE_CATEGORY = "inflection"
local DEFAULT_TITLE_FORMAT = "Inflection of ''%s''"
local VERTICAL_FLOW = "vertical"
local BASE_STYLE = "width: fit-content"
-- Palettes recognized by [[MediaWiki:Gadget-Palette.css]].
local PALETTES = {
red = true,
scarlet = true,
orange = true,
amber = true,
yellow = true,
lime = true,
green = true,
teal = true,
cyan = true,
blue = true,
indigo = true,
purple = true,
magenta = true,
rose = true,
grey = true,
brown = true,
}
local top_params = {
title = true,
tall = true,
class = true,
["min-width"] = true,
palette = true,
category = true,
lang = true,
["vs-category"] = true,
vsToggleElement = true,
}
local bottom_params = {
notes = true,
}
local box_top_params = {
title = true,
flow = true,
category = true,
}
local function nonempty(value)
return value ~= nil and value ~= "" and value or nil
end
-- Builds the opening <div> and the wikitable header. The markup is deliberately
-- unbalanced -- {{inflection-table-bottom}} closes both -- so this is assembled
-- as text rather than through mw.html, which cannot emit an unclosed node.
function export.make_top(args)
local palette = args.palette or DEFAULT_PALETTE
if not PALETTES[palette] then
error(("Unrecognized palette '%s'; see [[MediaWiki:Gadget-Palette.css]] for the recognized palettes.")
:format(palette))
end
local no_title = args.title == NO_TITLE_MARKER
local wrapper_classes = { WRAPPER_CLASS }
if no_title then
insert(wrapper_classes, NO_TITLE_CLASS)
end
if nonempty(args.tall) then
insert(wrapper_classes, COLLAPSIBLE_CLASSES)
end
if nonempty(args.class) then
insert(wrapper_classes, args.class)
end
local style = BASE_STYLE
local min_width = nonempty(args["min-width"])
if min_width then
style = ("%s; min-width: %s"):format(style, min_width)
end
local vs_category = nonempty(args["vs-category"])
local table_classes = { TABLE_CLASS }
if nonempty(args.lang) then
insert(table_classes, ("%s-%s"):format(TABLE_CLASS, args.lang))
end
if vs_category then
insert(table_classes, VS_SWITCHER_CLASS)
end
local lines = {
('<div class="%s" style="%s" data-wikt-palette-p="%s" data-toggle-category="%s">'):format(
concat(wrapper_classes, " "),
style,
palette,
args.category or DEFAULT_TOGGLE_CATEGORY
),
('{| class="%s"%s'):format(
concat(table_classes, " "),
vs_category and (' data-toggle-category="%s"'):format(vs_category) or ""
),
}
if not no_title then
insert(lines, ('|+ class="%s%s" | %s'):format(
TITLE_CLASS,
nonempty(args.vsToggleElement) and " " .. VS_TOGGLE_CLASS or "",
args.title or DEFAULT_TITLE_FORMAT:format(M.headword_data.pagename)
))
insert(lines, "|-")
end
return concat(lines, "\n") .. "\n"
end
-- Builds the opening markup for {{inflection-box-top}}, a wrapper holding
-- several complete inflection tables side by side. Boxes are always collapsible
-- and always place transliterations alongside, so those classes are fixed. No
-- palette is emitted: each table inside the box carries its own.
-- {{inflection-table-bottom}} closes this too.
function export.make_box_top(args)
local classes = {
WRAPPER_CLASS,
BOX_CLASS,
BOX_NARROW_CLASS,
COLLAPSIBLE_CLASSES,
TR_ALONGSIDE_CLASS,
}
if args.flow == VERTICAL_FLOW then
insert(classes, FLOW_VERTICAL_CLASS)
end
return concat({
('<div class="%s" style="%s" data-toggle-category="%s">'):format(
concat(classes, " "),
BASE_STYLE,
args.category or DEFAULT_TOGGLE_CATEGORY
),
('{| class="%s"'):format(BOX_CONTENT_CLASS),
('|+ class="%s" | %s'):format(
TITLE_CLASS,
args.title or DEFAULT_TITLE_FORMAT:format(M.headword_data.pagename)
),
"|-",
"|",
}, "\n") .. "\n"
end
-- Closes the wikitable and the wrapper opened by make_top, with the notes block
-- in between.
function export.make_bottom(args)
local notes = args and nonempty(args.notes)
if not notes then
-- The blank line is what the template emitted; kept so the parser sees
-- byte-identical wikitext.
return "|}\n\n</div>"
end
return ('|}\n<div class="%s">\n%s\n</div>\n</div>'):format(NOTES_CLASS, notes)
end
local function split_args(args)
local top_args, bottom_args = {}, {}
for k, v in pairs(args or {}) do
if bottom_params[k] then
bottom_args[k] = v
else
top_args[k] = v
end
end
return top_args, bottom_args
end
-- Builds a complete table around `contents`.
function export.make_table(args, contents)
local top_args, bottom_args = split_args(args)
return export.make_top(top_args) .. contents .. export.make_bottom(bottom_args)
end
-- As export.make_table, for boxes.
function export.make_box(args, contents)
local top_args, bottom_args = split_args(args)
return export.make_box_top(top_args) .. contents .. export.make_bottom(bottom_args)
end
-- Implementation of {{inflection-table-top}}. Other modules should call
-- make_top directly instead.
function export.top(frame)
local args = M.parameters.process(frame:getParent().args, top_params, nil, "inflection-table", "top")
return export.make_top(args)
end
-- Implementation of {{inflection-table-bottom}}. See the note on export.top.
function export.bottom(frame)
local args = M.parameters.process(frame:getParent().args, bottom_params, nil, "inflection-table", "bottom")
return export.make_bottom(args)
end
-- Implementation of {{inflection-box-top}}. See the note on export.top.
function export.box_top(frame)
local args = M.parameters.process(frame:getParent().args, box_top_params, nil, "inflection-table", "box_top")
return export.make_box_top(args)
end
-- Boxes close exactly like plain tables, so these are aliases rather than
-- separate implementations.
export.make_box_bottom = export.make_bottom
export.box_bottom = export.bottom
return export
6kiz9pqaah1j8t61f7zr7ltwi2gyzul
ကဏ္ဍ:ထာမ်ပလိက်ချက်ခ်အပြံၚ်အလှာဲပ္တဝ်ထ္ၜးပမာဏနာမဝိသေသနဂမၠိုၚ်
14
298504
401106
2026-08-12T17:54:53Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "[[ကဏ္ဍ:ထာမ်ပလိက်ချက်ခ်အပြံၚ်အလှာဲပ္တဝ်ထ္ၜးပမာဏဂမၠိုၚ်]][[ကဏ္ဍ:ထာမ်ပလိက်အပြံၚ်အလှာဲပ္တဝ်ထ္ၜးပမာဏနာမဝိသေသနဗက်အလိုက်အရေဝ်ဘာသာဂမၠိုၚ်|ခ]]"
401106
wikitext
text/x-wiki
[[ကဏ္ဍ:ထာမ်ပလိက်ချက်ခ်အပြံၚ်အလှာဲပ္တဝ်ထ္ၜးပမာဏဂမၠိုၚ်]][[ကဏ္ဍ:ထာမ်ပလိက်အပြံၚ်အလှာဲပ္တဝ်ထ္ၜးပမာဏနာမဝိသေသနဗက်အလိုက်အရေဝ်ဘာသာဂမၠိုၚ်|ခ]]
48lfbbao5muowayq97zd8kvvnbn4ugr
matematicky
0
298505
401107
2026-08-12T17:59:16Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "{{also|matematický|matematičky}} ==ချက်ခ်== ===ဗွဟ်ရမ္သာၚ်=== * {{cs-IPA|[ty]}} ===ကြိယာဝိသေသန=== {{cs-adv|matematičtěji|nejmatematičtěji}} # နကဵုလ္ပာ်သၚ်္ချာ။"
401107
wikitext
text/x-wiki
{{also|matematický|matematičky}}
==ချက်ခ်==
===ဗွဟ်ရမ္သာၚ်===
* {{cs-IPA|[ty]}}
===ကြိယာဝိသေသန===
{{cs-adv|matematičtěji|nejmatematičtěji}}
# နကဵုလ္ပာ်သၚ်္ချာ။
nergffudr8eswtkh3g2vkxvhxdt2idi
matematičtěji
0
298506
401108
2026-08-13T00:02:35Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "==ချက်ခ်== ===ကြိယာဝိသေသန=== {{head|cs|ဗီုပြၚ်ကြိယာဝိသေသန}} # {{comparative of|cs|matematicky}}"
401108
wikitext
text/x-wiki
==ချက်ခ်==
===ကြိယာဝိသေသန===
{{head|cs|ဗီုပြၚ်ကြိယာဝိသေသန}}
# {{comparative of|cs|matematicky}}
3lyq8k2wxp1woy9exo1hen6t3uazygs
nejmatematičtěji
0
298507
401109
2026-08-13T00:03:52Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "==ချက်ခ်== ===ကြိယာဝိသေသန=== {{head|cs|ဗီုပြၚ်ကြိယာဝိသေသန}} # {{superlative of|cs|matematicky}}"
401109
wikitext
text/x-wiki
==ချက်ခ်==
===ကြိယာဝိသေသန===
{{head|cs|ဗီုပြၚ်ကြိယာဝိသေသန}}
# {{superlative of|cs|matematicky}}
546vwgh25ctxwh5dydf3p67mxz2kf0o
ကဏ္ဍ:ဗီုပြၚ်ကြိယာဝိသေသနချက်ခ်ဂမၠိုၚ်
14
298508
401110
2026-08-13T00:05:33Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "[[ကဏ္ဍ:ဘာသာချက်ခ်]]"
401110
wikitext
text/x-wiki
[[ကဏ္ဍ:ဘာသာချက်ခ်]]
1e1hyks4j8a51b3o16gsz7gch8s3ruh
matematičky
0
298509
401111
2026-08-13T00:07:43Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "{{also|matematicky|matematický}} ==ချက်ခ်== ===ဗွဟ်ရမ္သာၚ်=== * {{cs-IPA}} ===နာမ်=== {{head|cs|noun form|g=f}} # {{infl of|cs|matematička||gen|s|;|nom//acc//voc|p}}"
401111
wikitext
text/x-wiki
{{also|matematicky|matematický}}
==ချက်ခ်==
===ဗွဟ်ရမ္သာၚ်===
* {{cs-IPA}}
===နာမ်===
{{head|cs|noun form|g=f}}
# {{infl of|cs|matematička||gen|s|;|nom//acc//voc|p}}
8jfwgxk21yt7vjdd45ru66dponrd572
matematička
0
298510
401112
2026-08-13T00:11:43Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "{{also|matematická}} ==ချက်ခ်== ===ဗွဟ်ရမ္သာၚ်=== * {{cs-IPA}} ===နာမ်=== {{cs-noun|f|m=matematik}} # {{female equivalent of|cs|matematik}} ====လဟုတ်စှ်ေ==== {{cs-ndecl|f}} ==သၠဝ်ဝေန်နဳယျာ== ===ဗွဟ်ရမ္သာၚ်=== * {{IPA|sk|/ˈmatɛmatit͡ʃka/}} ===နာမ်=== {{sk-noun|f|gen=matematičky|pl=matematič..."
401112
wikitext
text/x-wiki
{{also|matematická}}
==ချက်ခ်==
===ဗွဟ်ရမ္သာၚ်===
* {{cs-IPA}}
===နာမ်===
{{cs-noun|f|m=matematik}}
# {{female equivalent of|cs|matematik}}
====လဟုတ်စှ်ေ====
{{cs-ndecl|f}}
==သၠဝ်ဝေန်နဳယျာ==
===ဗွဟ်ရမ္သာၚ်===
* {{IPA|sk|/ˈmatɛmatit͡ʃka/}}
===နာမ်===
{{sk-noun|f|gen=matematičky|pl=matematičky|genpl=matematičiek|decl=žena}}
# ဗြဴတၠပညာသၚ်္ချာ။
====လဟုတ်စှ်ေ====
{{sk-ndecl|f}}
i0oh9w5xvvimklvkzuobbzn79nxol96
matematická
0
298511
401113
2026-08-13T00:15:58Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "{{also|matematička}} ==ချက်ခ်== ===ဗွဟ်ရမ္သာၚ်=== * {{cs-IPA|[ty]}} ====နာမဝိသေသန==== {{head|cs|adjective form}} # {{infl of|cs|matematický||f|nom|s|;|n|nom//acc|p}}"
401113
wikitext
text/x-wiki
{{also|matematička}}
==ချက်ခ်==
===ဗွဟ်ရမ္သာၚ်===
* {{cs-IPA|[ty]}}
====နာမဝိသေသန====
{{head|cs|adjective form}}
# {{infl of|cs|matematický||f|nom|s|;|n|nom//acc|p}}
0o3rpm54100bcasvul7wclykx0apml4