Module:sv-nouns

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 m_utilities = require("Module:utilities")
local m_links = require("Module:links")

local export = {}

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

-- Functions that do the actual inflecting by creating the forms of a basic term.
local inflections = {}

-- 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 = frame:getParent().args
	
	if args["base"] then
		require("Module:debug").track("sv-nouns/base")
	end
	
	if args["betydelser"] then
		require("Module:debug").track("sv-nouns/betydelser")
	end
	
	if args["definitions"] then
		require("Module:debug").track("sv-nouns/definitions")
	end
	
	if args["gender"] then
		require("Module:debug").track("sv-nouns/gender")
	end
	
	if args["genitive"] then
		require("Module:debug").track("sv-nouns/genitive")
	end
	
	if not inflections[infl_type] then
		error("Unknown inflection type '" .. infl_type .. "'")
	end
	
	local data = {forms = {}, title = nil, 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

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

inflections["c-ar"] = function(args, data)
	local par1 = args[1]; if par1 == "" then par1 = nil end
	local par2 = args[2]; if par2 == "" then par2 = nil end
	local fv = args["fv"] or ""
	
	par1 = par1 or mw.title.getCurrentTitle().text
	par2 = (par2 or par1) .. fv
	
	local s = "s"
	
	if par1:find("[xzsXZS]:?$") then
		s = ""
	end
	
	data.forms["indf_nom_sg"] = {par1}
	data.forms["indf_gen_sg"] = {par1 .. s}
	data.forms["defn_nom_sg"] = {par2 .. "en"}
	data.forms["defn_gen_sg"] = {par2 .. "ens"}
	
	data.forms["indf_nom_pl"] = {par2 .. "ar"}
	data.forms["indf_gen_pl"] = {par2 .. "ars"}
	data.forms["defn_nom_pl"] = {par2 .. "arna"}
	data.forms["defn_gen_pl"] = {par2 .. "arnas"}
end

inflections["c-er"] = function(args, data)
	local par1 = args[1]; if par1 == "" then par1 = nil end
	local par2 = args[2]; if par2 == "" then par2 = nil end
	local fv = args["fv"] or ""
	local ien = (args["ien"] or "") ~= ""
	
	local sg_nom_def = args["sg-nom-def"]; if sg_nom_def == "" then sg_nom_def = nil end
	local sg_gen_def = args["sg-gen-def"]; if sg_gen_def == "" then sg_gen_def = nil end
	
	if args["sg-nom-def"] or args["sg-gen-def"] then
		require("Module:debug").track("sv-nouns/manual")
	end
	
	par1 = par1 or mw.title.getCurrentTitle().text
	par2 = (par2 or par1) .. fv
	
	local s = "s"
	
	if par1:find("[xzsXZS]:?$") then
		s = ""
	end
	
	data.forms["indf_nom_sg"] = {par1}
	data.forms["indf_gen_sg"] = {par1 .. s}
	data.forms["defn_nom_sg"] = {sg_nom_def or par2 .. "en"}
	data.forms["defn_gen_sg"] = {sg_gen_def or par2 .. "ens"}
	
	data.forms["indf_nom_pl"] = {par2 .. "er"}
	data.forms["indf_gen_pl"] = {par2 .. "ers"}
	data.forms["defn_nom_pl"] = {par2 .. "erna"}
	data.forms["defn_gen_pl"] = {par2 .. "ernas"}
	
	if ien then
		table.insert(data.forms["defn_nom_sg"], 1, sg_nom_def or par2 .. "n")
		table.insert(data.forms["defn_gen_sg"], 1, sg_gen_def or par2 .. "ns")
	end
end

inflections["c-or"] = function(args, data)
	local par1 = args[1]; if par1 == "" then par1 = nil end
	
	if not par1 and mw.title.getCurrentTitle().nsText == "Template" then
		par1 = "{{{1}}}"
	elseif not par1 and mw.ustring.find(mw.title.getCurrentTitle().text, "a$") then
		par1 = mw.title.getCurrentTitle().text:sub(1, -2)
	end
	
	data.forms["indf_nom_sg"] = {par1 .. "a"}
	data.forms["indf_gen_sg"] = {par1 .. "as"}
	data.forms["defn_nom_sg"] = {par1 .. "an"}
	data.forms["defn_gen_sg"] = {par1 .. "ans"}
	
	data.forms["indf_nom_pl"] = {par1 .. "or"}
	data.forms["indf_gen_pl"] = {par1 .. "ors"}
	data.forms["defn_nom_pl"] = {par1 .. "orna"}
	data.forms["defn_gen_pl"] = {par1 .. "ornas"}
end

inflections["c-r"] = function(args, data)
	local par1 = args[1]; if par1 == "" then par1 = nil end
	local par2 = args[2]; if par2 == "" then par2 = nil end
	local par3 = args[3]; if par3 == "" then par3 = nil end
	
	par1 = par1 or mw.title.getCurrentTitle().text
	par2 = par2 or par1
	par3 = par3 or par2 or par1
	
	local s = "s"
	
	if par1:find("[xzsXZS]:?$") then
		s = ""
	end
	
	data.forms["indf_nom_sg"] = {par1}
	data.forms["indf_gen_sg"] = {par1 .. s}
	data.forms["defn_nom_sg"] = {par2 .. "n"}
	data.forms["defn_gen_sg"] = {par2 .. "ns"}
	
	data.forms["indf_nom_pl"] = {par3 .. "r"}
	data.forms["indf_gen_pl"] = {par3 .. "rs"}
	data.forms["defn_nom_pl"] = {par3 .. "rna"}
	data.forms["defn_gen_pl"] = {par3 .. "rnas"}
end

inflections["c-zero"] = function(args, data)
	local par1 = args[1]; if par1 == "" then par1 = nil end
	local par2 = args[2]; if par2 == "" then par2 = nil end
	local par3 = args[3]; if par3 == "" then par3 = nil end
	
	par1 = par1 or mw.title.getCurrentTitle().text
	par2 = par2 or par1
	par3 = par3 or par2 or par1
	
	if not par1 and mw.title.getCurrentTitle().nsText == "Template" then
		par1 = "{{{1}}}"
	end
	
	local s = "s"
	
	if par1:find("[xzsXZS]:?$") then
		s = ""
	end
	
	data.forms["indf_nom_sg"] = {par1}
	data.forms["indf_gen_sg"] = {par1 .. s}
	data.forms["defn_nom_sg"] = {par2 .. "n"}
	data.forms["defn_gen_sg"] = {par2 .. "ns"}
	
	data.forms["indf_nom_pl"] = {par1}
	data.forms["indf_gen_pl"] = {par1 .. s}
	data.forms["defn_nom_pl"] = {par3 .. "na"}
	data.forms["defn_gen_pl"] = {par3 .. "nas"}
end

inflections["c-are"] = function(args, data)
	if not mw.ustring.find(mw.title.getCurrentTitle().text, "are$") then
		error("The noun must end in -are.")
	end
	
	data.forms["indf_nom_sg"] = {mw.title.getCurrentTitle().text}
	data.forms["indf_gen_sg"] = {mw.title.getCurrentTitle().text .. "s"}
	data.forms["defn_nom_sg"] = {mw.title.getCurrentTitle().text .. "n"}
	data.forms["defn_gen_sg"] = {mw.title.getCurrentTitle().text .. "ns"}
	
	data.forms["indf_nom_pl"] = {mw.title.getCurrentTitle().text}
	data.forms["indf_gen_pl"] = {mw.title.getCurrentTitle().text .. "s"}
	data.forms["defn_nom_pl"] = {mw.ustring.sub(mw.title.getCurrentTitle().text, 1, -2) .. "na"}
	data.forms["defn_gen_pl"] = {mw.ustring.sub(mw.title.getCurrentTitle().text, 1, -2) .. "nas"}
end

inflections["c-nde"] = function(args, data)
	if not mw.ustring.find(mw.title.getCurrentTitle().text, "nde$") then
		error("The noun must end in -nde.")
	end
	
	data.forms["indf_nom_sg"] = {mw.title.getCurrentTitle().text}
	data.forms["indf_gen_sg"] = {mw.title.getCurrentTitle().text .. "s"}
	data.forms["defn_nom_sg"] = {mw.title.getCurrentTitle().text .. "n"}
	data.forms["defn_gen_sg"] = {mw.title.getCurrentTitle().text .. "ns"}
	
	data.forms["indf_nom_pl"] = {mw.title.getCurrentTitle().text}
	data.forms["indf_gen_pl"] = {mw.title.getCurrentTitle().text .. "s"}
	data.forms["defn_nom_pl"] = {mw.title.getCurrentTitle().text .. "na"}
	data.forms["defn_gen_pl"] = {mw.title.getCurrentTitle().text .. "nas"}
end

inflections["n-n"] = function(args, data)
	local par1 = args[1]; if par1 == "" then par1 = nil end
	local par2 = args[2]; if par2 == "" then par2 = nil end
	local par3 = args[3]; if par3 == "" then par3 = nil end
	
	par1 = par1 or mw.title.getCurrentTitle().text
	par2 = par2 or par1
	par3 = par3 or par2 or par1
	
	local s = "s"
	
	if par1:find("[xzsXZS]:?$") then
		s = ""
	end
	
	data.forms["indf_nom_sg"] = {par1}
	data.forms["indf_gen_sg"] = {par1 .. s}
	data.forms["defn_nom_sg"] = {par2 .. "t"}
	data.forms["defn_gen_sg"] = {par2 .. "ts"}
	
	data.forms["indf_nom_pl"] = {par3 .. "n"}
	data.forms["indf_gen_pl"] = {par3 .. "ns"}
	data.forms["defn_nom_pl"] = {par3 .. "na"}
	data.forms["defn_gen_pl"] = {par3 .. "nas"}
end

inflections["n-r"] = function(args, data)
	local par1 = args[1]; if par1 == "" then par1 = nil end
	local par2 = args[2]; if par2 == "" then par2 = nil end
	
	par1 = par1 or mw.title.getCurrentTitle().text
	par2 = par2 or par1
	
	local s = "s"
	
	if par1:find("[xzsXZS]:?$") then
		s = ""
	end
	
	data.forms["indf_nom_sg"] = {par1}
	data.forms["indf_gen_sg"] = {par1 .. s}
	data.forms["defn_nom_sg"] = {par2 .. "t"}
	data.forms["defn_gen_sg"] = {par2 .. "ts"}
	
	data.forms["indf_nom_pl"] = {par2 .. "r"}
	data.forms["indf_gen_pl"] = {par2 .. "rs"}
	data.forms["defn_nom_pl"] = {par2 .. "rna"}
	data.forms["defn_gen_pl"] = {par2 .. "rnas"}
end

inflections["n-zero"] = function(args, data)
	local par1 = args[1]; if par1 == "" then par1 = nil end
	local par2 = args[2] or args["stem"]; if par2 == "" then par2 = nil end
	local par3 = args[3]; if par3 == "" then par3 = nil end
	
	par1 = par1 or mw.title.getCurrentTitle().text
	par2 = par2 or par1
	par3 = par3 or par2 or par1
	
	if not par1 and mw.title.getCurrentTitle().nsText == "Template" then
		par1 = "{{{1}}}"
	end
	
	local s = "s"
	
	if par1:find("[xzsXZS]:?$") then
		s = ""
	end
	
	data.forms["indf_nom_sg"] = {par1}
	data.forms["indf_gen_sg"] = {par1 .. s}
	data.forms["defn_nom_sg"] = {par2 .. "et"}
	data.forms["defn_gen_sg"] = {par2 .. "ets"}
	
	data.forms["indf_nom_pl"] = {par1}
	data.forms["indf_gen_pl"] = {par1 .. s}
	data.forms["defn_nom_pl"] = {par3 .. "en"}
	data.forms["defn_gen_pl"] = {par3 .. "ens"}
end

-- Helper functions

function postprocess(args, data)
	local n = args["n"]; if n == "" then n = nil end
	
	if n == "pl" then
		table.insert(data.categories, lang:getCanonicalName() .. " pluralia tantum")
	end
	
	if n == "sg" then
		table.insert(data.categories, lang:getCanonicalName() .. " uncountable nouns")
	end
	
	for key, form in pairs(data.forms) do
		-- Do not show singular or plural forms for nominals that don't have them
		if (n == "pl" and key:find("_sg$")) or (n == "sg" and key:find("_pl$")) then
			form = nil
		end
		-- Escape any intemediate colons (for the link template) and remove any final colons.
		if form then
			for k, v in ipairs(form) do
				form[k] = v:gsub("()(:)", function(pos, colon)
					if pos == #v then
						return ""
					else
						return "\\:"
					end
				end)
			end
		end
		data.forms[key] = form
	end
	
	-- Check if the lemma form matches the page name
	if (lang:makeEntryName(data.forms[n == "pl" and "indf_nom_pl" or "indf_nom_sg"][1])) ~= 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 show_form(form)
		if not form then
			return "—"
		elseif type(form) ~= "table" then
			error("a non-table value was given in the list of inflected forms.")
		elseif #form == 0 then
			return "—"
		end
		
		local ret = {}
		
		for key, subform in ipairs(form) do
			table.insert(ret, m_links.full_link({lang = lang, term = subform}))
		end
		
		return table.concat(ret, "<br/>")
	end
	
	local function repl(param)
		if param == "lemma" then
			return m_links.full_link({lang = lang, alt = mw.title.getCurrentTitle().text}, "term")
		elseif param == "info" then
			return data.title and "(" .. data.title .. ")" or ""
		else
			return show_form(data.forms[param])
		end
	end
	
	local wikicode = [=[
<div class="NavFrame" style="max-width:50em" data-toggle-category="inflection">
<div class="NavHead">Declension of {{{lemma}}} {{{info}}}</div>
<div class="NavContent">
{| class="wikitable" style="width:100%"
! colspan="2" |
! [[nominative]]
! [[genitive]]
|-
! rowspan="2" | [[singular]]
! [[indefinite]]
| {{{indf_nom_sg}}}
| {{{indf_gen_sg}}}
|-
! [[definite]]
| {{{defn_nom_sg}}}
| {{{defn_gen_sg}}}
|-
! rowspan="2" | [[plural]]
! [[indefinite]]
| {{{indf_nom_pl}}}
| {{{indf_gen_pl}}}
|-
! [[definite]]
| {{{defn_nom_pl}}}
| {{{defn_gen_pl}}}
|}
</div>
</div>]=]
	return mw.ustring.gsub(wikicode, "{{{([a-z0-9_:]+)}}}", repl)
end

return export