Moduuli:fi-taivutus

Taivutusmalline

muokkaa

{{#invoke:fi-taivutus|Taivutusmalline|sana|taivutustyyppi[|astevaihtelun tunnus]}}

Palauttaa annettua taivutustyyppiä vastaavan taivutustaulukkomallineen useimmille suomen substantiiveille, verbeille ja adjektiiveille.

Esimerkkejä

muokkaa
  • KOODI: {{#invoke:fi-taivutus|Adjektiivitaivutus|ovela|10|a}}
    TULOS: {{fi-a-taiv-koira|ovel|||a|a}}
  • KOODI: {{#invoke:fi-taivutus|Substantiivitaivutus|kaakki|5|A}}
    TULOS: {{fi-subs-risti|kaa|kk|k|a|i}}
  • KOODI: {{#invoke:fi-taivutus|Verbitaivutus|venähtää|53|F}}
    TULOS: {{fi-verbi-taiv-muistaa|venäh|t|d|ä|y|ö}}
  • KOODI: {{#invoke:fi-taivutus|Verbitaivutus|valmistama|10}}
    TULOS: {{fi-verbi-taiv-koira|valmistam|||a}}

local mt = require("Moduuli:Mallinetyokalut")

local tyypit = {
    [1]  = "valo",
    [2]  = "palvelu",
    [3]  = "valtio",
    [4]  = "laatikko",
    [5]  = "risti",
    [6]  = "paperi",
    [7]  = "ovi",
    [8]  = "nalle",
    [9]  = "kala",
    [10] = "koira",
    [11] = "omena",
    [12] = "kulkija",
    [13] = "katiska",
    [14] = "solakka",
    [15] = "korkea",
    [16] = "vanhempi",
    [17] = "vapaa",
    [18] = "maa",
    [19] = "suo",
    [20] = "filee",
    [21] = "rosé",
    [22] = "parfait",
    [23] = "tiili",
    [24] = "uni",
    [25] = "toimi",
    [26] = "pieni",
    [27] = "käsi",
    [28] = "kynsi",
    [29] = "lapsi",
    [30] = "veitsi",
    [31] = "kaksi",
    [32] = "sisar",
    [33] = "kytkin",
    [34] = "onneton",
    [35] = "lämmin",
    [36] = "sisin",
    [37] = "vasen",
    [38] = "nainen",
    [39] = "vastaus",
    [40] = "kalleus",
    [41] = "vieras",
    [42] = "mies",
    [43] = "ohut",
    [44] = "kevät",
    [45] = "kahdeksas",
    [46] = "tuhat",
    [47] = "kuollut",
    [48] = "hame",
    [49] = "askel",
    [50] = "isoäiti",
    [51] = "nuoripari",
}


local astevaihtelut = {
    { "", "",   "" },
    { "A", "kk", "k" },
    { "B", "pp", "p" },
    { "C", "tt", "t" },
    { "D", "k", "" },
    { "E", "p", "v" },
    { "F", "t", "d" },
    { "G", "nk", "ng" },
    { "H", "mp", "mm" },
    { "I", "lt", "ll" },
    { "J", "nt", "nn" },
    { "K", "rt", "rr" },
    { "L", "k", "j" },
    { "M", "k", "v" },
}

local m = {}

local function yksmon(params)
    if params and params.eiyks then
        return "|yks=-"
    end
    return nil
end


local function tee_mallineen_nimi(params)
    local mnimi

    if params.sanaluokka == "s" then
        mnimi =  "fi-subs-" .. params.esimsana
    elseif params.sanaluokka == "v" then
        mnimi = "fi-verbi-taiv-" .. params.esimsana
    elseif params.sanaluokka == "a" then
        mnimi = "fi-a-taiv-" .. params.esimsana
        if params.eikomp then
            mnimi = mnimi .. "-eikomp"
        end
    else
        error("Sanaluokka puuttuu")
    end

    return mnimi
end

local function tee_parametrit(lista, params)
    local mnimi = tee_mallineen_nimi(params)

    local list = { mnimi }

    for j,paraf in ipairs(lista) do
        table.insert(list, paraf(params))
    end
    if yksmon(params) then
        table.insert(list, yksmon(params))
    end
    return list
end



local function etsi_vika(mj, re)
    local pos = 0
    local pos2 = nil
    repeat
        pos2 = mw.ustring.find(mj, re, pos+1)
        if pos2 then
            pos = pos2
        end
    until pos2 == nil

    if pos ~= 0 then
        return mw.ustring.sub(mj, pos, pos)
    end
    return nil
end


local function alku(params)
    return params.alku
end


local function vokso_a(params)
    local ma = etsi_vika(params.sana, "[aouyöä]")
    if ma == "a" or ma == "o" or ma == "u" then
        return "a"
    end
    return "ä"
end

local function vokso_o(params)
    local ma = etsi_vika(params.sana, "[aouyöä]")
    if ma == "a" or ma == "o" or ma == "u" then
        return "o"
    end
    return "ö"
end

local function vokso_u(params)
    local ma = etsi_vika(params.sana, "[aouyöä]")
    if ma == "a" or ma == "o" or ma == "u" then
        return "u"
    end
    return "y"
end


local function tOn(params)
    return "t" .. vokso_o(params) .. "n"
end

local function vika(params)
    return mw.ustring.match(params.sana, ".$")
end

local function vika_vokaali(params)
    if mw.ustring.match(params.sana, "t$") then
	mw.ustring.gsub(params.sana, "t$", "")
    end
    return mw.ustring.sub(params.sana, #params.sana)
end

local function vika_i(params)
    if mw.ustring.match(params.sana, "i$") then
        return "i"
    else
        return ""
    end
end


local function av1(params)
    return params.av1
end

local function av2(params)
    return params.av2
end

local function av1_plus_(params, c)
    if params.av1 ~= "" then
        return params.av1 .. c
    end
    return c
end

local function av2_plus_(params, c)
    if params.av2 ~= "" then
        return params.av2 .. c
    end
    return c
end

local function av1_plus_e(params)
    return av1_plus_(params, "e")
end

local function av2_plus_e(params)
    return av2_plus_(params, "e")
end

local function av1_plus_vok(params)
    -- ensimmäinen vokaali astevaihtelukonsonanttien jälkeen
    local c =  mw.ustring.match(params.loppu, "^" .. params.av1 .. "([aäeioöuy])")
    return av1_plus_(params, c or "")
end

local function av2_plus_vok(params)
    local c =  mw.ustring.match(params.loppu, "^" .. params.av1 .. "([aäeioöuy])")
    return av2_plus_(params, c or "")
end

local function av1_loppu(params)
    return params.av1_loppu
end

local function av2_loppu(params)
    return params.av2_loppu
end

local function av2_muuttuva(params)
    -- rt rr -> r, tt->t??, d t -> d
    local j = math.min(mw.ustring.len(params.av1), mw.ustring.len(params.av2))
    for i = 0, j do
        if params.av1[i] ~= params.av2[i] then
            j = i
            break
        end
    end
    return mw.ustring.sub(params.av2, j, -1)
end

local function alku_muuttuva(params)
    -- rt rr -> r, tt t -> t, t d -> ""
    if (params.av1 == '' and params.av2 == '') or mw.ustring.sub(params.av1, 1, 1) ~= mw.ustring.sub(params.av2, 1, 1) then
        return params.alku
    elseif mw.ustring.sub(params.av1, 2, 2) ~= mw.ustring.sub(params.av2, 2, 2) then
        return params.alku .. mw.ustring.sub(params.av2, 0, 1)
    else
        error("Outo astevaihtelu: " .. params.av1 .. ", " .. params.av2)
    end
end

local function yht_alku(params)
    return params.yht_alku
end

local function Xn(params)
    local c =  mw.ustring.match(params.loppu, "([aäui])n$")
    if not c then
        return mw.ustring.match(params.loppu, "([aäui])met$")
    end
    return c
end

local function i2e(params)
    local c =  mw.ustring.match(params.loppu, "([aäui])n$")
    if not c then
        return mw.ustring.match(params.loppu, "([aäui])met$")
    end

    if c == "i" then
	return "e"
    elseif c == "a" or c == "ä" then
	return c
    end
    error("Odottamaton merkki: " .. c)
end

local function xa_paate(params)
    return  mw.ustring.match(params.loppu, "([oöuy])[aä]$")
end



local function Xsi(params)
    return mw.ustring.match(params.alku, ".*([lnr])")  -- kynsi -> kyn -> n
end

local function Xs(params)
    return mw.ustring.match(params.loppu, "([aeiouyäö])[st]")
end



-- PARAMETRINMUODOSTUSFUNKTIOT
local function al(param)
    return tee_parametrit({ alku }, param)
end

local function alm_avm(param)
    return tee_parametrit({ alku_muuttuva, av2_muuttuva, vika}, param)
end

local function al_av1(param)
    return tee_parametrit({ alku, av1 }, param)
end

local function al_av_av(param)
    return tee_parametrit({ alku, av1, av2 }, param)
end

local function al_av_av_vi_aa(param)
    return tee_parametrit({ alku, av1, av2, vika, vokso_a }, param)
end



local function al_vi(param)
    return tee_parametrit({ alku, vika }, param)
end

local function al_vi_aa(param)
    return tee_parametrit({ alku, vika, vokso_a }, param)
end

local function al_av_av_aa_iv(param)
    return tee_parametrit({ alku, av1, av2, vokso_a, vika_i }, param)
end

local function al_av_av_aa_vi(param)
    return tee_parametrit({ alku, av1, av2, vokso_a, vika }, param)
end

local function al_aa(param)
    return tee_parametrit({ alku, vokso_a }, param)
end

local function alku_x_x_aa(param)
    return { tee_mallineen_nimi(param), param.alku, '', '', vokso_a(param) }

end


local function al_aa_iv2(param)
    if param.loppu == 'i' then
        return { tee_mallineen_nimi(param), param.alku, vokso_a(param) }
    else
        return { tee_mallineen_nimi(param), param.alku, vokso_a(param), '' }
    end
end

local function al_av_av_aa(param)
    return tee_parametrit({ alku, av1, av2, vokso_a }, param)
end

local function al_aa_oo(param)
    return tee_parametrit({ alku, vokso_a, vokso_o }, param)
end

local function al_av_av_aa_oo(param)
    return tee_parametrit({ alku, av1, av2, vokso_a, vokso_o }, param)
end

local function al_aa_uu_oo(param)
    return tee_parametrit({ alku, vokso_a, vokso_u, vokso_o }, param)
end

local function al_aa_uu_oo_vv(param)
    return tee_parametrit({ alku, vokso_a, vokso_u, vokso_o, av1_plus_vok }, param)
end

local function al_av_av_aa_uu_oo(param)
    return tee_parametrit({ alku, av1, av2, vokso_a, vokso_u, vokso_o }, param)
end

-- xa = -oa, ua -pääteiden toka vika vok
local function al_av_av_aa_uu_oo_xa(param)
    return tee_parametrit({ alku, av1, av2, vokso_a, vokso_u, vokso_o, xa_paate }, param)
end

local function alm_avm_aa_uu_oo(param)
    return tee_parametrit({ alku_muuttuva, av2_muuttuva, vokso_a, vokso_u, vokso_o }, param)
end

local function not_implemented(param)
    return tee_parametrit({ param.sana }, param)
end

-- <st><s>syöjätär</s><t><tn>32</tn><av>C</av></t></st>
-- <st><s>sävel</s><t><tn>32</tn></t></st>
-- <st><s>taimen</s><t><tn>32</tn></t></st>
local function sisar_f(param)
    if param.avtunnus == "" then
        param.yht_alku = param.sana
        param.av1_loppu = ""
        param.av2_loppu = ""
    else
        local pos = mw.ustring.find(param.sana, param.av1 .. "[aäe][rln]$")
        param.yht_alku = mw.ustring.sub(param.sana, 1, pos-1)           -- esim. tatar -> ta
        param.av1_loppu = mw.ustring.sub(param.sana, pos)               -- esim. tatar -> tar
        param.av2_loppu = param.av2 .. mw.ustring.sub(param.sana, -2)   -- esim. tatar -> ttar
    end
    return tee_parametrit({ yht_alku, av1_loppu, av2_loppu, vokso_a }, param)
end

local function al_av_av_aa_xn(param)
    return tee_parametrit({ alku, av1, av2, vokso_a, Xn }, param)
end

local function al_av_av_xn_i2e_na(param)
    return tee_parametrit({ alku, av1, av2, Xn, i2e, a = vokso_a }, param)
end

local function al_av_av_xs_aa(param)
    return tee_parametrit({ alku, av1, av2, Xs, vokso_a }, param)
end

local function al_oo_aa(param)
    if param.avtunnus == "" then
        return { tee_mallineen_nimi(param), param.alku, vokso_o(param), vokso_a(param), '' }
    else
        return { tee_mallineen_nimi(param), param.alku, vokso_o(param), vokso_a(param) }
    end
end

local function al_tOn(param)
    return tee_parametrit({ alku, tOn }, param)
end


local function al_uu_aa(param)
    return tee_parametrit({ alku, vokso_u, vokso_a }, param)
end

local function al_xsi_aa(param)
    local alku = mw.ustring.match(param.sana, "(.-[lnr])si$")
    return { tee_mallineen_nimi(param), alku, vokso_a(param) }
end

local function suo(param)
    local kons, vok1, vok2 = mw.ustring.match(param.sana, "([bcdfghjklmnpqrstvwxz]?)([uyi])([eoö])$")
    return { tee_mallineen_nimi(param), kons, vok1, vok2, vokso_a(param) }
end

local function filee(param)
    return { tee_mallineen_nimi(param), param.alku, mw.ustring.sub(param.loppu, 1, 1), vokso_a(param) }
end

local function lammin(param)
    if param.avtunnus == "" then
        param.yht_alku = param.sana
        param.av1_loppu = ""
        param.av2_loppu = ""
    else
        local pos = mw.ustring.find(param.sana, param.av1 .. "in$")
        param.yht_alku = mw.ustring.sub(param.sana, 1, pos-1)           -- esim. lämmin -> lä
        param.av1_loppu = mw.ustring.sub(param.sana, pos, param.sana:len() - 2)               -- esim. lämmin -> mmi
        param.av2_loppu = param.av2 .. mw.ustring.sub(param.sana, -2, param.sana:len() - 2)   -- esim. lämmin -> mpi
    end
    return tee_parametrit({ yht_alku, av1_loppu, av2_loppu, vokso_a }, param)
end

local function mies(param)
    param.esimsana = "vastaus"
    return { tee_mallineen_nimi(param), param.alku, vokso_a(param), 'h' }
end

local function ohut(param)
    local vok = mw.ustring.match(param.loppu, "([uy])t$")
    return { tee_mallineen_nimi(param), param.alku, param.av1, param.av2, vok, vokso_a(param) }
end

local function ohut_adj(param)
    local vok = mw.ustring.match(param.loppu, "([uy])t$")
    return { tee_mallineen_nimi(param), param.alku, vok, vokso_a(param) }
end

local function avoin_adj(param)
    local vok = mw.ustring.match(param.loppu, "([i])n$")
    return { tee_mallineen_nimi(param), param.alku, '', '', vok, 'e', vokso_a(param) }
end




local function al_av_av_vok_aa_uu_oo(param)
    local itaie =  function () return mw.ustring.match(param.sana, "([aeiouyäö])t[aä]$") end
    return tee_parametrit({ alku, av1, av2, itaie, vokso_a, vokso_u, vokso_o }, param)
end


-- udar 49 F
-- utare 49
-- vemmel 49 H
-- vempele 49
-- tantereet 49 J
local function askel_f(param)
    local apos = 0
    local bpos = 0
    local lisa = nil
    if true then
        -- poistetaan mahdollinen loppu-e
        apos = mw.ustring.find(param.sana, param.av1 .. "[aäe][lrn]e?$")
        local loppu = mw.ustring.match(param.sana, "([aäe][lrn])e?$")
        if apos == nil then
            apos = mw.ustring.find(param.sana, param.av2 .. "[aäe][lrn]eet$")
            loppu = mw.ustring.match(param.sana, "([aäe][lrn])eet$")
        end

        param.yht_alku = mw.ustring.sub(param.sana, 1, apos-1)              -- esim. kannel -> ka
        param.av1_loppu = param.av1 .. loppu  -- esim. kannel -> nnel
        param.av2_loppu = param.av2 ..loppu  -- esim. kannel -> ntel

        -- jos astevaihtelua ei ole yhdistetään pääte ekaan parametriin
        if param.av1_loppu == param.av2_loppu then
            param.yht_alku = param.yht_alku .. param.av1_loppu
            param.av1_loppu = ""
            param.av2_loppu = ""
        end
    end

    return tee_parametrit({ yht_alku, av1_loppu, av2_loppu, vokso_a }, param)
end

local function al_ave_ave_aa_uu_oo(param)
    local xxa =  function () return mw.ustring.match(param.sana, "([lrn])%1[aä]$") end
    return tee_parametrit({ alku, av1_plus_e, av2_plus_e, vokso_a, vokso_u, vokso_o }, param)
end


local function al_ave_ave_aa_uu_oo_xxa(param)
    local xxa =  function () return mw.ustring.match(param.sana, "([lrn])%1[aä]$") end
    return tee_parametrit({ alku, av1_plus_vok, av2_plus_vok, vokso_a, vokso_u, vokso_o, xxa }, param)
end

local function al_ava_ava_aa_uu_oo(param)
    local xxa =  function () return mw.ustring.match(param.sana, "([lrn])%1[aä]$") end
    return tee_parametrit({ alku, av1_plus_o, av2_plus_o, vokso_a, vokso_u, vokso_o, xxa }, param)
end

local function al_avv_avv_aa_uu_oo(param)
    local xxa =  function () return mw.ustring.match(param.sana, "([lrn])%1[eaä]$") end
    return tee_parametrit({ alku, av1_plus_vok, av2_plus_vok, vokso_a, vokso_u, vokso_o, xxa }, param)
end


local function tuntea(param)
    param.esimsana = "laskea"
    return { tee_mallineen_nimi(param), param.alku, param.av1, param.av2, vokso_a(param), vokso_u(param), vokso_o(param), 's', 's', param.taivtunnus }
end

local function lahtea(param)
    param.esimsana = "laskea"
    return { tee_mallineen_nimi(param), param.alku, param.av1, param.av2, vokso_a(param), vokso_u(param), vokso_o(param), 'd', 't', param.taivtunnus }
end

local function saada(param)
    local kons, vok1, vok2, vokp = mw.ustring.match(param.sana, "^(.-)([aeiouyäö])([aeiouyäö])d([aä])$")
    local alku = kons .. vok1
    local loppu = vok2 .. 'd' .. vokp
    local prees = alku .. vok2
    local perft

    if (vok1 == 'a' and vok2 == 'u') or (vok1 == 'ä' and vok2 == 'y') then
        perft = kons .. vok1 .. 'vi'
    else
        perft = kons .. vok2 .. 'i'
    end

    param.esimsana = "saada"
    local x = "fi-verbi-taiv-saada|sa|ada|saa|saa|saa||sai|sai|a|u|o|63"
    return { tee_mallineen_nimi(param), alku, loppu, prees, prees, prees, '', perft, perft, vokso_a(param), vokso_u(param), vokso_o(param), param.taivtunnus }
end

local function juosta(param)
    local vartalo = mw.ustring.match(param.sana, "^(.-)st[aä]$")
    param.esimsana = "rohkaista"
    return { tee_mallineen_nimi(param), vartalo .. 'k', vokso_a(param), vokso_u(param), vokso_o(param), vartalo, param.taivtunnus }
end

local function nahda(param)
    local alku, loppu = mw.ustring.match(param.sana, "^(.-)(hd[aä])$")
    return { tee_mallineen_nimi(param), alku, loppu, alku .. 'h', alku .. 'e', alku .. 'ke', 'e', alku .. 'i', alku .. 'ki',
             vokso_a(param), vokso_u(param), vokso_o(param), param.taivtunnus }
end



local alkudata = {
    -- sl, tt, av,  loppu,      vika,     malne,     1.p,  2.p,  3.p, 4.p
    { "s", 1, '{AVt}', '{AV1}[ouyö]', '{AV1}', '{AV2}', 'valo', false, al_av_av_vi_aa },
    { "s", 1, '{AVt}', '{AV1}[ouyö]t', '{AV1}', '{AV2}', 'valo', true, al_av_av_vi_aa },

    -- aito ai,t,d,o
    { "a", 1, '{AVt}', '{AV1}[ouyö]', '{AV1}', '{AV2}', 'valo', false, al_av_av_vi_aa },

    -- aidattu
    { "v", 1, '{AVt}', '{AV1}[ouyö]', '{AV1}', '{AV2}', 'valo', false, al_av_av_vi_aa },
    { "v", 1, '{AVt}', '{AV1}[ouyö]t', '{AV1}', '{AV2}', 'valo', true, al_av_av_vi_aa },

    { "s", 2, '', '[uyoö]', '', '', 'palvelu', false, al_vi_aa },
    { "s", 2, '', '[uyoö]t', '', '', 'palvelu', true, al_vi_aa },

    -- hontelo -> hontel|o|a
    { "a", 2, '', '[uyoö]', '', '', 'palvelu', false, al_vi_aa },

    { "s", 3, '', '[oöe]', '', '', 'valtio', false, al_vi_aa },
    { "s", 3, '', '[oöe]t', '', '', 'valtio', true, al_vi_aa },

    { "a", 3, '', '[oöe]', '', '', 'valtio', false, al_vi_aa },

    { "s", 4, '{AVt}', '{AV1}[oö]', '{AV1}', '{AV2}', 'laatikko', false, al_vi_aa },
    { "s", 4, '{AVt}', '{AV2}[oö]t', '{AV1}', '{AV2}', 'laatikko', true, al_vi_aa },

    -- ummikko
    { "a", 4, '{AVt}', '{AV1}[oö]', '{AV1}', '{AV2}', 'laatikko', false, al_vi_aa },

    { "s", 5, '{AVt}', '{AV1}i?', '{AV1}', '{AV2}', 'risti', false, al_av_av_aa_iv },
    { "s", 5, '{AVt}', '{AV2}it', '{AV1}', '{AV2}', 'risti', true, al_av_av_aa_iv },

    -- rehti -> reh|t|d|ä|i
    -- cool -> cool|||a|
    { "a", 5, '{AVt}', '{AV1}i?', '{AV1}', '{AV2}', 'risti', false, al_av_av_aa_iv },

    { "s", 6, '', 'i?', '', '', 'paperi', false, al_aa_iv2 },
    { "s", 6, '', 'it', '', '', 'paperi', true, al_aa_iv2 },

    -- intiimi -> intiim|ä
    { "a", 6, '', 'i?', '', '', 'paperi', false, al_aa_iv2 },

    { "s", 7, '{AVt}', '{AV1}i', '{AV1}', '{AV2}', 'ovi', false, al_av_av_aa },
    { "s", 7, '{AVt}', '{AV2}et', '{AV1}', '{AV2}', 'ovi', true, al_av_av_aa },

    -- kolme -> kolm
    { "a", 7, '{AVt}', '{AV1}[ei]', '{AV1}', '{AV2}', 'ovi', false, al_av_av_aa },

    { "s", 8, '{AVt}', '{AV1}e', '{AV1}', '{AV2}', 'nalle', false, al_av_av_aa },
    { "s", 8, '{AVt}', '{AV2}et', '{AV1}', '{AV2}', 'nalle', true, al_av_av_aa },

    { "s", 9, '{AVt}', '{AV1}[aä]', '{AV1}', '{AV2}', 'kala', false, al_av_av_aa_oo },
    { "s", 9, '{AVt}', '{AV2}[aä]t', '{AV1}', '{AV2}', 'kala', true, al_av_av_aa_oo },

    -- tarkka
    { "a", 9, '{AVt}', '{AV1}[aä]', '{AV1}', '{AV2}', 'kala', false, al_av_av_aa_oo },

    { "s", 10, '{AVt}', '{AV1}[aä]n?', '{AV1}', '{AV2}', 'koira', false, al_av_av_aa },
    { "s", 10, '{AVt}', '{AV2}[aä]t', '{AV1}', '{AV2}', 'koira', true, al_av_av_aa },

    -- jyrkkä
    { "a", 10, '{AVt}e', '{AV1}[aä]', '{AV1}', '{AV2}', 'koira', false, al_av_av_aa },
    -- vakava
    { "a", 10, 'a', '[aä]', '', '', 'koira', false, al_av_av_aa_vi },

    -- valmistama
    { "v", 10, '{AVt}', '{AV1}[aä]n?', '{AV1}', '{AV2}', 'koira', false, al_av_av_aa },
    { "v", 10, '{AVt}', '{AV2}[aä]t', '{AV1}', '{AV2}', 'koira', true, al_av_av_aa },

    { "s", 11, '', '[aä]', '', '', 'omena', false, al_aa_oo },
    { "s", 11, '', '[aä]t', '', '', 'omena', true, al_aa_oo },

    -- vanttera
    { "a", 11, '', '[aä]', '', '', 'omena', false, al_aa_oo },

    { "s", 12, '', '[aä]', '', '', 'kulkija', false, al_aa_oo },
    { "s", 12, '', '[aä]t', '', '', 'kulkija', true, al_aa_oo },

    { "s", 13, '', '[aä]', '', '', 'katiska', false, al_aa_oo },
    { "s", 13, '', '[aä]t', '', '', 'katiska', true, al_aa_oo },

    { "s", 14, '{AVt}', '{AV1}[aä]', '{AV1}', '{AV2}', 'solakka', false, al_av_av_aa_oo },
    { "s", 14, '{AVt}', '{AV2}[aä]t', '{AV1}', '{AV2}', 'solakka', true, al_av_av_aa_oo },

    -- solakka -> sola|kk|k|a|o
    { "a", 14, '{AVt}', '{AV1}[aä]', '{AV1}', '{AV2}', 'solakka', false, al_av_av_aa_oo },

    { "s", 15, '', '[aä]', '', '', 'korkea', false, al_aa },
    { "s", 15, '', '[aä]t', '', '', 'korkea', true, al_aa },

    -- käheä
    { "a", 15, '', '[aä]', '', '', 'korkea', false, al_aa },

    { "s", 16, 'H', 'mpi', '', '', 'vanhempi', false, al_aa },
    { "s", 16, 'H', 'mm[aä]t', '', '', 'vanhempi', true, al_aa },

    { "a", 16, 'H', 'mpi', '', '', 'vanhempi', false, al_aa },

    { "s", 17, '', 'aa', '', '', 'vapaa', false, al_vi_aa },
    { "s", 17, '', 'ee', '', '', 'vapaa', false, al_vi_aa },
    { "s", 17, '', 'ii', '', '', 'vapaa', false, al_vi_aa },
    { "s", 17, '', 'oo', '', '', 'vapaa', false, al_vi_aa },
    { "s", 17, '', 'uu', '', '', 'vapaa', false, al_vi_aa },
    { "s", 17, '', 'yy', '', '', 'vapaa', false, al_vi_aa },
    { "s", 17, '', 'ää', '', '', 'vapaa', false, al_vi_aa },
    { "s", 17, '', 'öö', '', '', 'vapaa', false, al_vi_aa },
    { "s", 17, '', 'aat', '', '', 'vapaa', true, al_vi_aa },
    { "s", 17, '', 'eet', '', '', 'vapaa', true, al_vi_aa },
    { "s", 17, '', 'iit', '', '', 'vapaa', true, al_vi_aa },
    { "s", 17, '', 'oot', '', '', 'vapaa', true, al_vi_aa },
    { "s", 17, '', 'uut', '', '', 'vapaa', true, al_vi_aa },
    { "s", 17, '', 'yyt', '', '', 'vapaa', true, al_vi_aa },
    { "s", 17, '', 'äät', '', '', 'vapaa', true, al_vi_aa },
    { "s", 17, '', 'ööt', '', '', 'vapaa', true, al_vi_aa },

    { "a", 17, '', 'aa', '', '', 'vapaa', false, al_vi_aa },

    -- vapaa -> vap|a
    { "a", 17, '', '[aeiouyäö]', '', '', 'vapaa', false, al_vi_aa },

    { "s", 18, '', '[aeiouyäö]', '', '', 'maa', false, al_vi_aa },
    { "s", 18, '', '[aeiouyäö]t', '', '', 'maa', true, al_vi_aa },

    { "s", 19, '', '[aeiouyäö][aeiouyäö]', '', '', 'suo', false, suo },
    { "s", 19, '', '[aeiouyäö][aeiouyäö]t', '', '', 'suo', true, not_implemented },

    { "s", 20, '', 'aa', '', '', 'filee', false, filee },
    { "s", 20, '', 'ee', '', '', 'filee', false, filee },
    { "s", 20, '', 'ii', '', '', 'filee', false, filee },
    { "s", 20, '', 'oo', '', '', 'filee', false, filee },
    { "s", 20, '', 'uu', '', '', 'filee', false, filee },
    { "s", 20, '', 'yy', '', '', 'filee', false, filee },
    { "s", 20, '', 'ää', '', '', 'filee', false, filee },
    { "s", 20, '', 'öö', '', '', 'filee', false, filee },
    { "s", 20, '', '[aeiouyäö][aeiouyäö]t', '', '', 'filee', true, not_implemented },

    { "s", 21, '', '[éuieayo]+', '', '', 'rosé', false, not_implemented },
    { "s", 21, '', '[éuieayo]+\\\'t', '', '', 'rosé', true, not_implemented },

    { "s", 22, '', '', '', '', 'parfait', false, not_implemented },
    { "s", 22, '', '\\\'t', '', '', 'parfait', true, not_implemented },

    { "s", 23, '', 'i', '', '', 'tiili', false, al_aa },
    { "s", 23, '', 'et', '', '', 'tiili', true, al_aa },

    { "s", 24, '', 'i', '', '', 'uni', false, al_aa },
    { "s", 24, '', 'et', '', '', 'uni', true, al_aa },


    { "s", 25, '', 'mi', '', '', 'toimi', false, al_aa },
    { "s", 25, '', 'met', '', '', 'toimi', true, al_aa },


    { "s", 26, '', 'i', '', '', 'pieni', false, al_aa },
    { "s", 26, '', 'et', '', '', 'pieni', true, al_aa },

    -- pieni -> pien|ä
    { "a", 26, '', 'i', '', '', 'pieni', false, al_aa },


    { "s", 27, '', 'si', '', '', 'käsi', false, al_aa },
    { "s", 27, '', 'det', '', '', 'käsi', true, al_aa },

    -- uusi
    { "a", 27, '', 'si', '', '', 'käsi', false, al_aa },

    { "s", 28, '{AVt}', 'lsi', '{AV1}', '{AV2}', 'kynsi', false, al_xsi_aa },
    { "s", 28, '{AVt}', 'nsi', '{AV1}', '{AV2}', 'kynsi', false, al_xsi_aa },
    { "s", 28, '{AVt}', 'rsi', '{AV1}', '{AV2}', 'kynsi', false, al_xsi_aa },
    { "s", 28, '{AVt}', 'llet', '{AV1}', '{AV2}', 'kynsi', false, al_xsi_aa },
    { "s", 28, '{AVt}', 'nnet', '{AV1}', '{AV2}', 'kynsi', true, al_xsi_aa },
    { "s", 28, '{AVt}', 'rret', '{AV1}', '{AV2}', 'kynsi', true, al_xsi_aa },

    { "s", 29, '', 'psi', '', '', 'lapsi', false, al_aa },
    { "s", 29, '', 'ksi', '', '', 'lapsi', false, al_aa },
    { "s", 29, '', 'psen', '', '', 'lapsi', true, al_aa },
    { "s", 29, '', 'ksen', '', '', 'lapsi', true, al_aa },

    { "s", 30, '', 'tsi', '', '', 'veitsi', false, al_aa },
    { "s", 30, '', 'tset', '', '', 'veitsi', true, al_aa },

    { "s", 31, '', 'ksi', '', '', 'kaksi', false, al_aa },
    { "s", 31, '', 'hdet', '', '', 'kaksi', true, al_aa },


    { "s", 32, '{AVt}', '{AV1}[aäe][lnr]', '{AV1}', '{AV2}', 'sisar', false, sisar_f },
    { "s", 32, '{AVt}', '{AV2}[aäe][lnr]et.', '{AV1}', '{AV2}', 'sisar', true, sisar_f },

    -- kymmen -> kymmen|||ä
    { "a", 32, '{AVt}', '{AV1}[aäe][lnr]', '{AV1}', '{AV2}', 'sisar', false, sisar_f },
    { "a", 32, '{AVt}', '{AV2}[aäe][lnr]et.', '{AV1}', '{AV2}', 'sisar', true, sisar_f },

    { "s", 33, '{AVt}', '{AV1}[aeiouyäö]n', '{AV1}', '{AV2}', 'kytkin', false, al_av_av_aa_xn },
    { "s", 33, '{AVt}', '[aeiouyäö][aeiouyäö]n', '{AV1}', '{AV2}', 'kytkin', false, al_av_av_aa_xn },
    { "s", 33, '{AVt}', '{AV2}[aeiouyäö][aeiouyäö]met', '{AV1}', '{AV2}', 'kytkin', true, al_av_av_aa_xn },

    -- avoin -> avo|||i|e
    { "s", 33, '{AVt}', '[aeiouyäö][aeiouyäö]n', '{AV1}', '{AV2}', 'kytkin', false, al_av_av_aa_xn },
    { "a", 33, '', 'in', '', '', 'kytkin', true, avoin_adj },

    { "s", 34, '', 't[oö]n', '', '', 'onneton', false, al_oo_aa },
    { "s", 34, '', 'tt[oö]mat', '', '', 'onneton', true, al_oo_aa },
    { "s", 34, 'C', 't[oö]n', '', '', 'onneton', false, al_oo_aa },
    { "s", 34, 'C', 'tt[oö]mat', '', '', 'onneton', true, al_oo_aa },

    -- päätön -> pää|tön
    -- Huom. alaston ei toimi mallineessa
    { "a", 34, 'C', 't[oö]n', '', '', 'onneton', false, al_tOn },

    { "v", 34, 'C', 't[oö]n', '', '', 'onneton', false, al_oo_aa },

    { "s", 35, 'H', 'mmin', 'mm', 'mp', 'lämmin', false, lammin },
    { "s", 35, 'H', 'pim[aä]t', '', '', 'lämmin', true, not_implemented },

    { "s", 36, '', 'in', '', '', 'sisin', false, al_aa },
    { "s", 36, '', 'imm[aä]t', '', '', 'sisin', true, al_aa },

    { "a", 36, '', 'in', '', '', 'sisin', false, al_aa },

    { "s", 37, '', 'n', '', '', 'vasen', false, al_aa },
    { "s", 37, '', 'mm[aä]t', '', '', 'vasen', true, not_implemented },

    { "s", 38, '', 'nen', '', '', 'nainen', false, al_aa },
    { "s", 38, '', 'set', '', '', 'nainen', true, al_aa },

    { "a", 38, '', 'nen', '', '', 'nainen', false, al_aa },

    { "s", 39, '', 's', '', '', 'vastaus', false, al_aa },
    { "s", 39, '', 'kset', '', '', 'vastaus', true, al_aa },

    { "s", 40, '', 's', '', '', 'kalleus', false, al_aa },
    { "s", 40, '', 'det', '', '', 'kalleus', true, al_aa },

    { "s", 41, '{AVt}', '{AV1}[aeiouyäö]s', '{AV1}', '{AV2}', 'vieras', false, al_av_av_xs_aa },
    { "s", 41, '{AVt}', '{AV2}[aeiouyäö][aeiouyäö]t', '{AV1}', '{AV2}', 'vieras', true, al_av_av_xs_aa },

    -- äänekäs -> ääne|k|kk|ä|ä
    { "a", 41, '{AVt}', '{AV1}[aeiouyäö]s', '{AV1}', '{AV2}', 'vieras', false, al_av_av_xs_aa },

    { "s", 42, '', 's', '', '', 'mies', false, mies },   -- ei mallinetta!!
    { "s", 42, '', 'het', '', '', 'mies', true, not_implemented },

    { "a", 43, '', '[uy]t', '', '', 'ohut', false, ohut_adj },
    { "s", 43, '{AVt}', '{AV1}[uy]t', '{AV1}', '{AV2}', 'ohut', false, ohut },
    { "s", 43, '{AVt}', 'et', '{AV1}', '{AV2}', 'ohut', true, not_implemented },

    { "s", 44, '{AVt}', '{AV1}[aäe]t', '{AV1}', '{AV2}', 'kevät', false, al_av_av_xs_aa },
    { "s", 44, '', '[aä]t', '', '', 'kevät', true, not_implemented },

    { "s", 45, '', 's', '', '', 'kahdeksas', false, al_aa },
    { "s", 45, '', 'nnet', '', '', 'kahdeksas', true, al_aa },

    { "a", 45, '', 's', '', '', 'kahdeksas', false, al_aa },

    { "s", 46, '', 't', '', '', 'tuhat', false, al_aa },
    { "s", 46, '', 'nnet', '', '', 'tuhat', true, al_aa },

    { "s", 47, '', '[uy]t', '', '', 'kuollut', false, al_uu_aa },
    { "s", 47, '', 'eet',   '', '', 'kuollut', true,  al_uu_aa },

    -- kuollut: kuoll|u|a
    { "a", 47, '', '[uy]t', '', '', 'kuollut', false, al_uu_aa },
    
    { "v", 47, '', '[uy]t', '', '', 'kuollut', false, al_uu_aa },

    { "s", 48, '{AVt}', '{AV1}[aeiouyäö]',   '{AV1}', '{AV2}', 'hame', false, al_av_av_aa },
    { "s", 48, '{AVt}', '{AV2}[aeiouyäö][aeiouyäö]t', '{AV1}', '{AV2}', 'hame', true,  al_av_av_aa },

    { "a", 48, '{AVt}', '{AV1}[aeiouyäö]',   '{AV1}', '{AV2}', 'hame', false, al_av_av_aa },

    { "s", 49, '{AVt}', '{AV1}[ae][lnr]e?',   '{AV1}', '{AV2}', 'askel', false, askel_f },
    { "s", 49, '{AVt}', '{AV2}[ae][lnr]eet', '{AV1}', '{AV2}', 'askel', true,  askel_f },

    -- VERBIT
    --{{fi-verbi-taiv-sanoa|lii|tt|t|ä|y|ö}}
    { "v", 52, '{AVt}', '{AV1}[uyoöie][aä]',   '{AV1}', '{AV2}', 'sanoa', false, al_av_av_aa_uu_oo_xa },

    --{{fi-verbi-taiv-muistaa|el|||ä|y|ö}}, {{fi-verbi-taiv-muistaa|o|tt|t}}
    { "v", 53, '{AVt}', '{AV1}[aä][aä]',   '{AV1}', '{AV2}', 'muistaa', false, al_av_av_aa_uu_oo },
    --{{fi-verbi-taiv-huutaa|kier|r|ä|y|ö}}
    { "v", 54, '{AVt}', '{AV1}[aä][aä]',   '{AV1}', '{AV2}', 'huutaa', false, alm_avm_aa_uu_oo },

    -- {{fi-verbi-taiv-soutaa|kyn|n|ä|y|ö}}
    { "v", 55, '{AVt}', '{AV1}[aä][aä]',   '{AV1}', '{AV2}', 'soutaa', false, alm_avm_aa_uu_oo },

    --
    { "v", 56, '{AVt}', '{AV1}[aä][aä]',   '{AV1}', '{AV2}', 'kaivaa', false, al_av_av_aa_uu_oo },

    --{{fi-verbi-taiv-saartaa|kaar|r}}  TODO
    { "v", 57, '{AVt}', '{AV1}[aä][aä]',   '{AV1}', '{AV2}', 'saartaa', false, alm_avm_aa_uu_oo },

    -- {{fi-verbi-taiv-laskea|ky|t|d|ä|y|ö}}
    { "v", 58, '{AVt}', '{AV1}e[aä]',   '{AV1}', '{AV2}', 'laskea', false, al_av_av_aa_uu_oo },

    { "v", 59, '{AVt}', '{AV1}e[aä]',   '{AV1}', '{AV2}', 'tuntea', false, tuntea },
    { "v", 60, '{AVt}', '{AV1}e[aä]',   '{AV1}', '{AV2}', 'lähteä', false, lahtea },

    -- {{fi-verbi-taiv-sallia|mie|tt|t|ä|y|ö}} , pörhistyä
    { "v", 61, '{AVt}', '{AV1}[iy][aä]',   '{AV1}', '{AV2}', 'sallia', false, al_av_av_aa_uu_oo },
    --{{fi-verbi-taiv-voida|eläm|ä|y|ö}} , naida, puida
    { "v", 62, '', '[oöaäuy]id[aä]',   '', '', 'voida', false, al_aa_uu_oo_vv },
    --{{fi-verbi-taiv-saada|sa|ada|saa|saa|saa||sai|sai|a|u|o|63}}, myydä
    { "v", 63, '', 'd[aä]',   '', '', 'saada', false, saada },
    --{{fi-verbi-taiv-saada|sy|ödä|syö|syö|syö||söi|söi|ä|y|ö|64}}
    { "v", 64, '{AVt}', '{AV1}[aä]',   '{AV1}', '{AV2}', 'juoda', false, saada },

    { "v", 65, '{AVt}', '{AV1}[aä]',   '{AV1}', '{AV2}', 'käydä', false, saada },

    -- {{fi-verbi-taiv-rohkaista|pe|ä|y|ö}} , hipaista, höpistä, hölistä, jorista, jupista, jymistä, jytistä, kahista, kusta, lestä
    { "v", 66, '',        'st[aä]',        '',        '',        'rohkaista', false, al_aa_uu_oo },
    -- {{fi-verbi-taiv-tulla|seli|te|tte|ä|y|ö}}, {{fi-verbi-taiv-tulla|me|||ä|y|ö|n}}
    { "v", 67, '{AVt}', '{AV1}e?[lnr][lnr][aä]',  '{AV1}', '{AV2}', 'tulla', false, al_ave_ave_aa_uu_oo_xxa },
    --{{fi-verbi-taiv-tupakoida|käräj|ä|y|ö}}
    { "v", 68, '{AVt}', '{AV1}[oö]id[aä]',   '{AV1}', '{AV2}', 'tupakoida', false, al_aa_uu_oo },
    --{{fi-verbi-taiv-valita|merki|ä|y|ö}}
    { "v", 69, '{AVt}', '{AV1}t[aä]',   '{AV1}', '{AV2}', 'valita', false, al_aa_uu_oo },

    { "v", 70, '{AVt}', '{AV1}[aä]',   '{AV1}', '{AV2}', 'juosta', false, juosta },

    { "v", 71, '{AVt}', '{AV1}[aä]',   '{AV1}', '{AV2}', 'nähdä', false, nahda },
    --{{fi-verbi-vanheta|mä|dä|tä|ä|y|ö}}, paksuta
    { "v", 72, '{AVt}', '{AV1}[aäeiöouy]t[aä]',   '{AV1}', '{AV2}', 'vanheta', false, al_avv_avv_aa_uu_oo },
    -- {{fi-verbi-taiv-salata|hyö|k|kk|ä|y|ö}}
    { "v", 73, '{AVt}', '{AV1}[aä]t[aä]',   '{AV1}', '{AV2}', 'salata', false, al_av_av_aa_uu_oo },

    --{{fi-verbi-taiv-katketa|her|je|ke|ä|y|ö}}
    { "v", 74,'{AVt}', '{AV1}[eoöuy]t[aä]',   '{AV1}', '{AV2}', 'katketa', false, al_avv_avv_aa_uu_oo },
    -- {{fi-verbi-taiv-selvitä|hel|ll|lt|i|ä|y|ö}}, {{fi-verbi-taiv-selvitä|nim|||e|ä|y|ö}}
    { "v", 75, '{AVt}', '{AV1}[aeiouyäö]t[aä]',   '{AV1}', '{AV2}', 'selvitä', false, al_av_av_vok_aa_uu_oo },

    --2: {{fi-verbi-taiv-taitaa|tie|ä|y|ö}}
    { "v", 76, '{AVt}', '{AV1}[aä][aä]',   '{AV1}', '{AV2}', 'taitaa', false, al_aa_uu_oo },

    { "v", 77, '', '[aä]j[aä][aä]',   '', '', 'kumajaa', false, al_aa },

    { "v", 78, '', '[aä][aä]',   '', '', 'kaikaa', false, al_aa_uu_oo },

}


local taivdata = { }



local function kasittele_rivi(rivi)
    local repl
    local nyk

    for j, item in ipairs(rivi) do
        if type(item) == "string" and mw.ustring.match(item, "{AVt}") then
            repl = 1
            break
        end
    end

    if repl == 1 then
        for i,avr in ipairs(astevaihtelut) do
            nyk = {}
            for j, item in ipairs(rivi) do
                if type(item) == "string" then
                    item = mw.ustring.gsub(item, "{AVt}", avr[1])
		    item = mw.ustring.gsub(item, "{AV1}", avr[2])
		    item = mw.ustring.gsub(item, "{AV2}", avr[3])
                end
                table.insert(nyk, item)
            end
            table.insert(taivdata, nyk)
        end
        for i,avr in ipairs(astevaihtelut) do
            nyk = {}
            for j, item in ipairs(rivi) do
                if type(item) == "string" then
                    item = mw.ustring.gsub(item, "{AVt}", avr[1])
		    item = mw.ustring.gsub(item, "{AV1}", avr[3])
		    item = mw.ustring.gsub(item, "{AV2}", avr[2])
                end
                table.insert(nyk, item)
            end
            table.insert(taivdata, nyk)
        end
    else
        table.insert(taivdata, rivi)
    end

end

function m.tee_taivdata()
    for i,rivi in ipairs(alkudata) do
        kasittele_rivi(rivi)
    end
end






local function hae_rivi(sanaluokka, mj, tt, av)
    av = av or ""
    for i, rivi in ipairs(taivdata) do
        if rivi[1] == sanaluokka and rivi[2] == tt and rivi[3] == av and mw.ustring.match(mj, rivi[4] .. "$") then
            return rivi
        end
    end
    return nil
end




function m.taivutusmalline(sanaluokka, mj, tt, av, lisaparametrit, eikomp)
    local rivi = hae_rivi(sanaluokka, mj, tt, av)
    if rivi then
        local params = {}
        local paate_re = "^(.-)(" .. rivi[4] .. ")$"
        params.sanaluokka = sanaluokka
        params.taivtunnus = rivi[2]
        params.avtunnus = rivi[3]
        params.sana = mj
        params.alku, params.loppu = mw.ustring.match(mj, paate_re)
        params.av1 = rivi[5]   -- Huom. aina perusmuodossa esiintyvä
        params.av2 = rivi[6]   --       taivutusmuodossa esiintyvä
        params.esimsana = rivi[7]
        params.eiyks = rivi[8]
        params.eikomp = eikomp
        local hajottajafunktio = rivi[9]
        local parametritaulukko = hajottajafunktio(params)
        if lisaparametrit ~= "" then
            table.insert(parametritaulukko, lisaparametrit)
        end
        return parametritaulukko
    end
    return error("Taivutusta ei löydy: " .. mj .. " " .. tt .. "-" .. av)
end


function m.Taivutusmalline(frame, sanaluokka)
    local args = mt.poista_tyhjat(frame.args)
    if not args[3] then
        args[3] = ""
    end
    local taivtunnus = tonumber(args[2])

    if taivtunnus > 0 and taivtunnus < 52 and sanaluokka == nil then
        sanaluokka = "s"
    elseif taivtunnus >= 52 and taivtunnus < 79 and sanaluokka == nil then
        sanaluokka = "v"
    elseif taivtunnus > 100 and taivtunnus < 152 and sanaluokka == nil then
        taivtunnus = taivtunnus - 100
        sanaluokka = "a"
    end

    local lisap = ""  -- nimetyt parametrit yks, mon tms.
    local list = {}
    -- tehdään nimetyistä parametreista taulukko.
    -- Paitsi jätetään eikomp pois, koska se liitetään mallineen nimen perään.
    for k,v in pairs(args) do
        if tonumber(k) == nil and k ~= "eikomp" and k ~= "sanaluokka" then
            table.insert(list, k .. "=" .. v)
        end
    end
    lisap = table.concat(list, "|")



    local tulos =  "{{" .. table.concat(m.taivutusmalline(
                                            sanaluokka,
                                            args[1],
                                            tonumber(args[2]),
                                            args[3],
                                            lisap,
                                            args.eikomp
                                                         ), "|") .. "}}"

    return tulos;
end

function m.Adjektiivitaivutus(frame)
    return m.Taivutusmalline(frame, "a")
end

function m.Adjektiivi(frame)
    return m.Adjektiivitaivutus(frame)
end

function m.Verbitaivutus(frame)
    return m.Taivutusmalline(frame, "v")
end

function m.Substantiivitaivutus(frame)
    return m.Taivutusmalline(frame, "s")
end

m.tee_taivdata()

return m