Jump to content

Module:smj-nominals

From Wiktionary, the free dictionary

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