Module:fi-nominals and Module:fi-nominals/sandbox: Difference between pages

(Difference between pages)
Jump to navigation Jump to search
Page 1
Page 2
Content deleted Content added
Undo revision 82639280 by Surjection (talk)
Tag: Undo
 
m replaced vsToggleCategory- class with data-toggle-category attribute, which is cleaner and easier for the JavaScript gadget to retrieve
 
Line 1: Line 1:
local m_utilities = require("Module:utilities")
local m_links = require("Module:links")

local export = {}
local export = {}


Line 6: Line 9:
local inflections = {}
local inflections = {}


-- The main entry point.
local kotus_grad_type = {
-- This is the only function that can be invoked from a template.
["kk-k"] = "A",
function export.show(frame)
["pp-p"] = "B",
local infl_type = frame.args[1] or error("Inflection type has not been specified. Please pass parameter 1 to the module invocation")
["tt-t"] = "C",
local args = frame:getParent().args
["k-"] = "D",
["p-v"] = "E",
["t-d"] = "F",
["nk-ng"] = "G",
["mp-mm"] = "H",
["lt-ll"] = "I",
["nt-nn"] = "J",
["rt-rr"] = "K",
["k-j"] = "L",
["k-v"] = "M"
}

local m_bit32 -- loaded later if needed

local RARE = '<span class="narrow-space"> </span><sup>rare</sup>'

local function normalize_apostrophes(term, link_target)
if link_target then
if term and mw.ustring.find(term, "’") then
term = mw.ustring.gsub(term, "’", "'")
end
else
if term and mw.ustring.find(term, "'") then
term = mw.ustring.gsub(term, "'", "’")
end
end
return term
end


-- Creates a link to a form.
local function make_link(term, accel_form)
-- do not link inflected forms of suffixes
if term:match("^-") then
if term == mw.title.getCurrentTitle().fullText then
return '<span class="Latn" lang="fi"><strong class="selflink">' .. term .. '</strong></span>'
end

return '<span class="Latn" lang="fi">' .. term .. '</span>'
end
if not inflections[infl_type] then
-- if there is something difficult, use full module.
error("Unknown inflection type '" .. infl_type .. "'")
if term:find(":") or term:find("<") then
if term:find(":") then term = mw.ustring.gsub(term, ":", "\\:") end
return require("Module:links").full_link({
lang = lang,
term = term,
accel = accel_form and ({ form = accel_form }) or nil
})
end
end
local data = {forms = {}, title = nil, categories = {}}
-- otherwise, we can save a ton of memory by doing this manually.
local target = normalize_apostrophes(term, true)
-- Generate the forms
if target == mw.title.getCurrentTitle().fullText then
inflections[infl_type](args, data)
return '<span class="Latn" lang="fi"><strong class="selflink">' .. term .. '</strong></span>'
end
if not accel_form then
return '<span class="Latn" lang="fi">[[' .. target .. '#Finnish|' .. term .. ']]</span>'
end
return '<span class="Latn form-of lang-fi ' .. accel_form .. '-form-of" lang="fi">[[' .. target .. '#Finnish|' .. term .. ']]</span>'
end

local function tag_term(term)
-- return require("Module:script utilities").tag_text(term, lang, nil, "term")
return '<i class="Latn mention" lang="fi">' .. term .. '</i>'
end

local function do_inflection_internal(data, argobj)
local args = argobj.args
argobj.pos = 1

data.words = {}
data.num = 1
data.forms = nil
data.categories = {}
for num, infl_type in ipairs(data.infl_types) do
-- initialize data for single word
local word_data = {forms = {}, title = nil, categories = {}}
-- word index
word_data.num = num
data.num = num
-- Generate the forms
inflections[infl_type](argobj, word_data)
postprocess_word(argobj, word_data, data, num == #data.infl_types)
word_data.class = infl_type
data.words[num] = word_data
end

if #data.words > 1 then
-- join the inflected word components
export.join_words(data, function (n) return args["space" .. tostring(n)] or args["space"] or " " end)
else
data.vh = data.words[1].vh
data.forms = data.words[1].forms
data.title = data.words[1].title
data.categories = data.words[1].categories
end
-- Postprocess
-- Postprocess
postprocess(args, data)
postprocess(args, data)
end

-- The main entry point.
-- This is the only function that can be invoked from a template.
function export.show(frame)
local infl_type = frame.args[1] or error("Inflection type has not been specified. Please pass parameter 1 to the module invocation")
local args = frame:getParent().args
local infl_types = {infl_type}
if args["nocheck"] then
infl_types = mw.text.split(infl_type, "%-")
table.insert(data.categories, "fi-decl with nocheck")
end
if args["nosg"] then
for _, type in ipairs(infl_types) do
table.insert(data.categories, "fi-decl with nosg")
if not inflections[type] then
error("Unknown inflection type '" .. infl_type .. "'")
end
end
end
local pos = args["pos"]; if not pos or pos == "" then pos = "noun" end
if args["nopl"] then
table.insert(data.categories, "fi-decl with nopl")
local allow_possessive = (pos == "noun" or pos == "adj") and not args["poss"]
end
if args["type"] then
-- initialize data for full inflection process
table.insert(data.categories, "fi-decl with type")
local data = {
pagename = mw.title.getCurrentTitle().text,
infl_types = infl_types,
poss = args["poss"]
}
local argobj = {args = args}

if args["title"] and mw.title.getCurrentTitle().namespace > 0 then
data.pagename = args.title
elseif data.pagename:find("^Unsupported titles/") then
data.pagename = data.pagename:gsub("^Unsupported titles/", "")
end
end
return make_table(data) .. m_utilities.format_categories(data.categories, lang)
data.pagename = normalize_apostrophes(data.pagename)

do_inflection_internal(data, argobj)

--if args["type"] then table.insert(data.categories, "fi-decl with type") end
--if args["nocheck"] then table.insert(data.categories, "fi-decl with nocheck") end
--if args["nosg"] then table.insert(data.categories, "fi-decl with nosg") end
--if args["nopl"] then table.insert(data.categories, "fi-decl with nopl") end
local function get_poss_forms(poss)
data.poss = poss
do_inflection_internal(data, argobj)
return data
end

local categories
if args["appendix"] then
categories = ""
else
categories = require("Module:utilities").format_categories(data.categories, lang)
end

return make_table(data, true)
.. (allow_possessive and make_possessive_table(data.pagename, args, pos, data.title, get_poss_forms) or "")
.. categories
.. require("Module:TemplateStyles")("Module:fi-nominals/style.css")
.. require("Module:TemplateStyles")("Module:fi-nominals/style.css")
end
end


local function args_get_required(args, i, purpose)
function get_params(args, num, invert_grades)
local v = args[i]
if not v then
error(purpose .. " (parameter " .. i .. ") may not be omitted.")
end
return v
end

local function args_get_vowel_harmony(args, i)
local v = args[i]
if not v or not mw.ustring.match(v, "^[aä]$") then
error("Vowel harmony (parameter " .. i .. ") must be \"a\" or \"ä\".")
end
return v
end

function get_params(argobj, num, invert_grades)
local params = {}
local params = {}
local args = argobj.args
local pos = argobj.pos

params.base = normalize_apostrophes(args[pos])
if num >= 2 then
if num >= 4 then
params.strong = normalize_apostrophes(args_get_required(args, pos + 1, "Nominative grade"))
params.weak = normalize_apostrophes(args_get_required(args, pos + 2, "Genitive grade"))
if num == 5 then
-- Swap the grades
params.base = args[1] or (mw.title.getCurrentTitle().nsText == "Template" and "{{{1}}}"); if not params.base or params.base == "" then error("Parameter 1 (base stem) may not be empty.") end
if invert_grades then
params.strong = args[2] or (mw.title.getCurrentTitle().nsText == "Template" and "{{{2}}}"); if not params.strong then error("Parameter 2 (nominative grade) may not be omitted.") end
params.strong, params.weak = params.weak, params.strong
params.weak = args[3] or (mw.title.getCurrentTitle().nsText == "Template" and "{{{3}}}"); if not params.weak then error("Parameter 3 (genitive grade) may not be omitted.") end
end
params.final = args[4] or (mw.title.getCurrentTitle().nsText == "Template" and "{{{4}}}"); if not params.final or params.final == "" then error("Parameter 4 (final letter(s)) may not be empty.") end
end
params.a = args[5] or (mw.title.getCurrentTitle().nsText == "Template" and "a"); if params.a ~= "a" and params.a ~= "ä" then error("Parameter 5 must be \"a\" or \"ä\".") end

if num >= 5 then
elseif num == 4 then
params.base = args[1] or (mw.title.getCurrentTitle().nsText == "Template" and "{{{1}}}"); if not params.base or params.base == "" then error("Parameter 1 (base stem) may not be empty.") end
params.final = args_get_required(args, pos + 3, "Final letter(s)")
params.strong = args[2] or (mw.title.getCurrentTitle().nsText == "Template" and "{{{2}}}"); if not params.strong then error("Parameter 2 (nominative grade) may not be omitted.") end
end
params.weak = args[3] or (mw.title.getCurrentTitle().nsText == "Template" and "{{{3}}}"); if not params.weak then error("Parameter 3 (genitive grade) may not be omitted.") end

params.a = args[4] or (mw.title.getCurrentTitle().nsText == "Template" and "a"); if params.a ~= "a" and params.a ~= "ä" then error("Parameter 4 must be \"a\" or \"ä\".") end
params.a = args_get_vowel_harmony(args, pos + num - 1)
elseif num == 2 then
else
params.base = args[1] or (mw.title.getCurrentTitle().nsText == "Template" and "{{{1}}}"); if not params.base or params.base == "" then error("Parameter 1 (base stem) may not be empty.") end
params.base = params.base or ""
params.a = args[2] or (mw.title.getCurrentTitle().nsText == "Template" and "a"); if params.a ~= "a" and params.a ~= "ä" then error("Parameter 2 must be \"a\" or \"ä\".") end
elseif num == 1 then
params.base = args[1] or ""
end
-- Swap the grades
if invert_grades then
params.strong, params.weak = params.weak, params.strong
end
end
Line 226: Line 78:
end
end
argobj.pos = argobj.pos + num
return params
return params
end
end


local make_weak = require("Module:fi-utilities").make_weak
function get_extra_arg(argobj, wdata, name, fallback)
return argobj.args[name .. wdata.num] or argobj.args[name]
end


--[=[
--[=[
Line 296: Line 145:
["ill_pl"] = "Vn",
["ill_pl"] = "Vn",
}
}



-- Make a copy of the endings, with front vowels
-- Make a copy of the endings, with front vowels
Line 306: Line 156:
end
end


-- Create any stems that were not given
-- data for generating possessive forms
local function make_stems(data, stems)
-- suffixes per person
if not stems["nom_sg"] and stems["sg"] then
local poss_forms = {["1s"] = "ni", ["2s"] = "si", ["3s"] = "nsa", ["1p"] = "mme", ["2p"] = "nne"}
stems["nom_sg"] = mw.clone(stems["sg"])
local poss_alt = {--["00"] = false, ["1s"] = false, ["2s"] = false, ["1p"] = false, ["2p"] = false,
end
["3s"] = true, -- shorter form -Vn
}
if not stems["par_sg"] and stems["sg"] then
-- which forms allow -nsa > -Vn?
stems["par_sg"] = mw.clone(stems["sg"])
local forms_alt_ok = {
["gen_sg"] = false, ["gen_pl"] = false,
["par_sg"] = false, ["par_pl"] = true,
["ine_sg"] = true, ["ine_pl"] = true,
["ela_sg"] = true, ["ela_pl"] = true,
["ill_sg"] = false, ["ill_pl"] = false,
["ade_sg"] = true, ["ade_pl"] = true,
["abl_sg"] = true, ["abl_pl"] = true,
["all_sg"] = true, ["all_pl"] = true,
["ess_sg"] = true, ["ess_pl"] = true,
["tra_sg"] = true, ["tra_pl"] = true,
["ins_sg"] = false, ["ins_pl"] = false,
["abe_sg"] = true, ["abe_pl"] = true,
["com_sg"] = true, ["com_pl"] = true,
}
-- which forms end in -n?
-- (in which case it is dropped before the possessive suffix)
local forms_gen_ok = {
["gen_sg"] = true, ["gen_pl"] = true,
["ill_sg"] = true, ["ill_pl"] = true,
["ins_sg"] = true, ["ins_pl"] = true,
}

local function feed_list(outputs, inputs)
for key, values in pairs(inputs) do
outputs[key] = outputs[key] or {}
for _, value in ipairs(values) do
table.insert(outputs[key], value)
end
end
end
end

local function process_stems(data, stems, vh)
-- Create any stems that were not given
stems["nom_sg"] = stems["nom_sg"] or mw.clone(stems["sg"])
stems["par_sg"] = stems["par_sg"] or mw.clone(stems["sg"])
stems["par_pl"] = stems["par_pl"] or mw.clone(stems["pl"])
stems["ill_pl"] = stems["ill_pl"] or mw.clone(stems["pl"])
if not stems["ill_sg"] and stems["sg"] then
if not stems["ill_sg"] and stems["sg"] then
Line 357: Line 171:
for _, stem in ipairs(stems["sg"]) do
for _, stem in ipairs(stems["sg"]) do
-- If the stem ends in a long vowel or diphthong, then add -h
-- If the stem ends in a long vowel or diphthong, then add -h
if mw.ustring.find(stem, "([aeiouyäö])%1$") or mw.ustring.find(stem, "[aeiouyäö][iuyü]$") then
if mw.ustring.find(stem, "([aeiouyäö])%1$") or mw.ustring.find(stem, "[aeiouyäö][iyü]$") then
table.insert(stems["ill_sg"], stem .. "h")
table.insert(stems["ill_sg"], stem .. "h")
else
else
table.insert(stems["ill_sg"], stem)
table.insert(stems["ill_sg"], stem)
end
end
end
end
if not stems["par_pl"] and stems["pl"] then
stems["par_pl"] = {}
for _, stem in ipairs(stems["pl"]) do
table.insert(stems["par_pl"], stem)
end
end
end
end
Line 378: Line 200:
end
end
end
end
if not stems["ill_pl"] and stems["pl"] then
stems["ill_pl"] = {}
for _, stem in ipairs(stems["pl"]) do
table.insert(stems["ill_pl"], stem)
end
end
end


-- Create forms based on each stem, by adding endings to it
-- Create forms based on each stem, by adding endings to it
local function process_stems(data, stems, vh)
stems["sg_weak"] = stems["sg_weak"] or mw.clone(stems["sg"])
stems["pl_weak"] = stems["pl_weak"] or mw.clone(stems["pl"])
if not stems["sg_weak"] and stems["sg"] then
stems["sg_weak"] = mw.clone(stems["sg"])
end
if not stems["pl_weak"] and stems["pl"] then
stems["pl_weak"] = mw.clone(stems["pl"])
end
-- Go through each of the stems given
-- Go through each of the stems given
Line 404: Line 241:
data["stems"] = stems
data["stems"] = stems
data["vh"] = vh
end
end




inflections["valo"] = function(args, data)
local function make_kotus_title_number(type_number)
return "[[Kotus]] type " .. type_number
data.title = "[[Kotus]] type 1/[[Appendix:Finnish nominal inflection/valo|valo]]"
table.insert(data.categories, "Finnish valo-type nominals")
end

local params = get_params(args, 5)

local function make_kotus_title_word(reference_word)
make_weak(params.base, params.strong, params.final, params.weak)
return '/<span lang="fi" class="Latn">[[Appendix:Finnish declension/' .. reference_word .. '|' .. reference_word .. ']]</span>'
end
if params.strong == params.weak then

data.title = data.title .. ", no gradation"

local function make_kotus_title(number, reference_word)
return make_kotus_title_number(number) .. make_kotus_title_word(reference_word)
end


local function inflection_type_is(data, number, reference_word, strong, weak)
local title = make_kotus_title_number(number)
local has_gradation = strong and strong ~= weak

if has_gradation then
local letter = kotus_grad_type[strong .. "-" .. weak]
if letter then
title = title .. "*" .. letter
else
title = title .. "*"
end
end

title = title .. make_kotus_title_word(reference_word)

if has_gradation then
local EMPTY = "<small>∅</small>"
local function format(grade)
if grade == "" then
return EMPTY
else
return "''" .. grade .. "''"
end
end
title = title .. ", " .. format(strong) .. "-" .. format(weak) .. " gradation"
else
else
title = title .. ", no gradation"
data.title = data.title .. ", ''" .. params.strong .. "-" .. params.weak .. "'' gradation"
end
end

data.title = title

table.insert(data.categories, "Finnish " .. reference_word .. "-type nominals")
end


--[=[
Inflection types
]=]--


inflections["valo"] = function(args, data)
local params = get_params(args, 5)
local wk_sg = params.weak
local wk_sg = params.weak
Line 487: Line 279:
stems["ill_pl"] = {params.base .. params.strong .. params.final .. "ih"}
stems["ill_pl"] = {params.base .. params.strong .. params.final .. "ih"}
make_stems(data, stems)
inflection_type_is(data, 1, "valo", params.strong, params.weak)
process_stems(data, stems, params.a)
process_stems(data, stems, params.a)
end
end


inflections["palvelu"] = function(args, data)
inflections["palvelu"] = function(args, data)
data.title = "[[Kotus]] type 2/[[Appendix:Finnish nominal inflection/palvelu|palvelu]], no gradation"
table.insert(data.categories, "Finnish palvelu-type nominals")
local params = get_params(args, 2)
local params = get_params(args, 2)
Line 500: Line 295:
stems["ill_pl"] = {params.base .. "ih"}
stems["ill_pl"] = {params.base .. "ih"}
inflection_type_is(data, 2, "palvelu")
make_stems(data, stems)
process_stems(data, stems, params.a)
process_stems(data, stems, params.a)
end
end


inflections["valtio"] = function(args, data)
inflections["valtio"] = function(args, data)
data.title = "[[Kotus]] type 3/[[Appendix:Finnish nominal inflection/valtio|valtio]], no gradation"
table.insert(data.categories, "Finnish valtio-type nominals")
local params = get_params(args, 2)
local params = get_params(args, 2)
local final = mw.ustring.sub(params.base, -1)
local final = mw.ustring.sub(params.base, -1)
Line 515: Line 313:
stems["ill_pl"] = {params.base .. "ih"}
stems["ill_pl"] = {params.base .. "ih"}
inflection_type_is(data, 3, "valtio")
make_stems(data, stems)
process_stems(data, stems, params.a)
process_stems(data, stems, params.a)
end
end


inflections["laatikko"] = function(args, data)
inflections["laatikko"] = function(args, data)
data.title = "[[Kotus]] type 4/[[Appendix:Finnish nominal inflection/laatikko|laatikko]]"
table.insert(data.categories, "Finnish laatikko-type nominals")
local params = get_params(args, 5, false, "kk", "k", "o")
local params = get_params(args, 5, false, "kk", "k", "o")
make_weak(params.base, params.strong, params.final, params.weak)
if params.strong == params.weak then
data.title = data.title .. ", no gradation"
else
data.title = data.title .. ", ''" .. params.strong .. "-" .. params.weak .. "'' gradation"
end
local stems = {}
local stems = {}
Line 530: Line 339:
stems["ill_pl"] = {params.base .. params.strong .. params.final .. "ih", params.base .. params.weak .. params.final .. "ih"}
stems["ill_pl"] = {params.base .. params.strong .. params.final .. "ih", params.base .. params.weak .. params.final .. "ih"}
make_stems(data, stems)
inflection_type_is(data, 4, "laatikko", params.strong, params.weak)
process_stems(data, stems, params.a)
process_stems(data, stems, params.a)
end
end


inflections["risti"] = function(args, data)
inflections["risti"] = function(args, data)
data.title = "[[Kotus]] type 5/[[Appendix:Finnish nominal inflection/risti|risti]]"
table.insert(data.categories, "Finnish risti-type nominals")
local params = get_params(args, 4)
local params = get_params(args, 4)
local i = get_extra_arg(args, data, "i"); if i == "0" then i = "" else i = "i" end
local i = args["i"]; if i == "0" then i = "" else i = "i" end

make_weak(params.base, params.strong, "i", params.weak)
if params.strong == params.weak then
data.title = data.title .. ", no gradation"
else
data.title = data.title .. ", ''" .. params.strong .. "-" .. params.weak .. "'' gradation"
end
local stems = {}
local stems = {}
stems["nom_sg"] = {params.base .. params.strong .. i}
stems["nom_sg"] = {params.base .. params.strong .. i}
Line 548: Line 368:
stems["ill_pl"] = {params.base .. params.strong .. "eih"}
stems["ill_pl"] = {params.base .. params.strong .. "eih"}
make_stems(data, stems)
inflection_type_is(data, 5, "risti", params.strong, params.weak)
process_stems(data, stems, params.a)
process_stems(data, stems, params.a)
end
end


inflections["paperi"] = function(args, data)
inflections["paperi"] = function(args, data)
data.title = "[[Kotus]] type 6/[[Appendix:Finnish nominal inflection/paperi|paperi]], no gradation"
table.insert(data.categories, "Finnish paperi-type nominals")
local params = get_params(args, 2)
local params = get_params(args, 2)
local i = get_extra_arg(args, data, "i"); if i == "0" then i = "" else i = "i" end
local i = args["i"]; if i == "0" then i = "" else i = "i" end
local stems = {}
local stems = {}
Line 564: Line 387:
stems["ill_pl"] = {params.base .. "eih"}
stems["ill_pl"] = {params.base .. "eih"}
inflection_type_is(data, 6, "paperi")
make_stems(data, stems)
process_stems(data, stems, params.a)
process_stems(data, stems, params.a)
end
end


inflections["ovi"] = function(args, data)
inflections["ovi"] = function(args, data)
data.title = "[[Kotus]] type 7/[[Appendix:Finnish nominal inflection/ovi|ovi]]"
table.insert(data.categories, "Finnish ovi-type nominals")
local params = get_params(args, 4)
local params = get_params(args, 4)
local nom_sg = get_extra_arg(args, data, "nom_sg"); if nom_sg == "" then nom_sg = nil end
local nom_sg = args["nom_sg"]; if nom_sg == "" then nom_sg = nil end
local wk_pl = params.weak
make_weak(params.base, params.strong, "e", params.weak)
if mw.ustring.sub(params.base, -1) == "i" and params.strong == "k" and params.weak == "" then
if params.strong == params.weak then
wk_pl = "’"
data.title = data.title .. ", no gradation"
else
data.title = data.title .. ", ''" .. params.strong .. "-" .. params.weak .. "'' gradation"
end
end

local stems = {}
local stems = {}
stems["nom_sg"] = {nom_sg or params.base .. params.strong .. "i"}
stems["nom_sg"] = {nom_sg or params.base .. params.strong .. "i"}
Line 582: Line 411:
stems["sg_weak"] = {params.base .. params.weak .. "e"}
stems["sg_weak"] = {params.base .. params.weak .. "e"}
stems["pl"] = {params.base .. params.strong .. "i"}
stems["pl"] = {params.base .. params.strong .. "i"}
stems["pl_weak"] = {params.base .. wk_pl .. "i"}
stems["pl_weak"] = {params.base .. params.weak .. "i"}
make_stems(data, stems)
inflection_type_is(data, 7, "ovi", params.strong, params.weak)
process_stems(data, stems, params.a)
process_stems(data, stems, params.a)
end
end


inflections["nalle"] = function(args, data)
inflections["nalle"] = function(args, data)
data.title = "[[Kotus]] type 8/[[Appendix:Finnish nominal inflection/nalle|nalle]]"
table.insert(data.categories, "Finnish nalle-type nominals")
local params = get_params(args, 4)
local params = get_params(args, 4)
make_weak(params.base, params.strong, "e", params.weak)
if params.strong == params.weak then
data.title = data.title .. ", no gradation"
else
data.title = data.title .. ", ''" .. params.strong .. "-" .. params.weak .. "'' gradation"
end
local stems = {}
local stems = {}
Line 599: Line 439:
stems["ill_pl"] = {params.base .. params.strong .. "eih"}
stems["ill_pl"] = {params.base .. params.strong .. "eih"}
make_stems(data, stems)
inflection_type_is(data, 8, "nalle", params.strong, params.weak)
process_stems(data, stems, params.a)
process_stems(data, stems, params.a)
Line 606: Line 446:


inflections["kala"] = function(args, data)
inflections["kala"] = function(args, data)
data.title = "[[Kotus]] type 9/[[Appendix:Finnish nominal inflection/kala|kala]]"
table.insert(data.categories, "Finnish kala-type nominals")
local params = get_params(args, 4)
local params = get_params(args, 4)
local ain = get_extra_arg(args, data, "ain"); if ain == "" then ain = nil end
make_weak(params.base, params.strong, params.a, params.weak)
if params.strong == params.weak then
data.title = data.title .. ", no gradation"
else
data.title = data.title .. ", ''" .. params.strong .. "-" .. params.weak .. "'' gradation"
end
local wk_sg = params.weak
local wk_sg = params.weak
Line 623: Line 473:
stems["ill_pl"] = {params.base .. params.strong .. params.o .. "ih"}
stems["ill_pl"] = {params.base .. params.strong .. params.o .. "ih"}
make_stems(data, stems)
inflection_type_is(data, 9, "kala", params.strong, params.weak)
process_stems(data, stems, params.a)
process_stems(data, stems, params.a)
local ain_form = params.base .. params.strong .. params.a .. "in"
data.forms["gen_pl"].rare = {params.base .. params.strong .. params.a .. "in"}
if ain == "2" then
table.insert(data.forms["gen_pl"], 1, ain_form)
elseif ain == "1" then
table.insert(data.forms["gen_pl"], ain_form)
else
data.forms["gen_pl"].rare = {ain_form}
end
end
end


inflections["koira"] = function(args, data)
inflections["koira"] = function(args, data)
data.title = "[[Kotus]] type 10/[[Appendix:Finnish nominal inflection/koira|koira]]"
table.insert(data.categories, "Finnish koira-type nominals")
local params = get_params(args, 4)
local params = get_params(args, 4)
local nom_sg = get_extra_arg(args, data, "nom_sg"); if nom_sg == "" then nom_sg = nil end
local nom_sg = args["nom_sg"]; if nom_sg == "" then nom_sg = nil end
local apo_pl = get_extra_arg(args, data, "apo_pl"); if apo_pl == "" then apo_pl = nil end
make_weak(params.base, params.strong, params.a, params.weak)
local ain = get_extra_arg(args, data, "ain"); if ain == "" then ain = nil end
if params.strong == params.weak then
data.title = data.title .. ", no gradation"
else
data.title = data.title .. ", ''" .. params.strong .. "-" .. params.weak .. "'' gradation"
end
local wk_sg = params.weak
local wk_sg = params.weak
Line 657: Line 509:
stems["sg"] = {params.base .. params.strong .. params.a}
stems["sg"] = {params.base .. params.strong .. params.a}
stems["sg_weak"] = {params.base .. wk_sg .. params.a}
stems["sg_weak"] = {params.base .. wk_sg .. params.a}
stems["pl"] = {params.base .. params.strong .. (apo_pl and "'" or "") .. "i"}
stems["pl"] = {params.base .. params.strong .. "i"}
stems["pl_weak"] = {params.base .. wk_pl .. (apo_pl and "'" or "") .. "i"}
stems["pl_weak"] = {params.base .. wk_pl .. "i"}
make_stems(data, stems)
inflection_type_is(data, 10, "koira", params.strong, params.weak)
process_stems(data, stems, params.a)
process_stems(data, stems, params.a)
local ain_form = params.base .. params.strong .. params.a .. "in"
data.forms["gen_pl"].rare = {params.base .. params.strong .. params.a .. "in"}
if ain == "2" then
table.insert(data.forms["gen_pl"], 1, ain_form)
elseif ain == "1" then
table.insert(data.forms["gen_pl"], ain_form)
else
data.forms["gen_pl"].rare = {ain_form}
end
end
end


inflections["omena"] = function(args, data)
inflections["omena"] = function(args, data)
data.title = "[[Kotus]] type 11/[[Appendix:Finnish nominal inflection/omena|omena]], no gradation"
table.insert(data.categories, "Finnish omena-type nominals")
local params = get_params(args, 2)
local params = get_params(args, 2)
Line 682: Line 530:
stems["ill_pl"] = {params.base .. "i", params.base .. params.o .. "ih"}
stems["ill_pl"] = {params.base .. "i", params.base .. params.o .. "ih"}
inflection_type_is(data, 11, "omena")
make_stems(data, stems)
process_stems(data, stems, params.a)
process_stems(data, stems, params.a)
Line 690: Line 538:


inflections["kulkija"] = function(args, data)
inflections["kulkija"] = function(args, data)
data.title = "[[Kotus]] type 12/[[Appendix:Finnish nominal inflection/kulkija|kulkija]], no gradation"
table.insert(data.categories, "Finnish kulkija-type nominals")
local params = get_params(args, 2)
local params = get_params(args, 2)
Line 698: Line 549:
stems["ill_pl"] = {params.base .. params.o .. "ih"}
stems["ill_pl"] = {params.base .. params.o .. "ih"}
inflection_type_is(data, 12, "kulkija")
make_stems(data, stems)
process_stems(data, stems, params.a)
process_stems(data, stems, params.a)
Line 705: Line 556:


inflections["katiska"] = function(args, data)
inflections["katiska"] = function(args, data)
data.title = "[[Kotus]] type 13/[[Appendix:Finnish nominal inflection/katiska|katiska]], no gradation"
table.insert(data.categories, "Finnish katiska-type nominals")
local params = get_params(args, 2)
local params = get_params(args, 2)
Line 713: Line 567:
stems["ill_pl"] = {params.base .. params.o .. "ih"}
stems["ill_pl"] = {params.base .. params.o .. "ih"}
inflection_type_is(data, 13, "katiska")
make_stems(data, stems)
process_stems(data, stems, params.a)
process_stems(data, stems, params.a)
Line 720: Line 574:


inflections["solakka"] = function(args, data)
inflections["solakka"] = function(args, data)
data.title = "[[Kotus]] type 14/[[Appendix:Finnish nominal inflection/solakka|solakka]]"
table.insert(data.categories, "Finnish solakka-type nominals")
local params = get_params(args, 4)
local params = get_params(args, 4)
make_weak(params.base, params.strong, params.a, params.weak)
if params.strong == params.weak then
data.title = data.title .. ", no gradation"
else
data.title = data.title .. ", ''" .. params.strong .. "-" .. params.weak .. "'' gradation"
end
local stems = {}
local stems = {}
Line 730: Line 595:
stems["ill_pl"] = {params.base .. params.weak .. params.o .. "ih", params.base .. params.strong .. params.o .. "ih"}
stems["ill_pl"] = {params.base .. params.weak .. params.o .. "ih", params.base .. params.strong .. params.o .. "ih"}
make_stems(data, stems)
inflection_type_is(data, 14, "solakka", params.strong, params.weak)
process_stems(data, stems, params.a)
process_stems(data, stems, params.a)
Line 737: Line 602:


inflections["korkea"] = function(args, data)
inflections["korkea"] = function(args, data)
data.title = "[[Kotus]] type 15/[[Appendix:Finnish nominal inflection/korkea|korkea]], no gradation"
table.insert(data.categories, "Finnish korkea-type nominals")
local params = get_params(args, 2)
local params = get_params(args, 2)
local final = mw.ustring.sub(params.base, -1)
local final = mw.ustring.sub(params.base, -1)
Line 747: Line 615:
stems["ill_pl"] = {params.base .. "isi", params.base .. "ih"}
stems["ill_pl"] = {params.base .. "isi", params.base .. "ih"}
inflection_type_is(data, 15, "korkea")
make_stems(data, stems)
process_stems(data, stems, params.a)
process_stems(data, stems, params.a)
Line 754: Line 622:


inflections["vanhempi"] = function(args, data)
inflections["vanhempi"] = function(args, data)
data.title = "[[Kotus]] type 16/[[Appendix:Finnish nominal inflection/vanhempi|vanhempi]], ''mp-mm'' gradation"
table.insert(data.categories, "Finnish vanhempi-type nominals")
local params = get_params(args, 2)
local params = get_params(args, 2)
Line 763: Line 634:
stems["pl_weak"] = {params.base .. "mmi"}
stems["pl_weak"] = {params.base .. "mmi"}
make_stems(data, stems)
inflection_type_is(data, 16, "vanhempi", "mp", "mm")
process_stems(data, stems, params.a)
process_stems(data, stems, params.a)
Line 770: Line 641:


inflections["vapaa"] = function(args, data)
inflections["vapaa"] = function(args, data)
data.title = "[[Kotus]] type 17/[[Appendix:Finnish nominal inflection/vapaa|vapaa]], no gradation"
table.insert(data.categories, "Finnish vapaa-type nominals")
local params = get_params(args, 2)
local params = get_params(args, 2)
local final = mw.ustring.sub(params.base, -1)
local final = mw.ustring.sub(params.base, -1)
Line 781: Line 655:
stems["ill_pl"] = {params.base .. "isi"}
stems["ill_pl"] = {params.base .. "isi"}
inflection_type_is(data, 17, "vapaa")
make_stems(data, stems)
process_stems(data, stems, params.a)
process_stems(data, stems, params.a)
Line 788: Line 662:


inflections["maa"] = function(args, data)
inflections["maa"] = function(args, data)
data.title = "[[Kotus]] type 18/[[Appendix:Finnish nominal inflection/maa|maa]], no gradation"
table.insert(data.categories, "Finnish maa-type nominals")
local params = get_params(args, 2)
local params = get_params(args, 2)
local nom_sg = args["nom_sg"]; if nom_sg == "" then nom_sg = nil end
local pl_stem = mw.ustring.sub(params.base, 1, -2)
local pl_stem = mw.ustring.sub(params.base, 1, -2)
local stems = {}
local stems = {}
stems["nom_sg"] = {nom_sg or params.base}
stems["sg"] = {params.base}
stems["sg"] = {params.base}
stems["par_sg"] = {params.base .. "t"}
stems["par_sg"] = {params.base .. "t"}
Line 799: Line 678:
stems["ill_pl"] = {pl_stem .. "ih"}
stems["ill_pl"] = {pl_stem .. "ih"}
inflection_type_is(data, 18, "maa")
make_stems(data, stems)
process_stems(data, stems, params.a)
process_stems(data, stems, params.a)
end
end


inflections["suo"] = function(args, data)
inflections["suo"] = function(args, data)
data.title = "[[Kotus]] type 19/[[Appendix:Finnish nominal inflection/suo|suo]], no gradation"
table.insert(data.categories, "Finnish suo-type nominals")
local params = get_params(args, 2)
local params = get_params(args, 2)
local final = mw.ustring.sub(params.base, -1)
local final = mw.ustring.sub(params.base, -1)
local stem = mw.ustring.sub(params.base, 1, -3)
local plural = mw.ustring.sub(params.base, 1, -3) .. final
local plural
if mw.ustring.sub(stem, -1) == final then
plural = stem .. "-" .. final
elseif mw.ustring.find(stem, "-$") and mw.ustring.sub(stem, -1) ~= final then
plural = mw.ustring.sub(stem, 1, -2) .. final
else
plural = stem .. final
end
local stems = {}
local stems = {}
Line 824: Line 698:
stems["ill_pl"] = {plural .. "ih"}
stems["ill_pl"] = {plural .. "ih"}
inflection_type_is(data, 19, "suo")
make_stems(data, stems)
process_stems(data, stems, params.a)
process_stems(data, stems, params.a)
end
end


inflections["filee"] = function(args, data)
inflections["filee"] = function(args, data)
data.title = "[[Kotus]] type 20/[[Appendix:Finnish nominal inflection/filee|filee]], no gradation"
table.insert(data.categories, "Finnish filee-type nominals")
local params = get_params(args, 2)
local params = get_params(args, 2)
local nom_sg = get_extra_arg(args, data, "nom_sg"); if nom_sg == "" then nom_sg = nil end
local pl_stem = mw.ustring.sub(params.base, 1, -2)
local pl_stem = mw.ustring.sub(params.base, 1, -2)
local stems = {}
local stems = {}
stems["nom_sg"] = {nom_sg or params.base}
stems["sg"] = {params.base}
stems["sg"] = {params.base}
stems["par_sg"] = {params.base .. "t"}
stems["par_sg"] = {params.base .. "t"}
Line 842: Line 717:
stems["ill_pl"] = {pl_stem .. "ih", pl_stem .. "isi"}
stems["ill_pl"] = {pl_stem .. "ih", pl_stem .. "isi"}
inflection_type_is(data, 20, "filee")
make_stems(data, stems)
process_stems(data, stems, params.a)
process_stems(data, stems, params.a)
end
end


inflections["rosé"] = function(args, data)
inflections["rosé"] = function(args, data)
data.title = "[[Kotus]] type 21/[[Appendix:Finnish nominal inflection/rosé|rosé]], no gradation"
table.insert(data.categories, "Finnish rosé-type nominals")
local params = get_params(args, 2)
local params = get_params(args, 2)
local ill_sg_vowel = get_extra_arg(args, data, "ill_sg_vowel"); if ill_sg_vowel == "" then error("Parameter \"ill_sg_vowel=\" cannot be empty.") end
local ill_sg_vowel = args["ill_sg_vowel"]; if ill_sg_vowel == "" then error("Parameter \"ill_sg_vowel=\" cannot be empty.") end
local ill_sg_vowel2 = get_extra_arg(args, data, "ill_sg_vowel2"); if ill_sg_vowel2 == "" then error("Parameter \"ill_sg_vowel2=\" cannot be empty.") end
local ill_sg_vowel2 = args["ill_sg_vowel2"]; if ill_sg_vowel2 == "" then error("Parameter \"ill_sg_vowel2=\" cannot be empty.") end
local nom_sg = get_extra_arg(args, data, "nom_sg"); if nom_sg == "" then nom_sg = nil end
local stems = {}
local stems = {}
stems["nom_sg"] = {nom_sg or params.base}
stems["sg"] = {params.base}
stems["sg"] = {params.base}
stems["par_sg"] = {params.base .. "t"}
stems["par_sg"] = {params.base .. "t"}
Line 861: Line 737:
stems["ill_pl"] = {params.base .. "ih"}
stems["ill_pl"] = {params.base .. "ih"}
inflection_type_is(data, 21, "rosé")
make_stems(data, stems)
process_stems(data, stems, params.a)
process_stems(data, stems, params.a)
Line 874: Line 750:


inflections["parfait"] = function(args, data)
inflections["parfait"] = function(args, data)
data.title = "[[Kotus]] type 22/[[Appendix:Finnish nominal inflection/parfait|parfait]], no gradation"
table.insert(data.categories, "Finnish parfait-type nominals")
local params = get_params(args, 2)
local params = get_params(args, 2)
local ill_sg_vowel = get_extra_arg(args, data, "ill_sg_vowel"); if ill_sg_vowel == "" then error("Parameter \"ill_sg_vowel=\" is missing.") end
local ill_sg_vowel = args["ill_sg_vowel"] or (mw.title.getCurrentTitle().nsText == "Template" and "e"); if not ill_sg_vowel or ill_sg_vowel == "" then error("Parameter \"ill_sg_vowel=\" is missing.") end
local ill_sg_vowel2 = get_extra_arg(args, data, "ill_sg_vowel2"); if ill_sg_vowel2 == "" then error("Parameter \"ill_sg_vowel2=\" cannot be empty.") end
local ill_sg_vowel2 = args["ill_sg_vowel2"]; if ill_sg_vowel2 == "" then error("Parameter \"ill_sg_vowel2=\" cannot be empty.") end
local stems = {}
local stems = {}
Line 886: Line 765:
stems["ill_pl"] = {params.base .. "’ih"}
stems["ill_pl"] = {params.base .. "’ih"}
inflection_type_is(data, 22, "parfait")
make_stems(data, stems)
process_stems(data, stems, params.a)
process_stems(data, stems, params.a)
Line 897: Line 776:


inflections["tiili"] = function(args, data)
inflections["tiili"] = function(args, data)
data.title = "[[Kotus]] type 23/[[Appendix:Finnish nominal inflection/tiili|tiili]], no gradation"
table.insert(data.categories, "Finnish tiili-type nominals")
local params = get_params(args, 2)
local params = get_params(args, 2)
Line 905: Line 787:
stems["pl"] = {params.base .. "i"}
stems["pl"] = {params.base .. "i"}
inflection_type_is(data, 23, "tiili")
make_stems(data, stems)
process_stems(data, stems, params.a)
process_stems(data, stems, params.a)
end
end


inflections["uni"] = function(args, data)
inflections["uni"] = function(args, data)
data.title = "[[Kotus]] type 24/[[Appendix:Finnish nominal inflection/uni|uni]], no gradation"
table.insert(data.categories, "Finnish uni-type nominals")
local params = get_params(args, 2)
local params = get_params(args, 2)
local par_sg_a = get_extra_arg(args, data, "par_sg_a"); if par_sg_a and par_sg_a ~= "a" and par_sg_a ~= "ä" then error("Parameter \"par_sg_a=\" must be \"a\" or \"ä\".") end
local par_sg_a = args["par_sg_a"]; if par_sg_a and par_sg_a ~= "a" and par_sg_a ~= "ä" then error("Parameter \"par_sg_a=\" must be \"a\" or \"ä\".") end
local stems = {}
local stems = {}
Line 920: Line 805:
stems["gen_pl"] = {params.base .. "i", params.base .. "t"}
stems["gen_pl"] = {params.base .. "i", params.base .. "t"}
inflection_type_is(data, 24, "uni")
make_stems(data, stems)
process_stems(data, stems, params.a)
process_stems(data, stems, params.a)
Line 933: Line 818:


inflections["toimi"] = function(args, data)
inflections["toimi"] = function(args, data)
data.title = "[[Kotus]] type 25/[[Appendix:Finnish nominal inflection/toimi|toimi]], no gradation"
table.insert(data.categories, "Finnish toimi-type nominals")
local params = get_params(args, 2)
local params = get_params(args, 2)
Line 942: Line 830:
stems["gen_pl"] = {params.base .. "mi", params.base .. "nt"}
stems["gen_pl"] = {params.base .. "mi", params.base .. "nt"}
inflection_type_is(data, 25, "toimi")
make_stems(data, stems)
process_stems(data, stems, params.a)
process_stems(data, stems, params.a)
end
end


inflections["pieni"] = function(args, data)
inflections["pieni"] = function(args, data)
data.title = "[[Kotus]] type 26/[[Appendix:Finnish nominal inflection/pieni|pieni]], no gradation"
table.insert(data.categories, "Finnish pieni-type nominals")
local params = get_params(args, 2)
local params = get_params(args, 2)
local par_sg_a = get_extra_arg(args, data, "par_sg_a"); if par_sg_a and par_sg_a ~= "a" and par_sg_a ~= "ä" then error("Parameter \"par_sg_a=\" must be \"a\" or \"ä\".") end
local par_sg_a = args["par_sg_a"]; if par_sg_a and par_sg_a ~= "a" and par_sg_a ~= "ä" then error("Parameter \"par_sg_a=\" must be \"a\" or \"ä\".") end
local stems = {}
local stems = {}
Line 957: Line 848:
stems["gen_pl"] = {params.base .. "t", params.base .. "i"}
stems["gen_pl"] = {params.base .. "t", params.base .. "i"}
inflection_type_is(data, 26, "pieni")
make_stems(data, stems)
process_stems(data, stems, params.a)
process_stems(data, stems, params.a)
Line 970: Line 861:


inflections["käsi"] = function(args, data)
inflections["käsi"] = function(args, data)
data.title = "[[Kotus]] type 27/[[Appendix:Finnish nominal inflection/käsi|käsi]], ''t-d'' gradation"
table.insert(data.categories, "Finnish käsi-type nominals")
local params = get_params(args, 2)
local params = get_params(args, 2)
Line 979: Line 873:
stems["pl"] = {params.base .. "si"}
stems["pl"] = {params.base .. "si"}
make_stems(data, stems)
inflection_type_is(data, 27, "käsi", "t", "d")
process_stems(data, stems, params.a)
process_stems(data, stems, params.a)
Line 986: Line 880:


inflections["kynsi"] = function(args, data)
inflections["kynsi"] = function(args, data)
data.title = "[[Kotus]] type 28/[[Appendix:Finnish nominal inflection/kynsi|kynsi]]"
table.insert(data.categories, "Finnish kynsi-type nominals")
local params = get_params(args, 2, false, "n")
local params = get_params(args, 2, false, "n")
local cons = mw.ustring.match(params.base, "[lnr]$")
local cons = mw.ustring.match(params.base, "([lnr]?)$")
if mw.title.getCurrentTitle().nsText ~= "Template" and cons == "" then
if not cons then error("Stem must end in \"l\", \"n\" or \"r\".") end
error("Stem must end in \"l\", \"n\" or \"r\".")
end
data.title = data.title .. ", ''" .. cons .. "t-" .. cons .. cons .. "'' gradation"
local stems = {}
local stems = {}
Line 998: Line 899:
stems["pl"] = {params.base .. "si"}
stems["pl"] = {params.base .. "si"}
make_stems(data, stems)
inflection_type_is(data, 28, "kynsi", cons .. "t", cons .. cons)
process_stems(data, stems, params.a)
process_stems(data, stems, params.a)
Line 1,005: Line 906:


inflections["lapsi"] = function(args, data)
inflections["lapsi"] = function(args, data)
data.title = "[[Kotus]] type 29/[[Appendix:Finnish nominal inflection/lapsi|lapsi]], no gradation"
table.insert(data.categories, "Finnish lapsi-type nominals")
local params = get_params(args, 2, false, "p")
local params = get_params(args, 2, false, "p")
if not mw.ustring.match(params.base, "[kp]$") then error("Stem must end in \"k\" or \"p\".") end
local syncopated_stem, cons = mw.ustring.match(params.base, "^(.-)([kp]?)$")
local syncopated_stem = mw.ustring.sub(params.base, 1, -2)
if mw.title.getCurrentTitle().nsText ~= "Template" and cons == "" then
error("Stem must end in \"k\" or \"p\".")
end
local stems = {}
local stems = {}
Line 1,016: Line 923:
stems["gen_pl"] = {params.base .. "si", syncopated_stem .. "st"}
stems["gen_pl"] = {params.base .. "si", syncopated_stem .. "st"}
inflection_type_is(data, 29, "lapsi")
make_stems(data, stems)
process_stems(data, stems, params.a)
process_stems(data, stems, params.a)
end
end


inflections["veitsi"] = function(args, data)
inflections["veitsi"] = function(args, data)
data.title = "[[Kotus]] type 30/[[Appendix:Finnish nominal inflection/veitsi|veitsi]], no gradation"
table.insert(data.categories, "Finnish veitsi-type nominals")
local params = get_params(args, 2)
local params = get_params(args, 2)
Line 1,029: Line 939:
stems["pl"] = {params.base .. "tsi"}
stems["pl"] = {params.base .. "tsi"}
inflection_type_is(data, 30, "veitsi")
make_stems(data, stems)
process_stems(data, stems, params.a)
process_stems(data, stems, params.a)
Line 1,036: Line 946:


inflections["kaksi"] = function(args, data)
inflections["kaksi"] = function(args, data)
data.title = "[[Kotus]] type 31/[[Appendix:Finnish nominal inflection/kaksi|kaksi]], ''t-d'' gradation"
table.insert(data.categories, "Finnish kaksi-type nominals")
local params = get_params(args, 2)
local params = get_params(args, 2)
Line 1,045: Line 958:
stems["pl"] = {params.base .. "ksi"}
stems["pl"] = {params.base .. "ksi"}
make_stems(data, stems)
inflection_type_is(data, 31, "kaksi", "t", "d")
process_stems(data, stems, params.a)
process_stems(data, stems, params.a)
end
end


inflections["sisar"] = function(args, data)
inflections["sisar"] = function(args, data)
data.title = "[[Kotus]] type 32/[[Appendix:Finnish nominal inflection/sisar|sisar]]"
table.insert(data.categories, "Finnish sisar-type nominals")
local params = get_params(args, 5, true)
local params = get_params(args, 5, true)
local nom_sg = get_extra_arg(args, data, "nom_sg"); if nom_sg == "" then nom_sg = nil end
local nom_sg = args["nom_sg"]; if nom_sg == "" then nom_sg = nil end
make_weak(params.base, params.strong, params.final, params.weak)
if params.strong == params.weak then
data.title = data.title .. ", no gradation"
else
data.title = data.title .. ", ''" .. params.strong .. "-" .. params.weak .. "'' gradation"
end
local stems = {}
local stems = {}
Line 1,060: Line 984:
stems["gen_pl"] = {params.base .. params.strong .. params.final .. "i", params.base .. params.weak .. params.final .. "t"}
stems["gen_pl"] = {params.base .. params.strong .. params.final .. "i", params.base .. params.weak .. params.final .. "t"}
make_stems(data, stems)
inflection_type_is(data, 32, "sisar", params.strong, params.weak)
process_stems(data, stems, params.a)
process_stems(data, stems, params.a)
end
end


inflections["kytkin"] = function(args, data)
inflections["kytkin"] = function(args, data)
data.title = "[[Kotus]] type 33/[[Appendix:Finnish nominal inflection/kytkin|kytkin]]"
table.insert(data.categories, "Finnish kytkin-type nominals")
local params = get_params(args, 5, true)
local params = get_params(args, 5, true)
make_weak(params.base, params.strong, params.final, params.weak)
if params.weak == params.strong then
data.title = data.title .. ", no gradation"
else
data.title = data.title .. ", ''" .. params.strong .. "-" .. params.weak .. "'' gradation"
end
local stems = {}
local stems = {}
Line 1,074: Line 1,009:
stems["gen_pl"] = {params.base .. params.strong .. params.final .. "mi", params.base .. params.weak .. params.final .. "nt"}
stems["gen_pl"] = {params.base .. params.strong .. params.final .. "mi", params.base .. params.weak .. params.final .. "nt"}
make_stems(data, stems)
inflection_type_is(data, 33, "kytkin", params.strong, params.weak)
process_stems(data, stems, params.a)
process_stems(data, stems, params.a)
end
end


inflections["onneton"] = function(args, data)
inflections["onneton"] = function(args, data)
data.title = "[[Kotus]] type 34/[[Appendix:Finnish nominal inflection/onneton|onneton]], ''tt-t'' gradation"
local no_gradation = get_extra_arg(args, data, "no_tt") == "1"
table.insert(data.categories, "Finnish onneton-type nominals")
local strong
if no_gradation then
strong = "t"
else
strong = "tt"
end
local params = get_params(args, 2)
local params = get_params(args, 2)
Line 1,091: Line 1,021:
local stems = {}
local stems = {}
stems["nom_sg"] = {params.base .. "t" .. params.o .. "n"}
stems["nom_sg"] = {params.base .. "t" .. params.o .. "n"}
stems["sg"] = {params.base .. strong .. params.o .. "m" .. params.a}
stems["sg"] = {params.base .. "tt" .. params.o .. "m" .. params.a}
stems["par_sg"] = {params.base .. "t" .. params.o .. "nt"}
stems["par_sg"] = {params.base .. "t" .. params.o .. "nt"}
stems["pl"] = {params.base .. strong .. params.o .. "mi"}
stems["pl"] = {params.base .. "tt" .. params.o .. "mi"}
make_stems(data, stems)
inflection_type_is(data, 34, "onneton", strong, "t")
process_stems(data, stems, params.a)
process_stems(data, stems, params.a)
Line 1,102: Line 1,032:


inflections["lämmin"] = function(args, data)
inflections["lämmin"] = function(args, data)
data.title = "[[Kotus]] type 35/[[Appendix:Finnish nominal inflection/lämmin|lämmin]], ''mp-mm'' gradation"
local params = get_params(args, 5, true)
table.insert(data.categories, "Finnish lämmin-type nominals")
local params = get_params(args, 1)
params.base = params.base .. "lä"
params.a = "ä"
local stems = {}
local stems = {}
stems["nom_sg"] = {params.base .. params.weak .. params.final .. "n"}
stems["nom_sg"] = {params.base .. "mmin"}
stems["sg"] = {params.base .. params.strong .. params.final .. "m" .. params.a}
stems["sg"] = {params.base .. "mpim" .. params.a}
stems["par_sg"] = {params.base .. params.weak .. params.final .. "nt"}
stems["par_sg"] = {params.base .. "mmint"}
stems["pl"] = {params.base .. params.strong .. params.final .. "mi"}
stems["pl"] = {params.base .. "mpimi"}
make_stems(data, stems)
inflection_type_is(data, 35, "lämmin", params.strong, params.weak)
process_stems(data, stems, params.a)
process_stems(data, stems, params.a)
data.forms["gen_pl"].rare = {params.base .. params.strong .. params.final .. "m" .. params.a .. "in"}
data.forms["gen_pl"].rare = {params.base .. "mpim" .. params.a .. "in"}
end
end


inflections["sisin"] = function(args, data)
inflections["sisin"] = function(args, data)
data.title = "[[Kotus]] type 36/[[Appendix:Finnish nominal inflection/sisin|sisin]], ''mp-mm'' gradation"
table.insert(data.categories, "Finnish sisin-type nominals")
local params = get_params(args, 2)
local params = get_params(args, 2)
Line 1,128: Line 1,066:
stems["gen_pl"] = {params.base .. "impi", params.base .. "int"}
stems["gen_pl"] = {params.base .. "impi", params.base .. "int"}
make_stems(data, stems)
inflection_type_is(data, 36, "sisin", "mp", "mm")
process_stems(data, stems, params.a)
process_stems(data, stems, params.a)
Line 1,135: Line 1,073:


inflections["vasen"] = function(args, data)
inflections["vasen"] = function(args, data)
data.title = "[[Kotus]] type 37/[[Appendix:Finnish nominal inflection/vasen|vasen]], ''mp-mm'' gradation"
table.insert(data.categories, "Finnish vasen-type nominals")
local params = get_params(args, 1)
local params = get_params(args, 1)
params.base = params.base .. "vase"
params.base = params.base .. "vase"
Line 1,148: Line 1,089:
stems["gen_pl"] = {params.base .. "mpi", params.base .. "nt"}
stems["gen_pl"] = {params.base .. "mpi", params.base .. "nt"}
make_stems(data, stems)
inflection_type_is(data, 37, "vasen", "mp", "mm")
process_stems(data, stems, params.a)
process_stems(data, stems, params.a)
Line 1,155: Line 1,096:


inflections["nainen"] = function(args, data)
inflections["nainen"] = function(args, data)
data.title = "[[Kotus]] type 38/[[Appendix:Finnish nominal inflection/nainen|nainen]], no gradation"
table.insert(data.categories, "Finnish nainen-type nominals")
local params = get_params(args, 2)
local params = get_params(args, 2)
Line 1,164: Line 1,108:
stems["gen_pl"] = {params.base .. "st", params.base .. "si"}
stems["gen_pl"] = {params.base .. "st", params.base .. "si"}
inflection_type_is(data, 38, "nainen")
make_stems(data, stems)
process_stems(data, stems, params.a)
process_stems(data, stems, params.a)
end
end


inflections["vastaus"] = function(args, data)
inflections["vastaus"] = function(args, data)
data.title = "[[Kotus]] type 39/[[Appendix:Finnish nominal inflection/vastaus|vastaus]], no gradation"
table.insert(data.categories, "Finnish vastaus-type nominals")
local params = get_params(args, 2)
local params = get_params(args, 2)
local nom_sg = get_extra_arg(args, data, "nom_sg"); if nom_sg == "" then nom_sg = nil end
local nom_sg = args["nom_sg"]; if nom_sg == "" then nom_sg = nil end
local stems = {}
local stems = {}
Line 1,179: Line 1,126:
stems["gen_pl"] = {params.base .. "st", params.base .. "ksi"}
stems["gen_pl"] = {params.base .. "st", params.base .. "ksi"}
inflection_type_is(data, 39, "vastaus")
make_stems(data, stems)
process_stems(data, stems, params.a)
process_stems(data, stems, params.a)
end
end


inflections["kalleus"] = function(args, data)
inflections["kalleus"] = function(args, data)
data.title = "[[Kotus]] type 40/[[Appendix:Finnish nominal inflection/kalleus|kalleus]], ''t-d'' gradation"
table.insert(data.categories, "Finnish kalleus-type nominals")
local params = get_params(args, 2)
local params = get_params(args, 2)
Line 1,193: Line 1,143:
stems["pl"] = {params.base .. "ksi"}
stems["pl"] = {params.base .. "ksi"}
make_stems(data, stems)
inflection_type_is(data, 40, "kalleus", "t", "d")
process_stems(data, stems, params.a)
process_stems(data, stems, params.a)
end
end


inflections["vieras"] = function(args, data)
inflections["vieras"] = function(args, data)
data.title = "[[Kotus]] type 41/[[Appendix:Finnish nominal inflection/vieras|vieras]]"
table.insert(data.categories, "Finnish vieras-type nominals")
local params = get_params(args, 5, true)
local params = get_params(args, 5, true)
local nom_sg = get_extra_arg(args, data, "nom_sg"); if nom_sg == "" then nom_sg = nil end
make_weak(params.base, params.strong, params.final, params.weak)
if params.weak == params.strong then
data.title = data.title .. ", no gradation"
else
data.title = data.title .. ", ''" .. params.strong .. "-" .. params.weak .. "'' gradation"
end
local stems = {}
local stems = {}
stems["nom_sg"] = {nom_sg or (params.base .. params.weak .. params.final .. "s")}
stems["nom_sg"] = {params.base .. params.weak .. params.final .. "s"}
stems["sg"] = {params.base .. params.strong .. params.final .. params.final}
stems["sg"] = {params.base .. params.strong .. params.final .. params.final}
stems["par_sg"] = {params.base .. params.weak .. params.final .. "st"}
stems["par_sg"] = {params.base .. params.weak .. params.final .. "st"}
Line 1,210: Line 1,170:
stems["ill_pl"] = {params.base .. params.strong .. params.final .. "isi"}
stems["ill_pl"] = {params.base .. params.strong .. params.final .. "isi"}
make_stems(data, stems)
inflection_type_is(data, 41, "vieras", params.strong, params.weak)
process_stems(data, stems, params.a)
process_stems(data, stems, params.a)
data.forms["gen_pl"].rare = {params.base .. params.weak .. params.final .. "sten"}
data.forms["ill_pl"].rare = {params.base .. params.strong .. params.final .. "ihin"}
data.forms["ill_pl"].rare = {params.base .. params.strong .. params.final .. "ihin"}
end
end


inflections["mies"] = function(args, data)
inflections["mies"] = function(args, data)
data.title = "[[Kotus]] type 42/[[Appendix:Finnish nominal inflection/mies|mies]], no gradation"
table.insert(data.categories, "Finnish mies-type nominals")
local params = get_params(args, 1)
local params = get_params(args, 1)
params.base = params.base .. "mie"
local cap = get_extra_arg(args, data, "cap"); if cap == "" then nom_sg = nil end
params.base = params.base .. (cap and "Mie" or "mie")
params.a = "ä"
params.a = "ä"
Line 1,230: Line 1,191:
stems["gen_pl"] = {params.base .. "st", params.base .. "hi"}
stems["gen_pl"] = {params.base .. "st", params.base .. "hi"}
inflection_type_is(data, 42, "mies")
make_stems(data, stems)
process_stems(data, stems, params.a)
process_stems(data, stems, params.a)
end
end


inflections["ohut"] = function(args, data)
inflections["ohut"] = function(args, data)
data.title = "[[Kotus]] type 43/[[Appendix:Finnish nominal inflection/ohut|ohut]]"
table.insert(data.categories, "Finnish ohut-type nominals")
local params = get_params(args, 5, true)
local params = get_params(args, 5, true)
make_weak(params.base, params.strong, params.final, params.weak)
if params.weak == params.strong then
data.title = data.title .. ", no gradation"
else
data.title = data.title .. ", ''" .. params.strong .. "-" .. params.weak .. "'' gradation"
end
local stems = {}
local stems = {}
Line 1,245: Line 1,217:
stems["ill_pl"] = {params.base .. params.strong .. params.final .. "isi", params.base .. params.strong .. params.final .. "ih"}
stems["ill_pl"] = {params.base .. params.strong .. params.final .. "isi", params.base .. params.strong .. params.final .. "ih"}
make_stems(data, stems)
inflection_type_is(data, 43, "ohut", params.strong, params.weak)
process_stems(data, stems, params.a)
process_stems(data, stems, params.a)
end
end


inflections["kevät"] = function(args, data)
inflections["kevät"] = function(args, data)
data.title = "[[Kotus]] type 44/[[Appendix:Finnish nominal inflection/kevät|kevät]], no gradation"
local params = get_params(args, 4, true)
table.insert(data.categories, "Finnish kevät-type nominals")
local vowel = params.a
local params = get_params(args, 2)
local vowel = mw.ustring.sub(params.base, -1)
local stems = {}
local stems = {}
stems["nom_sg"] = {params.base .. params.weak .. vowel .. "t"}
stems["nom_sg"] = {params.base .. "t"}
stems["sg"] = {params.base .. params.strong .. vowel .. vowel}
stems["sg"] = {params.base .. vowel}
stems["par_sg"] = {params.base .. params.weak .. vowel .. "tt"}
stems["par_sg"] = {params.base .. "tt"}
stems["ill_sg"] = {params.base .. vowel .. "se"}
stems["ill_sg"] = {params.base .. params.strong .. vowel .. vowel .. "se"}
stems["pl"] = {params.base .. "i"}
stems["pl"] = {params.base .. params.strong .. vowel .. "i"}
stems["par_pl"] = {params.base .. "it"}
stems["par_pl"] = {params.base .. params.strong .. vowel .. "it"}
stems["ill_pl"] = {params.base .. "isi"}
stems["ill_pl"] = {params.base .. params.strong .. vowel .. "isi"}
make_stems(data, stems)
inflection_type_is(data, 44, "kevät", params.strong, params.weak)
process_stems(data, stems, params.a)
process_stems(data, stems, params.a)
data.forms["ill_pl"].rare = {params.base .. params.strong .. vowel .. "ihin"}
data.forms["ill_pl"].rare = {params.base .. "ihin"}
end
end


inflections["kahdeksas"] = function(args, data)
inflections["kahdeksas"] = function(args, data)
data.title = "[[Kotus]] type 45/[[Appendix:Finnish nominal inflection/kahdeksas|kahdeksas]], ''nt-nn'' gradation"
table.insert(data.categories, "Finnish kahdeksas-type nominals")
local params = get_params(args, 2)
local params = get_params(args, 2)
Line 1,278: Line 1,256:
stems["pl"] = {params.base .. "nsi"}
stems["pl"] = {params.base .. "nsi"}
make_stems(data, stems)
inflection_type_is(data, 45, "kahdeksas", "nt", "nn")
process_stems(data, stems, params.a)
process_stems(data, stems, params.a)
end
end


inflections["tuhat"] = function(args, data)
inflections["tuhat"] = function(args, data)
data.title = "[[Kotus]] type 46/[[Appendix:Finnish nominal inflection/tuhat|tuhat]], ''nt-nn'' gradation"
table.insert(data.categories, "Finnish tuhat-type nominals")
local params = get_params(args, 2)
local params = get_params(args, 2)
Line 1,291: Line 1,272:
stems["par_sg"] = {params.base .. "tt"}
stems["par_sg"] = {params.base .. "tt"}
stems["pl"] = {params.base .. "nsi"}
stems["pl"] = {params.base .. "nsi"}

make_stems(data, stems)
inflection_type_is(data, 46, "tuhat", "nt", "nn")
process_stems(data, stems, params.a)
process_stems(data, stems, params.a)
Line 1,299: Line 1,280:


inflections["kuollut"] = function(args, data)
inflections["kuollut"] = function(args, data)
data.title = "[[Kotus]] type 47/[[Appendix:Finnish nominal inflection/kuollut|kuollut]], no gradation"
table.insert(data.categories, "Finnish kuollut-type nominals")
local params = get_params(args, 2)
local params = get_params(args, 2)
Line 1,310: Line 1,294:
stems["ill_pl"] = {params.base .. "eisi", params.base .. "eih"}
stems["ill_pl"] = {params.base .. "eisi", params.base .. "eih"}
inflection_type_is(data, 47, "kuollut")
make_stems(data, stems)
process_stems(data, stems, params.a)
process_stems(data, stems, params.a)
end
end


inflections["hame"] = function(args, data)
inflections["hame"] = function(args, data)
data.title = "[[Kotus]] type 48/[[Appendix:Finnish nominal inflection/hame|hame]]"
table.insert(data.categories, "Finnish hame-type nominals")
local params = get_params(args, 4, true)
local params = get_params(args, 4, true)
local stem_vowel = get_extra_arg(args, data, "stem_vowel"); if stem_vowel == "" then stem_vowel = nil end
stem_vowel = stem_vowel or "e"
local nom_sg = get_extra_arg(args, data, "nom_sg"); if nom_sg == "" then nom_sg = nil end
make_weak(params.base, params.strong, "e", params.weak)
local stems = {}
stems["nom_sg"] = {nom_sg or (params.base .. params.weak .. stem_vowel)}
stems["sg"] = {params.base .. params.strong .. stem_vowel .. stem_vowel}
stems["par_sg"] = {params.base .. params.weak .. stem_vowel .. "tt"}
stems["ill_sg"] = {params.base .. params.strong .. stem_vowel .. stem_vowel .. "se"}
stems["pl"] = {params.base .. params.strong .. stem_vowel .. "i"}
stems["par_pl"] = {params.base .. params.strong .. stem_vowel .. "it"}
stems["ill_pl"] = {params.base .. params.strong .. stem_vowel .. "isi", params.base .. params.strong .. stem_vowel .. "ih"}
inflection_type_is(data, 48, "hame", params.strong, params.weak)
if params.weak == params.strong then
data.title = data.title .. ", no gradation"
process_stems(data, stems, params.a)
end

inflections["askel"] = function(args, data)
local params = get_params(args, 5, true)
local prefer_hame = get_extra_arg(args, data, "e") == "1"
local stems_sisar = {}
stems_sisar["sg"] = {params.base .. params.strong .. params.final .. "e"}
stems_sisar["nom_sg"] = {params.base .. params.weak .. params.final}
stems_sisar["par_sg"] = {params.base .. params.weak .. params.final .. "t"}
stems_sisar["ill_sg"] = {params.base .. params.strong .. params.final .. "e"}
stems_sisar["pl"] = {params.base .. params.strong .. params.final .. "i"}
stems_sisar["gen_pl"] = {params.base .. params.strong .. params.final .. "i", params.base .. params.weak .. params.final .. "t"}
stems_sisar["par_pl"] = {params.base .. params.strong .. params.final .. "i"}
stems_sisar["ill_pl"] = {params.base .. params.strong .. params.final .. "i"}

local stems_hame = {}
stems_hame["sg"] = {params.base .. params.strong .. params.final .. "ee"}
stems_hame["nom_sg"] = {params.base .. params.strong .. params.final .. "e"}
stems_hame["par_sg"] = {params.base .. params.strong .. params.final .. "ett"}
stems_hame["ill_sg"] = {params.base .. params.strong .. params.final .. "eese"}
stems_hame["pl"] = {params.base .. params.strong .. params.final .. "ei"}
stems_hame["gen_pl"] = {params.base .. params.strong .. params.final .. "eid", params.base .. params.strong .. params.final .. "eitt"}
stems_hame["par_pl"] = {params.base .. params.strong .. params.final .. "eit"}
stems_hame["ill_pl"] = {params.base .. params.strong .. params.final .. "eisi", params.base .. params.strong .. params.final .. "eih"}

local stems = {}
if prefer_hame then
feed_list(stems, stems_hame)
feed_list(stems, stems_sisar)
else
else
data.title = data.title .. ", ''" .. params.strong .. "-" .. params.weak .. "'' gradation"
feed_list(stems, stems_sisar)
feed_list(stems, stems_hame)
end
end

inflection_type_is(data, 49, "askel", params.strong, params.weak)
process_stems(data, stems, params.a)
end

-- Helper functions

-- joins data.words[...].forms to data.forms
function export.join_words(data, sep_supplier)
local reorganized = {}
local classes = {}
local stems = {}
-- reorganize from words[n].forms[case](.rare) to forms[case],words[n](.rare)
stems["nom_sg"] = {params.base .. params.weak .. "e"}
for windex, word in ipairs(data.words) do
stems["sg"] = {params.base .. params.strong .. "ee"}
table.insert(classes, word.class)
stems["par_sg"] = {params.base .. params.weak .. "ett"}
for case, forms in pairs(word.forms) do
stems["ill_sg"] = {params.base .. params.strong .. "eese"}
if reorganized[case] == nil then
stems["pl"] = {params.base .. params.strong .. "ei"}
reorganized[case] = {}
stems["par_pl"] = {params.base .. params.strong .. "eit"}
end
stems["ill_pl"] = {params.base .. params.strong .. "eisi", params.base .. params.strong .. "eih"}
reorganized[case][windex] = {}
for _, form in ipairs(forms) do
table.insert(reorganized[case][windex], form)
end
if word.forms[case].rare then
reorganized[case][windex].rare = {}
for _, form in ipairs(word.forms[case].rare) do
table.insert(reorganized[case][windex].rare, form)
end
end
end
end
make_stems(data, stems)
-- merge the forms with a Cartesian product to produce all possible combinations
process_stems(data, stems, params.a)
data.forms = {}
for case, words in pairs(reorganized) do
data.forms[case] = forms_cart_product(words, case, sep_supplier, classes)
end

if #data.words <= 1 then
-- use title and categories of the sole word if there is only one
data.title = data.words[1].title
data.categories = data.words[1].categories
else
-- if there are multiple words, force nuoripari type
data.title = make_kotus_title(51, "nuoripari")
data.categories = {"Finnish nuoripari-type nominals"}
end
data.words = nil
end
end


local function cleanup_suffix(suffix)
if suffix and mw.ustring.find(suffix, "_") then
return mw.ustring.gsub(suffix, "_", " ")
else
return suffix
end
end


-- Helper functions
-- computes the Cartesian product of tables
function cart_product(words, depth)
depth = depth or 1
local prod = {}
for _, val in ipairs(words[depth]) do
if depth < #words then
-- go over the next list
for _, res in ipairs(cart_product(words, depth + 1)) do
table.insert(prod, { val, unpack(res) })
end
else
-- end of list, simply return the original
table.insert(prod, { val })
end
end
return prod
end

local function supplied_concat(list, sep_supplier)
local result = ""
local n = #list
if n >= 1 then
for i = 1, n - 1 do
local v = mw.ustring.match(list[i], "^[aeiouyäö]")
if v and mw.ustring.find(result, v .. "$") then
result = result .. "-"
end
result = result .. list[i] .. sep_supplier(i)
end
local v = mw.ustring.match(list[n], "^[aeiouyäö]")
if v and mw.ustring.find(result, v .. "$") then
result = result .. "-"
end
result = result .. list[n]
end
return result
end

-- computes the Cartesian product of tables, also concats
function cart_product_concat(words, sep_supplier)
local res = {}

for _, combination in ipairs(cart_product(words)) do
table.insert(res, supplied_concat(combination, sep_supplier))
end

return res
end

-- returns a bit mask (!) or nil
function get_rhyming_pattern(word, case, class)
if class == "askel" then
return nil
end
if case == "gen_pl" then
if mw.ustring.match(word, "tten$") then
return 2
elseif mw.ustring.match(word, "ten$") then
return 3
else
return 1
end
elseif case == "ill_sg" then
if mw.ustring.match(word, "seen$") then
return 1
elseif mw.ustring.match(word, "hen$") then
return 2
end
elseif case == "ill_pl" then
if mw.ustring.match(word, "siin$") then
return 1
elseif mw.ustring.match(word, "hin$") then
return 2
end
end
return nil -- not applicable
end

function is_nonrhyming(form, case, classes)
local expected = m_bit32.bnot(0) -- -1
for i, word in ipairs(form) do
local got = get_rhyming_pattern(word, case, classes[i])
if got then
expected = m_bit32.band(expected, got)
end
if expected == 0 then
return true
end
end

return false
end

-- computes the Cartesian product of tables, also concats
-- returns non-rhyming combinations as rare
function cart_product_concat_nonrhyming_rare(words, case, sep_supplier, classes)
local res = {}
local rare = {}
local multichoice = 0
local allow_pruning = false

for _, position in ipairs(words) do
if #position > 1 then
multichoice = multichoice + 1
end
end

allow_pruning = multichoice > 1

for _, combination in ipairs(cart_product(words)) do
local item = supplied_concat(combination, sep_supplier)
if is_nonrhyming(combination, case, classes) then
table.insert(rare, item)
else
table.insert(res, item)
end
end

if #res < 1 then
rare.rare = {}
return rare
end

res.rare = rare
return res
end

-- converts a list of words to extract the rare forms for ipairs
-- the number is interpreted bit-by-bit to decide which combination
-- to choose
function prepare_rare_tables(words, code)
local result = {}
for _, forms in ipairs(words) do
-- replace with rare if bit is 1
if m_bit32.band(code, 1) == 1 then
table.insert(result, forms.rare or {})
else
table.insert(result, forms)
end
-- shift right to test next bit
code = m_bit32.rshift(code, 1)
end
return result
end

-- copies all entries of source and inserts them to target
function merge_table(target, source)
for _, value in ipairs(source) do
table.insert(target, value)
end
end

function merge_table_rare(target, source)
for _, value in ipairs(source) do
table.insert(target, value)
end
target.rare = source.rare
end

-- the Cartesian product of possible forms
function forms_cart_product(words, case, sep_supplier, classes)
local result = {}
result.rare = {}

m_bit32 = require("bit32")
-- merge possible non-rare forms
merge_table_rare(result, cart_product_concat_nonrhyming_rare(words, case, sep_supplier, classes))
-- merge possible rare forms
-- for example, with two words:
-- 1 = rare A, common B
-- 2 = common A, rare B
-- 3 = rare A, rare B
-- (2 ^ #words) - 1 == m_bit32.lshift(1,#words)-1
-- (prepare_rare_tables actually takes out the rare forms)
for i = 1,m_bit32.lshift(1,#words)-1 do
merge_table(result.rare, cart_product_concat(prepare_rare_tables(words, i), sep_supplier))
end
-- if no rare forms, remove the table completely
if #result.rare < 1 then
result.rare = nil
end
return result
end

function make_word_possessive(args, data, poss, always_add)
local pos = get_extra_arg(args, data, "pos"); if not pos or pos == "" then pos = "noun" end
local par_nom_sg = get_extra_arg(args, data, "par_nom_sg") == "1"

-- "no possessive forms exist" sentinel value
if poss == "-" then
return data.forms
end

if always_add or pos == "noun" then
-- add possessive suffix
if poss == "3" or poss == "3p" then
poss = "3s" -- 3rd person forms are identical
end
if not poss_forms[poss] then
error("Invalid poss value: '" .. p .. "'")
end
return make_poss_with_suffix(data.forms, data.stems, poss_forms[poss], "", poss_alt[poss], par_nom_sg)
end
return data.forms
end

function postprocess_word(args, data, gdata, always_add)
local pos = get_extra_arg(args, data, "pos"); if not pos or pos == "" then pos = "noun" end
local alwayspl = get_extra_arg(args, data, "alwayspl"); if alwayspl == "" then alwayspl = nil end
if gdata.poss then
data.forms = make_word_possessive(args, data, gdata.poss, always_add)
elseif pos == "noun" and data.forms["com_pl"] then
-- Add the possessive suffix to the comitative plural, if the word is a noun
for key, subform in ipairs(data.forms["com_pl"]) do
data.forms["com_pl"][key] = subform .. "en"
end
gdata.tagged_com_pl = true
end
if get_extra_arg(args, data, "gen_nom_sg") == "1" then
data.forms["nom_sg"] = data.forms["gen_sg"]
elseif get_extra_arg(args, data, "par_nom_sg") == "1" then
data.forms["nom_sg"] = data.forms["par_sg"]
end
if gdata.poss then
data.forms["ins_pl"] = nil
end

if alwayspl then -- [[Saint Vincent ja Grenadiinit]]
for k, v in pairs(data.forms) do
local k_sg = k:gsub("_pl", "_sg")
if data.forms[k_sg] then
data.forms[k_sg] = data.forms[k]
end
end
end
end


function postprocess(args, data)
function postprocess(args, data)
Line 1,679: Line 1,333:
local nopl = args["nopl"]; if nopl == "" then nopl = nil end
local nopl = args["nopl"]; if nopl == "" then nopl = nil end
local n = args["n"]; if n == "" then n = nil end
local n = args["n"]; if n == "" then n = nil end
local suffix = cleanup_suffix(args["suffix"]); if suffix == "" then suffix = nil end
local suffix = args["suffix"]; if suffix == "" then suffix = nil end
local appendix = args["appendix"]; if appendix == "" then appendix = nil end
local appendix = args["appendix"]; if appendix == "" then appendix = nil end
local has_ins_sg = args["has_ins_sg"]; if has_ins_sg == "" then has_ins_sg = nil end
local has_ins_sg = args["has_ins_sg"]; if has_ins_sg == "" then has_ins_sg = nil end
local has_no_nom = args["has_no_nom"]; if has_no_nom == "" then has_no_nom = nil end
-- Add the possessive suffix to the comitative plural, if the word is a noun
-- Add the possessive suffix to the comitative plural, if the word is a noun
if pos == "noun" and data.forms["com_pl"] then
-- now done per word; see postprocess_word
for key, subform in ipairs(data.forms["com_pl"]) do
data.forms["com_pl"][key] = subform .. "en"
end
end
if nosg or n == "pl" then
if nosg or n == "pl" then
Line 1,694: Line 1,351:
if nopl or n == "sg" then
if nopl or n == "sg" then
table.insert(data.categories, "Finnish uncountable nouns")
table.insert(data.categories, "Finnish uncountable nouns")
end
if n == "csg" then -- "chiefly singular"
data.rare_plural = true
end
end
Line 1,727: Line 1,380:
-- Check if the lemma form matches the page name
-- Check if the lemma form matches the page name
local lemma = data.forms[(nosg or n == "pl") and "nom_pl" or "nom_sg"][1]
if not appendix and lang:makeEntryName(data.forms[(nosg or n == "pl") and "nom_pl" or "nom_sg"][1]) ~= mw.title.getCurrentTitle().text then
if not appendix and lemma ~= data.pagename and not data.poss then
--error("The lemma " .. lemma .. " does not match the page title. Check the parameters!")
mw.addWarning("<i>Please check the fi-decl-... parameters!</i>")
table.insert(data.categories, "Finnish entries with inflection not matching pagename")
table.insert(data.categories, "Finnish entries with inflection not matching pagename")
end
data.is_appendix = appendix
if has_no_nom then
data.forms["nom_sg"] = nil
data.forms["nom_pl"] = nil
end
end
end
end



-- Make the table
-- Make the table
function make_table(data, preview, title_override, collapse_class_override, accel_class_prefix, extra_classes)
function make_table(data)
local function show_form(form, no_rare)
local rare_plural = data.rare_plural
local note = rare_plural and "Plural forms of this word are not commonly used, but might be found in figurative uses, in some set phrases or in colloquial language." or nil

local com_forms

local function show_form(forms, code, no_rare)
local form = forms[code]
if not form then
if not form then
return "&mdash;"
return "&mdash;"
Line 1,758: Line 1,396:
local ret = {}
local ret = {}
local accel

if rare_plural and code:find("_pl$") then
-- plural is marginal
for key, subform in ipairs(form) do
table.insert(ret, "(''" .. make_link(subform) .. "'')")
end
if not no_rare and form.rare then
for key, subform in ipairs(form.rare) do
table.insert(ret, "(''" .. make_link(subform) .. "''" .. RARE .. ")")
end
end

return table.concat(ret, "<br/>")
end

-- See [[Module talk:fi-nominals]].
if code == "nom_sg" and not data.poss then
accel = nil
elseif code == "gen_sg" then
accel = "gen//acc|s"
elseif code == "nom_pl" then
accel = "nom//acc|p"
else
accel = code:gsub("%f[^_](%a%a)$", {sg = "s", pl = "p"}):gsub("ins", "ist"):gsub("_", "|")
end
if accel_class_prefix and accel then
accel = accel_class_prefix .. accel
end

for key, subform in ipairs(form) do
for key, subform in ipairs(form) do
table.insert(ret, make_link(subform, accel))
table.insert(ret, m_links.full_link({lang = lang, term = subform}))
end
end
if not no_rare and form.rare then
if not no_rare and form.rare then
if accel then
accel = 'rare-' .. accel
end

for key, subform in ipairs(form.rare) do
for key, subform in ipairs(form.rare) do
table.insert(ret, make_link(subform, accel) .. RARE)
table.insert(ret, m_links.full_link({lang = lang, term = subform}) .. "<sup>rare</sup>")
end
end
end
end
Line 1,808: Line 1,411:
local function repl(param)
local function repl(param)
if param == "title" then
if param == "lemma" then
return m_links.full_link({lang = lang, alt = mw.title.getCurrentTitle().text}, "term")
if title_override then return title_override end
elseif param == "info" then
return "[[Appendix:Finnish nominal forms|Inflection]] of " .. (data.is_appendix and make_link(data.pagename) or tag_term(data.pagename)) .. ( data.title and " (" .. data.title .. ")" or "")
return data.title and " (" .. data.title .. ")" or ""
elseif param == "maybenote" then
if note then
return [=[
|- class="vsHide"
| colspan="4" class="fi-decl-maybenote" | ]=] .. note .. "\n"
else
return ""
end
elseif param == "com_forms" then
return com_forms
else
else
local param2 = mw.ustring.match(param, "^(.-):c$")
local param2 = mw.ustring.match(param, "^(.-):c$")
if param2 then
if param2 then
return show_form(data.forms, param2, true)
return show_form(data.forms[param2], true)
else
else
return show_form(data.forms, param)
return show_form(data.forms[param])
end
end
end
end
end
end

local wikicode = [=[
if not data.poss and data.tagged_com_pl then
{| class="inflection-table fi-decl vsSwitcher" data-toggle-category="inflection"
com_forms = 'colspan="2" | \'\'See the possessive forms below.\'\''
|-
else
! class="vsToggleElement" colspan="4" | Inflection of {{{lemma}}}{{{info}}}
com_forms = mw.ustring.gsub('{{{com_sg}}} || {{{com_pl}}}', "{{{([a-z0-9_:]+)}}}", repl)
end

if preview then
preview = [=[
|- class="vsShow"
|- class="vsShow"
! class="case-column" colspan="2" | nominative
! class="case-column" colspan="2" | nominative
| class="number-column" | {{{nom_sg:c}}}
| class="number-column" | {{{nom_sg:c}}}
| class="number-column" | {{{nom_pl:c}}}
| class="number-column" | <span class="form-of plural-nominative-form-of lang-fi">{{{nom_pl:c}}}</span>
|- class="vsShow"
|- class="vsShow"
! colspan="2" | genitive
! colspan="2" | genitive
| {{{gen_sg:c}}}
| <span class="form-of singular-genitive-form-of lang-fi">{{{gen_sg:c}}}</span>
| {{{gen_pl:c}}}
| <span class="form-of plural-genitive-form-of lang-fi">{{{gen_pl:c}}}</span>
|- class="vsShow"
|- class="vsShow"
! colspan="2" | partitive
! colspan="2" | partitive
| <span class="form-of singular-partitive-form-of lang-fi">{{{par_sg:c}}}</span>
| {{{par_sg:c}}}
| {{{par_pl:c}}}
| <span class="form-of plural-partitive-form-of lang-fi">{{{par_pl:c}}}</span>
|- class="vsShow"
|- class="vsShow"
! colspan="2" | illative
! colspan="2" | illative
| {{{ill_sg:c}}}
| <span class="form-of singular-illative-form-of lang-fi">{{{ill_sg:c}}}</span>
| {{{ill_pl:c}}}
| <span class="form-of plural-illative-form-of lang-fi">{{{ill_pl:c}}}</span>

]=]
else
preview = ""
end
local wikicode = [=[
<div class="noresize">
{| class="inflection-table fi-decl vsSwitcher ]=] .. (extra_classes or "") .. [=[" data-toggle-category="]=] .. (collapse_class_override or "declension") .. [=["
|-
! class="vsToggleElement" colspan="4" | {{{title}}}
]=] .. preview .. [=[
|- class="vsHide"
|- class="vsHide"
! class="case-column" colspan="2" |
! colspan="2" |
! class="number-column" | singular
! singular
! class="number-column" | plural
! plural
|- class="vsHide"
|- class="vsHide"
! colspan="2" | nominative
! class="case-column" colspan="2" | nominative
| {{{nom_sg}}}
| class="number-column" | {{{nom_sg}}}
| class="number-column" | <span class="form-of plural-nominative-form-of lang-fi">{{{nom_pl}}}</span>
| {{{nom_pl}}}
|- class="vsHide"
|- class="vsHide"
! rowspan="2" | accusative
! rowspan="2" | accusative
! <abbr title="The nominative accusative is used, for example, as the object of certain passives and imperatives. Click the Inflection link and see the section on accusatives for more information.">nom.</abbr>
! nom.<sup title="The nominative accusative is used, for example, as the object of certain passives and imperatives."></sup>
| {{{nom_sg}}}
| {{{nom_sg}}}
| rowspan="2" | {{{nom_pl}}}
| rowspan="2" | <span class="form-of plural-accusative-form-of lang-fi">{{{nom_pl}}}</span>
|- class="vsHide"
|- class="vsHide"
! gen.
! gen.
| <span class="form-of singular-genitive-form-of lang-fi">{{{gen_sg}}}</span>
| {{{gen_sg}}}
|- class="vsHide"
|- class="vsHide"
! colspan="2" | genitive
! colspan="2" | genitive
| <span class="form-of singular-genitive-form-of lang-fi">{{{gen_sg}}}</span>
| {{{gen_sg}}}
| <span class="form-of plural-genitive-form-of lang-fi">{{{gen_pl}}}</span>
| {{{gen_pl}}}
|- class="vsHide"
|- class="vsHide"
! colspan="2" | partitive
! colspan="2" | partitive
| <span class="form-of singular-partitive-form-of lang-fi">{{{par_sg}}}</span>
| {{{par_sg}}}
| <span class="form-of plural-partitive-form-of lang-fi">{{{par_pl}}}</span>
| {{{par_pl}}}
|- class="vsHide"
|- class="vsHide"
! colspan="2" | inessive
! colspan="2" | inessive
| <span class="form-of singular-inessive-form-of lang-fi">{{{ine_sg}}}</span>
| {{{ine_sg}}}
| <span class="form-of plural-inessive-form-of lang-fi">{{{ine_pl}}}</span>
| {{{ine_pl}}}
|- class="vsHide"
|- class="vsHide"
! colspan="2" | elative
! colspan="2" | elative
| <span class="form-of singular-elative-form-of lang-fi">{{{ela_sg}}}</span>
| {{{ela_sg}}}
| <span class="form-of plural-elative-form-of lang-fi">{{{ela_pl}}}</span>
| {{{ela_pl}}}
|- class="vsHide"
|- class="vsHide"
! colspan="2" | illative
! colspan="2" | illative
| <span class="form-of singular-illative-form-of lang-fi">{{{ill_sg}}}</span>
| {{{ill_sg}}}
| <span class="form-of plural-illative-form-of lang-fi">{{{ill_pl}}}</span>
| {{{ill_pl}}}
|- class="vsHide"
|- class="vsHide"
! colspan="2" | adessive
! colspan="2" | adessive
| <span class="form-of singular-adessive-form-of lang-fi">{{{ade_sg}}}</span>
| {{{ade_sg}}}
| <span class="form-of plural-adessive-form-of lang-fi">{{{ade_pl}}}</span>
| {{{ade_pl}}}
|- class="vsHide"
|- class="vsHide"
! colspan="2" | ablative
! colspan="2" | ablative
| <span class="form-of singular-ablative-form-of lang-fi">{{{abl_sg}}}</span>
| {{{abl_sg}}}
| <span class="form-of plural-ablative-form-of lang-fi">{{{abl_pl}}}</span>
| {{{abl_pl}}}
|- class="vsHide"
|- class="vsHide"
! colspan="2" | allative
! colspan="2" | allative
| <span class="form-of singular-allative-form-of lang-fi">{{{all_sg}}}</span>
| {{{all_sg}}}
| <span class="form-of plural-allative-form-of lang-fi">{{{all_pl}}}</span>
| {{{all_pl}}}
|- class="vsHide"
|- class="vsHide"
! colspan="2" | essive
! colspan="2" | essive
| <span class="form-of singular-essive-form-of lang-fi">{{{ess_sg}}}</span>
| {{{ess_sg}}}
| <span class="form-of plural-essive-form-of lang-fi">{{{ess_pl}}}</span>
| {{{ess_pl}}}
|- class="vsHide"
|- class="vsHide"
! colspan="2" | translative
! colspan="2" | translative
| <span class="form-of singular-translative-form-of lang-fi">{{{tra_sg}}}</span>
| {{{tra_sg}}}
| <span class="form-of plural-translative-form-of lang-fi">{{{tra_pl}}}</span>
| {{{tra_pl}}}
|- class="vsHide"
! colspan="2" | instructive
| <span class="form-of singular-instructive-form-of lang-fi">{{{ins_sg}}}</span>
| <span class="form-of plural-instructive-form-of lang-fi">{{{ins_pl}}}</span>
|- class="vsHide"
|- class="vsHide"
! colspan="2" | abessive
! colspan="2" | abessive
| <span class="form-of singular-abessive-form-of lang-fi">{{{abe_sg}}}</span>
| {{{abe_sg}}}
| <span class="form-of plural-abessive-form-of lang-fi">{{{abe_pl}}}</span>
| {{{abe_pl}}}
|- class="vsHide"
! colspan="2" | instructive
| {{{ins_sg}}}
| {{{ins_pl}}}
|- class="vsHide"
|- class="vsHide"
! colspan="2" | comitative
! colspan="2" | comitative
| {{{com_forms}}}
| {{{com_sg}}}
{{{maybenote}}}|}
| {{{com_pl}}}
</div>]=]
|}]=]
return mw.ustring.gsub(wikicode, "{{{([a-z0-9_:]+)}}}", repl)
end

------------------------------------------
-- POSSESSIVE FORM GENERATION & DISPLAY --
------------------------------------------

local function prepare_possessive_list(forms)
local res = {}
for _, v in ipairs(forms) do
table.insert(res, v)
end
if forms["rare"] then
for _, v in ipairs(forms["rare"]) do
table.insert(res, v)
res[v] = "rare"
end
end
return res
end

local function wrap_rare_forms(forms)
local newforms = {}
for case, subforms in pairs(forms) do
local common = {}
local rare = {}
for _, v in ipairs(subforms) do
if subforms[v] == "rare" then
table.insert(rare, v)
else
table.insert(common, v)
end
end
common.rare = rare
newforms[case] = common
end
return newforms
end

local function make_possessives_from_stems(stems, suffix, extra_suffix)
local pforms = {}
for _, stem in pairs(stems) do
table.insert(pforms, stem .. suffix .. extra_suffix)
end
return pforms
end

function make_poss_with_suffix(forms, stems, poss_suffix, extra_suffix, allow_alt, par_nom_sg)
local result = {}
local par_sg_a = false
if poss_suffix:find("a") and mw.ustring.sub(forms["ine_sg"][1], -1) == "ä" then
poss_suffix = mw.ustring.gsub(poss_suffix, "a", "ä")
end
if mw.ustring.sub(forms["ine_sg"][1], -1) ~= mw.ustring.sub(forms["par_sg"][1], -1) then
par_sg_a = true
end

for k, v in pairs(forms_alt_ok) do
if forms[k] then
local suffix = poss_suffix
if k == "par_sg" and par_sg_a and mw.ustring.find(suffix, "ä$") then
suffix = mw.ustring.gsub(poss_suffix, "ä", "a")
end

result[k] = {}
if k == "par_sg" and allow_alt then
-- par_sg is a bit of an exception: it allows
-- alt form if it doesn't end in two "aa"/"ää"
local prepared = prepare_possessive_list(forms[k])
for _, form in ipairs(prepared) do
local modform = form
if mw.ustring.sub(modform, -2, -2) ~= mw.ustring.sub(modform, -1) then
local final = modform .. mw.ustring.sub(modform, -1) .. "n"
table.insert(result[k], final)
result[k][final] = prepared[form]
end
end
elseif forms_alt_ok[k] and allow_alt then
local prepared = prepare_possessive_list(forms[k])
for _, form in ipairs(prepared) do
local modform = form
if k == "tra_sg" or k == "tra_pl" then
modform = mw.ustring.sub(form, 1, -2) .. "e"
end
local final = modform .. mw.ustring.sub(modform, -1) .. "n"
table.insert(result[k], final)
result[k][final] = prepared[form]
end
end
if k == "gen_sg" or k == "ins_sg" then
result[k] = make_possessives_from_stems(stems["sg"], suffix, extra_suffix)
elseif k == "ins_pl" then
result[k] = make_possessives_from_stems(stems["pl"], suffix, extra_suffix)
elseif forms_gen_ok[k] then
local prepared = prepare_possessive_list(forms[k])
for _, form in ipairs(prepared) do
local tmp = form
tmp = mw.ustring.sub(tmp, 1, -2)
local final = tmp .. suffix .. extra_suffix
table.insert(result[k], final)
result[k][final] = prepared[form]
end
else
local prepared = prepare_possessive_list(forms[k])
for _, form in ipairs(prepared) do
local modform = form
if k == "tra_sg" or k == "tra_pl" then
modform = mw.ustring.sub(form, 1, -2) .. "e"
end
local final = modform .. suffix .. extra_suffix
table.insert(result[k], final)
result[k][final] = prepared[form]
end
end
end
end

-- nominative forms are (usually) identical to genitive singular
result["nom_sg"] = result[par_nom_sg and "par_sg" or "gen_sg"]
result["nom_pl"] = result["gen_sg"]
return wrap_rare_forms(result)
end

local function serialize_args(args)
local items = {}
local entries = {}
local max_number = 0

for key, value in pairs(args) do
if type(key) == "number" and key > 0 and key == math.floor(key) then
items[key] = value
max_number = math.max(key, max_number)
else
table.insert(entries, key .. "=" .. value)
end
end

for i = 1,max_number,1 do
items[i] = items[i] or ""
end
-- entries before items
for i, v in ipairs(entries) do
table.insert(items, i, v)
end
return table.concat(items, "|")
end

local poss_headings = {
["1s"] = "first-person singular", ["2s"] = "second-person singular",
["1p"] = "first-person plural", ["2p"] = "second-person plural",
["3"] = "third-person",
}

local poss_accel = {
["1s"] = "1|s", ["2s"] = "2|s", ["1p"] = "1|p", ["2p"] = "2|p", ["3"] = "3"
}

function make_possessive_table(pagename, args, pos, infl_title, get_forms)
local note = nil

if args["noposs"] then
return ""
elseif pos == "adj" then
note = not (args["adjpossok"] or args["hideadjnote"]) and "'''[[Appendix:Finnish possessive suffixes#Adjectives|Rare]]'''. Only used with [[substantive adjective]]s." or ""
elseif pos ~= "noun" then
return ""
end

return "\n" .. make_possessive_table_internal(pagename, args, infl_title, note, get_forms)
end

function make_possessive_table_internal(pagename, args, infl_title, note, get_forms)
local function show_subtable(code)
return make_table(get_forms(code), false, poss_headings[code] .. " possessor", "possessive inflection", poss_accel[code] .. "|poss|form|of|", "fi-decl-poss-subtable")
end
local function repl(param)
if param == "lemma" then
return tag_term(pagename)
elseif param == "info" then
return " <small>(" .. infl_title .. ")</small>"
elseif param == "maybenote" then
if note then
return [=[
|- class="vsHide"
| colspan="3" | ]=] .. note .. "\n"
else
return ""
end
else
return show_subtable(param)
end
end
local wikicode = [=[
<div class="noresize">
{| class="inflection-table vsSwitcher fi-decl-poss" data-toggle-category="possessive inflection" cellspacing="1" cellpadding="2"
|- class="fi-decl-poss-header"
! class="vsToggleElement" colspan="3" | [[Appendix:Finnish possessive suffixes|Possessive forms]] of {{{lemma}}}{{{info}}}
{{{maybenote}}}|- class="vsHide"
|
{{{1s}}}
{{{2s}}}
{{{1p}}}
{{{2p}}}
{{{3}}}
|}
</div>]=]
return mw.ustring.gsub(wikicode, "{{{([a-z0-9_:]+)}}}", repl)
return mw.ustring.gsub(wikicode, "{{{([a-z0-9_:]+)}}}", repl)
end
end