La documentation pour ce module peut être créée à Module:hu-conj/Documentation

-- À faire :
--  * Verbes de 2 lettres
--  * Verbes irréguliers
local p = {}

local bases = require('Module:bases')


-- En hongrois, il y a trois couleurs de mots : les mots sombres,
-- les mots clairs et les mots mixtes.
-- sombres : a, á, o, ó, u, ú
-- clairs : e, é, i, í
-- mixtes : ö, ő, ü, ű
function p.get_color(word)
    local couleur = {}
    couleur.clair = 0
    couleur.sombre = 0
    couleur.mixte = 0
    for ch in mw.ustring.gmatch(word, '.') do
        if mw.ustring.match(ch, '[aáoóuú]') then couleur.sombre = couleur.sombre + 1 end
        if mw.ustring.match(ch, '[eéií]') then couleur.clair = couleur.clair + 1 end
        if mw.ustring.match(ch, '[öőüű]') then couleur.mixte = couleur.mixte + 1 end
    end

    local key = next(couleur)
    local max = couleur[key]

    for k, v in pairs(couleur) do
        if couleur[k] > max then
            key, max = k, v
        end
    end
    return key
end

-- Détermine si les 2 caractères d'entrée dont 2 consonnes hongroises.
function p.double_consonants(two_letters)
    return not not mw.ustring.find(two_letters, '[^aáoóuúeéiíöőüű][^aáoóuúeéiíöőüű]')  -- TODO: {2}
end

-- Détermine si une chaîne de caractères de longeur 2 est composée
-- de 2 consonnes différentes.
function double_different_consonants(two_letters)
    if (not p.double_consonants(two_letters)) then return false end
    return (mw.ustring.sub(two_letters, 1, 1) ~= mw.ustring.sub(two_letters, 2, 2))
end

function p.remove_last_vowel(word)
	return mw.ustring.gsub(word, '(.*)([aáoóuúeéiíöőüű])([^aáoóuúeéiíöőüű]+)$', '%1%3')
end

function p.get_word_info(word, args)
    local caract = {}
    caract.color = args.conj or p.get_color(word)
    caract.last_1 = mw.ustring.sub(word, -1, -1)
    caract.last_2 = mw.ustring.sub(word, -2, -1)
    caract.last_3 = mw.ustring.sub(word, -3, -1)
    caract.without_last_1 = mw.ustring.sub(word, 1, -2)
    caract.without_last_2 = mw.ustring.sub(word, 1, -3)
    caract.ends_with_s_or_z = not not mw.ustring.find(caract.last_1, '[sz]')
    caract.ends_with_sz = (caract.last_2 == 'sz')
    caract.ends_with_diff_consonants = double_different_consonants(caract.last_2)
    caract.ends_with_ik = (caract.last_2 == 'ik')
    caract.ends_with_it = (caract.last_2 == 'ít')  -- ends with -ít
    return caract
end

function p.get_roots(word, caract, args)
    local root  = args.rac or word
    if (caract.ends_with_ik) then
        root = args.rac or caract.without_last_2
    end

    local root_imp = root .. 'j'  -- TODO: add param
    if (caract.ends_with_s_or_z) then
        root_imp = root .. caract.last_1
    end
    if (mw.ustring.match(word, '[íűjlmnr]t$')) then
        root_imp = root .. 's'
    end
    if (caract.last_2 == 'st') then
        root_imp = caract.without_last_1 .. 's'
    end
    if (caract.last_3 == 'szt') then
        root_imp = caract.without_last_2 .. 'sz'
    end
    if (mw.ustring.match(word, '[aáeioöuü]t$')) then
        root_imp = caract.without_last_1 .. 'ss'
    end
    if (mw.ustring.match(word, '[sz]$')) then
        root_imp = root .. caract.last_1
    end
    if (mw.ustring.match(word, '[sz]ik$')) then
        root_imp = root .. mw.ustring.sub(root, -1, -1)
    end
    if (mw.ustring.match(word, '[sd]z$')) then
        root_imp = caract.without_last_1 .. caract.last_2
    end

    -- voyelle de liaison
    local root_passe = root
    local root_voy = root
    if (caract.ends_with_it or caract.ends_with_diff_consonants) then
        if (caract.color == 'sombre') then
            root_passe = root .. 'ot'
            root_voy = root .. 'a'
        elseif (caract.color == 'clair') then
            root_passe = root .. 'et'
            root_voy = root .. 'e'
        elseif (caract.color == 'mixte') then
            root_passe = root .. 'öt'
            root_voy = root .. 'e'
        end
    end

    if (args.passe) then
        root_passe = root .. mw.ustring.sub(args.passe, 1, -2)
    end
    
    -- root2 : racine alternative si la dernière voyelle doit être omise
    local root2 = root
    if (args.voy or args.voy_var) then
    	root2 = p.remove_last_vowel(root)
    end

    return root, root2, root_imp, root_passe, root_voy
end

function p.get_declinaisons(word, caract, args)
	local forms = {}
    local conj = {
        ['clair'] = p.conj_claire_reguliere,
        ['sombre'] = p.conj_sombre_reguliere,
        ['mixte'] = p.conj_mixte_reguliere,
    }
    return conj[caract.color](word, forms, caract, args)
end

function p.mise_en_forme(forms, args)
    local flexions = {}
    local i = 1
    local arg_var = ''
    local flexion = ''
    local ordre = {
    	['inf'] = 49,
    	['p_ind_subj_s1']  = 1,
    	['p_ind_subj_s2']  = 2,
    	['p_ind_subj_s3']  = 3,
    	['p_ind_subj_p1']  = 4,
    	['p_ind_subj_p2']  = 5,
    	['p_ind_subj_p3']  = 6,
    	['p_ind_obj_s1']   = 7,
    	['p_ind_obj_s2']   = 8,
    	['p_ind_obj_s3']   = 9,
    	['p_ind_obj_p1']   = 10,
    	['p_ind_obj_p2']   = 11,
    	['p_ind_obj_p3']   = 12,
    	['p_cond_subj_s1'] = 13,
    	['p_cond_subj_s2'] = 14,
    	['p_cond_subj_s3'] = 15,
    	['p_cond_subj_p1'] = 16,
    	['p_cond_subj_p2'] = 17,
    	['p_cond_subj_p3'] = 18,
    	['p_cond_obj_s1']  = 19,
    	['p_cond_obj_s2']  = 20,
    	['p_cond_obj_s3']  = 21,
    	['p_cond_obj_p1']  = 22,
    	['p_cond_obj_p2']  = 23,
    	['p_cond_obj_p3']  = 24,
    	['p_imp_subj_s1']  = 25,
    	['p_imp_subj_s2']  = 26,
    	['p_imp_subj_s3']  = 27,
    	['p_imp_subj_p1']  = 28,
    	['p_imp_subj_p2']  = 29,
    	['p_imp_subj_p3']  = 30,
    	['p_imp_obj_s1']   = 31,
    	['p_imp_obj_s2']   = 32,
    	['p_imp_obj_s3']   = 33,
    	['p_imp_obj_p1']   = 34,
    	['p_imp_obj_p2']   = 35,
    	['p_imp_obj_p3']   = 36,
    	['pa_subj_s1']     = 37,
    	['pa_subj_s2']     = 38,
    	['pa_subj_s3']     = 39,
    	['pa_subj_p1']     = 40,
    	['pa_subj_p2']     = 41,
    	['pa_subj_p3']     = 42,
    	['pa_obj_s1']      = 43,
    	['pa_obj_s2']      = 44,
    	['pa_obj_s3']      = 45,
    	['pa_obj_p1']      = 46,
    	['pa_obj_p2']      = 47,
    	['pa_obj_p3']      = 48,
	}
    while (i < 4) do  -- 2 variants possibles
        for cas, n in pairs(ordre) do
            arg_var = tostring(n)
            if i > 1 then
                cas = cas .. '_' .. tostring(i)
                arg_var = tostring(n) .. '_' .. tostring(i)
            end
            if (i == 1) then
                flexion = args[n] or args[cas] or forms[cas]
                if (flexion) then
                	flexions[n] = bases.lien_modele(flexion, 'hu')
                end
            elseif (forms[cas] or args[cas] or args[arg_var]) then
                flexion = args[cas] or args[arg_var] or forms[cas] or ''
                if (flexion and flexion ~= '') then
                    flexions[n] = flexions[n] .. ', ' .. bases.lien_modele(flexion, 'hu')
                end
            end
        end
        i = i + 1
    end
    return flexions
end

function tableau_generique(flexions)
	local txt = '{| class="flextable flextable-hu"\n' ..
				'! class="invisible" |\n' ..
				'|-\n' ..
				'| rowspan=2 class="inf" | ' .. flexions[49] .. '\n' ..
				'! colspan=2 | Indicatif\n' ..
				'! colspan=2 | Conditionnel\n' ..
				'! colspan=2 | Subjonctif - Impératif\n' ..
				'|-\n' ..
				'! Subjectif\n' ..
				'! Objectif\n' ..
				'! Subjectif\n' ..
				'! Objectif\n' ..
				'! Subjectif\n' ..
				'! Objectif\n' ..
				'|-\n' ..
				'! rowspan=6 | Présent\n' ..
				'| class="p_ind_subj_s1" | ' .. flexions[1] .. '\n' ..
				'| class="p_ind_obj_s1" | ' .. flexions[7] .. '\n' ..
				'| class="p_cond_subj_s1" | ' .. flexions[13] .. '\n' ..
				'| class="p_cond_obj_s1" | ' .. flexions[19] .. '\n' ..
				'| class="p_imp_subj_s1" | ' .. flexions[25] .. '\n' ..
				'| class="p_imp_obj_s1" | ' .. flexions[31] .. '\n' ..
				'|-\n' ..
				'| class="p_ind_subj_s2" | ' .. flexions[2] .. '\n' ..
				'| class="p_ind_obj_s2" | ' .. flexions[8] .. '\n' ..
				'| class="p_cond_subj_s2" | ' .. flexions[14] .. '\n' ..
				'| class="p_cond_obj_s2" | ' .. flexions[20] .. '\n' ..
				'| class="p_imp_subj_s2" | ' .. flexions[26] .. '\n' ..
				'| class="p_imp_obj_s2" | ' .. flexions[32] .. '\n' ..
				'|-\n' ..
				'| class="p_ind_subj_s3" | ' .. flexions[3] .. '\n' ..
				'| class="p_ind_obj_s3" | ' .. flexions[9] .. '\n' ..
				'| class="p_cond_subj_s3" | ' .. flexions[15] .. '\n' ..
				'| class="p_cond_obj_s3" | ' .. flexions[21] .. '\n' ..
				'| class="p_imp_subj_s3" | ' .. flexions[27] .. '\n' ..
				'| class="p_imp_obj_s3" | ' .. flexions[33] .. '\n' ..
				'|-\n' ..
				'| class="p_ind_subj_p1" | ' .. flexions[4] .. '\n' ..
				'| class="p_ind_obj_p1" | ' .. flexions[10] .. '\n' ..
				'| class="p_cond_subj_p1" | ' .. flexions[16] .. '\n' ..
				'| class="p_cond_obj_p1" | ' .. flexions[22] .. '\n' ..
				'| class="p_imp_subj_p1" | ' .. flexions[28] .. '\n' ..
				'| class="p_imp_obj_p1" | ' .. flexions[34] .. '\n' ..
				'|-\n' ..
				'| class="p_ind_subj_p2" | ' .. flexions[5] .. '\n' ..
				'| class="p_ind_obj_p2" | ' .. flexions[11] .. '\n' ..
				'| class="p_cond_subj_p2" | ' .. flexions[17] .. '\n' ..
				'| class="p_cond_obj_p2" | ' .. flexions[23] .. '\n' ..
				'| class="p_imp_subj_p2" | ' .. flexions[29] .. '\n' ..
				'| class="p_imp_obj_p2" | ' .. flexions[35] .. '\n' ..
				'|-\n' ..
				'| class="p_ind_subj_p3" | ' .. flexions[6] .. '\n' ..
				'| class="p_ind_obj_p3" | ' .. flexions[12] .. '\n' ..
				'| class="p_cond_subj_p3" | ' .. flexions[18] .. '\n' ..
				'| class="p_cond_obj_p3" | ' .. flexions[24] .. '\n' ..
				'| class="p_imp_subj_p3" | ' .. flexions[30] .. '\n' ..
				'| class="p_imp_obj_p3" | ' .. flexions[36] .. '\n' ..
				'|-\n' ..
				'! rowspan=6 | Passé\n' ..
				'| class="pa_ind_subj_s1" | ' .. flexions[37] .. '\n' ..
				'| class="pa_ind_obj_s1" | ' .. flexions[43] .. '\n' ..
				'| class="pa_cond_subj_s1" | ' .. flexions[37] .. ' volna\n' ..
				'| class="pa_cond_obj_s1" | ' .. flexions[43] .. ' volna\n' ..
				'|-\n' ..
				'| class="pa_ind_subj_s2" | ' .. flexions[38] .. '\n' ..
				'| class="pa_ind_obj_s2" | ' .. flexions[44] .. '\n' ..
				'| class="pa_cond_subj_s2" | ' .. flexions[38] .. ' volna\n' ..
				'| class="pa_cond_obj_s2" | ' .. flexions[44] .. ' volna\n' ..
				'|-\n' ..
				'| class="pa_ind_subj_s3" | ' .. flexions[39] .. '\n' ..
				'| class="pa_ind_obj_s3" | ' .. flexions[45] .. '\n' ..
				'| class="pa_cond_subj_s3" | ' .. flexions[39] .. ' volna\n' ..
				'| class="pa_cond_obj_s3" | ' .. flexions[45] .. ' volna\n' ..
				'|-\n' ..
				'| class="pa_ind_subj_p1" | ' .. flexions[40] .. '\n' ..
				'| class="pa_ind_obj_p1" | ' .. flexions[46] .. '\n' ..
				'| class="pa_cond_subj_p1" | ' .. flexions[40] .. ' volna\n' ..
				'| class="pa_cond_obj_p1" | ' .. flexions[46] .. ' volna\n' ..
				'|-\n'
	
	txt = txt ..'| class="pa_ind_subj_p2" | ' .. flexions[41] .. '\n' ..
				'| class="pa_ind_obj_p2" | ' .. flexions[47] .. '\n' ..
				'| class="pa_cond_subj_p2" | ' .. flexions[41] .. ' volna\n' ..
				'| class="pa_cond_obj_p2" | ' .. flexions[47] .. ' volna\n' ..
				'|-\n' ..
				'| class="pa_ind_subj_p3" | ' .. flexions[42] .. '\n' ..
				'| class="pa_ind_obj_p3" | ' .. flexions[48] .. '\n' ..
				'| class="pa_cond_subj_p3" | ' .. flexions[42] .. ' volna\n' ..
				'| class="pa_cond_obj_p3" | ' .. flexions[48] .. ' volna\n' ..
				'|-\n' ..
				'! rowspan=6 | Futur\n' ..
				'| ' .. flexions[49] .. ' fogok\n' ..
				'| ' .. flexions[49] .. ' fogom\n' ..
				'|-\n' ..
				'| ' .. flexions[49] .. ' fogsz\n' ..
				'| ' .. flexions[49] .. ' fogod\n' ..
				'|-\n' ..
				'| ' .. flexions[49] .. ' fog\n' ..
				'| ' .. flexions[49] .. ' fogja\n' ..
				'|-\n' ..
				'| ' .. flexions[49] .. ' fogunk\n' ..
				'| ' .. flexions[49] .. ' fogjuk\n' ..
				'|-\n' ..
				'| ' .. flexions[49] .. ' fogtok\n' ..
				'| ' .. flexions[49] .. ' fogjátok\n' ..
				'|-\n' ..
				'| ' .. flexions[49] .. ' fognak\n' ..
				'| ' .. flexions[49] .. ' fogják\n' ..
				'|}'
	return txt
end

function tableau_intransitif(flexions)
	local txt = '{| class="flextable flextable-hu"\n' ..
				'! class="invisible" |\n' ..
				'|-\n' ..
				'| rowspan=2 class="inf" | ' .. flexions[49] .. '\n' ..
				'! colspan=2 | Indicatif\n' ..
				'! colspan=2 | Conditionnel\n' ..
				'! colspan=2 | Subjonctif - Impératif\n' ..
				'|-\n' ..
				'! Subjectif\n' ..
				'! Objectif\n' ..
				'! Subjectif\n' ..
				'! Objectif\n' ..
				'! Subjectif\n' ..
				'! Objectif\n' ..
				'|-\n' ..
				'! rowspan=6 | Présent\n' ..
				'| class="p_ind_subj_s1" | ' .. flexions[1] .. '\n' ..
				'| rowspan=6 | &mdash;\n' ..
				'| class="p_cond_subj_s1" | ' .. flexions[13] .. '\n' ..
				'| rowspan=6 | &mdash;\n' ..
				'| class="p_imp_subj_s1" | ' .. flexions[25] .. '\n' ..
				'| rowspan=6 | &mdash;\n' ..
				'|-\n' ..
				'| class="p_ind_subj_s2" | ' .. flexions[2] .. '\n' ..
				'| class="p_cond_subj_s2" | ' .. flexions[14] .. '\n' ..
				'| class="p_imp_subj_s2" | ' .. flexions[26] .. '\n' ..
				'|-\n' ..
				'| class="p_ind_subj_s3" | ' .. flexions[3] .. '\n' ..
				'| class="p_cond_subj_s3" | ' .. flexions[15] .. '\n' ..
				'| class="p_imp_subj_s3" | ' .. flexions[27] .. '\n' ..
				'|-\n' ..
				'| class="p_ind_subj_p1" | ' .. flexions[4] .. '\n' ..
				'| class="p_cond_subj_p1" | ' .. flexions[16] .. '\n' ..
				'| class="p_imp_subj_p1" | ' .. flexions[28] .. '\n' ..
				'|-\n' ..
				'| class="p_ind_subj_p2" | ' .. flexions[5] .. '\n' ..
				'| class="p_cond_subj_p2" | ' .. flexions[17] .. '\n' ..
				'| class="p_imp_subj_p2" | ' .. flexions[29] .. '\n' ..
				'|-\n' ..
				'| class="p_ind_subj_p3" | ' .. flexions[6] .. '\n' ..
				'| class="p_cond_subj_p3" | ' .. flexions[18] .. '\n' ..
				'| class="p_imp_subj_p3" | ' .. flexions[30] .. '\n' ..
				'|-\n' ..
				'! rowspan=6 | Passé\n' ..
				'| class="pa_ind_subj_s1" | ' .. flexions[37] .. '\n' ..
				'| rowspan=6 | &mdash;\n' ..
				'| class="pa_cond_subj_s1" | ' .. flexions[37] .. ' volna\n' ..
				'| rowspan=6 | &mdash;\n' ..
				'|-\n' ..
				'| class="pa_ind_subj_s2" | ' .. flexions[38] .. '\n' ..
				'| class="pa_cond_subj_s2" | ' .. flexions[38] .. ' volna\n' ..
				'|-\n' ..
				'| class="pa_ind_subj_s3" | ' .. flexions[39] .. '\n' ..
				'| class="pa_cond_subj_s3" | ' .. flexions[39] .. ' volna\n' ..
				'|-\n' ..
				'| class="pa_ind_subj_p1" | ' .. flexions[40] .. '\n' ..
				'| class="pa_cond_subj_p1" | ' .. flexions[40] .. ' volna\n' ..
				'|-\n'
	
	txt = txt ..'| class="pa_ind_subj_p2" | ' .. flexions[41] .. '\n' ..
				'| class="pa_cond_subj_p2" | ' .. flexions[41] .. ' volna\n' ..
				'|-\n' ..
				'| class="pa_ind_subj_p3" | ' .. flexions[42] .. '\n' ..
				'| class="pa_cond_subj_p3" | ' .. flexions[42] .. ' volna\n' ..
				'|-\n' ..
				'! rowspan=6 | Futur\n' ..
				'| ' .. flexions[49] .. ' fogok\n' ..
				'| rowspan=6 | &mdash;\n' ..
				'|-\n' ..
				'| ' .. flexions[49] .. ' fogsz\n' ..
				'|-\n' ..
				'| ' .. flexions[49] .. ' fog\n' ..
				'|-\n' ..
				'| ' .. flexions[49] .. ' fogunk\n' ..
				'|-\n' ..
				'| ' .. flexions[49] .. ' fogtok\n' ..
				'|-\n' ..
				'| ' .. flexions[49] .. ' fognak\n' ..
				'|}'
	return txt
end

function p.get_conj(frame)
	local t = {
		['ek'] = 'claire',
		['ok'] = 'sombre',
		['ök'] = 'mixte',
	}
	local args = frame:getParent().args
    local word = args['mot'] or args[3] or mw.title.getCurrentTitle().text
    if args.i then args.intransitif = true end
    if args.intrans then args.intransitif = true end
    if args.term then args.conj = t[args.term] end
    local caract = p.get_word_info(word, args)

    local forms = p.get_declinaisons(word, caract, args)
	local flexions = p.mise_en_forme(forms, args)
	if (args.intransitif) then return tableau_intransitif(flexions) end
    return tableau_generique(flexions)
end

--------------------
-- Verbes claires --
--------------------
function p.conj_claire_reguliere(title, forms, caract, args)
    -- Déclinaisons en -ek à la 1ère personne du singulier
    -- du présent de l'indicatif

    root, root2, root_imp, root_passe, root_voy = p.get_roots(title, caract, args)
    
    -- infinitif
    forms.inf = root_voy .. 'ni'

	-- indicatif subjectif
	forms.p_ind_subj_s1 = root2 .. 'ek'
    forms.p_ind_subj_s1_2 = nil
    if (args.m) then
        forms.p_ind_subj_s1 = root2 .. 'em'
        forms.p_ind_subj_s1_2 = root2 .. 'ek'
    end
    if (args.voy_var) then
    	forms.p_ind_subj_s1 = root2 .. 'ek'
    	forms.p_ind_subj_s1_2 = root .. 'ek'
    end
    
    forms.p_ind_subj_s2 = root_voy .. 'sz'
    if mw.ustring.match(root, '[aáoóuúeéiíöőüű]z$') then
    	forms.p_ind_subj_s2 = root2 .. 'el'
    	if (args.voy_var) then
    		forms.p_ind_subj_s2_2 = root .. 'el'
    	end
    elseif (caract.ends_with_s_or_z or caract.ends_with_sz or mw.ustring.match(title, '[sz]ik$')) then
        forms.p_ind_subj_s2 = root .. 'el'
    end
    
	forms.p_ind_subj_s3 = title  -- par définition
	if (args.voy_var) then
		forms.p_ind_subj_p1_2 = root .. 'ünk'
	end
	forms.p_ind_subj_p1 = root2 .. 'ünk'
	forms.p_ind_subj_p2 = root .. 'tek'
    if (root_passe ~= root and not args.passe) then
        forms.p_ind_subj_p2 = root_passe .. 'ek'
    end
    if (args.passe == 't') then
        forms.p_ind_subj_p2 = root .. 'etek'
        forms.p_ind_subj_p2_2 = root .. 'tek'
    end
	forms.p_ind_subj_p3 = root_voy .. 'nek'

	-- indicatif objectif
	if (args.voy_var) then
		forms.p_ind_obj_s1_2 = root .. 'em'
		forms.p_ind_obj_s2_2 = root .. 'ed'
		forms.p_ind_obj_s3_2 = root .. 'i'
	end
	forms.p_ind_obj_s1 = root2 .. 'em'
	forms.p_ind_obj_s2 = root2 .. 'ed'
	forms.p_ind_obj_s3 = root2 .. 'i'
    forms.p_ind_obj_p1 = root .. 'jük'
    if (caract.ends_with_s_or_z) then
        forms.p_ind_obj_p1 = root .. caract.last_1 .. 'ük'
    end
    if (args.voy_var) then
    	forms.p_ind_obj_p2_2 = root .. 'itek'
		forms.p_ind_obj_p3_2 = root .. 'ik'
	end
	forms.p_ind_obj_p2 = root2 .. 'itek'
	forms.p_ind_obj_p3 = root2 .. 'ik'

	-- conditionnel subjectif
	forms.p_cond_subj_s1 = root_voy .. 'nék'
	forms.p_cond_subj_s2 = root_voy .. 'nél'
	forms.p_cond_subj_s3 = root_voy .. 'ne'
	forms.p_cond_subj_p1 = root_voy .. 'nénk'
	forms.p_cond_subj_p2 = root_voy .. 'nétek'
	forms.p_cond_subj_p3 = root_voy .. 'nének'

	-- conditionnel objectif
	forms.p_cond_obj_s1 = root_voy .. 'ném'
	forms.p_cond_obj_s2 = root_voy .. 'néd'
	forms.p_cond_obj_s3 = root_voy .. 'né'
	forms.p_cond_obj_p1 = root_voy .. 'nénk'
	forms.p_cond_obj_p2 = root_voy .. 'nétek'
	forms.p_cond_obj_p3 = root_voy .. 'nék'

	-- impératif subjectif
	forms.p_imp_subj_s1     = root_imp .. 'ek'
    forms.p_imp_subj_s1_2 = nil
    if (args.m) then
        if (mw.ustring.match(root, '[sz]$')) then
            local root_last_1 = mw.ustring.sub(root, -1, -1)
            forms.p_imp_subj_s1 = root .. root_last_1 .. 'em'
            forms.p_imp_subj_s1_2 = root .. root_last_1 .. 'ek'
        else
            forms.p_imp_subj_s1 = root_imp .. 'em'
            forms.p_imp_subj_s1_2 = root_imp .. 'ek'
        end
    end
	forms.p_imp_subj_s2     = root_imp
    forms.p_imp_subj_s2_2 = root_imp .. 'él'
	forms.p_imp_subj_s3     = root_imp .. 'en'
	if (args.subj_s3) then
		forms.p_imp_subj_s3_2 = root_imp .. 'ék'
	end
	forms.p_imp_subj_p1     = root_imp .. 'ünk'
	forms.p_imp_subj_p2     = root_imp .. 'etek'
	forms.p_imp_subj_p3     = root_imp .. 'enek'

	-- impératif objectif
	forms.p_imp_obj_s1 = root_imp .. 'em'
    forms.p_imp_obj_s2 = root .. 'd'
    if (mw.ustring.match(title, 'sz?t$')) then
        forms.p_imp_obj_s2 = caract.without_last_1 .. 'd'
    elseif (caract.ends_with_it or caract.ends_with_diff_consonants) then
        forms.p_imp_obj_s2 = root .. 'sd'
    elseif (mw.ustring.match(title, '[eöuü]t$')) then
        forms.p_imp_obj_s2 = caract.without_last_1 .. 'sd'
    end
    forms.p_imp_obj_s2_2 = root_imp .. 'ed'
	forms.p_imp_obj_s3 = root_imp .. 'e'
	forms.p_imp_obj_p1 = root_imp .. 'ük'
	forms.p_imp_obj_p2 = root_imp .. 'étek'
	forms.p_imp_obj_p3 = root_imp .. 'ék'

    -- passé indicatif subjectif
	forms.pa_subj_s1 = root_passe .. 'tem'
	forms.pa_subj_s2 = root_passe .. 'tél'
    forms.pa_subj_s3 = root_passe .. 't'
    if (caract.ends_with_s_or_z or caract.ends_with_sz or caract.ends_with_ik or args.passe) then
        forms.pa_subj_s3 = root .. 'ett'
    end
	forms.pa_subj_p1 = root_passe .. 'tünk'
	forms.pa_subj_p2 = root_passe .. 'tetek'
	forms.pa_subj_p3 = root_passe .. 'tek'

	-- passé indicatif objectif
	forms.pa_obj_s1 = root_passe .. 'tem'
	forms.pa_obj_s2 = root_passe .. 'ted'
	forms.pa_obj_s3 = root_passe .. 'te'
	forms.pa_obj_p1 = root_passe .. 'tük'
	forms.pa_obj_p2 = root_passe .. 'tétek'
	forms.pa_obj_p3 = root_passe .. 'ték'

    if (forms.p_imp_obj_s2) then
        forms.p_imp_obj_s2 = mw.ustring.gsub(forms.p_imp_obj_s2, 'dsd$', 'dd')
    end

    if (args.intransitif) then
        for key, value in pairs(forms) do
            if mw.ustring.find(key, 'obj') then forms[key] = nil end
        end
    end

	return forms
end

--------------------
-- Verbes sombres --
--------------------
function p.conj_sombre_reguliere(title, forms, caract, args)
    -- Déclinaisons en -ek à la 1ère personne du singulier
    -- du présent de l'indicatif

    --local root = ''
    --local root_imp = ''
    --local root_passe = ''
    --local root_voy = ''
    root, root2, root_imp, root_passe, root_voy = p.get_roots(title, caract, args)

    -- infinitif
    forms.inf = root_voy .. 'ni'

	-- indicatif subjectif
	forms.p_ind_subj_s1 = root2 .. 'ok'
    forms.p_ind_subj_s1_2 = nil
    if (args.m) then
        forms.p_ind_subj_s1 = root2 .. 'om'
        forms.p_ind_subj_s1_2 = root2 .. 'ok'
    end
    if (args.voy_var) then
    	forms.p_ind_subj_s1 = root2 .. 'ok'
    	forms.p_ind_subj_s1_2 = root .. 'ok'
    end
    
	forms.p_ind_subj_s2 = root_voy .. 'sz'
	if mw.ustring.match(root, '[aáoóuúeéiíöőüű]z$') then
    	forms.p_ind_subj_s2 = root2 .. 'ol'
    	if (args.voy_var) then
    		forms.p_ind_subj_s2_2 = root .. 'ol'
    	end
    elseif (caract.ends_with_s_or_z or caract.ends_with_sz or mw.ustring.match(title, '[sz]ik$')) then
        forms.p_ind_subj_s2 = root .. 'ol'
    end
    
	forms.p_ind_subj_s3 = title
	if (args.voy_var) then
		forms.p_ind_subj_p1_2 = root .. 'unk'
	end
	forms.p_ind_subj_p1 = root2 .. 'unk'
    forms.p_ind_subj_p2 = root .. 'tok'
    if (root_passe ~= root and not args.passe) then  -- bricolage
        forms.p_ind_subj_p2 = root_passe .. 'ok'
    end
    if (args.passe == 't') then
        forms.p_ind_subj_p2 = root .. 'otok'
        forms.p_ind_subj_p2_2 = root .. 'tok'
    end
	forms.p_ind_subj_p3 = root_voy .. 'nak'

	-- indicatif objectif
	if (args.voy_var) then
		forms.p_ind_obj_s1_2 = root .. 'om'
		forms.p_ind_obj_s2_2 = root .. 'od'
	end
	forms.p_ind_obj_s1 = root2 .. 'om'
	forms.p_ind_obj_s2 = root2 .. 'od'
	forms.p_ind_obj_s3 = root .. 'ja'
    if (caract.ends_with_s_or_z or caract.ends_with_sz) then
        forms.p_ind_obj_s3 = root .. caract.last_1 .. 'a'
    end
	forms.p_ind_obj_p1 = root .. 'juk'
    forms.p_ind_obj_p2 = root .. 'játok'
	forms.p_ind_obj_p3 = root .. 'ják'
    if (caract.ends_with_s_or_z) then
        forms.p_ind_obj_p1 = root .. caract.last_1 .. 'uk'
        forms.p_ind_obj_p2 = root .. caract.last_1 .. 'átok'
    	forms.p_ind_obj_p3 = root .. caract.last_1 .. 'ák'
    end

	-- conditionnel subjectif
	forms.p_cond_subj_s1 = root_voy .. 'nék'
	forms.p_cond_subj_s2 = root_voy .. 'nál'
	forms.p_cond_subj_s3 = root_voy .. 'na'
	forms.p_cond_subj_p1 = root_voy .. 'nánk'
	forms.p_cond_subj_p2 = root_voy .. 'nátok'
	forms.p_cond_subj_p3 = root_voy .. 'nának'

	-- conditionnel objectif
	forms.p_cond_obj_s1 = root_voy .. 'nám'
	forms.p_cond_obj_s2 = root_voy .. 'nád'
	forms.p_cond_obj_s3 = root_voy .. 'ná'
	forms.p_cond_obj_p1 = root_voy .. 'nánk'
	forms.p_cond_obj_p2 = root_voy .. 'nátok'
	forms.p_cond_obj_p3 = root_voy .. 'nák'

	-- impératif subjectif
	forms.p_imp_subj_s1 = root_imp .. 'ak'
    forms.p_imp_subj_s1_2 = nil
    if (args.m) then
        if (mw.ustring.match(root, '[sz]$')) then
            local root_last_1 = mw.ustring.sub(root, -1, -1)
            forms.p_imp_subj_s1 = root .. root_last_1 .. 'am'
            forms.p_imp_subj_s1_2 = root .. root_last_1 .. 'ak'
        else
            forms.p_imp_subj_s1 = root_imp .. 'am'
            forms.p_imp_subj_s1_2 = root_imp .. 'ak'
        end
    end
	forms.p_imp_subj_s2 = root_imp
    forms.p_imp_subj_s2_2 = root_imp .. 'ál'
	forms.p_imp_subj_s3 = root_imp .. 'on'
	if (args.subj_s3) then
		forms.p_imp_subj_s3_2 = root_imp .. 'ék'
	end
	forms.p_imp_subj_p1 = root_imp .. 'unk'
	forms.p_imp_subj_p2 = root_imp .. 'atok'
	forms.p_imp_subj_p3 = root_imp .. 'anak'

	-- impératif objectif
	forms.p_imp_obj_s1 = root_imp .. 'am'
    forms.p_imp_obj_s2 = root .. 'd'
    if (mw.ustring.match(title, 'sz?t$')) then
        forms.p_imp_obj_s2 = caract.without_last_1 .. 'd'
    elseif (caract.ends_with_it or caract.ends_with_diff_consonants) then
        forms.p_imp_obj_s2 = root .. 'sd'
    elseif (mw.ustring.match(title, '[eöuü]t$')) then
        forms.p_imp_obj_s2 = caract.without_last_1 .. 'sd'
    end
    forms.p_imp_obj_s2_2 = root_imp .. 'ad'
	forms.p_imp_obj_s3 = root_imp .. 'a'
	forms.p_imp_obj_p1 = root_imp .. 'uk'
	forms.p_imp_obj_p2 = root_imp .. 'átok'
	forms.p_imp_obj_p3 = root_imp .. 'ák'

    -- passé indicatif subjectif
	forms.pa_subj_s1 = root_passe .. 'tam'
	forms.pa_subj_s2 = root_passe .. 'tál'
	forms.pa_subj_s3 = root_passe .. 't'
    if (caract.ends_with_s_or_z or caract.ends_with_sz or caract.ends_with_ik or args.passe) then
        forms.pa_subj_s3 = root .. 'ott'
    end
	forms.pa_subj_p1 = root_passe .. 'tunk'
	forms.pa_subj_p2 = root_passe .. 'tatok'
	forms.pa_subj_p3 = root_passe .. 'tak'

	-- passé indicatif objectif
	forms.pa_obj_s1 = root_passe .. 'tam'
	forms.pa_obj_s2 = root_passe .. 'tad'
	forms.pa_obj_s3 = root_passe .. 'ta'
	forms.pa_obj_p1 = root_passe .. 'tuk'
	forms.pa_obj_p2 = root_passe .. 'tátok'
	forms.pa_obj_p3 = root_passe .. 'ták'

    if (forms.p_imp_obj_s2) then
        forms.p_imp_obj_s2 = mw.ustring.gsub(forms.p_imp_obj_s2, 'dsd$', 'dd')
    end

    if (args.intransitif) then
        for key, value in pairs(forms) do
            if mw.ustring.find(key, 'obj') then forms[key] = nil end
        end
    end

	return forms
end

-------------------
-- Verbes mixtes --
-------------------

function p.conj_mixte_reguliere(title, forms, caract, args)
    root, root2, root_imp, root_passe, root_voy = p.get_roots(title, caract, args)

    -- infinitif
    forms.inf = root_voy .. 'ni'

	-- indicatif subjectif
	forms.p_ind_subj_s1 = root2 .. 'ök'
    forms.p_ind_subj_s1_2 = nil
    if (args.m) then
        forms.p_ind_subj_s1 = root2 .. 'öm'
        forms.p_ind_subj_s1_2 = root2 .. 'ök'
    end
    if (args.voy_var) then
    	forms.p_ind_subj_s1 = root2 .. 'ök'
    	forms.p_ind_subj_s1_2 = root .. 'ök'
    end
    
	forms.p_ind_subj_s2 = root_voy .. 'sz'
	if mw.ustring.match(root, '[aáoóuúeéiíöőüű]z$') then
    	forms.p_ind_subj_s2 = root2 .. 'öl'
    	if (args.voy_var) then
    		forms.p_ind_subj_s2_2 = root .. 'öl'
    	end
    elseif (caract.ends_with_s_or_z or caract.ends_with_sz or mw.ustring.match(title, '[sz]ik$')) then
        forms.p_ind_subj_s2 = root .. 'öl'
    end
	forms.p_ind_subj_s3 = title
	if (args.voy_var) then
		forms.p_ind_subj_p1_2 = root .. 'ünk'
	end
	forms.p_ind_subj_p1 = root2 .. 'ünk'
    forms.p_ind_subj_p2 = root .. 'tök'
    if (root_passe ~= root and not args.passe) then  -- bricolage
        forms.p_ind_subj_p2 = root_passe .. 'ök'
    end
    if (args.passe == 't') then
        forms.p_ind_subj_p2 = root .. 'ötök'
        forms.p_ind_subj_p2_2 = root .. 'tök'
    end
	forms.p_ind_subj_p3 = root_voy .. 'nek'

	-- indicatif objectif
	if (args.voy_var) then
		forms.p_ind_obj_s1_2 = root .. 'öm'
		forms.p_ind_obj_s2_2 = root .. 'öd'
		forms.p_ind_obj_s3_2 = root .. 'i'
	end
	forms.p_ind_obj_s1 = root2 .. 'öm'
	forms.p_ind_obj_s2 = root2 .. 'öd'
	forms.p_ind_obj_s3 = root2 .. 'i'
	forms.p_ind_obj_p1 = root .. 'jük'
	if (caract.ends_with_s_or_z) then
        forms.p_ind_obj_p1 = root .. caract.last_1 .. 'ük'
    end
	if (args.voy_var) then
    	forms.p_ind_obj_p2_2 = root .. 'itek'
		forms.p_ind_obj_p3_2 = root .. 'ik'
	end
    forms.p_ind_obj_p2 = root2 .. 'itek'
	forms.p_ind_obj_p3 = root2 .. 'ik'

	-- conditionnel subjectif
	forms.p_cond_subj_s1 = root_voy .. 'nék'
	forms.p_cond_subj_s2 = root_voy .. 'nél'
	forms.p_cond_subj_s3 = root_voy .. 'ne'
	forms.p_cond_subj_p1 = root_voy .. 'nénk'
	forms.p_cond_subj_p2 = root_voy .. 'nétek'
	forms.p_cond_subj_p3 = root_voy .. 'nének'

	-- conditionnel objectif
	forms.p_cond_obj_s1 = root_voy .. 'ném'
	forms.p_cond_obj_s2 = root_voy .. 'néd'
	forms.p_cond_obj_s3 = root_voy .. 'né'
	forms.p_cond_obj_p1 = root_voy .. 'nénk'
	forms.p_cond_obj_p2 = root_voy .. 'nétek'
	forms.p_cond_obj_p3 = root_voy .. 'nék'

	-- impératif subjectif
	forms.p_imp_subj_s1 = root_imp .. 'ek'
    forms.p_imp_subj_s1_2 = nil
    if (args.m) then
        if (mw.ustring.match(root, '[sz]$')) then
            local root_last_1 = mw.ustring.sub(root, -1, -1)
            forms.p_imp_subj_s1 = root .. root_last_1 .. 'em'
            forms.p_imp_subj_s1_2 = root .. root_last_1 .. 'ek'
        else
            forms.p_imp_subj_s1 = root_imp .. 'em'
            forms.p_imp_subj_s1_2 = root_imp .. 'ek'
        end
    end
	forms.p_imp_subj_s2 = root_imp
    forms.p_imp_subj_s2_2 = root_imp .. 'él'
	forms.p_imp_subj_s3 = root_imp .. 'ön'
	if (args.subj_s3) then
		forms.p_imp_subj_s3_2 = root_imp .. 'ék'
	end
	forms.p_imp_subj_p1 = root_imp .. 'ünk'
	forms.p_imp_subj_p2 = root_imp .. 'etek'
	forms.p_imp_subj_p3 = root_imp .. 'enek'

	-- impératif objectif
	forms.p_imp_obj_s1 = root_imp .. 'em'
    forms.p_imp_obj_s2 = root .. 'd'
    if (mw.ustring.match(title, 'sz?t$')) then
        forms.p_imp_obj_s2 = caract.without_last_1 .. 'd'
    --elseif (caract.ends_with_it or caract.ends_with_diff_consonants) then
        --forms.p_imp_obj_s2 = root .. 'sd'
    elseif (mw.ustring.match(title, '[eöuü]t$')) then
        forms.p_imp_obj_s2 = caract.without_last_1 .. 'sd'
    end
    forms.p_imp_obj_s2_2 = root_imp .. 'ed'
	forms.p_imp_obj_s3 = root_imp .. 'e'
	forms.p_imp_obj_p1 = root_imp .. 'ük'
	forms.p_imp_obj_p2 = root_imp .. 'étek'
	forms.p_imp_obj_p3 = root_imp .. 'ék'

    -- passé indicatif subjectif
	forms.pa_subj_s1 = root_passe .. 'tem'
	forms.pa_subj_s2 = root_passe .. 'tél'
	forms.pa_subj_s3 = root_passe .. 't'
    if (caract.ends_with_s_or_z or caract.ends_with_sz or caract.ends_with_ik or args.passe) then
        forms.pa_subj_s3 = root .. 'ött'
    end
	forms.pa_subj_p1 = root_passe .. 'tünk'
	forms.pa_subj_p2 = root_passe .. 'tetek'
	forms.pa_subj_p3 = root_passe .. 'tek'

	-- passé indicatif objectif
	forms.pa_obj_s1 = root_passe .. 'tem'
	forms.pa_obj_s2 = root_passe .. 'ted'
	forms.pa_obj_s3 = root_passe .. 'te'
	forms.pa_obj_p1 = root_passe .. 'tük'
	forms.pa_obj_p2 = root_passe .. 'tétek'
	forms.pa_obj_p3 = root_passe .. 'ték'

    if (forms.p_imp_obj_s2) then
        forms.p_imp_obj_s2 = mw.ustring.gsub(forms.p_imp_obj_s2, 'dsd$', 'dd')
    end

    if (args.intransitif) then
        for key, value in pairs(forms) do
            if mw.ustring.find(key, 'obj') then forms[key] = nil end
        end
    end

	return forms
end

return p