Module:User:Mårtensås/sv-verbs

local m_utilities = require("Module:utilities") local m_links = require("Module:links")

local export = {}

local lang = require("Module:languages").getByCode("sv") local vowel = "[aeiouyåäö]" local consonant = "[bcdfghjklmnpqrstvwxz]"

local current_title = mw.title.getCurrentTitle local namespace = current_title.nsText

local inflections = {}

-- Shifts down all integer arguments, removing argument 1, even when there are -- gaps. For instance, { 1, nil, 3 } will become { nil, 3 }. -- An improved version of table.remove(args, 1). local function remove_arg_1(args) local new_args = {} for k, v in pairs(args) do		if require("Module:table").isPositiveInteger(k) then if k > 1 then new_args[k - 1] = v			end else new_args[k] = v		end end return new_args 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 if current_title.text == "Module:User:Mårtensås/sv-nouns-obs" or current_title.text == "Module:User:Mårtensås/sv-nouns-obs/documentation" then args = frame:getParent.args else args = remove_arg_1(frame.args) end if not inflections[infl_type] then error("Unknown inflection type '" .. infl_type .. "'") end

local data = {head = args["head"] or mw.title.getCurrentTitle.text, definitions = "", forms = {}, categories = {}}

-- Generate the forms inflections[infl_type](args, data)

-- Postprocess postprocess(args, data)

return make_table(data) .. m_utilities.format_categories(data.categories, lang) end

function postprocess(args, data) if args["noa"] then for key, form in pairs(data.forms) do			if (key:find("actv$")) then data.forms[key] = nil end end

-- default handling of participles for passive-only verbs if not args["prepart"] then for key, form in pairs(data.forms) do				if key == "prespart" then for i, subform in ipairs(form) do form[i] = form[i] .. "s" end end end end if not args["pp"] then data.forms["pastpart"] = nil end else -- only deponent verbs have passive imperative forms data.forms["imppasv"] = nil data.forms["impppasv"] = nil end

if args["nop"] then for key, form in pairs(data.forms) do			if (key:find("pasv$")) then data.forms[key] = nil end end end

if args["noprepart"] then data.forms["prespart"] = nil end

if args["nopp"] then data.forms["pastpart"] = nil end

-- add particle to participles; it is added separately for the table later if args["particle"] or args["particle2"] then data.particle = args["particle"] table.insert(data.categories, "Swedish phrasal verbs") local part = args["particle2"] or args["particle"] or "" for key, form in pairs(data.forms) do			if key == "prespart" or key == "pastpart" then for i, subform in ipairs(form) do form[i] = part .. form[i] end end end end if args["note"] and data.definitions and data.definitions:find("%)$") then		data.definitions = mw.ustring.sub(data.definitions, 1, mw.ustring.len(data.definitions) - 1) .. ", " .. args["note"] .. ")" end end

local function split_multi(forms) if not forms or forms == "" or forms == "-" then return nil end return mw.text.split(forms, ",") end

--[=[	Inflection functions ]=]--

local function make_passive(forms) local pasv = {} for i, subform in ipairs(forms) do table.insert(pasv, subform .. "s") end return pasv end

local weak_present_endings = { ["r"] = "", ["a"] = "r", ["vw"] = "r", ["fv"] = "ver", ["mm"] = "mer", ["nn"] = "ner" }

local weak_past_endings = { ["t"] = "", ["d"] = "", ["s"] = "t", ["vl"] = "t", ["vw"] = "dd" }

local weak_sup_endings = { ["t"] = "", ["vw"] = "tt" }

local weak_part_endings = { ["vw"] = "ende" }

local weak_prespasv_endings1 = { ["nn"] = "ns" }

local weak_prespasv_endings2 = { ["fv"] = "ves", ["mm"] = "mes", ["nn"] = "nes" }

local weak_subj_endings = { ["mm"] = "me", ["nn"] = "ne" }

local function make_weak_present_form(stem, endc) local result = {stem .. (weak_present_endings[endc] or "er")} if endc == "dj" then table.insert(result, stem .. "jer") end return result end

local function make_weak_prespasv_form(stem, endc) if endc == "s" then return {stem .. "es"} end local result = {stem .. (weak_prespasv_endings1[endc] or "s")} if endc ~= "vw" and endc ~= "a" then table.insert(result, stem .. (weak_prespasv_endings2[endc] or "es")) end if endc == "dj" then table.insert(result, stem .. "jes") end return result end

inflections["weak"] = function(args, data) data.definitions = "(weak)" table.insert(data.categories, "Swedish weak verbs")

local head = data.head -- remove passive final -s to make forms correct if head:find("s$") and args["noa"] then head = mw.ustring.sub(head, 1, mw.ustring.len(head) - 1) end local basic = args[1] or head local past = args[2] or basic local full = args["full"] or head local endc = args["end"] or (args[1] and "" or "a") local bare = basic local vowelstem = mw.ustring.find(basic, vowel .. "$") if endc == "a" then bare = mw.ustring.sub(bare, 1, mw.ustring.len(bare) - 1) vowelstem = false end

data.forms["infactv"]     = {head} data.forms["indpresactv"] = make_weak_present_form(basic, endc) data.forms["indpastactv"] = args["past"] and split_multi(args["past"]) or {past .. (weak_past_endings[endc] or "d") .. "e"} data.forms["supactv"]     = args["sup"] and split_multi(args["sup"]) or {past .. (weak_sup_endings[endc] or "t")} data.forms["impactv"]     = args["imp"] and split_multi(args["imp"]) or {basic .. ((endc == "nn") and "n" or "")} data.forms["imppactv"]    = args["impp"] and split_multi(args["impp"]) or {basic .. ((endc == "vw") and "n" or "en")} data.forms["prespart"]    = args["prepart"] and split_multi(args["prepart"]) or {full .. (not args["full"] and weak_part_endings[endc] or "nde")} data.forms["pastpart"]    = args["pp"] and split_multi(args["pp"]) or {past .. (weak_past_endings[endc] or "d")} data.forms["indppresactv"] = data.forms["infactv"] data.forms["indppastactv"] = data.forms["indpastactv"] data.forms["subjpresactv"] = args["sbj"] and split_multi(args["sbj"]) or (vowelstem and data.forms["infactv"] or {bare .. (weak_subj_endings[endc] or "e")}) data.forms["subjpastactv"] = data.forms["indpastactv"]

data.forms["infpasv"]     = make_passive(data.forms["infactv"]) data.forms["indprespasv"] = make_weak_prespasv_form(basic, endc) data.forms["indpastpasv"] = make_passive(data.forms["indpastactv"]) data.forms["suppasv"]     = make_passive(data.forms["supactv"]) data.forms["imppasv"]     = make_passive(data.forms["impactv"]) data.forms["impppasv"]    = make_passive(data.forms["imppactv"]) data.forms["indpprespasv"] = data.forms["infpasv"] data.forms["indppastpasv"] = data.forms["indpastpasv"] data.forms["subjprespasv"] = make_passive(data.forms["subjpresactv"]) data.forms["subjpastpasv"] = data.forms["indpastpasv"] end

local strong_pres_endings = { ["r"] = "", ["vw"] = "r", ["fv"] = "ver", ["mm"] = "mer", ["nn"] = "ner" }

local strong_sup_endings = { ["fv"] = "vit", ["mm"] = "mit", ["nn"] = "nit" }

local strong_pastpart_endings = { ["fv"] = "ven", ["mm"] = "men", ["nn"] = "nen" }

local strong_subj_endings = { ["vw"] = "", ["fv"] = "ve", ["mm"] = "me", ["nn"] = "ne" }

local strong_impp_endings = { ["vw"] = "n", ["fv"] = "ven", ["mm"] = "men", ["nn"] = "nen" }

local function make_strong_ppl_stem(class, endc, past, sup) local base if class == "3" or class == "4" then base = sup else base = past end if endc == "mm" then base = base .. "m" elseif endc == "nn" then base = base .. "n" end return base end

local function make_strong_prespasv_form(stem, endc) if endc == "s" then return {stem .. "es"} end local result = {stem .. (weak_prespasv_endings1[endc] or "s")} if endc ~= "vw" and endc ~= "a" then table.insert(result, stem .. (weak_prespasv_endings2[endc] or "es")) end if endc == "dj" then table.insert(result, stem .. "jes") end return result end

local function get_final_vowel(stem) return mw.ustring.match(stem, ".*(" .. vowel .. ")") end

local function try_detect_strong_class(pres, past, sup, endc) local presv = get_final_vowel(pres) local pastv = get_final_vowel(past) local supv = get_final_vowel(sup)

if supv == "i" or supv == "ä" or supv == "e" then if supv == "i" and pastv == "e" and presv == "i" then return "1" elseif (pastv == "a" or pastv == "å") and (presv == "e" or presv == "i" or presv == "ä") then return "5" end elseif supv == "u" then if pastv == "ö" and (presv == "u" or presv == "y") then return "2" elseif pastv == "a" then if presv == "i" then return "3" elseif presv == "e" or presv == "ä" then if pres:find(consonant .. consonant .. "$") then return "3" else return "4" end end end elseif supv == "a" or supv == "å" then if supv == "a" and pastv == "o" and presv == "a" then return "6" elseif (pastv == "ö" or pastv == "ä") and (presv == "å" or presv == "a") then return "7" end end

return nil end

inflections["strong"] = function(args, data) table.insert(data.categories, "Swedish strong verbs")

local head = data.head -- remove passive final -s to make forms correct if head:find("s$") and args["noa"] then head = mw.ustring.sub(head, 1, mw.ustring.len(head) - 1) end local endc = args["end"] or "" local pres = args[1] or error("At least 3 arguments required for strong verb inflections (missing present stem)") local past = args[2] or error("At least 3 arguments required for strong verb inflections (missing past stem)") local sup = args[3] -- it's fine to not specify the supine stem if supine and pp forms are manually given if not sup and (not args["sup"] or not (args["pp"] or args["nopp"])) then error("At least 3 arguments required for strong verb inflections (missing supine stem; alternatively specify supine and past participle forms manually)") elseif not sup then sup = mw.ustring.sub(args["sup"], 1, mw.ustring.len(args["sup"]) - 1) end local class = args["class"] or try_detect_strong_class(pres, past, sup, endc) local full = args["full"] or (head .. (endc == "vw" and "e" or "")) local ppl = args["ppl"] or make_strong_ppl_stem(class, endc, past, sup) if class then table.insert(data.categories, "Swedish class " .. class .. " strong verbs") data.definitions = "(class " .. class .. " strong)" else data.definitions = "(strong)" end

if class == "5" then -- for class 5, replace final -a- with -å- in plural/subjunctive stem ppl = mw.ustring.gsub(ppl, "(.*)a(.*)", "%1å%2") end if endc == "fv" and ppl:find("f$") then ppl = ppl .. "v" end

data.forms["infactv"]     = {head} data.forms["indpresactv"] = {pres .. (strong_pres_endings[endc] or "er")} data.forms["indpastactv"] = {past} data.forms["supactv"]     = args["sup"] and split_multi(args["sup"]) or {sup .. (strong_sup_endings[endc] or "it")} data.forms["impactv"]     = args["imp"] and split_multi(args["imp"]) or {pres} data.forms["imppactv"]    = args["impp"] and split_multi(args["impp"]) or {pres .. (strong_impp_endings[endc] or "en")} data.forms["prespart"]    = args["prepart"] and split_multi(args["prepart"]) or {full .. "nde"} data.forms["pastpart"]    = args["pp"] and split_multi(args["pp"]) or {sup .. (strong_pastpart_endings[endc] or "en")} data.forms["indppresactv"] = args["pl"] and split_multi(args["pl"]) or data.forms["infactv"] data.forms["indppastactv"] = {ppl .. "o"} data.forms["subjpresactv"] = args["sbj"] and split_multi(args["sbj"]) or {pres .. (strong_subj_endings[endc] or "e")} data.forms["subjpastactv"] = args["psbj"] and split_multi(args["psbj"]) or {ppl .. "e"}

data.forms["infpasv"]     = make_passive(data.forms["infactv"]) data.forms["indprespasv"] = make_strong_prespasv_form(pres, endc) data.forms["indpastpasv"] = make_passive(data.forms["indpastactv"]) data.forms["suppasv"]     = make_passive(data.forms["supactv"]) data.forms["imppasv"]     = make_passive(data.forms["impactv"]) data.forms["impppasv"]    = make_passive(data.forms["imppactv"]) data.forms["indpprespasv"] = make_passive(data.forms["indppresactv"]) data.forms["indppastpasv"] = make_passive(data.forms["indppastactv"]) data.forms["subjprespasv"] = make_passive(data.forms["subjpresactv"]) data.forms["subjpastpasv"] = make_passive(data.forms["subjpastactv"]) end

inflections["irreg"] = function(args, data) table.insert(data.categories, "Swedish irregular verbs") data.definitions = "(irregular)"

data.forms["infactv"]     = split_multi(args[1]) data.forms["indpresactv"] = split_multi(args[2]) data.forms["indpastactv"] = split_multi(args[3]) data.forms["supactv"]     = split_multi(args[4]) data.forms["impactv"]     = split_multi(args[5]) data.forms["imppactv"]    = split_multi(args["impp"]) data.forms["prespart"]    = split_multi(args[6]) data.forms["pastpart"]    = split_multi(args[7]) data.forms["indppresactv"] = split_multi(args["pl"]) data.forms["indppastactv"] = split_multi(args["ppl"]) data.forms["subjpresactv"] = split_multi(args["sbj"]) data.forms["subjpastactv"] = split_multi(args["psbj"]) end

function convert_to_accel(form) -- no accel for now return nil end

-- Make the table function make_table(data) local function show_form(form, accel, show_particle) if not form then return "&mdash;" elseif type(form) ~= "table" then error("a non-table value was given in the list of inflected forms.") end

local ret = {} local part = "" if show_particle and data.particle then part = " " .. m_links.full_link({lang = lang, term = data.particle}) end

for key, subform in ipairs(form) do table.insert(ret, m_links.full_link({lang = lang, term = subform, accel = accel and { ["form"] = accel } or nil}) .. part) end

return table.concat(ret, ", ") end

local function repl(param) if param == "head" then return data.particle and (data.head .. " " .. data.particle) or data.head elseif param == "definitions" then return data.definitions else return show_form(data.forms[param], convert_to_accel(param), param ~= "prespart" and param ~= "pastpart") end end

local wikicode = [=[ Conjugation of

return mw.ustring.gsub(wikicode, "", repl) end

return export