Module:User:Wikitiki89/yi-verb

ពីWiktionary

Documentation for this module may be created at Module:User:Wikitiki89/yi-verb/doc

local m_utilities = require("Module:utilities")
local m_tr = require("Module:yi-translit")

local export = {}

local lang = require("Module:languages").getLanguageByCode("yi")

-- Within this module, conjugations are the functions that do the actual
-- conjugating by creating the forms of a basic verb (not prefixed or
-- separable). They are defined further down.
local conjugations = {}

-- The main entry point.
-- This is the only function that can be invoked from a template.
function export.conjugate(frame)
    local conj_type = frame.args[1] or error("Conjugation type has not been specified. Please pass parameter 1 to the module invocation.")
    local args = frame:getParent().args
    PAGENAME = mw.title.getCurrentTitle().text
    SUBPAGENAME = mw.title.getCurrentTitle().subpageText
    NAMESPACE = mw.title.getCurrentTitle().nsText

    local forms, title, categories

    if conjugations[conj_type] then
        forms, title, categories = conjugations[conj_type](args)
    else
        error("Unknown conjugation type '" .. conj_type .. "'")
    end

    local pre = args["pre"] or ""
    if pre ~= "" then
        table.insert(categories, "Yiddish prefixed verbs")
        title = title .. ", prefixed"
    end

    local sep = args["sep"] or ""
    if sep ~= "" then
        table.insert(categories, "Yiddish separable verbs")
        title = title .. ", separable"
    end

    sep_pre(forms, sep, pre)

    if (args["bot"] or "") ~= "" then
        return make_bot_list(forms, sep ~= "")
    else
        return make_table(forms, title, args["aux"] or "hebben", sep ~= "") .. m_utilities.format_categories(categories, lang)
    end
end

local requires_e = {
    ["נ"] = true,
    ["ן"] = true,
    ["נג"] = true,
    ["נק"] = true,
    ["מ"] = true,
    ["ם"] = true,
    ["יי"] = true,
    ["ײ"] = true,
    ["ייַ"] = true,
    ["ײַ"] = true,
    ["ײַ"] = true,
    ["י"] = true,
    ["יִ"] = true,
    ["יִ"] = true,
    ["וּ"] = true,
    ["אָ"] = true,
    ["אַ"] = true,
    ["ע"] = true,
}

local to_final_map = {
    ["כ"] = "ך",
    ["מ"] = "ם",
    ["נ"] = "ן",
    ["פ"] = "ף",
    ["צ"] = "ץ",
}

local from_final_map = {
    ["ך"] = "כ",
    ["ם"] = "מ",
    ["ן"] = "נ",
    ["ף"] = "פ",
    ["ץ"] = "צ",
}

function to_final_replacer(letter, rest)
    return (to_final_map[letter] or letter) .. rest
end

function from_final_replacer(letter, rest)
    return (from_final_map[letter] or letter) .. rest
end

function finalize(x)
    return mw.ustring.gsub(x, "[א-ת][^א-ת]*$", to_final_replacer)
end

function unfinalize(x)
    return mw.ustring.gsub(x, "[א-ת][^א-ת]*$", from_final_replacer)
end

function stem_requires_e(stem)
    stem3 = mw.ustring.sub(stem, -3)
    stem2 = mw.ustring.sub(stem3, 2)
    stem1 = mw.ustring.sub(stem2, 1)
    return requires_e[stem1] or requires_e[stem2] or requires_e[stem3]
end

function get_stem(args)
    local inf = args["inf"] or SUBPAGENAME
    if args["e"] == "" then
        args["e"] = nil
    elseif args["e"] == "-" then
        args["e"] = false
    end
    if args["en"] == "" then
        args["en"] = nil
    elseif args["en"] == "-" then
        args["en"] = false
    end
    local stem = args["stem"] or args[1]
    if stem then
        if mw.ustring.sub(inf, -1) ~= "ן" then
            if mw.ustring.sub(inf, -1) == "ע" then
                args["e"] = true
                stem = mw.ustring.sub(inf, 1, -2)
            else
                stem = inf
            end
        elseif mw.ustring.sub(inf, -2, -2) ~= "ע" then
            stem = mw.ustring.sub(inf, 1, -2)
        else
            stem = mw.ustring.sub(inf, 1, -3)
            x = stem_requires_e(stem)
            if args["en"] == nil then
                args["en"] = true
            end
            if args["e"] == nil then
                args["e"] = not x
            end
        end mw.ustring.sub(inf, -3)
    end
    if args["en"] == nil then
        args["en"] = stem_requires_e(stem)
    end
    if stem == "" then
        stem = "־"
    end
    args["stem"] = unfinalize(stem)
    args["tr"] = args["tr"] or m_tr.tr(args["stem"])
end


--[=[
    *** REGULAR VERBS (mostly) ***
]=]--

-- Conjugate a weak verb
conjugations["weak"] = function(args)
    local forms = {}
    local categories = {"Yiddish weak verbs"}
    local title = "weak"

    local pres_stem = args[1] or (NAMESPACE == "Template" and "(1)") or error("The first parameter is missing")
    local pres_stemE = (args[2] or ""); if pres_stemE == "" then pres_stemE = pres_stem .. "e" else pres_stemE = pres_stemE end

    local dt = args["dt"] or ""; if dt == "" then if pres_stemE:find("[cfhkpqstx]e$") then dt = "t" else dt = "d" end end
    local past_stem = pres_stem:gsub("([^aeiou])i$", "%1ie") .. dt .. "e"

    local past_ptc_stem = (args[3] or ""); if past_ptc_stem == "" then past_ptc_stem = make_long(pres_stem) .. (pres_stem:find("[dt]$") and "" or dt) end

    if past_ptc_stem:find("n$") then
        table.insert(categories, "Yiddish weak verbs with strong past participles")
        title = title .. " with strong past participle"
    end

    present(forms, pres_stem, pres_stemE)
    past(forms, past_stem, past_stem, past_stem)
    forms["past_ptc"] = past_ptc_stem

    -- "zeggen" has an irregular past tense alongside the regular one
    if pres_stem == "zeg" then
        local forms2 = {}
        past(forms2, "zei", "zeide", "zeidt")

        for key, form in pairs(forms2) do
            forms[key] = {forms2[key], forms[key]}
        end
        table.insert(categories, "Yiddish irregular weak verbs")
        title = title .. ", irregular"
    end

    return forms, title, categories
end

-- Conjugate a weak verb with a past tense in -cht
conjugations["weak-cht"] = function(args)
    local forms = {}
    local categories = {"Yiddish weak verbs (-cht)"}
    local title = "weak with past in ''-cht''"

    local pres_stem = args[1] or (NAMESPACE == "Template" and "(1)") or error("The first parameter is missing")
    local pres_stemE = args[2] or ""; if pres_stemE == "" then pres_stemE = pres_stem .. "e" end

    local past_stem = (args[3] or (NAMESPACE == "Template" and "(3)") or error("The third parameter is missing")) .. "cht"

    present(forms, pres_stem, pres_stemE)
    past(forms, past_stem, past_stem .. "e", past_stem)
    forms["past_ptc"] = past_stem

    return forms, title, categories
end

-- Conjugate a strong verb
conjugations["strong"] = function(args)
    local forms = {}
    local class = args["class"] or ""; if class ~= "" then class = " class " .. class end
    local categories = {"Yiddish" .. class .. " strong verbs"}
    local title = "strong" .. class

    local pres_stem = args[1] or (NAMESPACE == "Template" and "(1)") or error("The first parameter is missing")
    local pres_stemE = args[4] or ""; if pres_stemE == "" then pres_stemE = pres_stem .. "e" end

    local past_stem = args[2] or (NAMESPACE == "Template" and "(2)") or error("The second parameter is missing")
    local past_stemT = args[6] or ""; if past_stemT == "" then past_stemT = past_stem .. (past_stem:find("t$") and "" or "t") end
    local past_stemE = args[5] or ""; if past_stemE == "" then past_stemE = past_stem .. "e" end

    local past_ptc_stem = args[3] or (NAMESPACE == "Template" and "(3)") or error("The third parameter is missing")

    -- If the final consonant of the past participle is not n, then it is a weak past participle.
    if not past_ptc_stem:find("n$") then
        table.insert(categories, "Yiddish strong verbs with weak past participles")
        title = title .. " with weak past participle"
    end

    present(forms, pres_stem, pres_stemE)
    past(forms, past_stem, past_stemE, past_stemT)
    forms["past_ptc"] = past_ptc_stem

    -- "houden" and "snijden" have alternative forms without the final -d
    if pres_stem == "houd" then
        forms["pres_indc_1sg"] = {"hou", "houd"}
        forms["impr_sg"] = {"hou", "houd"}
        table.insert(categories, "Yiddish irregular strong verbs")
        title = title .. ", irregular"
    elseif pres_stem == "snijd" then
        forms["pres_indc_1sg"] = {"snij", "snijd"}
        forms["impr_sg"] = {"snij", "snijd"}
        table.insert(categories, "Yiddish irregular strong verbs")
        title = title .. ", irregular"
    -- If the initial or final consonants of the present stem don't match, then this verb is irregular.
    elseif pres_stem:match("^([^aeiouyj]*)") ~= past_stem:match("^([^aeiouyj]*)") or pres_stem:match("([^aeiouyj]*)$") ~= past_stem:match("([^aeiouyj]*)$") then
        table.insert(categories, "Yiddish irregular strong verbs")
        title = title .. ", irregular"
    end

    return forms, title, categories
end


--[=[
    *** IRREGULAR VERBS ***
]=]--

conjugations["hebben"] = function(args)
    local forms = {}
    local categories = {"Yiddish irregular weak verbs"}
    local title = "weak, irregular"

    present(forms, "heb", "hebbe")
    past(forms, "had", "hadde", "hadt")
    forms["past_ptc"] = "had"

    forms["pres_indc_u"] = {"hebt", "heeft"}
    forms["pres_indc_3sg"] = "heeft"

    return forms, title, categories
end

conjugations["kunnen"] = function(args)
    local forms = {}
    local categories = {"Yiddish preterite-present verbs"}
    local title = "preterite-present"

    forms["pres_indc_1sg"] = "kan"
    forms["pres_indc_2sg"] = {"kunt", "kan"}
    forms["pres_indc_gij"] = "kunt"
    forms["pres_indc_3sg"] = "kan"
    forms["pres_indc_pl"]  = "kunnen"
    forms["pres_subj_sg"]  = "kunne"

    past(forms, "kon", "konde", "kondt")

    forms["impr_sg"] = ""
    forms["impr_pl"] = ""

    forms["pres_ptc"] = "kunnend"
    forms["past_ptc"] = "kund"

    return forms, title, categories
end

conjugations["moeten"] = function(args)
    local forms = {}
    local categories = {"Yiddish preterite-present verbs"}
    local title = "preterite-present"

    present(forms, "moet", "moete")
    past(forms, "moest", "moeste", "moest")
    forms["past_ptc"] = "moeten"

    return forms, title, categories
end

conjugations["mogen"] = function(args)
    local forms = {}
    local categories = {"Yiddish preterite-present verbs"}
    local title = "preterite-present"

    forms["pres_indc_1sg"] = "mag"
    forms["pres_indc_2sg"] = "mag"
    forms["pres_indc_gij"] = "moogt"
    forms["pres_indc_3sg"] = "mag"
    forms["pres_indc_pl"]  = "mogen"
    forms["pres_subj_sg"]  = "moge"

    past(forms, "mocht", "mochte", "mocht")

    forms["impr_sg"] = ""
    forms["impr_pl"] = ""

    forms["pres_ptc"] = "mogend"
    forms["past_ptc"] = "mogen"

    return forms, title, categories
end

conjugations["weten"] = function(args)
    local forms = {}
    local categories = {"Yiddish preterite-present verbs"}
    local title = "preterite-present"

    present(forms, "weet", "wete")
    past(forms, "wist", "wiste", "wist")
    forms["past_ptc"] = "weten"

    return forms, title, categories
end

conjugations["willen"] = function(args)
    local forms = {}
    local forms2 = {}
    local categories = {"Yiddish irregular verbs"}
    local title = "irregular"

    present(forms, "wil", "wille")
    past(forms, "wilde", "wilde", "wilde")

    -- has two possible past tenses
    past(forms2, "wou", "woude", "woudt")
    for key, form in pairs(forms2) do
        forms[key] = {forms[key], forms2[key]}
    end

    forms["past_ptc"] = "wild"

    forms["pres_indc_2sg"] = {"wil", "wilt"}
    forms["pres_indc_3sg"] = "wil"

    return forms, title, categories
end

conjugations["zijn"] = function(args)
    local forms = {}
    local categories = {"Yiddish irregular verbs"}
    local title = "irregular, suppletive"

    present(forms, "ben", "zij")
    past(forms, "was", "ware", "waart")
    forms["past_ptc"] = "weest"

    forms["pres_indc_gij"] = "zijt"
    forms["pres_indc_3sg"] = "is"
    forms["impr_sg"] = {"wees", "ben"}
    forms["impr_pl"] = {"weest", "zijt"}

    return forms, title, categories
end

conjugations["zullen"] = function(args)
    local forms = {}
    local categories = {"Yiddish preterite-present verbs"}
    local title = "preterite-present"

    forms["pres_indc_1sg"] = "zal"
    forms["pres_indc_2sg"] = {"zult", "zal"}
    forms["pres_indc_3sg"] = "zal"
    forms["pres_indc_gij"] = "zult"
    forms["pres_indc_pl"]  = "zullen"
    forms["pres_subj_sg"]  = "zulle"

    past(forms, "zou", "zoude", "zoudt")

    forms["impr_sg"] = ""
    forms["impr_pl"] = ""

    forms["pres_ptc"] = ""
    forms["past_ptc"] = ""

    return forms, title, categories
end

--[=[
    *** HELPER FUNCTIONS ***
]=]--

-- Create regular present-tense forms
function present(forms, pres_stem, pres_stemE)
    local pres_stemT = make_long(pres_stem) .. (pres_stem:find("t$") and "" or "t")

    forms["pres_indc_1sg"] = pres_stem
    forms["pres_indc_2sg"] = pres_stemT
    forms["pres_indc_gij"] = pres_stemT
    forms["pres_indc_3sg"] = pres_stemT
    forms["pres_indc_pl"]  = make_long(pres_stemE) .. "n"
    forms["pres_subj_sg"] = pres_stemE

    forms["impr_sg"] = pres_stem
    forms["impr_pl"] = pres_stemT

    forms["pres_ptc"] = make_long(pres_stemE) .. "nd"
end

-- Create regular past-tense forms
function past(forms, past_stem, past_stemE, past_stemT)
    forms["past_indc_sg"]  = past_stem
    forms["past_indc_gij"] = past_stemT
    forms["past_indc_pl"]  = past_stemE .. "n"
    forms["past_subj_sg"] = past_stemE
end

-- Add the separable part and unstressed prefix to all the verb forms
function sep_pre(forms, sep, pre)
    -- sepSuf is empty if sep is empty
    local sepSuf = (sep ~= "" and " " .. sep or "")
    local sepHyphen = sep

    -- Add a hyphen after the separable part if it ends with the same vowel
    -- that the main/prefixed verb begins with, for verbs like na-apen
    if sep ~= "" and mw.ustring.find("aeiou", sep:sub(-1)) and sep:sub(-1) == (pre ~= "" and pre or forms["pres_ptc"]):sub(1,1) then
        sepHyphen = sepHyphen .. "-"
    end

    -- For forms without a separate main clause form
    local function add1(key)
        if forms[key] == "" then
            return
        elseif type(forms[key]) == "table" then
            for n, subform in pairs(forms[key]) do
                forms[key][n] = pre .. forms[key][n] .. sepSuf
            end
        else
            forms[key] = pre .. forms[key] .. sepSuf
        end
    end

    -- For forms with a separate main clause form
    local function add2(key)
        if forms[key] == "" then
            return
        elseif type(forms[key]) == "table" then
            forms[key .. "_main"] = {}
            for n, subform in pairs(forms[key]) do
                forms[key .. "_main"][n] = pre .. forms[key][n] .. sepSuf
                forms[key][n]           = sepHyphen .. pre .. forms[key][n]
            end
        else
            forms[key .. "_main"] = pre .. forms[key] .. sepSuf
            forms[key]          = sepHyphen .. pre .. forms[key]
        end
    end

    add2("pres_indc_1sg")
    add2("pres_indc_2sg")
    add2("pres_indc_gij")
    if forms["pres_indc_u"] then add2("pres_indc_u") end
    add2("pres_indc_3sg")
    add2("pres_indc_pl")
    add2("pres_subj_sg")

    add2("past_indc_sg")
    add2("past_indc_gij")
    add2("past_indc_pl")
    add2("past_subj_sg")

    add1("impr_sg")
    add1("impr_pl")

    if forms["pres_ptc"] ~= "" then forms["pres_ptc"] = sepHyphen .. pre .. forms["pres_ptc"] end

    if forms["past_ptc"] ~= "" then
        if pre == "" then
            if mw.ustring.find(forms["past_ptc"], "^[eiu]") and not mw.ustring.find(forms["past_ptc"], "^ij") then
                forms["past_ptc"] = forms["past_ptc"]:gsub("^e", "ë"):gsub("^i", "ï"):gsub("^u", "ü")
            end

            forms["past_ptc"] = sep .. "ge" .. forms["past_ptc"]
        else
            forms["past_ptc"] = sepHyphen .. pre .. forms["past_ptc"]
        end
    end
end

-- A small helper function for those few verbs that have a stem ending in a
-- vowel (like gaan, staan, skiën, echoën). This lengthens the stem-final vowel.
function make_long(form)
    return form:gsub("([^aeiou])([ao])$", "%1%2%2"):gsub("([^aeiou])i$", "%1ie")
end

-- Make the table
function make_table(forms, title, aux, hasSep)
    -- Make links out of all forms
    for key, form in pairs(forms) do
        forms[key] = com.link_form(form)
    end

    if forms["past_ptc"] ~= "—" then
        forms["past_ptc"] = "(" .. com.link_form(aux) .. ") " .. forms["past_ptc"]
    end

    return [=[
<div class="NavFrame" style="width: ]=] .. (hasSep and 72 or 42) .. [=[em;">
<div class="NavHead" style="background: #CCCCFF; text-align: left;">Conjugation of '']=] .. forms["pres_indc_pl"] .. "''" .. (title and " (" .. title .. ")" or "") .. [=[</div>
<div class="NavContent">
{| style="width:100%; border:1px solid #CCCCFF; text-align:center; line-height:125%" class="inflection-table" cellspacing="1" cellpadding="3"
|- style="background: #F2F2FF;"
! style="background: #CCCCFF;" | [[infinitive]]
| colspan="4" | ]=] .. forms["pres_indc_pl"] .. [=[

]=] .. (hasSep and [=[|- style="background: #E6E6FF;"
|
| colspan="2" style="font-weight: bold;" | [[main&nbsp;clause]]
| colspan="2" style="font-weight: bold;" | [[subordinate&nbsp;clause]]
|- style="background: #E6E6FF;"
|
| style="width: 25%; font-weight: bold" | [[present&nbsp;tense]]
| style="width: 25%; font-weight: bold" | [[past&nbsp;tense]]
| style="width: 25%; font-weight: bold" | [[present&nbsp;tense]]
| style="width: 25%; font-weight: bold" | [[past&nbsp;tense]]]=] or [=[

|- style="background: #E6E6FF;"
|
| style="width: 50%; font-weight: bold" | [[present&nbsp;tense]]
| style="width: 50%; font-weight: bold" | [[past&nbsp;tense]]]=]) .. [=[

|- style="background: #F2F2FF;"
! style="background: #CCCCFF;" | [[first-person|1st&nbsp;person]]&nbsp;[[singular]]
| ]=] .. (hasSep and forms["pres_indc_1sg_main"] .. " || " .. forms["past_indc_sg_main"] .. " || " or "") .. forms["pres_indc_1sg"] .. " || " .. forms["past_indc_sg"] .. [=[

|- style="background: #F2F2FF;"
! style="background: #CCCCFF;" | [[second-person|2nd&nbsp;person]]&nbsp;[[singular]]
| ]=] .. (hasSep and forms["pres_indc_2sg_main"] .. " || " .. forms["past_indc_sg_main"] .. " || " or "") .. forms["pres_indc_2sg"] .. " || " .. forms["past_indc_sg"] .. [=[

]=] .. (forms["pres_indc_u"] and [=[|- style="background: #F2F2FF;"
! style="background: #CCCCFF;" | [[second-person|2nd&nbsp;person]]&nbsp;[[singular|sing.]]&nbsp;(<span lang="yi">[[u#Yiddish|u]]</span>)
| ]=] .. (hasSep and forms["pres_indc_u_main"] .. " || " .. forms["past_indc_sg_main"] .. " || " or "") .. forms["pres_indc_u"] .. " || " .. forms["past_indc_sg"] .. [=[

]=] or "") .. ((forms["pres_indc_gij"] ~= forms["pres_indc_2sg"] or forms["past_indc_gij"] ~= forms["past_indc_sg"]) and [=[|- style="background: #F2F2FF;"
! style="background: #CCCCFF;" | [[second-person|2nd&nbsp;person]]&nbsp;[[singular|sing.]]&nbsp;(<span lang="yi">[[gij#Yiddish|gij]]</span>)
| ]=] .. (hasSep and forms["pres_indc_gij_main"] .. " || " .. forms["past_indc_gij_main"] .. " || " or "") .. forms["pres_indc_gij"] .. " || " .. forms["past_indc_gij"] .. [=[

]=] or "") .. [=[|- style="background: #F2F2FF;"
! style="background: #CCCCFF;" | [[third-person|3rd&nbsp;person]]&nbsp;[[singular]]
| ]=] .. (hasSep and forms["pres_indc_3sg_main"] .. " || " .. forms["past_indc_sg_main"] .. " || " or "") .. forms["pres_indc_3sg"] .. " || " .. forms["past_indc_sg"] .. [=[

|- style="background: #F2F2FF;"
! style="background: #CCCCFF;" | [[plural]]
| ]=] .. (hasSep and forms["pres_indc_pl_main"] .. " || " .. forms["past_indc_pl_main"] .. " || " or "") .. forms["pres_indc_pl"] .. " || " .. forms["past_indc_pl"] .. [=[

|- style="background: #E6E6FF; height: 0.5em"
|
| colspan="2" |]=] .. (hasSep and [=[ || colspan="2" |]=] or "") .. [=[

|- style="background: #F2F2FF;"
! style="background: #CCCCFF;" | [[subjunctive]]&nbsp;[[singular|sing.]]<sup>1</sup>
| ]=] .. (hasSep and forms["pres_subj_sg_main"] .. " || " .. forms["past_subj_sg_main"] .. " || " or "") .. forms["pres_subj_sg"] .. " || " .. forms["past_subj_sg"] .. [=[

|- style="background: #F2F2FF;"
! style="background: #CCCCFF;" | [[subjunctive]]&nbsp;[[plural|plur.]]<sup>1</sup>
| ]=] .. (hasSep and forms["pres_indc_pl_main"] .. " || " .. forms["past_indc_pl_main"] .. " || " or "") .. forms["pres_indc_pl"] .. " || " .. forms["past_indc_pl"] .. [=[

|- style="background: #E6E6FF; height: 0.5em"
|
| colspan="2" |]=] .. (hasSep and [=[ || rowspan="5" colspan="2" |]=] or "") .. [=[

|- style="background: #F2F2FF;"
! style="background: #CCCCFF;" | [[imperative]]&nbsp;[[singular|sing.]]
| ]=] .. forms["impr_sg"] .. [=[

| rowspan="2" style="background: #E6E6FF;" |
|- style="background: #F2F2FF;"
! style="background: #CCCCFF;" | [[imperative]]&nbsp;[[plural|plur.]]<sup>1</sup>
| ]=] .. forms["impr_pl"] .. [=[

|- style="background: #E6E6FF; height: 0.5em"
|
| colspan="2" |
|- style="background: #F2F2FF;"
! style="background: #CCCCFF;" | [[participles]]
| ]=] .. forms["pres_ptc"] .. " || " .. forms["past_ptc"] .. [=[

|- style="background: #E6E6FF;"
| colspan="5" style="text-align:left; vertical-align:top; font-size: smaller; line-height: 1em" | <sup>1)</sup> [[Wiktionary:Glossary#archaic|Archaic]].
|}</div></div>]=]
end

function make_bot_list(forms, hasSep)
    local ret = ""

    if hasSep then
        ret = ret .. "* sep=1\n"
    end

    for key, form in pairs(forms) do
        if type(form) == "table" then
            for key2, subform in ipairs(form) do
                ret = ret .. "* " .. key .. "_" .. key2 .. "=" .. subform .. "\n"
            end
        else
            ret = ret .. "* " .. key .. "=" .. form .. "\n"
        end
    end

    return ret
end

return export