Module:fi-verbs
Jump to navigation
Jump to search
- The following documentation is located at Module:fi-verbs/documentation. [edit] Categories were auto-generated by Module:module categorization. [edit]
- Useful links: subpage list • links • transclusions • testcases • sandbox
This module is used for the various Finnish verb inflection tables.
local export = {}
local lang = require("Module:languages").getByCode("fi")
-- Functions that do the actual inflecting by creating the forms of a basic term.
local inflections = {}
local kotus_grad_type = {
["kk-k"] = "A",
["pp-p"] = "B",
["tt-t"] = "C",
["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 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 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("^-") or term:find("%[%[%-") then
term = mw.ustring.gsub(term, "[%[%]]", "")
if target == 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 there is something difficult, use full module.
if term:find(":") or term:find("<") or (accel_form and 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
-- otherwise, we can save a ton of memory by doing this manually.
local target = normalize_apostrophes(term, true)
if target == mw.title.getCurrentTitle().fullText then
return '<span class="Latn" lang="fi"><strong class="selflink">' .. term .. '</strong></span>'
end
if term:find("%[") then
return '<span class="Latn" lang="fi">' .. term .. '</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
-- 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
if not inflections[infl_type] then
error("Unknown inflection type '" .. infl_type .. "'")
end
local data = {
forms = {},
title = nil,
categories = {},
vh = nil,
pagename = mw.title.getCurrentTitle().text
}
if args["title"] and mw.title.getCurrentTitle().namespace > 0 then
data.pagename = args.title
end
data.pagename = normalize_apostrophes(data.pagename)
-- Generate the forms
inflections[infl_type](args, data)
-- Postprocess
postprocess(args, data)
if args["appendix"] then
table.insert(data.categories, "fi-conj with appendix")
end
if args["noagent"] then
table.insert(data.categories, "fi-conj with noagent")
end
if args["qual"] or
args["q1sg"] or args["q2sg"] or args["q1pl"] or args["q2pl"] or args["q3p"] or args["qpass"] or
args["q1sgp"] or args["q2sgp"] or args["q1plp"] or args["q2plp"] or args["q3pp"] or args["qpassp"] or args["q4i"] then
table.insert(data.categories, "fi-conj with qual")
end
local categories
if args["appendix"] then
categories = ""
else
categories = require("Module:utilities").format_categories(data.categories, lang)
end
return make_table(data) .. categories
.. require("Module:TemplateStyles")("Module:fi-verbs/style.css")
end
local function args_get_required(args, i, purpose)
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
-- Get parameters from the template, in standard order and numbering
local function get_params(args, num, invert_grades)
local params = {}
params.base = normalize_apostrophes(args[1])
if num >= 2 then
if num >= 4 then
params.strong = normalize_apostrophes(args_get_required(args, 2, "Infinitive grade"))
params.weak = normalize_apostrophes(args_get_required(args, 3, "Other grade"))
-- Swap the grades
if invert_grades then
params.strong, params.weak = params.weak, params.strong
end
end
if num >= 5 then
params.final = args_get_required(args, 4, "Final letter(s)")
end
params.a = args_get_vowel_harmony(args, num)
end
if params.a then
params.o = params.a == "ä" and "ö" or "o"
params.u = params.a == "ä" and "y" or "u"
end
return params
end
--[=[
Inflection functions
]=]--
local stem_endings = {}
stem_endings["inf1"] = {
["inf1"] = "a",
["inf1_long"] = "akse¤",
}
stem_endings["inf2"] = {
["inf2_ine"] = "essa¤",
["inf2_ins"] = "en",
}
stem_endings["pres"] = {
["pres_3sg"] = "V",
["pres_3pl"] = "vat",
["inf3_ine"] = "massa",
["inf3_ela"] = "masta",
["inf3_ill"] = "maan",
["inf3_ade"] = "malla",
["inf3_abe"] = "matta",
["inf3_ins"] = "man",
["inf4"] = "minen",
["inf5"] = "maisilla¤",
["pres_part"] = "va",
["agnt_part"] = "ma",
["nega_part"] = "maton",
}
stem_endings["pres_weak"] = {
["pres_1sg"] = "n",
["pres_2sg"] = "t",
["pres_1pl"] = "mme",
["pres_2pl"] = "tte",
["pres_conn"] = "",
["impr_2sg"] = "",
}
stem_endings["past"] = {
["past_3sg"] = "",
["past_3pl"] = "vat",
}
stem_endings["past_weak"] = {
["past_1sg"] = "n",
["past_2sg"] = "t",
["past_1pl"] = "mme",
["past_2pl"] = "tte",
}
stem_endings["cond"] = {
["cond_1sg"] = "sin",
["cond_2sg"] = "sit",
["cond_3sg"] = "si",
["cond_1pl"] = "simme",
["cond_2pl"] = "sitte",
["cond_3pl"] = "sivat",
["cond_conn"] = "si",
}
stem_endings["impr"] = {
["impr_3sg"] = "oon",
["impr_1pl"] = "aamme",
["impr_2pl"] = "aa",
["impr_3pl"] = "oot",
["impr_conn"] = "o",
}
stem_endings["potn"] = {
["potn_1sg"] = "en",
["potn_2sg"] = "et",
["potn_3sg"] = "ee",
["potn_1pl"] = "emme",
["potn_2pl"] = "ette",
["potn_3pl"] = "evat",
["potn_conn"] = "e",
["past_part"] = "ut",
["past_part_pl"] = "eet",
}
stem_endings["pres_pasv"] = {
["pres_pasv"] = "aan",
["pres_pasv_conn"] = "a",
}
stem_endings["past_pasv"] = {
["past_pasv"] = "iin",
["cond_pasv"] = "aisiin",
["cond_pasv_conn"] = "aisi",
["impr_pasv"] = "akoon",
["impr_pasv_conn"] = "ako",
["potn_pasv"] = "aneen",
["potn_pasv_conn"] = "ane",
["inf2_pasv_ine"] = "aessa",
["inf3_pasv_ins"] = "aman",
["pres_pasv_part"] = "ava",
["past_pasv_part"] = "u",
}
-- Make a copy of the endings, with front vowels
stem_endings = {["a"] = stem_endings, ["ä"] = mw.clone(stem_endings)}
for stem_key, endings in pairs(stem_endings["ä"]) do
for key, ending in pairs(endings) do
endings[key] = mw.ustring.gsub(endings[key], "([aou])", {["a"] = "ä", ["o"] = "ö", ["u"] = "y"})
end
end
local function process_stems(data, stems, vh, no_make_stems)
-- Create any stems that were not given
if not no_make_stems then
stems["inf1"] = stems["inf1"] or mw.clone(stems["pres"])
if not stems["cond"] and stems["pres"] then
stems["cond"] = {}
for _, stem in ipairs(stems["pres"]) do
table.insert(stems["cond"], mw.ustring.gsub(stem, "[ei]$", "") .. "i")
end
end
if not stems["impr"] and stems["pres"] then
stems["impr"] = {}
for _, stem in ipairs(stems["pres"]) do
table.insert(stems["impr"], stem .. "k")
end
end
if not stems["potn"] and stems["pres"] then
stems["potn"] = {}
for _, stem in ipairs(stems["pres"]) do
table.insert(stems["potn"], stem .. "n")
end
end
end
-- Create forms based on each stem, by adding endings to it
if not stems["inf2"] and stems["inf1"] then
stems["inf2"] = {}
for _, stem in ipairs(stems["inf1"]) do
table.insert(stems["inf2"], (mw.ustring.gsub(stem, "e$", "i")))
end
end
stems["pres_weak"] = stems["pres_weak"] or mw.clone(stems["pres"])
stems["past_weak"] = stems["past_weak"] or mw.clone(stems["past"])
-- Go through each of the stems given
for stem_key, substems in pairs(stems) do
for _, stem in ipairs(substems) do
-- Attach the endings to the stem
for form_key, ending in pairs(stem_endings[vh][stem_key]) do
if not data.forms[form_key] then
data.forms[form_key] = {}
end
-- If the ending is "V" then it is a copy of the preceding vowel...
if ending == "V" then
-- ...but not if the stem ends in a long vowel or diphthong.
if mw.ustring.find(stem, "([aeiouyäö])%1$") or mw.ustring.find(stem, "([aeiouyäö])[iuy]$") or mw.ustring.find(stem, "ie$") or mw.ustring.find(stem, "uo$") or mw.ustring.find(stem, "yö$") then
ending = ""
else
ending = mw.ustring.match(stem, "([aeiouyäö])$") or ""
end
end
table.insert(data.forms[form_key], stem .. ending)
end
end
end
data["vh"] = vh
end
local KOTUS_TYPE = "[[Kotus]] type "
local function make_kotus_title_number(type_number)
return KOTUS_TYPE .. type_number
end
local function make_kotus_title_word(reference_word)
return '/<span lang="fi" class="Latn">[[Appendix:Finnish conjugation/' .. reference_word .. '|' .. reference_word .. ']]</span>'
end
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
title = title .. ", no gradation"
end
data.title = title
table.insert(data.categories, "Finnish " .. reference_word .. "-type verbs")
end
local function inflection_type_is_t_d(data, number, reference_word, weak)
if weak == "d" then
inflection_type_is(data, number, reference_word, "t", "d")
else
inflection_type_is(data, number, reference_word, weak .. "t", weak .. weak)
end
end
local function inflection_type_is_combo(data, number_a, reference_word_a, number_b, reference_word_b, strong, weak)
local title = KOTUS_TYPE
local has_gradation = strong and strong ~= weak
local gradation_suffix = ""
if has_gradation then
local letter = kotus_grad_type[strong .. "-" .. weak]
if letter then
gradation_suffix = "*" .. letter
else
gradation_suffix = "*"
end
end
title = title .. number_a .. gradation_suffix .. make_kotus_title_word(reference_word_a)
title = title .. " and " .. number_b .. gradation_suffix .. make_kotus_title_word(reference_word_b)
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
title = title .. ", no gradation"
end
data.title = title
table.insert(data.categories, "Finnish " .. reference_word_a .. "-type verbs")
table.insert(data.categories, "Finnish " .. reference_word_b .. "-type verbs")
end
--[=[
Inflection types
]=]--
inflections["sanoa"] = function(args, data)
local params = get_params(args, 5)
local apo = (params.weak == "" and mw.ustring.sub(params.base, -1) == params.final) and "'" or ""
local stems = {}
stems["pres"] = {params.base .. params.strong .. params.final}
stems["pres_weak"] = {params.base .. params.weak .. apo .. params.final}
stems["past"] = {params.base .. params.strong .. params.final .. "i"}
stems["past_weak"] = {params.base .. params.weak .. apo .. params.final .. "i"}
stems["pres_pasv"] = {params.base .. params.weak .. apo .. params.final .. "t"}
stems["past_pasv"] = {params.base .. params.weak .. apo .. params.final .. "tt"}
inflection_type_is(data, 52, "sanoa", params.strong, params.weak)
process_stems(data, stems, params.a)
end
inflections["muistaa"] = function(args, data)
local params = get_params(args, 4)
local stems = {}
stems["pres"] = {params.base .. params.strong .. params.a}
stems["pres_weak"] = {params.base .. params.weak .. params.a}
stems["past"] = {params.base .. params.strong .. "i"}
stems["past_weak"] = {params.base .. params.weak .. "i"}
stems["pres_pasv"] = {params.base .. params.weak .. "et"}
stems["past_pasv"] = {params.base .. params.weak .. "ett"}
inflection_type_is(data, 53, "muistaa", params.strong, params.weak)
process_stems(data, stems, params.a)
end
inflections["huutaa"] = function(args, data)
local params = get_params(args, 2)
local weak = mw.ustring.match(params.base, "([lnr])$") or "d"
local stems = {}
stems["pres"] = {params.base .. "t" .. params.a}
stems["pres_weak"] = {params.base .. weak .. params.a}
stems["past"] = {params.base .. "si"}
stems["pres_pasv"] = {params.base .. weak .. "et"}
stems["past_pasv"] = {params.base .. weak .. "ett"}
inflection_type_is_t_d(data, 54, "huutaa", weak)
process_stems(data, stems, params.a)
end
inflections["soutaa"] = function(args, data)
local params = get_params(args, 2)
local weak = mw.ustring.match(params.base, "([lnr])$") or "d"
local stems = {}
stems["pres"] = {params.base .. "t" .. params.a}
stems["pres_weak"] = {params.base .. weak .. params.a}
stems["past"] = {params.base .. "ti", params.base .. "si"}
stems["past_weak"] = {params.base .. weak .. "i", params.base .. "si"}
stems["pres_pasv"] = {params.base .. weak .. "et"}
stems["past_pasv"] = {params.base .. weak .. "ett"}
inflection_type_is_t_d(data, 55, "soutaa", weak)
process_stems(data, stems, params.a)
end
inflections["kaivaa"] = function(args, data)
local params = get_params(args, 4)
local stems = {}
stems["pres"] = {params.base .. params.strong .. params.a}
stems["pres_weak"] = {params.base .. params.weak .. params.a}
stems["past"] = {params.base .. params.strong .. params.o .. "i"}
stems["past_weak"] = {params.base .. params.weak .. params.o .. "i"}
stems["pres_pasv"] = {params.base .. params.weak .. "et"}
stems["past_pasv"] = {params.base .. params.weak .. "ett"}
inflection_type_is(data, 56, "kaivaa", params.strong, params.weak)
process_stems(data, stems, params.a)
end
inflections["saartaa"] = function(args, data)
local params = get_params(args, 2)
local weak = mw.ustring.match(params.base, "([lnr])$") or "d"
local stems = {}
stems["pres"] = {params.base .. "t" .. params.a}
stems["pres_weak"] = {params.base .. weak .. params.a}
stems["past"] = {params.base .. "si", params.base .. "t" .. params.o .. "i"}
stems["past_weak"] = {params.base .. "si", params.base .. weak .. params.o .. "i"}
stems["pres_pasv"] = {params.base .. weak .. "et"}
stems["past_pasv"] = {params.base .. weak .. "ett"}
inflection_type_is_t_d(data, 57, "saartaa", weak)
process_stems(data, stems, params.a)
end
inflections["laskea"] = function(args, data)
local params = get_params(args, 4)
local stems = {}
stems["pres"] = {params.base .. params.strong .. "e"}
stems["pres_weak"] = {params.base .. params.weak .. "e"}
stems["past"] = {params.base .. params.strong .. "i"}
stems["past_weak"] = {params.base .. params.weak .. "i"}
stems["pres_pasv"] = {params.base .. params.weak .. "et"}
stems["past_pasv"] = {params.base .. params.weak .. "ett"}
inflection_type_is(data, 58, "laskea", params.strong, params.weak)
process_stems(data, stems, params.a)
end
inflections["tuntea"] = function(args, data)
local params = get_params(args, 2)
local weak = mw.ustring.match(params.base, "([lnr])$") or "d"
local stems = {}
stems["pres"] = {params.base .. "te"}
stems["pres_weak"] = {params.base .. weak .. "e"}
stems["past"] = {params.base .. "si"}
stems["pres_pasv"] = {params.base .. weak .. "et"}
stems["past_pasv"] = {params.base .. weak .. "ett"}
inflection_type_is_t_d(data, 59, "tuntea", weak)
process_stems(data, stems, params.a)
end
inflections["lähteä"] = function(args, data)
local params = get_params(args, 2)
local stems = {}
stems["pres"] = {params.base .. "hte"}
stems["pres_weak"] = {params.base .. "hde"}
stems["past"] = {params.base .. "hti", params.base .. "ksi"}
stems["past_weak"] = {params.base .. "hdi", params.base .. "ksi"}
stems["pres_pasv"] = {params.base .. "hdet"}
stems["past_pasv"] = {params.base .. "hdett"}
inflection_type_is(data, 60, "lähteä", "t", "d")
process_stems(data, stems, params.a)
end
inflections["sallia"] = function(args, data)
local params = get_params(args, 4)
local apo = (params.weak == "" and mw.ustring.sub(params.base, -1) == "i") and "'" or ""
local stems = {}
stems["pres"] = {params.base .. params.strong .. "i"}
stems["pres_weak"] = {params.base .. params.weak .. apo .. "i"}
stems["past"] = {params.base .. params.strong .. "i"}
stems["past_weak"] = {params.base .. params.weak .. apo .. "i"}
stems["pres_pasv"] = {params.base .. params.weak .. apo .. "it"}
stems["past_pasv"] = {params.base .. params.weak .. apo .. "itt"}
inflection_type_is(data, 61, "sallia", params.strong, params.weak)
process_stems(data, stems, params.a)
end
inflections["voida"] = function(args, data)
local params = get_params(args, 2)
local stems = {}
stems["inf1"] = {params.base .. "d"}
stems["pres"] = {params.base}
stems["past"] = {params.base}
stems["pres_pasv"] = {params.base .. "d"}
stems["past_pasv"] = {params.base .. "t"}
inflection_type_is(data, 62, "voida")
process_stems(data, stems, params.a)
end
inflections["saada"] = function(args, data)
local params = get_params(args, 2)
local vowel = mw.ustring.sub(params.base, -1)
local stems = {}
stems["inf1"] = {params.base .. vowel .. "d"}
stems["pres"] = {params.base .. vowel}
stems["past"] = {params.base .. "i"}
stems["cond"] = {params.base .. "i"}
stems["pres_pasv"] = {params.base .. vowel .. "d"}
stems["past_pasv"] = {params.base .. vowel .. "t"}
inflection_type_is(data, 63, "saada")
process_stems(data, stems, params.a)
end
inflections["juoda"] = function(args, data)
local params = get_params(args, 2)
local past_cond_stem = mw.ustring.sub(params.base, 1, -3) .. mw.ustring.sub(params.base, -1)
local stems = {}
stems["inf1"] = {params.base .. "d"}
stems["pres"] = {params.base}
stems["past"] = {past_cond_stem .. "i"}
stems["cond"] = {past_cond_stem .. "i"}
stems["pres_pasv"] = {params.base .. "d"}
stems["past_pasv"] = {params.base .. "t"}
inflection_type_is(data, 64, "juoda")
process_stems(data, stems, params.a)
end
inflections["käydä"] = function(args, data)
local params = get_params(args, 2)
local stems = {}
stems["inf1"] = {params.base .. params.u .. "d"}
stems["pres"] = {params.base .. params.u}
stems["past"] = {params.base .. "vi"}
stems["cond"] = {params.base .. "vi"}
stems["pres_pasv"] = {params.base .. params.u .. "d"}
stems["past_pasv"] = {params.base .. params.u .. "t"}
inflection_type_is(data, 65, "käydä")
process_stems(data, stems, params.a)
end
inflections["rohkaista"] = function(args, data)
local params = get_params(args, 5, true)
local stems = {}
stems["inf1"] = {params.base .. params.weak .. params.final .. "st"}
stems["pres"] = {params.base .. params.strong .. params.final .. "se"}
stems["past"] = {params.base .. params.strong .. params.final .. "si"}
stems["impr"] = {params.base .. params.weak .. params.final .. "sk"}
stems["potn"] = {params.base .. params.weak .. params.final .. "ss"}
stems["pres_pasv"] = {params.base .. params.weak .. params.final .. "st"}
stems["past_pasv"] = {params.base .. params.weak .. params.final .. "st"}
inflection_type_is(data, 66, "rohkaista", params.strong, params.weak)
process_stems(data, stems, params.a)
end
inflections["tulla"] = function(args, data)
local params = get_params(args, 5, true)
local cons = mw.ustring.sub(params.final, -1)
local stems = {}
stems["inf1"] = {params.base .. params.weak .. params.final .. cons}
stems["pres"] = {params.base .. params.strong .. params.final .. "e"}
stems["past"] = {params.base .. params.strong .. params.final .. "i"}
stems["impr"] = {params.base .. params.weak .. params.final .. "k"}
stems["potn"] = {params.base .. params.weak .. params.final .. cons}
stems["pres_pasv"] = {params.base .. params.weak .. params.final .. cons}
stems["past_pasv"] = {params.base .. params.weak .. params.final .. "t"}
inflection_type_is(data, 67, "tulla", params.strong, params.weak)
process_stems(data, stems, params.a)
end
inflections["tupakoida"] = function(args, data)
local params = get_params(args, 2)
local stems = {}
stems["inf1"] = {params.base .. "d"}
stems["pres"] = {params.base, params.base .. "tse"}
stems["past"] = {params.base, params.base .. "tsi"}
stems["impr"] = {params.base .. "k"}
stems["potn"] = {params.base .. "n"}
stems["pres_pasv"] = {params.base .. "d"}
stems["past_pasv"] = {params.base .. "t"}
inflection_type_is(data, 68, "tupakoida")
process_stems(data, stems, params.a)
end
inflections["valita"] = function(args, data)
local params = get_params(args, 2)
local stems = {}
stems["inf1"] = {params.base .. "t"}
stems["pres"] = {params.base .. "tse"}
stems["past"] = {params.base .. "tsi"}
stems["impr"] = {params.base .. "tk"}
stems["potn"] = {params.base .. "nn"}
stems["pres_pasv"] = {params.base .. "t"}
stems["past_pasv"] = {params.base .. "tt"}
inflection_type_is(data, 69, "valita")
process_stems(data, stems, params.a)
end
inflections["juosta"] = function(args, data)
local params = get_params(args, 2)
local stems = {}
stems["inf1"] = {params.base .. "st"}
stems["pres"] = {params.base .. "kse"}
stems["past"] = {params.base .. "ksi"}
stems["impr"] = {params.base .. "sk"}
stems["potn"] = {params.base .. "ss"}
stems["pres_pasv"] = {params.base .. "st"}
stems["past_pasv"] = {params.base .. "st"}
inflection_type_is(data, 70, "juosta")
process_stems(data, stems, params.a)
end
inflections["nähdä"] = function(args, data)
local params = get_params(args, 2)
local stems = {}
stems["inf1"] = {params.base .. "hd"}
stems["pres"] = {params.base .. "ke"}
stems["pres_weak"] = {params.base .. "e"}
stems["past"] = {params.base .. "ki"}
stems["past_weak"] = {params.base .. "i"}
stems["impr"] = {params.base .. "hk"}
stems["potn"] = {params.base .. "hn"}
stems["pres_pasv"] = {params.base .. "hd"}
stems["past_pasv"] = {params.base .. "ht"}
inflection_type_is(data, 71, "nähdä", "k", "")
process_stems(data, stems, params.a)
end
inflections["vanheta"] = function(args, data)
local params = get_params(args, 5, true)
local stems = {}
stems["inf1"] = {params.base .. params.weak .. params.final .. "t"}
stems["pres"] = {params.base .. params.strong .. params.final .. "ne"}
stems["past"] = {params.base .. params.strong .. params.final .. "ni"}
stems["impr"] = {params.base .. params.weak .. params.final .. "tk"}
stems["potn"] = {params.base .. params.weak .. params.final .. "nn"}
stems["pres_pasv"] = {params.base .. params.weak .. params.final .. "t"}
stems["past_pasv"] = {params.base .. params.weak .. params.final .. "tt"}
inflection_type_is(data, 72, "vanheta", params.strong, params.weak)
process_stems(data, stems, params.a)
end
inflections["salata"] = function(args, data)
local params = get_params(args, 4, true)
local stems = {}
stems["inf1"] = {params.base .. params.weak .. params.a .. "t"}
stems["pres"] = {params.base .. params.strong .. params.a .. params.a}
stems["past"] = {params.base .. params.strong .. params.a .. "si"}
stems["cond"] = {params.base .. params.strong .. params.a .. "i"}
stems["impr"] = {params.base .. params.weak .. params.a .. "tk"}
stems["potn"] = {params.base .. params.weak .. params.a .. "nn"}
stems["pres_pasv"] = {params.base .. params.weak .. params.a .. "t"}
stems["past_pasv"] = {params.base .. params.weak .. params.a .. "tt"}
inflection_type_is(data, 73, "salata", params.strong, params.weak)
process_stems(data, stems, params.a)
end
inflections["katketa"] = function(args, data)
local params = get_params(args, 5, true)
local stems = {}
stems["inf1"] = {params.base .. params.weak .. params.final .. "t"}
stems["pres"] = {params.base .. params.strong .. params.final .. params.a}
stems["past"] = {params.base .. params.strong .. params.final .. "si"}
stems["cond"] = {params.base .. params.strong .. params.final .. params.a .. "i", params.base .. params.strong .. params.final .. "i"}
stems["impr"] = {params.base .. params.weak .. params.final .. "tk"}
stems["potn"] = {params.base .. params.weak .. params.final .. "nn"}
stems["pres_pasv"] = {params.base .. params.weak .. params.final .. "t"}
stems["past_pasv"] = {params.base .. params.weak .. params.final .. "tt"}
inflection_type_is(data, 74, "katketa", params.strong, params.weak)
process_stems(data, stems, params.a)
end
inflections["selvitä"] = function(args, data)
local params = get_params(args, 5, true)
local stems = {}
stems["inf1"] = {params.base .. params.weak .. params.final .. "t"}
stems["pres"] = {params.base .. params.strong .. params.final .. params.a}
stems["past"] = {params.base .. params.strong .. params.final .. "si"}
stems["impr"] = {params.base .. params.weak .. params.final .. "tk"}
stems["potn"] = {params.base .. params.weak .. params.final .. "nn"}
stems["pres_pasv"] = {params.base .. params.weak .. params.final .. "t"}
stems["past_pasv"] = {params.base .. params.weak .. params.final .. "tt"}
inflection_type_is(data, 75, "selvitä", params.strong, params.weak)
process_stems(data, stems, params.a)
end
inflections["taitaa"] = function(args, data)
local params = get_params(args, 2)
local stems = {}
stems["pres"] = {params.base .. "t" .. params.a}
stems["pres_weak"] = {params.base .. "d" .. params.a}
stems["past"] = {params.base .. "si"}
stems["potn"] = {params.base .. "t" .. params.a .. "n", params.base .. "nn"}
stems["pres_pasv"] = {params.base .. "det"}
stems["past_pasv"] = {params.base .. "dett"}
inflection_type_is(data, 76, "taitaa", "t", "d")
process_stems(data, stems, params.a)
end
inflections["virkkaa"] = function(args, data)
local stems = {}
stems["inf1"] = {"virkka"}
stems["pres"] = {"virkka"}
stems["pres_weak"] = {"virka"}
stems["past"] = {"virkkoi"}
stems["past_weak"] = {"virkoi"}
stems["cond"] = {"virkkai"}
stems["impr"] = {"virkkak"}
stems["potn"] = {"virkkan"}
process_stems(data, stems, "a", true)
local stems = {}
stems["pres_pasv"] = {"virket"}
stems["past_pasv"] = {"virkett"}
process_stems(data, stems, "ä", true)
inflection_type_is_combo(data, 56, "kaivaa", 53, "muistaa", "kk", "k")
data.title = data.title .. ", irregular vowel harmony"
end
inflections["seistä"] = function(args, data)
local stems = {}
stems["inf1"] = {"seist"}
stems["impr"] = {"seisk"}
stems["potn"] = {"seiss"}
stems["pres_pasv"] = {"seist"}
stems["past_pasv"] = {"seist"}
process_stems(data, stems, "ä", true)
local stems = {}
stems["pres"] = {"seiso"}
stems["past"] = {"seisoi"}
stems["cond"] = {"seisoi"}
process_stems(data, stems, "a", true)
inflection_type_is_combo(data, 52, "sanoa", 66, "rohkaista")
end
inflections["olla"] = function(args, data)
local stems = {}
stems["inf1"] = {"oll"}
stems["pres"] = {"ole"}
stems["past"] = {"oli"}
stems["impr"] = {"olk"}
stems["potn"] = {"oll"}
stems["pres_pasv"] = {"oll"}
stems["past_pasv"] = {"olt"}
process_stems(data, stems, "a")
data.forms["pres_3sg"] = {"on"}
data.forms["pres_3pl"] = {"ovat"}
data.forms["potn_1sg"] = {"lienen"}
data.forms["potn_2sg"] = {"lienet"}
data.forms["potn_3sg"] = {"lienee"}
data.forms["potn_1pl"] = {"lienemme"}
data.forms["potn_2pl"] = {"lienette"}
data.forms["potn_3pl"] = {"lienevät"}
data.forms["potn_conn"] = {"liene"}
inflection_type_is_combo(data, 67, "tulla", 64, "juoda")
end
-- Helper functions
local complex_forms = {
-- Present
["pres_1sg_neg"] = { "en", "pres_conn" },
["pres_2sg_neg"] = { "et", "pres_conn" },
["pres_3sg_neg"] = { "ei", "pres_conn" },
["pres_1pl_neg"] = { "emme", "pres_conn" },
["pres_2pl_neg"] = { "ette", "pres_conn" },
["pres_3pl_neg"] = { "eivät", "pres_conn" },
["pres_pasv_neg"] = { "ei", "pres_pasv_conn" },
["pres_perf_1sg"] = { "olen", "past_part" },
["pres_perf_2sg"] = { "olet", "past_part" },
["pres_perf_3sg"] = { "on", "past_part" },
["pres_perf_1pl"] = { "olemme", "past_part_pl" },
["pres_perf_2pl"] = { "olette", "past_part_pl" },
["pres_perf_3pl"] = { "ovat", "past_part_pl" },
["pres_perf_pasv"] = { "on", "past_pasv_part" },
["pres_perf_1sg_neg"] = { "en ole", "past_part" },
["pres_perf_2sg_neg"] = { "et ole", "past_part" },
["pres_perf_3sg_neg"] = { "ei ole", "past_part" },
["pres_perf_1pl_neg"] = { "emme ole", "past_part_pl" },
["pres_perf_2pl_neg"] = { "ette ole", "past_part_pl" },
["pres_perf_3pl_neg"] = { "eivät ole", "past_part_pl" },
["pres_perf_pasv_neg"] = { "ei ole", "past_pasv_part" },
-- Past
["past_1sg_neg"] = { "en", "past_part" },
["past_2sg_neg"] = { "et", "past_part" },
["past_3sg_neg"] = { "ei", "past_part" },
["past_1pl_neg"] = { "emme", "past_part_pl" },
["past_2pl_neg"] = { "ette", "past_part_pl" },
["past_3pl_neg"] = { "eivät", "past_part_pl" },
["past_pasv_neg"] = { "ei", "past_pasv_part" },
["past_perf_1sg"] = { "olin", "past_part" },
["past_perf_2sg"] = { "olit", "past_part" },
["past_perf_3sg"] = { "oli", "past_part" },
["past_perf_1pl"] = { "olimme", "past_part_pl" },
["past_perf_2pl"] = { "olitte", "past_part_pl" },
["past_perf_3pl"] = { "olivat", "past_part_pl" },
["past_perf_pasv"] = { "oli", "past_pasv_part" },
["past_perf_1sg_neg"] = { "en ollut", "past_part" },
["past_perf_2sg_neg"] = { "et ollut", "past_part" },
["past_perf_3sg_neg"] = { "ei ollut", "past_part" },
["past_perf_1pl_neg"] = { "emme olleet", "past_part_pl" },
["past_perf_2pl_neg"] = { "ette olleet", "past_part_pl" },
["past_perf_3pl_neg"] = { "eivät olleet", "past_part_pl" },
["past_perf_pasv_neg"] = { "ei ollut", "past_pasv_part" },
-- Conditional
["cond_1sg_neg"] = { "en", "cond_conn" },
["cond_2sg_neg"] = { "et", "cond_conn" },
["cond_3sg_neg"] = { "ei", "cond_conn" },
["cond_1pl_neg"] = { "emme", "cond_conn" },
["cond_2pl_neg"] = { "ette", "cond_conn" },
["cond_3pl_neg"] = { "eivät", "cond_conn" },
["cond_pasv_neg"] = { "ei", "cond_pasv_conn" },
["cond_perf_1sg"] = { "olisin", "past_part" },
["cond_perf_2sg"] = { "olisit", "past_part" },
["cond_perf_3sg"] = { "olisi", "past_part" },
["cond_perf_1pl"] = { "olisimme", "past_part_pl" },
["cond_perf_2pl"] = { "olisitte", "past_part_pl" },
["cond_perf_3pl"] = { "olisivat", "past_part_pl" },
["cond_perf_pasv"] = { "olisi", "past_pasv_part" },
["cond_perf_1sg_neg"] = { "en olisi", "past_part" },
["cond_perf_2sg_neg"] = { "et olisi", "past_part" },
["cond_perf_3sg_neg"] = { "ei olisi", "past_part" },
["cond_perf_1pl_neg"] = { "emme olisi", "past_part_pl" },
["cond_perf_2pl_neg"] = { "ette olisi", "past_part_pl" },
["cond_perf_3pl_neg"] = { "eivät olisi", "past_part_pl" },
["cond_perf_pasv_neg"] = { "ei olisi", "past_pasv_part" },
-- Imperative
["impr_2sg_neg"] = { "älä", "impr_2sg" },
["impr_3sg_neg"] = { "älköön", "impr_conn" },
["impr_1pl_neg"] = { "älkäämme", "impr_conn" },
["impr_2pl_neg"] = { "älkää", "impr_conn" },
["impr_3pl_neg"] = { "älkööt", "impr_conn" },
["impr_pasv_neg"] = { "älköön", "impr_pasv_conn" },
["impr_perf_3sg"] = { "olkoon", "past_part" },
["impr_perf_3pl"] = { "olkoot", "past_part_pl" },
["impr_perf_pasv"] = { "olkoon", "past_pasv_part" },
["impr_perf_3sg_neg"] = { "älköön olko", "past_part" },
["impr_perf_3pl_neg"] = { "älkööt olko", "past_part_pl" },
["impr_perf_pasv_neg"] = { "älköön olko", "past_pasv_part" },
-- Potential
["potn_1sg_neg"] = { "en", "potn_conn" },
["potn_2sg_neg"] = { "et", "potn_conn" },
["potn_3sg_neg"] = { "ei", "potn_conn" },
["potn_1pl_neg"] = { "emme", "potn_conn" },
["potn_2pl_neg"] = { "ette", "potn_conn" },
["potn_3pl_neg"] = { "eivät", "potn_conn" },
["potn_pasv_neg"] = { "ei", "potn_pasv_conn" },
["potn_perf_1sg"] = { "lienen", "past_part" },
["potn_perf_2sg"] = { "lienet", "past_part" },
["potn_perf_3sg"] = { "lienee", "past_part" },
["potn_perf_1pl"] = { "lienemme", "past_part_pl" },
["potn_perf_2pl"] = { "lienette", "past_part_pl" },
["potn_perf_3pl"] = { "lienevät", "past_part_pl" },
["potn_perf_pasv"] = { "lienee", "past_pasv_part" },
["potn_perf_1sg_neg"] = { "en liene", "past_part" },
["potn_perf_2sg_neg"] = { "et liene", "past_part" },
["potn_perf_3sg_neg"] = { "ei liene", "past_part" },
["potn_perf_1pl_neg"] = { "emme liene", "past_part_pl" },
["potn_perf_2pl_neg"] = { "ette liene", "past_part_pl" },
["potn_perf_3pl_neg"] = { "eivät liene", "past_part_pl" },
["potn_perf_pasv_neg"] = { "ei liene", "past_pasv_part" },
}
function postprocess(args, data)
local appendix = args["appendix"]; if appendix == "" then appendix = nil end
local qual = args["qual"]; if qual == "" then qual = nil end
local q4i = args["q4i"]; if q4i == "" then q4i = nil end
local extranotes = {}
-- Create the periphrastic forms (negative and perfect)
local function make_forms(aux, forms)
if not forms then
return nil
end
local ret = {}
for _, form in ipairs(forms) do
table.insert(ret, aux .. " [[" .. form .. "]]")
end
return ret
end
if qual then data.no_accel = true end
-- Present
for key, value in pairs(complex_forms) do
data.forms[key] = make_forms(value[1], data.forms[value[2]])
end
-- Add qualifier
for key, form in pairs(data.forms) do
-- Add qual
-- for participles, qual is before, while for others it is after
if q4i and key == "inf4" then
for i, subform in ipairs(form) do
subform = (q4i and q4i .. " " or "") .. subform
form[i] = subform
end
if form.rare then
for i, subform in ipairs(form.rare) do
subform = (q4i and q4i .. " " or "") .. subform
form.rare[i] = subform
end
end
elseif string.sub(key, -5) == "_part" then
for i, subform in ipairs(form) do
subform = (qual and qual .. " " or "") .. subform
form[i] = subform
end
if form.rare then
for i, subform in ipairs(form.rare) do
subform = (qual and qual .. " " or "") .. subform
form.rare[i] = subform
end
end
else
for i, subform in ipairs(form) do
subform = subform .. (qual and " " .. qual or "")
form[i] = subform
end
if form.rare then
for i, subform in ipairs(form.rare) do
subform = subform .. (qual and " " .. qual or "")
form.rare[i] = subform
end
end
end
data.forms[key] = form
end
data.is_appendix = appendix
if args.noagent then
data.forms["agnt_part"] = nil
end
if data.forms["inf1"][1] == data.forms["pres_3sg"][1] then
table.insert(extranotes, "* The third-person singular indicative form " .. tag_term(data.forms["inf1"][1]) .. " does not exhibit [[Appendix:Finnish pronunciation#Final gemination|final gemination]], <br/>unlike the first infinitive (the lemma form), even though they are spelled identically.")
end
if extranotes then
data.extranotes = extranotes
end
-- Check if the lemma form matches the page name
if not appendix and not (args["q1sg"] or args["q2sg"] or args["q1pl"] or args["q2pl"] or args["q3p"] or args["qpass"]) and (lang:makeEntryName(data.forms["inf1"][1])) ~= normalize_apostrophes(data.pagename, true) then
table.insert(data.categories, "Finnish entries with inflection not matching pagename")
end
end
local inf_to_accel = {
["1"] = nil,
["1_long"] = "long|first|inf",
["2_ine"] = "ine|of|second|actv|inf",
["2_pasv_ine"] = "ine|of|second|pasv|inf",
["2_ins"] = "ist|of|second|actv|inf",
["3_ine"] = "ine|of|third|actv|inf",
["3_ela"] = "ela|of|third|actv|inf",
["3_ill"] = "ill|of|third|actv|inf",
["3_ade"] = "ade|of|third|actv|inf",
["3_abe"] = "abe|of|third|actv|inf",
["3_ins"] = "ist|of|third|actv|inf",
["3_pasv_ins"] = "ist|of|third|pasv|inf",
["4"] = "vnoun",
["5"] = "fifth|inf"
}
local part_to_accel = {
["pres_part"] = "pres|actv|part",
["pres_pasv_part"] = "pres|pasv|part",
["past_part"] = "past|actv|part",
["past_pasv_part"] = "past|pasv|part",
["agnt_part"] = "agentpart",
["nega_part"] = "neg|part"
}
function convert_to_accel_inf(form)
return inf_to_accel[form:sub(4)]
end
function convert_to_accel_part(form)
return "participle-" .. part_to_accel[form]
end
function convert_to_accel(form, vh)
if mw.ustring.match(form, "_perf") then
-- all perf forms involve the past participle which we do not want
-- to create manually
return nil
elseif form == "inf4" then
return "vnoun-" .. vh
elseif mw.ustring.match(form, "^inf") then
return convert_to_accel_inf(form)
elseif mw.ustring.match(form, "_part$") then
return convert_to_accel_part(form)
end
-- imperative connegative is special
if form == "impr_2sg_neg" then
return "2|s|impr|conn"
elseif mw.ustring.match(form, "impr_%d%a%a_neg") then
return "3|or|p|impr|conn"
end
-- split to tense/mood, person, extra
local tmood, person, extra = unpack(mw.text.split(form, "_"))
local tense, mood = "", tmood
if tmood == "pres" or tmood == "past" then
tense, mood = tmood .. "|", "indc"
end
-- negative/connegative?
if extra == "neg" then
local result = tense
if person == "pasv" then
result = result .. "pasv"
else
-- not passive => active (no distinction between person here)
result = result .. "actv"
end
result = result .. "|" .. mood .. "|conn"
return result
end
-- convert person if not passive
person = person:gsub("(%d)(%a)%a", "%1|%2")
return person .. "|" .. tense .. mood
end
local poss_endings = {
["1s"] = "ni", ["2s"] = "si", ["1p"] = "mme", ["2p"] = "nne", ["3"] = "nsa"
}
local accel_prefixes = {
["1s"] = "1|s", ["2s"] = "2|s", ["1p"] = "1|p", ["2p"] = "2|p", ["3"] = "3"
}
-- Make the table
function make_table(data)
local vh = data.vh
local function show_form(form, accel_form)
if not form then
return "—"
elseif type(form) ~= "table" then
error("a non-table value was given in the list of inflected forms.")
end
local ret = {}
for key, subform in ipairs(form) do
if mw.ustring.find(subform, "¤") then subform = mw.ustring.gsub(subform, "¤", "") end
local accel = (accel_form and not data.no_accel) and accel_form or nil
table.insert(ret, make_link(subform, accel))
end
return table.concat(ret, "<br/>")
end
local function make_and_show_poss_table(form, vh, accel_suffix)
local short
if mw.ustring.find(form, "([aäe])¤") then
short = mw.ustring.gsub(form, "([aäe])¤", "%1%1n")
end
local function poss_repl(mode)
local ending = poss_endings[mode]
if ending:find("a") then ending = mw.ustring.gsub(ending, "a", vh) end
local forms = {(mw.ustring.gsub(form, "¤", ending))}
if mode == "3" and short then
table.insert(forms, 1, short)
end
local ret = {}
for key, subform in ipairs(forms) do
local accel = (accel_suffix and not data.no_accel) and accel_prefixes[mode] .. "|form|of|" .. accel_suffix or nil
table.insert(ret, make_link(subform, accel))
end
return table.concat(ret, "<br/>")
end
local poss_table_wikicode = [=[
{| class="inflection-table vsSwitcher fi-conj-poss" data-toggle-category="possessive inflection"
|- class="fi-conj-poss-header"
! class="vsToggleElement fi-conj-poss-toggle" colspan="3" | Possessive forms
|- class="vsHide"
! Person
! sing.
! plur.
|- class="vsHide"
! 1st
| {{{1s}}}
| {{{1p}}}
|- class="vsHide"
! 2nd
| {{{2s}}}
| {{{2p}}}
|- class="vsHide"
! 3rd
| colspan="2" | {{{3}}}
|}]=]
return mw.ustring.gsub(poss_table_wikicode, "{{{([a-z0-9_:]+)}}}", poss_repl)
end
local function repl(param)
if param == "lemma" then
return (data.is_appendix and make_link(data.pagename) or tag_term(data.pagename))
elseif param == "info" then
return data.title and " (" .. data.title .. ")" or ""
elseif param == "extranotes" then
if data.extranotes and #data.extranotes > 0 then
return "<br/>\n" .. table.concat(data.extranotes, "<br/>\n")
else
return ""
end
elseif param:find("^m_") then
return tag_term(param:sub(3))
elseif param:find("^poss_") then
local result = ""
local accel_suffix = convert_to_accel(param:sub(6), nil)
for _, subform in ipairs(data.forms[param:sub(6)]) do
result = result .. make_and_show_poss_table(subform, vh, accel_suffix) .. "\n"
end
return result
else
return show_form(data.forms[param], convert_to_accel(param, vh))
end
end
local wikicode = [=[
<div class="noresize">
{| class="inflection-table vsSwitcher fi-conj" data-toggle-category="conjugation"
|-
! class="vsToggleElement" colspan="7" | [[Appendix:Finnish verb forms|Inflection]] of {{{lemma}}}{{{info}}}
|- class="vsHide"
! colspan="7" | [[indicative mood]]
|- class="vsHide"
! colspan="4" | [[present tense]]
! colspan="3" | perfect
|- class="vsHide"
! class="fi-conj-header-person" colspan="2" | person
! class="fi-conj-header-posneg thsub" | positive
! class="fi-conj-header-posneg thsub" | negative
! class="fi-conj-header-person" | person
! class="fi-conj-header-posneg thsub" | positive
! class="fi-conj-header-posneg thsub" | negative
|- class="vsHide"
! colspan="2" | <span title="first-person singular">1st sing.</span>
| data-accel-col="1" | {{{pres_1sg}}}
| data-accel-col="2" | {{{pres_1sg_neg}}}
! <span title="first-person singular">1st sing.</span>
| data-accel-col="3" | {{{pres_perf_1sg}}}
| data-accel-col="4" | {{{pres_perf_1sg_neg}}}
|- class="vsHide"
! colspan="2" | <span title="second-person singular">2nd sing.</span>
| data-accel-col="1" | {{{pres_2sg}}}
| data-accel-col="2" | {{{pres_2sg_neg}}}
! <span title="second-person singular">2nd sing.</span>
| data-accel-col="3" | {{{pres_perf_2sg}}}
| data-accel-col="4" | {{{pres_perf_2sg_neg}}}
|- class="vsHide"
! colspan="2" | <span title="third-person singular">3rd sing.</span>
| data-accel-col="1" | {{{pres_3sg}}}
| data-accel-col="2" | {{{pres_3sg_neg}}}
! <span title="third-person singular">3rd sing.</span>
| data-accel-col="3" | {{{pres_perf_3sg}}}
| data-accel-col="4" | {{{pres_perf_3sg_neg}}}
|- class="vsHide"
! colspan="2" | <span title="first-person plural">1st plur.</span>
| data-accel-col="1" | {{{pres_1pl}}}
| data-accel-col="2" | {{{pres_1pl_neg}}}
! <span title="first-person plural">1st plur.</span>
| data-accel-col="3" | {{{pres_perf_1pl}}}
| data-accel-col="4" | {{{pres_perf_1pl_neg}}}
|- class="vsHide"
! colspan="2" | <span title="second-person plural">2nd plur.</span>
| data-accel-col="1" | {{{pres_2pl}}}
| data-accel-col="2" | {{{pres_2pl_neg}}}
! <span title="second-person plural">2nd plur.</span>
| data-accel-col="3" | {{{pres_perf_2pl}}}
| data-accel-col="4" | {{{pres_perf_2pl_neg}}}
|- class="vsHide"
! colspan="2" | <span title="third-person plural">3rd plur.</span>
| data-accel-col="1" | {{{pres_3pl}}}
| data-accel-col="2" | {{{pres_3pl_neg}}}
! <span title="third-person plural">3rd plur.</span>
| data-accel-col="3" | {{{pres_perf_3pl}}}
| data-accel-col="4" | {{{pres_perf_3pl_neg}}}
|- class="vsHide"
! colspan="2" | <span title="passive/impersonal">passive</span>
| data-accel-col="1" | {{{pres_pasv}}}
| data-accel-col="2" | {{{pres_pasv_neg}}}
! <span title="passive/impersonal">passive</span>
| data-accel-col="3" | {{{pres_perf_pasv}}}
| data-accel-col="4" | {{{pres_perf_pasv_neg}}}
|- class="vsHide"
! colspan="4" | [[past tense]]
! colspan="3" | pluperfect
|- class="vsHide"
! class="fi-conj-header-person" colspan="2" | person
! class="fi-conj-header-posneg thsub" | positive
! class="fi-conj-header-posneg thsub" | negative
! class="fi-conj-header-person" | person
! class="fi-conj-header-posneg thsub" | positive
! class="fi-conj-header-posneg thsub" | negative
|- class="vsHide"
! colspan="2" | <span title="first-person singular">1st sing.</span>
| data-accel-col="1" | {{{past_1sg}}}
| data-accel-col="2" | {{{past_1sg_neg}}}
! <span title="first-person singular">1st sing.</span>
| data-accel-col="3" | {{{past_perf_1sg}}}
| data-accel-col="4" | {{{past_perf_1sg_neg}}}
|- class="vsHide"
! colspan="2" | <span title="second-person singular">2nd sing.</span>
| data-accel-col="1" | {{{past_2sg}}}
| data-accel-col="2" | {{{past_2sg_neg}}}
! <span title="second-person singular">2nd sing.</span>
| data-accel-col="3" | {{{past_perf_2sg}}}
| data-accel-col="4" | {{{past_perf_2sg_neg}}}
|- class="vsHide"
! colspan="2" | <span title="third-person singular">3rd sing.</span>
| data-accel-col="1" | {{{past_3sg}}}
| data-accel-col="2" | {{{past_3sg_neg}}}
! <span title="third-person singular">3rd sing.</span>
| data-accel-col="3" | {{{past_perf_3sg}}}
| data-accel-col="4" | {{{past_perf_3sg_neg}}}
|- class="vsHide"
! colspan="2" | <span title="first-person plural">1st plur.</span>
| data-accel-col="1" | {{{past_1pl}}}
| data-accel-col="2" | {{{past_1pl_neg}}}
! <span title="first-person plural">1st plur.</span>
| data-accel-col="3" | {{{past_perf_1pl}}}
| data-accel-col="4" | {{{past_perf_1pl_neg}}}
|- class="vsHide"
! colspan="2" | <span title="second-person plural">2nd plur.</span>
| data-accel-col="1" | {{{past_2pl}}}
| data-accel-col="2" | {{{past_2pl_neg}}}
! <span title="second-person plural">2nd plur.</span>
| data-accel-col="3" | {{{past_perf_2pl}}}
| data-accel-col="4" | {{{past_perf_2pl_neg}}}
|- class="vsHide"
! colspan="2" | <span title="third-person plural">3rd plur.</span>
| data-accel-col="1" | {{{past_3pl}}}
| data-accel-col="2" | {{{past_3pl_neg}}}
! <span title="third-person plural">3rd plur.</span>
| data-accel-col="3" | {{{past_perf_3pl}}}
| data-accel-col="4" | {{{past_perf_3pl_neg}}}
|- class="vsHide"
! colspan="2" | <span title="passive/impersonal">passive</span>
| data-accel-col="1" | {{{past_pasv}}}
| data-accel-col="2" | {{{past_pasv_neg}}}
! <span title="passive/impersonal">passive</span>
| data-accel-col="3" | {{{past_perf_pasv}}}
| data-accel-col="4" | {{{past_perf_pasv_neg}}}
|- class="vsHide"
! colspan="7" | [[conditional mood]]
|- class="vsHide"
! colspan="4" | present
! colspan="3" | perfect
|- class="vsHide"
! class="fi-conj-header-person" colspan="2" | person
! class="fi-conj-header-posneg thsub" | positive
! class="fi-conj-header-posneg thsub" | negative
! class="fi-conj-header-person" | person
! class="fi-conj-header-posneg thsub" | positive
! class="fi-conj-header-posneg thsub" | negative
|- class="vsHide"
! colspan="2" | <span title="first-person singular">1st sing.</span>
| data-accel-col="1" | {{{cond_1sg}}}
| data-accel-col="2" | {{{cond_1sg_neg}}}
! <span title="first-person singular">1st sing.</span>
| data-accel-col="3" | {{{cond_perf_1sg}}}
| data-accel-col="4" | {{{cond_perf_1sg_neg}}}
|- class="vsHide"
! colspan="2" | <span title="second-person singular">2nd sing.</span>
| data-accel-col="1" | {{{cond_2sg}}}
| data-accel-col="2" | {{{cond_2sg_neg}}}
! <span title="second-person singular">2nd sing.</span>
| data-accel-col="3" | {{{cond_perf_2sg}}}
| data-accel-col="4" | {{{cond_perf_2sg_neg}}}
|- class="vsHide"
! colspan="2" | <span title="third-person singular">3rd sing.</span>
| data-accel-col="1" | {{{cond_3sg}}}
| data-accel-col="2" | {{{cond_3sg_neg}}}
! <span title="third-person singular">3rd sing.</span>
| data-accel-col="3" | {{{cond_perf_3sg}}}
| data-accel-col="4" | {{{cond_perf_3sg_neg}}}
|- class="vsHide"
! colspan="2" | <span title="first-person plural">1st plur.</span>
| data-accel-col="1" | {{{cond_1pl}}}
| data-accel-col="2" | {{{cond_1pl_neg}}}
! <span title="first-person plural">1st plur.</span>
| data-accel-col="3" | {{{cond_perf_1pl}}}
| data-accel-col="4" | {{{cond_perf_1pl_neg}}}
|- class="vsHide"
! colspan="2" | <span title="second-person plural">2nd plur.</span>
| data-accel-col="1" | {{{cond_2pl}}}
| data-accel-col="2" | {{{cond_2pl_neg}}}
! <span title="second-person plural">2nd plur.</span>
| data-accel-col="3" | {{{cond_perf_2pl}}}
| data-accel-col="4" | {{{cond_perf_2pl_neg}}}
|- class="vsHide"
! colspan="2" | <span title="third-person plural">3rd plur.</span>
| data-accel-col="1" | {{{cond_3pl}}}
| data-accel-col="2" | {{{cond_3pl_neg}}}
! <span title="third-person plural">3rd plur.</span>
| data-accel-col="3" | {{{cond_perf_3pl}}}
| data-accel-col="4" | {{{cond_perf_3pl_neg}}}
|- class="vsHide"
! colspan="2" | <span title="passive/impersonal">passive</span>
| data-accel-col="1" | {{{cond_pasv}}}
| data-accel-col="2" | {{{cond_pasv_neg}}}
! <span title="passive/impersonal">passive</span>
| data-accel-col="3" | {{{cond_perf_pasv}}}
| data-accel-col="4" | {{{cond_perf_pasv_neg}}}
|- class="vsHide"
! colspan="7" | [[imperative mood]]
|- class="vsHide"
! colspan="4" | present
! colspan="3" | perfect
|- class="vsHide"
! class="fi-conj-header-person" colspan="2" | person
! class="fi-conj-header-posneg thsub" | positive
! class="fi-conj-header-posneg thsub" | negative
! class="fi-conj-header-person" | person
! class="fi-conj-header-posneg thsub" | positive
! class="fi-conj-header-posneg thsub" | negative
|- class="vsHide"
! colspan="2" | <span title="first-person singular">1st sing.</span>
| —
| —
! <span title="first-person singular">1st sing.</span>
| —
| —
|- class="vsHide"
! colspan="2" | <span title="second-person singular">2nd sing.</span>
| data-accel-col="1" | {{{impr_2sg}}}
| data-accel-col="2" | {{{impr_2sg_neg}}}
! <span title="second-person singular">2nd sing.</span>
| data-accel-col="3" | —
| data-accel-col="4" | —
|- class="vsHide"
! colspan="2" | <span title="third-person singular">3rd sing.</span>
| data-accel-col="1" | {{{impr_3sg}}}
| data-accel-col="2" | {{{impr_3sg_neg}}}
! <span title="third-person singular">3rd sing.</span>
| data-accel-col="3" | {{{impr_perf_3sg}}}
| data-accel-col="4" | {{{impr_perf_3sg_neg}}}
|- class="vsHide"
! colspan="2" | <span title="first-person plural">1st plur.</span>
| data-accel-col="1" | {{{impr_1pl}}}
| data-accel-col="2" | {{{impr_1pl_neg}}}
! <span title="first-person plural">1st plur.</span>
| data-accel-col="3" | —
| data-accel-col="4" | —
|- class="vsHide"
! colspan="2" | <span title="second-person plural">2nd plur.</span>
| data-accel-col="1" | {{{impr_2pl}}}
| data-accel-col="2" | {{{impr_2pl_neg}}}
! <span title="second-person plural">2nd plur.</span>
| data-accel-col="3" | —
| data-accel-col="4" | —
|- class="vsHide"
! colspan="2" | <span title="third-person plural">3rd plur.</span>
| data-accel-col="1" | {{{impr_3pl}}}
| data-accel-col="2" | {{{impr_3pl_neg}}}
! <span title="third-person plural">3rd plur.</span>
| data-accel-col="3" | {{{impr_perf_3pl}}}
| data-accel-col="4" | {{{impr_perf_3pl_neg}}}
|- class="vsHide"
! colspan="2" | <span title="passive/impersonal">passive</span>
| data-accel-col="1" | {{{impr_pasv}}}
| data-accel-col="2" | {{{impr_pasv_neg}}}
! <span title="passive/impersonal">passive</span>
| data-accel-col="3" | {{{impr_perf_pasv}}}
| data-accel-col="4" | {{{impr_perf_pasv_neg}}}
|- class="vsHide"
! colspan="7" | [[potential mood]]
|- class="vsHide"
! colspan="4" | present
! colspan="3" | perfect
|- class="vsHide"
! class="fi-conj-header-person" colspan="2" | person
! class="fi-conj-header-posneg thsub" | positive
! class="fi-conj-header-posneg thsub" | negative
! class="fi-conj-header-person" | person
! class="fi-conj-header-posneg thsub" | positive
! class="fi-conj-header-posneg thsub" | negative
|- class="vsHide"
! colspan="2" | <span title="first-person singular">1st sing.</span>
| data-accel-col="1" | {{{potn_1sg}}}
| data-accel-col="2" | {{{potn_1sg_neg}}}
! <span title="first-person singular">1st sing.</span>
| data-accel-col="3" | {{{potn_perf_1sg}}}
| data-accel-col="4" | {{{potn_perf_1sg_neg}}}
|- class="vsHide"
! colspan="2" | <span title="second-person singular">2nd sing.</span>
| data-accel-col="1" | {{{potn_2sg}}}
| data-accel-col="2" | {{{potn_2sg_neg}}}
! <span title="second-person singular">2nd sing.</span>
| data-accel-col="3" | {{{potn_perf_2sg}}}
| data-accel-col="4" | {{{potn_perf_2sg_neg}}}
|- class="vsHide"
! colspan="2" | <span title="third-person singular">3rd sing.</span>
| data-accel-col="1" | {{{potn_3sg}}}
| data-accel-col="2" | {{{potn_3sg_neg}}}
! <span title="third-person singular">3rd sing.</span>
| data-accel-col="3" | {{{potn_perf_3sg}}}
| data-accel-col="4" | {{{potn_perf_3sg_neg}}}
|- class="vsHide"
! colspan="2" | <span title="first-person plural">1st plur.</span>
| data-accel-col="1" | {{{potn_1pl}}}
| data-accel-col="2" | {{{potn_1pl_neg}}}
! <span title="first-person plural">1st plur.</span>
| data-accel-col="3" | {{{potn_perf_1pl}}}
| data-accel-col="4" | {{{potn_perf_1pl_neg}}}
|- class="vsHide"
! colspan="2" | <span title="second-person plural">2nd plur.</span>
| data-accel-col="1" | {{{potn_2pl}}}
| data-accel-col="2" | {{{potn_2pl_neg}}}
! <span title="second-person plural">2nd plur.</span>
| data-accel-col="3" | {{{potn_perf_2pl}}}
| data-accel-col="4" | {{{potn_perf_2pl_neg}}}
|- class="vsHide"
! colspan="2" | <span title="third-person plural">3rd plur.</span>
| data-accel-col="1" | {{{potn_3pl}}}
| data-accel-col="2" | {{{potn_3pl_neg}}}
! <span title="third-person plural">3rd plur.</span>
| data-accel-col="3" | {{{potn_perf_3pl}}}
| data-accel-col="4" | {{{potn_perf_3pl_neg}}}
|- class="vsHide"
! colspan="2" | <span title="passive/impersonal">passive</span>
| data-accel-col="1" | {{{potn_pasv}}}
| data-accel-col="2" | {{{potn_pasv_neg}}}
! <span title="passive/impersonal">passive</span>
| data-accel-col="3" | {{{potn_perf_pasv}}}
| data-accel-col="4" | {{{potn_perf_pasv_neg}}}
|- class="vsHide"
! colspan="7" | Nominal forms
|- class="vsHide"
! colspan="4" | [[infinitive]]s
! colspan="3" | [[participle]]s
|- class="vsHide"
! colspan="2" |
! class="thsub" |active
! class="thsub" |passive
!
! class="thsub" | active
! class="thsub" |passive
|- class="vsHide"
! colspan="2" | 1st
| data-accel-col="1" colspan="2" | {{{inf1}}}
! present
| data-accel-col="1" | {{{pres_part}}}
| data-accel-col="1" | {{{pres_pasv_part}}}
|- class="vsHide"
! colspan="2" | long 1st<sup>1</sup>
| data-accel-col="1" colspan="2" |
{{{poss_inf1_long}}}
! past
| data-accel-col="1" | {{{past_part}}}
| data-accel-col="1" | {{{past_pasv_part}}}
|- class="vsHide"
! rowspan="3" | 2nd
! class="thsub" rowspan="2" | inessive<sup>2</sup>
| data-accel-col="1" | {{{inf2_ine}}}
| data-accel-col="1" | {{{inf2_pasv_ine}}}
! agent<sup>4</sup>
| data-accel-col="1" colspan="2" | {{{agnt_part}}}
|- class="vsHide"
| data-accel-col="1" colspan="2" |
{{{poss_inf2_ine}}}
! negative
| data-accel-col="1" colspan="2" | {{{nega_part}}}
|- class="vsHide"
! class="thsub" | instructive
| data-accel-col="1" | {{{inf2_ins}}}
| —
| colspan="3" rowspan="10" class="fi-conj-notes" | <div style="white-space:normal;min-width:100%;max-width:min-content;"><sup>1)</sup> Used only with a possessive suffix.<br/>
<sup>2)</sup> Usually with a possessive suffix (active only).<br/>
<sup>3)</sup> Some uses of the verbal noun are called the 'fourth infinitive' by certain sources ([[Appendix:Finnish verb forms#Fourth infinitive|more details]]).<br/>
<sup>4)</sup> Usually with a possessive suffix. May not be used with all verbs, especially intransitive ones ([[Appendix:Finnish participles#Agent participles|more details]]). Distinct from nouns with the {{{m_-ma}}} suffix and third infinitive forms.{{{extranotes}}}</div>
|- class="vsHide"
! rowspan="6" | 3rd
! class="thsub" | inessive
| data-accel-col="1" | {{{inf3_ine}}}
| —
|- class="vsHide"
! class="thsub" | elative
| data-accel-col="1" | {{{inf3_ela}}}
| —
|- class="vsHide"
! class="thsub" | illative
| data-accel-col="1" | {{{inf3_ill}}}
| —
|- class="vsHide thsub" |
! class="thsub" | adessive
| data-accel-col="1" | {{{inf3_ade}}}
| —
|- class="vsHide thsub" |
! class="thsub" | abessive
| data-accel-col="1" | {{{inf3_abe}}}
| —
|- class="vsHide thsub" |
! class="thsub" | instructive
| data-accel-col="1" | {{{inf3_ins}}}
| data-accel-col="1" | {{{inf3_pasv_ins}}}
|- class="vsHide thsub" |
! 4th<sup>3</sup>
! class="thsub" | verbal noun
| colspan="2" data-accel-col="1" | {{{inf4}}}
|- class="vsHide thsub" |
! colspan="2" | 5th<sup>1</sup>
| colspan="2" data-accel-col="1" |
{{{poss_inf5}}}
|}
</div>]=]
return mw.ustring.gsub(wikicode, "{{{([a-z0-9_-]+)}}}", repl)
end
return export