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

local export = {}

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

-- 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 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)
	
	if args["nosg"] then
		table.insert(data.categories, "et-decl with nosg")
	end
	
	if args["nopl"] then
		table.insert(data.categories, "et-decl with nopl")
	end
	
	if args["type"] then
		table.insert(data.categories, "et-decl with type")
	end
	
	return make_table(data) .. m_utilities.format_categories(data.categories, lang)
end


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

local stem_endings = {}

-- Singular
stem_endings["nom_sg"] = {{stem = "nom_sg", ending = ""}}
stem_endings["gen_sg"] = {{stem = "gen_sg", ending = ""}}
stem_endings["par_sg"] = {{stem = "par_sg", ending = ""}}

stem_endings["ill_sg"] = {{stem = "ill_sg", ending = ""}}
stem_endings["ine_sg"] = {{stem = "gen_sg", ending = "n"}, {stem = "gen_sg", ending = "hn"}}
stem_endings["ela_sg"] = {{stem = "gen_sg", ending = "st"}}

stem_endings["all_sg"] = {{stem = "gen_sg", ending = "lõ"}}
stem_endings["ade_sg"] = {{stem = "gen_sg", ending = "l"}}
stem_endings["abl_sg"] = {{stem = "gen_sg", ending = "lt"}}

stem_endings["tra_sg"] = {{stem = "gen_sg", ending = "s"}}
stem_endings["ter_sg"] = {{stem = "gen_sg", ending = "niq"}}
stem_endings["abe_sg"] = {{stem = "gen_sg", ending = "ldaq"}}
stem_endings["com_sg"] = {{stem = "gen_sg", ending = "gaq"}}

-- Plural
stem_endings["nom_pl"] = {{stem = "gen_sg", ending = "q"}}
stem_endings["gen_pl"] = {{stem = "gen_pl", ending = ""}}
stem_endings["par_pl"] = {{stem = "par_pl", ending = ""}}

stem_endings["ill_pl"] = {{stem = "ill_pl", ending = ""}}
stem_endings["ine_pl"] = {{stem = "all_pl", ending = "n"}, {stem = "all_pl", ending = "hn"}}
stem_endings["ela_pl"] = {{stem = "all_pl", ending = "st"}}

stem_endings["all_pl"] = {{stem = "all_pl", ending = "lõ"}}
stem_endings["ade_pl"] = {{stem = "all_pl", ending = "l"}}
stem_endings["abl_pl"] = {{stem = "all_pl", ending = "lt"}}

stem_endings["tra_pl"] = {{stem = "all_pl", ending = "s"}}
stem_endings["ter_pl"] = {{stem = "all_pl", ending = "niq"}}
stem_endings["abe_pl"] = {{stem = "all_pl", ending = "ldaq"}}
stem_endings["com_pl"] = {{stem = "gen_pl", ending = "gaq"}}

-- Make a copy of the endings, with front vowels
stem_endings = {["a"] = stem_endings, ["ä"] = mw.clone(stem_endings)}
 
for form_key, subforms in pairs(stem_endings["ä"]) do
	for _, form in pairs(subforms) do
		form.ending = mw.ustring.gsub(form.ending, "([aouõ])", {["a"] = "ä", ["o"] = "ö", ["u"] = "ü", ["õ"] = "e"})
	end
end


-- Create forms based on each stem, by adding endings to it
local function process_stems(data, stems, vh)
	-- For each of the case-and-number combinations that is defined above...
	for form_key, subforms in pairs(stem_endings[vh]) do
		--- ...and each subform defined for it
		for _, form in ipairs(subforms) do
			-- If the required stem has been provided, then...
			if stems[form.stem] and #stems[form.stem] > 0 then
				if not data.forms[form_key] then
					data.forms[form_key] = {}
				end
				
				-- ...add the ending to each provided stem
				for _, stem in ipairs(stems[form.stem]) do
					table.insert(data.forms[form_key], stem .. form.ending)
				end
			end
		end
	end
end

local function get_param(args, first, prefix)
	local param = args[first]; if param == "" then param = nil end
	
	if not param then
		return {mw.title.getCurrentTitle().nsText == "Template" and "{{{" .. first .. "}}}" or nil}
	end
	
	local ret = {param}
	local i = 2
	
	while args[prefix .. i] do
		param = args[prefix .. i]; if param == "" then param = nil end
		table.insert(ret, param)
		i = i + 1
	end
	
	return ret
end

inflections["stems"] = function(args, data)
	local vh = args[1] or (mw.title.getCurrentTitle().nsText == "Template" and "a"); if not (vh == "a" or vh == "ä") then error("Parameter 9 must be \"a\" or \"ä\".") end
	
	local stems = {}
	stems["nom_sg"] = get_param(args, 2, "nom_sg")
	stems["gen_sg"] = get_param(args, 3, "gen_sg")
	stems["par_sg"] = get_param(args, 4, "par_sg")
	stems["ill_sg"] = get_param(args, 5, "ill_sg")
	stems["gen_pl"] = get_param(args, 6, "gen_pl")
	stems["par_pl"] = get_param(args, 7, "par_pl")
	stems["ill_pl"] = get_param(args, 8, "ill_pl")
	stems["all_pl"] = get_param(args, 9, "all_pl")
	
	process_stems(data, stems, vh)
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
	
	-- TODO: This says "nouns", but this module is also used for adjectives!
	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
		
		data.forms[key] = form
	end
	
	-- Check if the lemma form matches the page name
	local lemma_key = n == "pl" and "nom_pl" or "nom_sg"
	
	if data.forms[lemma_key] and data.forms[lemma_key][1] and (lang:makeEntryName(data.forms[lemma_key][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.")
		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="width: 40%">
<div class="NavHead" style="background:rgb(80%,80%,100%);">Inflection of {{{lemma}}}{{{info}}}</div>
<div class="NavContent">
{| class="inflection-table" style="width:100%; border:solid 1px rgb(80%,80%,100%); text-align:left;" cellspacing="1" cellpadding="2"
|- style="background:rgb(80%,80%,100%);vertical-align:top;"
! style="width:30%;" |
! style="width:35%;" | singular
! style="width:35%;" | plural
|- style="background:rgb(95%,95%,100%);vertical-align:top;"
! style="background:rgb(80%,80%,100%);" | nominative
| {{{nom_sg}}}
| {{{nom_pl}}}
|- style="background:rgb(95%,95%,100%);vertical-align:top;"
! style="background:rgb(80%,80%,100%);" | accusative
| {{{gen_sg}}}
| {{{nom_pl}}}
|- style="background:rgb(95%,95%,100%);vertical-align:top;"
! style="background:rgb(80%,80%,100%);" | genitive
| {{{gen_sg}}}
| {{{gen_pl}}}
|- style="background:rgb(95%,95%,100%);vertical-align:top;"
! style="background:rgb(80%,80%,100%);" | partitive
| {{{par_sg}}}
| {{{par_pl}}}
|- style="background:rgb(95%,95%,100%);vertical-align:top;"
! style="background:rgb(80%,80%,100%);" | illative
| {{{ill_sg}}}
| {{{ill_pl}}}
|- style="background:rgb(95%,95%,100%);vertical-align:top;"
! style="background:rgb(80%,80%,100%);" | inessive
| {{{ine_sg}}}
| {{{ine_pl}}}
|- style="background:rgb(95%,95%,100%);vertical-align:top;"
! style="background:rgb(80%,80%,100%);" | elative
| {{{ela_sg}}}
| {{{ela_pl}}}
|- style="background:rgb(95%,95%,100%);vertical-align:top;"
! style="background:rgb(80%,80%,100%);" | allative
| {{{all_sg}}}
| {{{all_pl}}}
|- style="background:rgb(95%,95%,100%);vertical-align:top;"
! style="background:rgb(80%,80%,100%);" | adessive
| {{{ade_sg}}}
| {{{ade_pl}}}
|- style="background:rgb(95%,95%,100%);vertical-align:top;"
! style="background:rgb(80%,80%,100%);" | ablative
| {{{abl_sg}}}
| {{{abl_pl}}}
|- style="background:rgb(95%,95%,100%);vertical-align:top;"
! style="background:rgb(80%,80%,100%);" | translative
| {{{tra_sg}}}
| {{{tra_pl}}}
|- style="background:rgb(95%,95%,100%);vertical-align:top;"
! style="background:rgb(80%,80%,100%);" | terminative
| {{{ter_sg}}}
| {{{ter_pl}}}
|- style="background:rgb(95%,95%,100%);vertical-align:top;"
! style="background:rgb(80%,80%,100%);" | abessive
| {{{abe_sg}}}
| {{{abe_pl}}}
|- style="background:rgb(95%,95%,100%);vertical-align:top;"
! style="background:rgb(80%,80%,100%);" | comitative
| {{{com_sg}}}
| {{{com_pl}}}
|}
</div>
</div>]=]
	return mw.ustring.gsub(wikicode, "{{{([a-z0-9_]+)}}}", repl)
end

return export