Module:smj-nominals

From Wiktionary, the free dictionary
Jump to navigation Jump to search

This module needs documentation.
Please document this module by describing its purpose and usage on the documentation page.

local lang = require("Module:languages").getByCode("smj")

local export = {}


-- Inflection functions

function export.even(frame)
	local fparams = {
		[1] = {required = true},
		
		["nograd"] = {type = "boolean"},
	}
	
	local fargs = require("Module:parameters").process(frame.args, fparams)
	
	local params = {
		[1] = {required = true, default = "{{{1}}}"},
		
		["attr"] = fargs[1] == "adjectives" and {list = true} or nil,
		["n"] = fargs[1] == "nouns" and {} or nil,
		["novowel"] = {type = "boolean"},
		["poss"] = fargs[1] == "nouns" and {} or nil,
	}
	
	local args = require("Module:parameters").process(frame:getParent().args, params)
	local stem = require("Module:smj-common").Stem(args[1], not fargs["nograd"])
	
	local data = {
		has_attr = fargs[1] == "adjectives",
		has_poss = fargs[1] == "nouns" and not args["poss"],
		forms = {},
		info = "even " .. require("Module:links").full_link({lang = lang, alt = stem.uvowel}, "term") .. "-stem",
		categories = {},
	}
	
	if stem.gradation then
		data.info = data.info .. ", " ..
			require("Module:links").full_link({lang = lang, alt = stem.gradation.strong.scons}, "term") .. "-" ..
			require("Module:links").full_link({lang = lang, alt = stem.gradation.weak.scons}, "term") .. " gradation"
	else
		data.info = data.info .. ", no gradation"
	end
	
	if not mw.ustring.find(stem.uvowel, "^[aáeioå]$") and mw.title.getCurrentTitle().nsText ~= "Template" then
		error("The final vowel(s) of the stem must be one of a, á, e, i, o, å.")
	end
	
	if fargs[1] == "nouns" and args["poss"] and args["poss"] ~= "-" then
	else
		table.insert(data.categories, lang:getCanonicalName() .. " even " .. fargs[1])
		table.insert(data.categories, lang:getCanonicalName() .. " even " .. (stem.uvowel or "") .. "-stem " .. fargs[1])
		
		if not stem.gradation then
			table.insert(data.categories, lang:getCanonicalName() .. " non-gradating even " .. fargs[1])
		end
		
		data.forms["nom|s"] = {stem:make_form{grade = "strong", variant = args["novowel"] and "none" or nil}}
		data.forms["acc|s"] = {stem:make_form{grade = "weak", ending = "v"}}
		data.forms["gen|s"] = {stem:make_form{grade = "weak"}}
		data.forms["ill|s"] = {stem:make_form{grade = "strong", ending = "j", variant = "e"}}
		data.forms["ine|s"] = {stem:make_form{grade = "weak", ending = "n"}}
		data.forms["ela|s"] = {stem:make_form{grade = "weak", ending = "s"}}
		data.forms["com|s"] = {stem:make_form{grade = "weak", ending = "jn", variant = "j"}, stem:make_form{grade = "weak", ending = "jn", variant = "je"}}
		data.forms["abe|s"] = {stem:make_form{grade = "weak", ending = "dagá"}, stem:make_form{grade = "weak", ending = "dagi"}}
		
		data.forms["nom|p"] = {stem:make_form{grade = "weak"}}
		data.forms["acc|p"] = {stem:make_form{grade = "weak", ending = "jt", variant = "j"}}
		data.forms["gen|p"] = {stem:make_form{grade = "weak", ending = "j", variant = "j"}}
		data.forms["ill|p"] = {stem:make_form{grade = "weak", ending = "jda", variant = "j"}}
		data.forms["ine|p"] = {stem:make_form{grade = "weak", ending = "jn", variant = "j"}}
		data.forms["ela|p"] = {stem:make_form{grade = "weak", ending = "js", variant = "j"}}
		data.forms["com|p"] = {stem:make_form{grade = "weak", ending = "j", variant = "j"}}
		data.forms["abe|p"] = {stem:make_form{grade = "weak", ending = "jdagá", variant = "j"}, stem:make_form{grade = "weak", ending = "jdagi", variant = "j"}}
		
		data.forms["ess"]    = {stem:make_form{grade = "strong", ending = "n"}}
		
		if data.forms["com|s"][2] == data.forms["com|s"][1] then
			data.forms["com|s"][2] = nil
		end
		
		if fargs[1] == "nouns" then
			data.forms["1|s|poss"] = {stem:make_form{grade = "strong", ending = "m", variant = "e"}}
			data.forms["2|s|poss"] = {stem:make_form{grade = "strong", ending = "t", variant = "e"}}
			data.forms["3|s|poss"] = {stem:make_form{grade = "strong", ending = "s"}}
			data.forms["1|d|poss"] = {stem:make_form{grade = "strong", ending = "ma", variant = "e"}}
			data.forms["2|d|poss"] = {stem:make_form{grade = "strong", ending = "da", variant = "e"}}
			data.forms["3|d|poss"] = {stem:make_form{grade = "strong", ending = "ska"}}
			data.forms["1|p|poss"] = {stem:make_form{grade = "strong", ending = "ma", variant = "e"}}
			data.forms["2|p|poss"] = {stem:make_form{grade = "strong", ending = "da", variant = "e"}}
			data.forms["3|p|poss"] = {stem:make_form{grade = "strong", ending = "sa"}}
		end
	end
	
	postprocess(args, data)
	
	return make_table(data)
end


function export.odd(frame)
	local fparams = {
		[1] = {required = true},
		
		["nograd"] = {type = "boolean"},
	}
	
	local fargs = require("Module:parameters").process(frame.args, fparams)
	
	local params = {
		[1] = {default = mw.title.getCurrentTitle().nsText == "Template" and "{{{1}}}" or ""},
		
		["attr"] = fargs[1] == "adjectives" and {list = true} or nil,
		["n"] = fargs[1] == "nouns" and {} or nil,
		["poss"] = fargs[1] == "nouns" and {} or nil,
	}
	
	local args = require("Module:parameters").process(frame:getParent().args, params)
	local strong = require("Module:smj-common").Stem(args[1], not fargs["nograd"])
	local weak = require("Module:smj-common").Stem(args[1], not fargs["nograd"])
	local variant = nil
	
	local data = {
		has_attr = fargs[1] == "adjectives",
		has_poss = fargs[1] == "nouns" and not args["poss"],
		forms = {},
		info = "odd",
		categories = {},
	}
	
	if strong.gradation then
		data.info = data.info .. ", " ..
			require("Module:links").full_link({lang = lang, alt = strong.gradation.strong.scons}, "term") .. "-" ..
			require("Module:links").full_link({lang = lang, alt = strong.gradation.weak.scons}, "term") .. " gradation"
		
		variant = "e"
		
		if weak.ucons == "g" then
			weak.ucons = ""
		elseif weak.ucons == "m" then
			weak.ucons = "v"
		end
	else
		data.info = data.info .. ", no gradation"
	end
	
	if strong.ucons == "" and mw.title.getCurrentTitle().nsText ~= "Template" then
		error("The strong-grade stem must end in a consonant.")
	end
	
	if fargs[1] == "nouns" and args["poss"] and args["poss"] ~= "-" then
	else
		table.insert(data.categories, lang:getCanonicalName() .. " odd " .. fargs[1])
		
		if strong.gradation then
			table.insert(data.categories, lang:getCanonicalName() .. " gradating odd " .. fargs[1])
		else
			table.insert(data.categories, lang:getCanonicalName() .. " non-gradating odd " .. fargs[1])
		end
		
		data.forms["nom|s"] = {weak:make_form{grade = "weak"}}
		data.forms["acc|s"] = {strong:make_form{grade = "strong", ending = "av", variant = variant}}
		data.forms["gen|s"] = {strong:make_form{grade = "strong", ending = "a", variant = variant}}
		data.forms["ill|s"] = {strong:make_form{grade = "strong", ending = "ij", variant = variant}}
		data.forms["ine|s"] = {strong:make_form{grade = "strong", ending = "in", variant = variant}}
		data.forms["ela|s"] = {strong:make_form{grade = "strong", ending = "is", variant = variant}}
		data.forms["com|s"] = {strong:make_form{grade = "strong", ending = "ijn", variant = variant}}
		data.forms["abe|s"] = {strong:make_form{grade = "strong", ending = "adagá", variant = variant}, strong:make_form{grade = "strong", ending = "adagi", variant = variant}}
		
		data.forms["nom|p"] = {strong:make_form{grade = "strong", ending = "a", variant = variant}}
		data.forms["acc|p"] = {strong:make_form{grade = "strong", ending = "ijt", variant = variant}}
		data.forms["gen|p"] = {strong:make_form{grade = "strong", ending = "ij", variant = variant}}
		data.forms["ill|p"] = {strong:make_form{grade = "strong", ending = "ijda", variant = variant}}
		data.forms["ine|p"] = {strong:make_form{grade = "strong", ending = "ijn", variant = variant}}
		data.forms["ela|p"] = {strong:make_form{grade = "strong", ending = "ijs", variant = variant}}
		data.forms["com|p"] = {strong:make_form{grade = "strong", ending = "ij", variant = variant}}
		data.forms["abe|p"] = {strong:make_form{grade = "strong", ending = "ijdagá", variant = variant}, strong:make_form{grade = "strong", ending = "ijdagi", variant = variant}}
		
		data.forms["ess"]    = {strong:make_form{grade = "strong", ending = (strong.ucons == "" and "" or "i") .. "n", variant = variant}}
		
		if strong.gradation then
			local ess2 = require("Module:smj-common").Stem(weak.init .. weak.svowel .. weak.scons .. weak.uvowel, args["Q31"] and "Q31" or true)
			table.insert(data.forms["ess"], 1, ess2:make_form{grade = "weak", ending = "n"})
		end
		
		if fargs[1] == "nouns" then
			data.forms["1|s|poss"] = {strong:make_form{grade = "strong", ending = "im", variant = variant}, strong:make_form{grade = "strong", ending = "am", variant = variant}}
			data.forms["2|s|poss"] = {strong:make_form{grade = "strong", ending = "it", variant = variant}, strong:make_form{grade = "strong", ending = "at", variant = variant}}
			data.forms["3|s|poss"] = {strong:make_form{grade = "strong", ending = "is", variant = variant}}
			data.forms["1|d|poss"] = {strong:make_form{grade = "strong", ending = "imme", variant = variant}}
			data.forms["2|d|poss"] = {strong:make_form{grade = "strong", ending = "ihtte", variant = variant}}
			data.forms["3|d|poss"] = {strong:make_form{grade = "strong", ending = "iska", variant = variant}}
			data.forms["1|p|poss"] = {strong:make_form{grade = "strong", ending = "imme", variant = variant}}
			data.forms["2|p|poss"] = {strong:make_form{grade = "strong", ending = "ihtte", variant = variant}}
			data.forms["3|p|poss"] = {strong:make_form{grade = "strong", ending = "isá", variant = variant}}
		end
	end
	
	postprocess(args, data)
	
	return make_table(data)
end


function export.contr(frame)
	local fparams = {
		[1] = {required = true},
		
		["nograd"] = {type = "boolean"},
	}
	
	local fargs = require("Module:parameters").process(frame.args, fparams)
	
	local params = {
		[1] = {default = mw.title.getCurrentTitle().nsText == "Template" and "{{{1}}}" or ""},
		
		["attr"] = fargs[1] == "adjectives" and {list = true} or nil,
		["n"] = fargs[1] == "nouns" and {} or nil,
		["poss"] = fargs[1] == "nouns" and {} or nil,
		["Q31"] = {type = "boolean"},
	}
	
	local args = require("Module:parameters").process(frame:getParent().args, params)
	local strong = require("Module:smj-common").Stem(args[1], args["Q31"] and "Q31" or not fargs["nograd"])
	local weak = require("Module:smj-common").Stem(args[1], args["Q31"] and "Q31" or not fargs["nograd"])
	strong.ucons = ""  -- final consonant is lost in the strong grade
	
	local data = {
		has_attr = fargs[1] == "adjectives",
		has_poss = fargs[1] == "nouns" and not args["poss"],
		forms = {},
		info = "contracted " .. require("Module:links").full_link({lang = lang, alt = strong.uvowel}, "term") .. "-stem",
		categories = {},
	}
	
	if strong.gradation then
		data.info = data.info .. ", " ..
			require("Module:links").full_link({lang = lang, alt = strong.gradation.strong.scons}, "term") .. "-" ..
			require("Module:links").full_link({lang = lang, alt = strong.gradation.weak.scons}, "term") .. " gradation"
	else
		data.info = data.info .. ", no gradation"
	end
	
	if not (mw.ustring.find(strong.uvowel, "^[eo]$") or strong.uvowel == "å̄") and mw.title.getCurrentTitle().nsText ~= "Template" then
		error("The final vowel(s) of the strong grade stem must be one of á, u, å.")
	end
	
	table.insert(data.categories, lang:getCanonicalName() .. " contracted " .. fargs[1])
	table.insert(data.categories, lang:getCanonicalName() .. " contracted " .. (strong.uvowel or "") .. "-stem " .. fargs[1])
	
	if fargs[1] == "nouns" and args["poss"] and args["poss"] ~= "-" then
	else
		data.forms["nom|s"] = {weak:make_form{grade = "weak"}}
		data.forms["acc|s"] = {strong:make_form{grade = "strong", ending = "v", variant = "e"}}
		data.forms["gen|s"] = {strong:make_form{grade = "strong", variant = "e"}}
		data.forms["ill|s"] = {strong:make_form{grade = "strong", ending = "j", variant = "e"}}
		data.forms["ine|s"] = {strong:make_form{grade = "strong", ending = "n", variant = "e"}}
		data.forms["ela|s"] = {strong:make_form{grade = "strong", ending = "s", variant = "e"}}
		data.forms["com|s"] = {strong:make_form{grade = "strong", ending = "jn", variant = "e"}}
		data.forms["abe|s"] = {strong:make_form{grade = "strong", ending = "dagá", variant = "e"}, strong:make_form{grade = "strong", ending = "dagi", variant = "e"}}
		
		data.forms["nom|p"] = {strong:make_form{grade = "strong", variant = "e"}}
		data.forms["acc|p"] = {strong:make_form{grade = "strong", ending = "j", variant = "e"}}
		data.forms["gen|p"] = {strong:make_form{grade = "strong", ending = "jt", variant = "e"}}
		data.forms["ill|p"] = {strong:make_form{grade = "strong", ending = "jda", variant = "e"}}
		data.forms["ine|p"] = {strong:make_form{grade = "strong", ending = "jn", variant = "e"}}
		data.forms["ela|p"] = {strong:make_form{grade = "strong", ending = "js", variant = "e"}}
		data.forms["com|p"] = {strong:make_form{grade = "strong", ending = "j", variant = "e"}}
		data.forms["abe|p"] = {strong:make_form{grade = "strong", ending = "jdagá", variant = "e"}, strong:make_form{grade = "strong", ending = "jdagi", variant = "e"}}
		
		data.forms["ess"]    = {strong:make_form{grade = "strong", ending = "n", variant = "e"}}
		
		if strong.gradation then
			local ess2 = require("Module:smj-common").Stem(weak.init .. weak.svowel .. weak.scons .. weak.uvowel, args["Q31"] and "Q31" or true)
			table.insert(data.forms["ess"], 1, ess2:make_form{grade = "weak", ending = "n"})
		end
		
		if fargs[1] == "nouns" then
			data.forms["1|s|poss"] = {strong:make_form{grade = "strong", ending = "m", variant = "e"}}
			data.forms["2|s|poss"] = {strong:make_form{grade = "strong", ending = "t", variant = "e"}}
			data.forms["3|s|poss"] = {strong:make_form{grade = "strong", ending = "s", variant = "e"}}
			data.forms["1|d|poss"] = {strong:make_form{grade = "strong", ending = "ma", variant = "e"}}
			data.forms["2|d|poss"] = {strong:make_form{grade = "strong", ending = "da", variant = "e"}}
			data.forms["3|d|poss"] = {strong:make_form{grade = "strong", ending = "ska", variant = "e"}}
			data.forms["1|p|poss"] = {strong:make_form{grade = "strong", ending = "ma", variant = "e"}}
			data.forms["2|p|poss"] = {strong:make_form{grade = "strong", ending = "da", variant = "e"}}
			data.forms["3|p|poss"] = {strong:make_form{grade = "strong", ending = "sa", variant = "e"}}
		end
	end
	
	postprocess(args, data)
	
	return make_table(data)
end


function postprocess(args, data)
	if args["poss"] then
		data.has_poss = false
	end
	
	data.n = args["n"]
	
	if args["n"] == "p" then
		table.insert(data.categories, lang:getCanonicalName() .. " pluralia tantum")
	elseif args["n"] == "s" then
		table.insert(data.categories, lang:getCanonicalName() .. " uncountable nouns")
	elseif args["n"] then
		error("args= must be \"s\" or \"p\".")
	end
	
	for key, form in pairs(data.forms) do
		-- Do not show singular or plural forms for nominals that don't have them
		if (args["n"] == "p" and key:find("|s$")) or (args["n"] == "s" and key:find("|p$")) then
			form = nil
		end
		
		data.forms[key] = form
	end
	
	if data.has_attr then
		if not args["attr"][1] then
			data.forms["attr"] = mw.clone(data.forms["nom|s"])
		elseif args["attr"][1] ~= "-" then
			data.forms["attr"] = args["attr"]
		end
	end
	
	data.lemma = (data.forms["nom|" .. (data.n or "s")] or data.forms["acc|" .. (data.n or "s")])[1]
	
	-- Check if the lemma form matches the page name
	if (lang:makeEntryName(data.lemma)) ~= mw.title.getCurrentTitle().text then
		table.insert(data.categories, lang:getCanonicalName() .. " entries with inflection not matching pagename")
	end
end


-- Make the table
function make_table(data)
	local function repl(param)
		local accel = true
		local no_store = false
		
		if param == "info" then
			return mw.getContentLanguage():ucfirst(data.info or "")
		elseif string.sub(param, 1, 1) == "!" then
			no_store = true
			param = string.sub(param, 2)
		elseif string.sub(param, 1, 1) == "#" then
			accel = false
			param = string.sub(param, 2)
		end
		
		local forms = data.forms[param]
		
		if not forms then
			return "—"
		end
		
		local ret = {}
		
		for key, subform in ipairs(forms) do
			table.insert(ret, require("Module:links").full_link({lang = lang, term = subform, accel = accel and {form = param, lemma = data.lemma, no_store = no_store} or nil}))
		end
		
		return table.concat(ret, "<br/>")
	end
	
	local wikicode = {}
	table.insert(wikicode, [=[
{| class="inflection-table vsSwitcher" data-toggle-category="inflection" style="border:solid 1px #CCCCFF; text-align: left;" cellspacing="1" cellpadding="2"
|- style="background: #E2F6E2; text-align: left;"
! class="vsToggleElement" colspan="3" | {{{info}}}]=])

	if data.has_attr then
		table.insert(wikicode, [=[

|- class="vsShow" style="background: #F2F2FF;"
! style="background: #E2F6E2;" | Attributive
| colspan="2" | {{{!attr}}}]=])
	end
	
	table.insert(wikicode, [=[

|- class="vsShow" style="background: #F2F2FF;"
! style="width: 8em; background: #E2F6E2;" | Nominative
| style="width: 15em;" colspan="2" | {{{!nom|]=] .. (data.n or "s") .. [=[}}}
|- class="vsShow" style="background: #F2F2FF;"
! style="background: #E2F6E2;" | Genitive
| colspan="2" | {{{!gen|]=] .. (data.n or "s") .. [=[}}}]=])
	
	if data.has_attr then
		table.insert(wikicode, [=[

|- class="vsHide" style="background: #F2F2FF;"
! style="background: #E2F6E2;" | Attributive
| colspan="2" | {{{attr}}}
]=])
	end
	
	table.insert(wikicode, [=[

|- class="vsHide"
! style="width: 8em; background: #C0E4C0;" |
! style="width: 12em; background: #C0E4C0;" | Singular
! style="width: 12em; background: #C0E4C0;" | Plural
|- class="vsHide" style="background: #F2F2FF;"
! style="background: #E2F6E2;" | Nominative
| data-accel-col="1" | {{{nom|s}}}
| data-accel-col="2" | {{{nom|p}}}
|- class="vsHide" style="background: #F2F2FF;"
! style="background: #E2F6E2;" | Accusative
| data-accel-col="1" | {{{acc|s}}}
| data-accel-col="2" | {{{acc|p}}}
|- class="vsHide" style="background: #F2F2FF;"
! style="background: #E2F6E2;" | Genitive
| data-accel-col="1" | {{{gen|s}}}
| data-accel-col="2" | {{{gen|p}}}
|- class="vsHide" style="background: #F2F2FF;"
! style="background: #E2F6E2;" | Illative
| data-accel-col="1" | {{{ill|s}}}
| data-accel-col="2" | {{{ill|p}}}
|- class="vsHide" style="background: #F2F2FF;"
! style="background: #E2F6E2;" | Inessive
| data-accel-col="1" | {{{ine|s}}}
| data-accel-col="2" | {{{ine|p}}}
|- class="vsHide" style="background: #F2F2FF;"
! style="background: #E2F6E2;" | Elative
| data-accel-col="1" | {{{ela|s}}}
| data-accel-col="2" | {{{ela|p}}}
|- class="vsHide" style="background: #F2F2FF;"
! style="background: #E2F6E2;" | Comitative
| data-accel-col="1" | {{{com|s}}}
| data-accel-col="2" | {{{com|p}}}
|- class="vsHide" style="background: #F2F2FF;"
! style="background: #E2F6E2;" | Abessive
| data-accel-col="1" | {{{abe|s}}}
| data-accel-col="2" | {{{abe|p}}}
|- class="vsHide" style="background: #F2F2FF;"
! style="background: #E2F6E2;" | Essive
| colspan="2" | {{{ess}}}]=])
	
	-- Possessive forms
	if data.has_poss then
		table.insert(wikicode, [=[

|- class="vsHide"
| colspan="3" style="padding: 0;" |
{| class="inflection-table vsSwitcher" style="text-align: left; width: 100%;" cellspacing="1" cellpadding="2"
|- style="background: #E2F6E2; text-align: left;"
! class="vsToggleElement" colspan="4" | Possessive forms
|- class="vsHide"
! style="width: 8em; background: #C0E4C0;" |
! style="width: 12em; background: #C0E4C0;" | Singular
! style="width: 12em; background: #C0E4C0;" | Dual
! style="width: 12em; background: #C0E4C0;" | Plural
|- class="vsHide" style="background: #F2F2FF;"
! style="background: #E2F6E2;" | 1st&nbsp;person
| {{{1|s|poss}}}
| {{{1|d|poss}}}
| {{{1|p|poss}}}
|- class="vsHide" style="background: #F2F2FF;"
! style="background: #E2F6E2;" | 2nd&nbsp;person
| {{{2|s|poss}}}
| {{{2|d|poss}}}
| {{{2|p|poss}}}
|- class="vsHide" style="background: #F2F2FF;"
! style="background: #E2F6E2;" | 3rd&nbsp;person
| {{{3|s|poss}}}
| {{{3|d|poss}}}
| {{{3|p|poss}}}
|}]=])
	end
	
	table.insert(wikicode, "\n|}")
	
	return mw.ustring.gsub(table.concat(wikicode), "{{{([#!]?[a-z0-9|]+)}}}", repl) .. require("Module:utilities").format_categories(data.categories, lang)
end

return export