Jump to content

Module:odt-decl-noun

From Wiktionary, the free dictionary


local export = {}

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

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

local decl_data = {}

--

local function devoice(stem)
	stem = mw.ustring.gsub(stem, "ng$", "nc")
	stem = mw.ustring.gsub(stem, "g$", "h")
	stem = mw.ustring.gsub(stem, "d$", "t")
	stem = mw.ustring.gsub(stem, "b$", "p")
	stem = mw.ustring.gsub(stem, "v$", "f")
	stem = mw.ustring.gsub(stem, "z$", "s")
	return stem
end

local function umlaut(stem)
    	stem = stem.gsub(stem, "ie", "iu")
    if not string.find(stem, "ei") then
    	stem = stem.gsub(stem, "e", "i")
    end
    	stem = stem.gsub(stem, "a", "e")
    if not string.find(stem, "u") then
    	stem = stem.gsub(stem, "o", "u")
    end
    return stem
end

local function C_to_K(stem)
    stem = mw.ustring.gsub(stem, "cc$", "ck")
    stem = mw.ustring.gsub(stem, "c$", "k")
    return stem
end

local function K_to_C(stem)
    stem = mw.ustring.gsub(stem, "ck$", "cc")
    stem = mw.ustring.gsub(stem, "k$", "c")
    return stem
end

--
decl_data["noun"] = {
	params = {
		[1] = {},
		["decl"] = {},
		["g"] = {},
		["length"] = {},
		["defect"] = {},
		},
}
--
if args.decl == 'a' then
	nom_sg = devoice(args[1])
	acc_sg = devoice(args[1])
	gen_sg = C_to_K(args[1]) .. "es"
	dat_sg = C_to_K(args[1]) .. "e"
	gen_pl = args[1] .. "o"
	dat_pl = args[1] .. "on"
	if args.g== "m" then
		decl_type = "maculine a-stem"
		nom_pl = args[1] .. "a"
		acc_pl = args[1] .. "a"
	elseif args.g== "n" then
		decl_type = "neuter a-stem"
		if not args.length or args.length == "l" then
			nom_pl = args[1]
			acc_pl = args[1]
		elseif args.length == "s" then
			nom_pl = args[1] .. "o"
			acc_pl = args[1] .. "o"
		end

elseif args.decl == 'o' then
	nom_sg = args[1] .. "a"
	acc_sg = args[1] .. "a"
	gen_sg = args[1] .. "a" 
	gen_sg_2 = args[1] .. "on"
	dat_sg = args[1] .. "on"
	nom_pl = args[1] .. "a"
	nom_pl_2 = args[1] .. "on"
	acc_pl = args[1] .. "a"
	acc_pl_2 = args[1] .. "on"
	gen_pl = args[1] .. "ono"
	dat_pl = args[1] .. "on"
	decl_type = "feminine ō/ōn-stem"
	
elseif args.decl == 'i' then
	if not args.length or args.length == "l" then
		umlauted_stem = umlaut(args[1])
		nom_sg = devoice(args[1])
		acc_sg = devoice(args[1])
	elseif args.length == "s" then
		umlauted_stem = args[1]
		nom_sg = args[1] .. "i"
		acc_sg = args[1] .. "i"
	end
	dat_sg = C_to_K(umlauted_stem) .. "i"
	nom_pl = C_to_K(umlauted_stem) .. "i"
	acc_pl = C_to_K(umlauted_stem) .. "i"
	gen_pl = K_to_C(umlauted_stem) .. "o"
	dat_pl = C_to_K(umlauted_stem) .. "in"
	dat_pl_2 = K_to_C(umlauted_stem) .. "on"
	if args.g== "m" then
		decl_type = "masculine i-stem"
		gen_sg = C_to_K(umlauted_stem) .. "is"
	elseif args.g== "f" then
		decl_type = "feminine i-stem"
		gen_sg = C_to_K(umlauted_stem) .. "i"
	end		

elseif args.decl == 'u' then
	if not args.length or args.length == "l" then
		umlauted_stem = umlaut(args[1])
		nom_sg = devoice(args[1])
		acc_sg = devoice(args[1])
	elseif args.length == "s" then
		umlauted_stem = args[1]
		nom_sg = args[1] .. "u"
		acc_sg = args[1] .. "u"
	end
	dat_sg = C_to_K(umlauted_stem) .. "i"
	nom_pl = C_to_K(umlauted_stem) .. "i"
	acc_pl = C_to_K(umlauted_stem) .. "i"
	gen_pl = K_to_C(umlauted_stem) .. "o"
	dat_pl = K_to_C(umlauted_stem) .. "in"
	dat_pl_2 = K_to_C(umlauted_stem) .. "on"
	if args.g== "m" then
		decl_type = "masculine u-stem"
		gen_sg = C_to_K(umlauted_stem) .. "is"
	elseif args.g== "m" then
		decl_type = "neuter u-stem"
		gen_sg = C_to_K(umlauted_stem) .. "is"
	elseif args.g== "f" then
		decl_type = "feminine u-stem"
		gen_sg = C_to_K(umlauted_stem) .. "i"
	end

elseif args.decl == 'ja' then
	nom_sg = args[1] .. "i"
	acc_sg = args[1] .. "i"
	gen_sg = args[1] .. "is"
	dat_sg = args[1] .. "i"
	nom_pl = args[1] .. "i"
	acc_pl = args[1] .. "i"
	gen_pl = K_to_C(args[1]) .. "o"
	dat_pl = K_to_C(args[1]) .. "on"
	if args.g== "m" then
		decl_type = "maculine ja-stem"
	elseif args.g== "n" then
		decl_type = "neuter ja-stem"
	end

elseif args.decl == 'jo' then
	nom_sg = args[1] .. "i"
	acc_sg = args[1] .. "i"
	gen_sg = args[1] .. "i"
	dat_sg = args[1] .. "i"
	nom_pl = args[1] .. "i"
	acc_pl = args[1] .. "i"
	gen_pl = K_to_C(args[1]) .. "o"
	dat_pl = K_to_C(args[1]) .. "on"
	decl_type = "feminine ī/jō-stem"
	end		

elseif args.decl == 'wa' then
	nom_sg = args[1] .. "o"
	acc_sg = args[1] .. "o"
	gen_sg = args[1] .. "wes"
	dat_sg = args[1] .. "we"
	gen_pl = args[1] .. "wo"
	dat_pl = args[1] .. "on"
	if args.g== "m" then
		nom_pl = args[1] .. "wa"
		acc_pl = args[1] .. "wa"
		decl_type = "maculine wa-stem"
	elseif args.g== "n" then
		nom_pl = args[1] .. "o"
		acc_pl = args[1] .. "o"
		decl_type = "neuter wa-stem"
	end

elseif args.decl == 'wo' then
	nom_sg = args[1] .. "wa"
	acc_sg = args[1] .. "wa"
	gen_sg = args[1] .. "wa"
	gen_sg_2 = args[1] .. "won"
	dat_sg = args[1] .. "won"
	nom_pl = args[1] .. "wa"
	nom_pl_2 = args[1] .. "won"
	acc_pl = args[1] .. "wa"
	acc_pl_2 = args[1] .. "won"
	gen_pl = args[1] .. "wono"
	dat_pl = args[1] .. "won"
	decl_type = "feminine wō-stem"

elseif args.decl == 'an' then
	gen_sg = C_to_K(args[1]) .. "en"
	dat_sg = C_to_K(args[1]) .. "en"
	nom_pl = args[1] .. "on"
	acc_pl = args[1] .. "on"
	gen_pl = args[1] .. "ono"
	dat_pl = args[1] .. "on"
	if args.g== "m" then
		decl_type = "maculine an-stem"
		nom_sg = args[1] .. "o"
		acc_sg = args[1] .. "on"
	elseif args.g== "n" then
		decl_type = "neuter an-stem"
		nom_sg = args[1] .. "a"
		acc_sg = args[1] .. "a"
		nom_pl_2 = args[1] .. "a"
		acc_pl_2 = args[1] .. "a"
	end	

elseif args.decl == 'in' then
	nom_sg = args[1] .. "i"
	acc_sg = args[1] .. "i"
	gen_sg = args[1] .. "i"
	dat_sg = args[1] .. "i"
	decl_type = "feminine in-stem"

elseif args.decl == 'nd' then
	nom_sg = devoice(args[1])
	acc_sg = devoice(args[1])
	dat_sg = args[1] .. "e"
	nom_pl = devoice(args[1])
	acc_pl = devoice(args[1])
	gen_pl = args[1] .. "o"
	dat_pl = args[1] .. "on"
	if args.g== "m" then
		gen_sg = args[1] .. "es"
		decl_type = "maculine nd-stem"
	elseif args.g== "n" then
		gen_sg = args[1] .. "es"
		decl_type = "neuter nd-stem"
	elseif args.g== "f" then
		gen_sg = args[1] .. "e"
		decl_type = "feminine nd-stem"
	end

elseif args.decl == 'r' then
	nom_sg = args[1] .. "er"
	acc_sg = args[1] .. "er"
	gen_sg = args[1] .. "er"
	dat_sg = args[1] .. "er"
	nom_pl = args[1] .. "er"
	nom_pl_2 = args[1] .. "era"
	acc_pl = args[1] .. "er"
	acc_pl_2 = args[1] .. "era"
	gen_pl = args[1] .. "ro"
	dat_pl = args[1] .. "ron"
	if args.g== "m" then
		decl_type = "maculine r-stem"
	elseif args.g== "f" then
		decl_type = "feminine r-stem"
	end

elseif args.decl == 'z' then
	nom_sg = devoice(args[1])
	acc_sg = devoice(args[1])
	gen_sg = C_to_K(args[1]) .. "es"
	dat_sg = C_to_K(args[1]) .. "e"
	nom_pl = C_to_K(args[1]) .. "ero"
	acc_pl = C_to_K(args[1]) .. "ero"
	gen_pl = C_to_K(args[1]) .. "ero"
	dat_pl = C_to_K(args[1]) .. "eron"
	if args.g== "m" then
		decl_type = "maculine z-stem"
	elseif args.g== "n" then
		decl_type = "neuter z-stem"
	elseif args.g== "f" then
		decl_type = "feminine z-stem"
	end
end
--
if g=='m' then
	table.insert(data.categories, "Old Dutch masculine nouns")
elseif g=='n' then
	table.insert(data.categories, "Old Dutch neuter nouns")
elseif g=='f' then
	table.insert(data.categories, "Old Dutch feminine nouns")
elseif not args.g then
		error("Gender parameter ('g') required for Old Dutch Nouns")
else
		error("Can't determine gender parameter")
end

if decl=='a' then
	table.insert(data.categories, "Old Dutch a-stem nouns")
elseif decl=='o' then
	table.insert(data.categories, "Old Dutch ō/ōn-stem nouns")
elseif decl=='i' then
	table.insert(data.categories, "Old Dutch i-stem nouns")
elseif decl=='ja' then
	table.insert(data.categories, "Old Dutch ja-stem nouns")
elseif decl=='jo' then
	table.insert(data.categories, "Old Dutch ī/jō-stem nouns")
elseif decl=='wa' then
	table.insert(data.categories, "Old Dutch wa-stem nouns")
elseif decl=='wo' then
	table.insert(data.categories, "Old Dutch wō-stem nouns")
elseif decl=='an' then
	table.insert(data.categories, "Old Dutch an-stem nouns")
elseif decl=='in' then
	table.insert(data.categories, "Old Dutch in-stem nouns")
elseif decl=='nd' then
	table.insert(data.categories, "Old Dutch nd-stem nouns")
elseif decl=='r' then
	table.insert(data.categories, "Old Dutch r-stem nouns")
elseif decl=='z' then
	table.insert(data.categories, "Old Dutch z-stem nouns")
elseif not args.decl then
	error("Declension parameter ('decl') required for Old Dutch Nouns")
else
	error("Can't determine declension parameter")
end
--
setmetatable(decl_data["noun"], {__call = function(self, args, data)
	data.decl_type = decl_type

	data.forms["nom_sg"] = nom_sg
	data.forms["acc_sg"] = acc_sg
	data.forms["gen_sg"] = gen_sg
	data.forms["dat_sg"] = dat_sg

	data.forms["nom_pl"] = nom_pl
	data.forms["acc_pl"] = acc_pl
	data.forms["gen_pl"] = gen_pl
	data.forms["dat_pl"] = dat_pl

	if args.defect == 'mass' or 'uncount' then
		data.forms["nom_pl"] = '-'
		data.forms["acc_pl"] = '-'
		data.forms["gen_pl"] = '-'
		data.forms["dat_pl"] = '-'
		if args.nopl == 'mass' then
			table.insert(data.categories, "Old Dutch mass nouns")
		elseif args.nopl == 'uncount' then
			table.insert(data.categories, "Old Dutch uncountable nouns")
		end
	elseif args.defect == 'pl_tantum' then
		data.forms["nom_sg"] = '-'
		data.forms["acc_sg"] = '-'
		data.forms["gen_sg"] = '-'
		data.forms["dat_sg"] = '-'
		table.insert(data.categories, "Old Dutch plurale tantum")
	end
end
})

-- The main entry point for automatic declension.
function export.show(frame)

	local parent_args = frame:getParent().args
	local decl_type = (frame.args["decl"] or parent_args["decl"]) or "a"

	if not decl_data[decl_type] then
		error("Unknown declension '" .. decl_type .. "'")
	end
	
	local data = {forms = {}, categories = {}}
	
	data.head = parent_args["head"] or nil

	local args = require("Module:parameters").process(parent_args, decl_data[decl_type].params, true)
	
	-- Override for templates
	if not args[1] then
		setmetatable(args, {__index = function(self, key)
			return "{{{" .. key .. "}}}"
		end
		})
	end
	
	-- Generate the forms
	if parent_args.irr then
		table.insert(data.categories, "Old Saxon irregular nouns")
		if decl_data.irregular[parent_args.irr] then
			decl_data.irregular[parent_args.irr](data)
		else
			decl_data[decl_type](args, data)
		end
	else
		decl_data[decl_type](args, data)
	end

	-- Make the table
	return make_table(data)
end

-- The main entry point for manual declension.
function export.show_manual(frame)
	local parent_args = frame:getParent().args
	local params = {
		[1] = {},
		[2] = {},
		[3] = {},
		[4] = {},
		[5] = {},
		[6] = {},
		[7] = {},
		[8] = {},
		["head"] = {}, -- currently ignored
	}

	local data = {forms = {}, categories = {}}
	local args = require("Module:parameters").process(parent_args, params)
	
	local function split(arg)
		return arg and mw.text.split(arg, "%s*,%s*") or nil
	end
	data.forms.nom_sg = split(args[1])
	data.forms.nom_pl = split(args[2])
	data.forms.acc_sg = split(args[3])
	data.forms.acc_pl = split(args[4])
	data.forms.gen_sg = split(args[5])
	data.forms.gen_pl = split(args[6])
	data.forms.dat_sg = split(args[7])
	data.forms.dat_pl = split(args[8])
	data.decl_type = "irregular"

	-- Make the table
	return make_table(data)
end

function make_table(data)
	local function show_form(form)
		if not form then
			return "—"
		end
		
		local ret = {}
		
		for key, subform in ipairs(form) do
			if mw.title.getCurrentTitle().nsText == "Reconstruction" and subform ~= "—" then
				subform = "*" .. subform
			end
			table.insert(ret, m_links.full_link({lang = lang, term = subform}))
		end
			
		return table.concat(ret, ", ")
	end
	
	local function repl(param)
		if param == "decl_type" then
			return data.decl_type
		else
			return show_form(data.forms[param])
		end
	end

	local wikicode = [=[
<div class="NavFrame" style="float: left; width: 45%;">
<div class="NavHead">Declension of {{{nom_sg}}} ({{{decl_type}}})</div>
<div class="NavContent">
{| style="width: 100%; line-height: 125%; background-color:#F9F9F9; text-align:center; border: 1px solid #CCCCFF;" cellpadding="3" cellspacing="1" class="inflection-table"
|- style="background-color:#EFEFEF; "
|-
| 
! style="width: 50%; background-color:#F3E5AB" | singular
! style="width: 50%; background-color:#F3E5AB" | plural
|-
! style="background: #FAEBD7" | [[Appendix:Glossary#nominative case|nominative]]
| {{{nom_sg}}}
| {{{nom_pl}}}
|-
! style="background: #FAEBD7" | [[Appendix:Glossary#accusative case|accusative]]
| {{{acc_sg}}}
| {{{acc_pl}}}
|-
! style="background: #FAEBD7" | [[Appendix:Glossary#genitive case|genitive]]
| {{{gen_sg}}}
| {{{gen_pl}}}
|-
! style="background: #FAEBD7" | [[Appendix:Glossary#dative case|dative]]
| {{{dat_sg}}}
| {{{dat_pl}}}
|-
! style="background: #FAEBD7" | [[Appendix:Glossary#instrumental case|instrumental]]
| {{{ins_sg}}}
| {{{ins_pl}}}
|}</div></div>
<br clear="all" />]=]

	return (mw.ustring.gsub(wikicode, "{{{([a-z0-9_]+)}}}", repl)) .. m_utils.format_categories(data.categories, lang)
end

return export