Module:la-noun/data

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 decl = {}

local lang = require("Module:languages").getByCode("la")
local m_links = require("Module:links")
local m_utilities = require("Module:utilities")

local rsplit = mw.text.split
local rfind = mw.ustring.find
local rmatch = mw.ustring.match
local rsubn = mw.ustring.gsub

-- version of rsubn() that discards all but the first return value
local function rsub(term, foo, bar)
	local retval = rsubn(term, foo, bar)
	return retval
end

local function glossary_link(anchor, text)
	text = text or anchor
	return "[[Appendix:Glossary#" .. anchor .. "|" .. text .. "]]"
end

local current_title = mw.title.getCurrentTitle().nsText
local NAMESPACE = current_title.nsText
local PAGENAME = current_title.text

decl["1"] = function(data, args)
	local stem = args[1]

	-- normal 1st
	data.forms["nom_sg"] = stem .. "a"
	data.forms["gen_sg"] = stem .. "ae"
	data.forms["dat_sg"] = stem .. "ae"
	data.forms["acc_sg"] = stem .. "am"
	data.forms["abl_sg"] = stem .. "ā"
	data.forms["voc_sg"] = stem .. "a"

	data.forms["nom_pl"] = stem .. "ae"
	data.forms["gen_pl"] = stem .. "ārum"
	data.forms["dat_pl"] = stem .. "īs"
	data.forms["acc_pl"] = stem .. "ās"
	data.forms["abl_pl"] = stem .. "īs"
	data.forms["voc_pl"] = stem .. "ae"

	-- abus
	if data.types.abus then
		table.insert(data.subtitles, {"dative/ablative plural in ", "''-ābus''"})

		data.forms["dat_pl"] = stem .. "ābus"
		data.forms["abl_pl"] = stem .. "ābus"
	elseif data.types.not_abus then
		table.insert(data.subtitles, {"dative/ablative plural in ", "''-īs''"})
	end

	-- am
	if data.types.am then
		table.insert(data.subtitles, {"nominative/vocative singular in ", "''-ām''"})

		data.forms["nom_sg"] = stem .. "ām"
		data.forms["acc_sg"] = stem .. "ām"
		data.forms["voc_sg"] = stem .. "ām"
		data.forms["abl_sg"] = {stem .. "ām", stem .. "ā"}

	-- all Greek
	elseif data.types.Greek then

		--Greek Ma
		if data.types.Ma then
			table.insert(data.subtitles, "masculine Greek-type with nominative singular in ''-ās''")

			data.forms["nom_sg"] = stem .. "ās"
			data.forms["acc_sg"] = stem .. "ān"
			data.forms["voc_sg"] = stem .. "ā"

		-- Greek Me
		elseif data.types.Me then
			table.insert(data.subtitles, "masculine Greek-type with nominative singular in ''-ēs''")

			data.forms["nom_sg"] = stem .. "ēs"
			data.forms["acc_sg"] = stem .. "ēn"
			data.forms["abl_sg"] = stem .. "ē"
			data.forms["voc_sg"] = stem .. "ē"

		-- Greek
		else
			table.insert(data.subtitles, "Greek-type")

			data.forms["nom_sg"] = stem .. "ē"
			data.forms["gen_sg"] = stem .. "ēs"
			data.forms["acc_sg"] = stem .. "ēn"
			data.forms["abl_sg"] = stem .. "ē"
			data.forms["voc_sg"] = stem .. "ē"
		end
	elseif data.types.not_Greek then
		table.insert(data.subtitles, "non-Greek-type")
	elseif data.types.not_am then
		table.insert(data.subtitles, {"nominative/vocative singular in ", "''-a''"})
	end

	-- with locative
	if data.loc then
		data.forms["loc_sg"] = stem .. "ae"
		data.forms["loc_pl"] = stem .. "īs"
	end
end

decl["2"] = function(data, args)
	local stem1 = args[1]
	local stem2 = args[2]

	-- normal 2nd
	data.forms["nom_sg"] = stem1 .. "us"
	data.forms["gen_sg"] = stem1 .. "ī"
	data.forms["dat_sg"] = stem1 .. "ō"
	data.forms["acc_sg"] = stem1 .. "um"
	data.forms["abl_sg"] = stem1 .. "ō"
	data.forms["voc_sg"] = stem1 .. "e"

	data.forms["nom_pl"] = stem1 .. "ī"
	data.forms["gen_pl"] = stem1 .. "ōrum"
	data.forms["dat_pl"] = stem1 .. "īs"
	data.forms["acc_pl"] = stem1 .. "ōs"
	data.forms["abl_pl"] = stem1 .. "īs"
	data.forms["voc_pl"] = stem1 .. "ī"

	-- all neuter
	if data.types.N then
		table.insert(data.subtitles, "neuter")

		data.forms["nom_sg"] = stem1 .. "um"
		data.forms["voc_sg"] = stem1 .. "um"

		data.forms["nom_pl"] = stem1 .. "a"
		data.forms["acc_pl"] = stem1 .. "a"
		data.forms["voc_pl"] = stem1 .. "a"

		-- neuter ium
		if data.types.ium then
			data.forms["nom_sg"] = stem1 .. "ium"
			data.forms["gen_sg"] = {stem1 .. "iī", stem1 .. "ī"}
			data.forms["dat_sg"] = stem1 .. "iō"
			data.forms["acc_sg"] = stem1 .. "ium"
			data.forms["abl_sg"] = stem1 .. "iō"
			data.forms["voc_sg"] = stem1 .. "ium"

			data.forms["nom_pl"] = stem1 .. "ia"
			data.forms["gen_pl"] = stem1 .. "iōrum"
			data.forms["dat_pl"] = stem1 .. "iīs"
			data.forms["acc_pl"] = stem1 .. "ia"
			data.forms["abl_pl"] = stem1 .. "iīs"
			data.forms["voc_pl"] = stem1 .. "ia"

			data.notes["gen_sg2"] = "Found in older Latin (until the Augustan Age)."
			
		-- neuter us, plural a
		elseif data.types.a then
			table.insert(data.subtitles, "nominative/accusative/vocative plural in ''-a''")

			data.forms["nom_sg"] = stem1 .. "us"
			data.forms["acc_sg"] = stem1 .. "us"
			data.forms["voc_sg"] = stem1 .. "us"

			data.forms["nom_pl"] = stem1 .. "a"
			data.forms["acc_pl"] = stem1 .. "a"
			data.forms["voc_pl"] = stem1 .. "a"
		-- -vom (aevom, etc.)
		elseif data.types.vom then
			table.insert(data.subtitles, "nominative singular in ''-om'' after ''v''")
			data.forms["nom_sg"] = stem1 .. "om"
			data.forms["acc_sg"] = stem1 .. "om"
			data.forms["voc_sg"] = stem1 .. "om"

		-- neuter Greek in -os (cētos)
		elseif data.types.Greek and data.types.us then
			table.insert(data.subtitles, "Greek-type")
			table.insert(data.subtitles, "nominative/accusative/vocative in ''-os''")

			data.forms["nom_sg"] = stem1 .. "os"
			data.forms["acc_sg"] = stem1 .. "os"
			data.forms["voc_sg"] = stem1 .. "os"

			data.forms["nom_pl"] = stem1 .. "ē"
			data.forms["gen_pl"] = stem1 .. "ōn"
			data.forms["acc_pl"] = stem1 .. "ē"
			data.forms["voc_pl"] = stem1 .. "ē"

		-- neuter Greek
		elseif data.types.Greek then
			table.insert(data.subtitles, "Greek-type")

			data.forms["nom_sg"] = stem1 .. "on"
			data.forms["acc_sg"] = stem1 .. "on"
			data.forms["voc_sg"] = stem1 .. "on"

		-- neuter us
		elseif data.types.us then
			table.insert(data.subtitles, "nominative/accusative/vocative in ''-us''")

			data.forms["nom_sg"] = stem1 .. "us"
			data.forms["acc_sg"] = stem1 .. "us"
			data.forms["voc_sg"] = stem1 .. "us"

			data.forms["nom_pl"] = stem1 .. "ī"
			data.forms["acc_pl"] = stem1 .. "ōs"
			data.forms["voc_pl"] = stem1 .. "ī"

		elseif data.types.not_Greek or data.types.not_us then
			table.insert(data.subtitles, "nominative/accusative/vocative in ''-um''")
		end

	-- er
	elseif data.types.er then
		if mw.ustring.match(stem1, "[aiouy]r$") then
			table.insert(data.subtitles, "nominative singular in ''-r''")
		else
			table.insert(data.subtitles, "nominative singular in ''-er''")
		end

		data.forms["nom_sg"] = stem1
		data.forms["gen_sg"] = stem2 .. "ī"
		data.forms["dat_sg"] = stem2 .. "ō"
		data.forms["acc_sg"] = stem2 .. "um"
		data.forms["abl_sg"] = stem2 .. "ō"
		data.forms["voc_sg"] = stem1

		data.forms["nom_pl"] = stem2 .. "ī"
		data.forms["gen_pl"] = stem2 .. "ōrum"
		data.forms["dat_pl"] = stem2 .. "īs"
		data.forms["acc_pl"] = stem2 .. "ōs"
		data.forms["abl_pl"] = stem2 .. "īs"
		data.forms["voc_pl"] = stem2 .. "ī"

	-- ius
	elseif data.types.ius then
		data.forms["nom_sg"] = stem1 .. "ius"
		data.forms["gen_sg"] = {stem1 .. "iī", stem1 .. "ī"}
		data.forms["dat_sg"] = stem1 .. "iō"
		data.forms["acc_sg"] = stem1 .. "ium"
		data.forms["abl_sg"] = stem1 .. "iō"
		if data.types.voci then
			-- Only for proper names and fīlius, genius
			data.forms["voc_sg"] = stem1 .. "ī"
		else
			data.forms["voc_sg"] = stem1 .. "ie"
		end

		data.forms["nom_pl"] = stem1 .. "iī"
		data.forms["gen_pl"] = stem1 .. "iōrum"
		data.forms["dat_pl"] = stem1 .. "iīs"
		data.forms["acc_pl"] = stem1 .. "iōs"
		data.forms["abl_pl"] = stem1 .. "iīs"
		data.forms["voc_pl"] = stem1 .. "iī"

		data.notes["gen_sg2"] = "Found in older Latin (until the Augustan Age)."

	-- -vos (servos, etc.)
	elseif data.types.vos then
		table.insert(data.subtitles, "nominative singular in ''-os'' after ''v''")
		data.forms["nom_sg"] = stem1 .. "os"
		data.forms["acc_sg"] = stem1 .. "om"

	-- Greek
	elseif data.types.Greek then
		table.insert(data.subtitles, "Greek-type")

		data.forms["nom_sg"] = stem1 .. "os"
		data.forms["acc_sg"] = {stem1 .. "on"}

	elseif data.types.not_Greek then
		table.insert(data.subtitles, "non-Greek-type")
	end

	-- with -um genitive plural
	if data.types.genplum then
		table.insert(data.subtitles, {"contracted", " genitive plural"})
		data.notes["gen_pl2"] = "Contraction found in poetry."
		if data.types.ius or  data.types.ium then
			data.forms["gen_pl"] = {stem2 .. "iōrum", stem2 .. "ium"}
		else
			data.forms["gen_pl"] = {stem2 .. "ōrum", stem2 .. "um"}
		end
	elseif data.types.not_genplum then
		table.insert(data.subtitles, {"normal", " genitive plural"})
	end

	-- with locative
	if data.loc then
		if data.types.ius or data.types.ium then
			data.forms["loc_sg"] = stem2 .. "iī"
			data.forms["loc_pl"] = stem2 .. "iīs"
		else
			data.forms["loc_sg"] = stem2 .. "ī"
			data.forms["loc_pl"] = stem2 .. "īs"
		end
	end
end

local acc_sg_i_stem_subtypes = {
	acc_im = {
		-- amussis, basis, buris, cucumis, gummis, mephitis, paraphrasis, poesis, ravis, sitis, tussis, (vis) [abl -ī];
		-- cannabis, senapis, sinapis [abl -e, -ī]
		acc_sg = {"im"},
		title = {"accusative singular in ''-im''"},
	},
	acc_im_in = {
		-- cities, rivers, gods, e.g. Bilbilis, Syrtis, Tiberis, Anubis, Osiris [abl -ī];
		-- Baetis, Tigris [acc -e, -ī]
		acc_sg = {"im", "in"},
		title = {"accusative singular in ''-im'' or ''-in''"},
	},
	acc_im_in_em = {
		-- e.g. tigris, river Līris
		acc_sg = {"im", "in", "em"},
		title = {"accusative singular in ''-im'', ''-in'' or ''-em''"},
	},
	acc_im_em = {
		acc_sg = {"im", "em"},
		title = {"accusative singular in ''-im'' or ''-em''"},
	},
	acc_im_occ_em = {
		-- febris, pelvis, puppis, restis, securis, turris [abl -ī, -e]
		acc_sg = {"im", "em"},
		title = {"accusative singular in ''-im'' or occasionally ''-em''"},
	},
	acc_em_im = {
		-- aqualis, clavis, lens, navis [abl -e, -ī];
		-- cutis, restis [abl -e]
		acc_sg = {"em", "im"},
		title = {"accusative singular in ''-em'' or ''-im''"},
	},
}

local abl_sg_i_stem_subtypes = {
	abl_i = {
		-- amussis, basis, buris, cucumis, gummis, mephitis, paraphrasis, poesis, ravis, sitis, tussis, (vis) [acc -im];
		-- cities, rivers, gods, e.g. Bilbilis, Syrtis, Tiberis, Anubis, Osiris [acc -im or -in];
		-- canalis "water pipe", months in -is or -er, nouns originally i-stem adjectives such as aedilis, affinis, bipennis, familiaris, sodalis, volucris, etc. [acc -em]
		abl_sg = {"ī"},
		title = {"ablative singular in ''-ī''"},
	},
	abl_i_e = {
		-- febris, pelvis, puppis, restis, securis, turris [acc -im, -em]
		abl_sg = {"ī", "e"},
		title = {"ablative singular in ''-ī'' or ''-e''"},
	},
	abl_e_i = {
		-- cannabis, senapis, sinapis [acc -im];
		-- Baetis, Tigris [acc -im, -in];
		-- aqualis, clavis, lens, navis [acc -em, -im];
		-- finis, mugilis, occiput, pugil, rus, supellex, vectis [acc -em]
		abl_sg = {"e", "ī"},
		title = {"ablative singular in ''-e'' or ''-ī''"},
	},
	abl_e_occ_i = {
		-- amnis, anguis, avis, civis, classis, fustis, ignis, imber, orbis, pars, postis, sors, unguis, vesper [acc -em]
		abl_sg = {"e", "ī"},
		title = {"ablative singular in ''-e'' or occasionally ''-ī''"},
	},
}

local function extract_stem(form, ending)
	local base = rmatch(form, "^(.*)" .. ending .. "$")
	if not base then
		error("Form " .. form .. " should end in -" .. ending)
	end
	return base
end

decl["3"] = function(data, args)
	local stem1 = args[1]
	local stem2 = args[2]

	local function parisyllabic_type()
		local stem1_vowels = rsub(
			require("Module:la-utilities").strip_macrons(stem1),
			"[^AEIOUYaeiouy]", ""
		)
		local stem2_vowels = rsub(
			require("Module:la-utilities").strip_macrons(stem2),
			"[^AEIOUYaeiouy]", ""
		)
		return #stem1_vowels > #stem2_vowels and "parisyllabic" or "imparisyllabic"
	end

	local function non_i_stem_type()
		return parisyllabic_type() .. " non-i-stem"
	end

	--normal 3rd
	data.forms["nom_sg"] = stem1
	data.forms["gen_sg"] = stem2 .. "is"
	data.forms["dat_sg"] = stem2 .. "ī"
	data.forms["acc_sg"] = stem2 .. "em"
	data.forms["abl_sg"] = stem2 .. "e"
	data.forms["voc_sg"] = stem1

	data.forms["nom_pl"] = stem2 .. "ēs"
	data.forms["gen_pl"] = stem2 .. "um"
	data.forms["dat_pl"] = stem2 .. "ibus"
	data.forms["acc_pl"] = stem2 .. "ēs"
	data.forms["abl_pl"] = stem2 .. "ibus"
	data.forms["voc_pl"] = stem2 .. "ēs"

	local acc_sg_i_stem_subtype = false
	local not_acc_sg_i_stem_subtype = false
	for subtype, _ in pairs(data.types) do
		if acc_sg_i_stem_subtypes[subtype] then
			acc_sg_i_stem_subtype = true
			break
		end
	end
	for acc_sg_subtype, _ in pairs(acc_sg_i_stem_subtypes) do
		if data.types["not_" .. acc_sg_subtype] then
			not_acc_sg_i_stem_subtype = true
			break
		end
	end
	local abl_sg_i_stem_subtype = false
	local not_abl_sg_i_stem_subtype = false
	for subtype, _ in pairs(data.types) do
		if abl_sg_i_stem_subtypes[subtype] then
			abl_sg_i_stem_subtype = true
			break
		end
	end
	for abl_sg_subtype, _ in pairs(abl_sg_i_stem_subtypes) do
		if data.types["not_" .. abl_sg_subtype] then
			not_abl_sg_i_stem_subtype = true
			break
		end
	end

	-- all Greek
	if data.types.Greek then
		table.insert(data.subtitles, "Greek-type")

		-- Greek er
		if data.types.er then
			table.insert(data.subtitles, "variant with nominative singular in ''-ēr''")
			stem1 = extract_stem(stem1, "ēr")

			data.forms["nom_sg"] = stem1 .. "ēr"
			data.forms["gen_sg"] = stem1 .. "eris"
			data.forms["dat_sg"] = stem1 .. "erī"
			data.forms["acc_sg"] = {stem1 .. "era", stem1 .. "erem"}
			data.forms["abl_sg"] = stem1 .. "ere"
			data.forms["voc_sg"] = stem1 .. "ēr"

			data.forms["nom_pl"] = stem1 .. "erēs"
			data.forms["gen_pl"] = stem1 .. "erum"
			data.forms["dat_pl"] = stem1 .. "eribus"
			data.forms["acc_pl"] = stem1 .. "erēs"
			data.forms["abl_pl"] = stem1 .. "eribus"
			data.forms["voc_pl"] = stem1 .. "erēs"

		-- Greek on
		elseif data.types.on then
			table.insert(data.subtitles, "variant with nominative singular in ''-ōn''")
			stem1 = extract_stem(stem1, "ōn")

			data.forms["nom_sg"] = stem1 .. "ōn"
			data.forms["gen_sg"] = {stem1 .. "ontis", stem1 .. "ontos"}
			data.forms["dat_sg"] = stem1 .. "ontī"
			data.forms["acc_sg"] = stem1 .. "onta"
			data.forms["abl_sg"] = stem1 .. "onte"
			data.forms["voc_sg"] = stem1 .. "ōn"

			data.forms["nom_pl"] = stem1 .. "ontēs"
			data.forms["gen_pl"] = {stem1 .. "ontum", stem1 .. "ontium"}
			data.forms["dat_pl"] = stem1 .. "ontibus"
			data.forms["acc_pl"] = {stem1 .. "ontēs", stem1 .. "ontās"}
			data.forms["abl_pl"] = stem1 .. "ontibus"
			data.forms["voc_pl"] = stem1 .. "ontēs"

		-- Greek i-stem
		elseif data.types.I then
			table.insert(data.subtitles, "i-stem")
			data.forms["gen_sg"] = {stem2 .. "is", stem2 .. "eōs", stem2 .. "ios"}
			data.forms["acc_sg"] = {stem2 .. "im", stem2 .. "in", stem2 .. "em"}
			data.forms["abl_sg"] = {stem2 .. "ī", stem2 .. "e"}
			data.forms["voc_sg"] = {stem2 .. "is", stem2 .. "i"}

			data.notes["acc_sg3"] = "Found sometimes in Medieval and New Latin."
			data.notes["abl_sg2"] = "Found sometimes in Medieval and New Latin."

			data.forms["nom_pl"] = {stem2 .. "ēs", stem2 .. "eis"}
			data.forms["gen_pl"] = {stem2 .. "ium", stem2 .. "eōn"}
			data.forms["acc_pl"] = {stem2 .. "ēs", stem2 .. "eis"}
			data.forms["voc_pl"] = {stem2 .. "ēs", stem2 .. "eis"}

			if data.types.poetic_esi then
				data.forms["dat_pl"] = {stem2 .. "ibus", stem2 .. "esi"}
				data.forms["abl_pl"] = {stem2 .. "ibus", stem2 .. "esi"}
				data.notes["dat_pl2"] = "Primarily in poetry."
				data.notes["abl_pl2"] = "Primarily in poetry."
			end

		-- normal Greek
		else
			table.insert(data.subtitles, "normal variant")
			data.forms["gen_sg"] = stem2 .. "os"
			if stem2:find("y$") then
				data.forms["acc_sg"] = stem2 .. "n"
			else
				data.forms["acc_sg"] = stem2 .. "a"
			end

			data.forms["nom_pl"] = stem2 .. "es"
			data.forms["acc_pl"] = stem2 .. "as"
			data.forms["voc_pl"] = stem2 .. "es"
			if rfind(stem1, "[iyï]s$") then
				-- Per Hiley, words in -is and -ys have a poetic vocative
				-- without the -s, but otherwise the vocative is the same
				-- as the nominative.
				data.forms["voc_sg"] = {stem1, rsub(stem1, "s", "")}
				data.notes["voc_sg2"] = "In poetry."
			end
		end
	elseif data.types.not_Greek then
		table.insert(data.subtitles, "non-Greek-type")
	end

	-- polis
	if data.types.polis then
		stem1 = extract_stem(stem1, "polis")
		table.insert(data.subtitles, "i-stem, partially Greek-type")

		data.forms["nom_sg"] = stem1 .. "polis"
		data.forms["gen_sg"] = stem1 .. "polis"
		data.forms["dat_sg"] = stem1 .. "polī"
		data.forms["acc_sg"] = {stem1 .. "polim", stem1 .. "polin"}
		data.forms["abl_sg"] = stem1 .. "polī"
		data.forms["voc_sg"] = {stem1 .. "polis", stem1 .. "polī"}
	elseif data.types.not_polis then
		table.insert(data.subtitles, non_i_stem_type())
	end

	-- all neuter
	if data.types.N then
		table.insert(data.subtitles, "neuter")

		data.forms["acc_sg"] = stem1

		-- neuter I stem
		if data.types.I then

			-- pure variety
			if data.types.pure then
				table.insert(data.subtitles, "“pure” i-stem")
				data.forms["abl_sg"] = stem2 .. "ī"

				data.forms["nom_pl"] = stem2 .. "ia"
				data.forms["gen_pl"] = stem2 .. "ium"
				data.forms["acc_pl"] = stem2 .. "ia"
				data.forms["voc_pl"] = stem2 .. "ia"

			-- non-pure variety (rare)
			else
				table.insert(data.subtitles, "i-stem")
				data.forms["nom_pl"] = stem2 .. "a"
				data.forms["gen_pl"] = {stem2 .. "ium", stem2 .. "um"}
				data.forms["acc_pl"] = stem2 .. "a"
				data.forms["voc_pl"] = stem2 .. "a"
			end

		-- normal neuter
		else
			table.insert(data.subtitles, non_i_stem_type())
			data.forms["nom_pl"] = stem2 .. "a"
			data.forms["acc_pl"] = stem2 .. "a"
			data.forms["voc_pl"] = stem2 .. "a"
		end

	-- I stem
	elseif data.types.I or acc_sg_i_stem_subtype or abl_sg_i_stem_subtype then
		if data.types.not_N then
			table.insert(data.subtitles, "non-neuter i-stem")
		else
			table.insert(data.subtitles, "i-stem")
		end

		data.forms["gen_pl"] = stem2 .. "ium"
		-- Per Allen and Greenough, Hiley and others, the acc_pl in -īs
		-- applied originally to all i-stem nouns, and was current as an
		-- alternative form up through Caesar.
		data.forms["acc_pl"] = {stem2 .. "ēs", stem2 .. "īs"}

		for subtype, _ in pairs(data.types) do
			local acc_sg_i_stem_props = acc_sg_i_stem_subtypes[subtype]
			if acc_sg_i_stem_props then
				data.forms["acc_sg"] = {}
				for _, ending in ipairs(acc_sg_i_stem_props.acc_sg) do
					table.insert(data.forms["acc_sg"], stem2 .. ending)
				end
				if data.num ~= "pl" then
					for _, t in ipairs(acc_sg_i_stem_props.title) do
						table.insert(data.subtitles, t)
					end
				end
				break
			end
		end

		for subtype, _ in pairs(data.types) do
			local abl_sg_i_stem_props = abl_sg_i_stem_subtypes[subtype]
			if abl_sg_i_stem_props then
				data.forms["abl_sg"] = {}
				for _, ending in ipairs(abl_sg_i_stem_props.abl_sg) do
					table.insert(data.forms["abl_sg"], stem2 .. ending)
				end
				if data.num ~= "pl" then
					for _, t in ipairs(abl_sg_i_stem_props.title) do
						table.insert(data.subtitles, t)
					end
				end
				break
			end
		end
	elseif data.types.not_N and data.types.not_I then
		table.insert(data.subtitles, "non-neuter " .. non_i_stem_type())
	elseif data.types.not_N then
		table.insert(data.subtitles, "non-neuter")
	elseif data.types.not_I then
		table.insert(data.subtitles, non_i_stem_type())
	end

	-- with locative
	if data.loc then
		-- As far as I can tell, in general both dative singular and
		-- ablative singular could be used for the third-declension locative,
		-- with different time periods preferring different forms.
		-- http://dcc.dickinson.edu/grammar/latin/3rd-declension-locative-case
		-- mentions rūrī along with either Carthāginī or Carthāgine.
		-- Wikipedia in https://en.wikipedia.org/wiki/Locative_case#Latin
		-- says this:
		--
		-- In archaic times, the locative singular of third declension nouns
		-- was still interchangeable between ablative and dative forms, but in
		-- the Augustan Period the use of the ablative form became fixed.
		-- Therefore, both forms "rūrī" and "rūre" may be encountered.
		--
		-- Lewis and Short confirm this.
		local m_table = require("Module:table")
		local loc_sg = data.forms["dat_sg"]
		if type(loc_sg) ~= "table" then
			loc_sg = {loc_sg}
		end
		loc_sg = m_table.deepcopy(loc_sg)
		local abl_sg = data.forms["abl_sg"]
		if type(abl_sg) ~= "table" then
			abl_sg = {abl_sg}
		end
		for _, form in ipairs(abl_sg) do
			m_table.insertIfNot(loc_sg, form)
		end
		data.forms["loc_sg"] = loc_sg
		data.forms["loc_pl"] = data.forms["abl_pl"]
		--The following is what we used to have, but I simply cannot believe it.
		--if data.types.Greek and not data.types.s then
		--	data.forms["loc_pl"] = stem2 .. "ēs"
		--end
	end
end

decl["4"] = function(data, args)
	local stem = args[1]

	-- normal 4th
	data.forms["nom_sg"] = stem .. "us"
	data.forms["gen_sg"] = stem .. "ūs"
	data.forms["dat_sg"] = stem .. "uī"
	data.forms["acc_sg"] = stem .. "um"
	data.forms["abl_sg"] = stem .. "ū"
	data.forms["voc_sg"] = stem .. "us"

	data.forms["nom_pl"] = stem .. "ūs"
	data.forms["gen_pl"] = stem .. "uum"
	data.forms["dat_pl"] = stem .. "ibus"
	data.forms["acc_pl"] = stem .. "ūs"
	data.forms["abl_pl"] = stem .. "ibus"
	data.forms["voc_pl"] = stem .. "ūs"

	if data.types.echo then
		table.insert(data.subtitles, "nominative/vocative singular in ''-ō''")
		data.forms["nom_sg"] = stem .. "ō"
		data.forms["voc_sg"] = stem .. "ō"
	elseif data.types.argo then
		table.insert(data.subtitles, "nominative/accusative/vocative singular in ''-ō'', ablative singular in ''-uī''")
		data.forms["nom_sg"] = stem .. "ō"
		data.forms["acc_sg"] = stem .. "ō"
		data.forms["abl_sg"] = stem .. "uī"
		data.forms["voc_sg"] = stem .. "ō"
	elseif data.types.Callisto then
		table.insert(data.subtitles, "all cases except the genitive singular in ''-ō''")
		data.forms["nom_sg"] = stem .. "ō"
		data.forms["dat_sg"] = stem .. "ō"
		data.forms["acc_sg"] = stem .. "ō"
		data.forms["abl_sg"] = stem .. "ō"
		data.forms["voc_sg"] = stem .. "ō"
	end

	-- neuter
	if data.types.N then
		table.insert(data.subtitles, "neuter")

		data.forms["nom_sg"] = stem .. "ū"
		data.forms["dat_sg"] = stem .. "ū"
		data.forms["acc_sg"] = stem .. "ū"
		data.forms["voc_sg"] = stem .. "ū"

		data.forms["nom_pl"] = stem .. "ua"
		data.forms["acc_pl"] = stem .. "ua"
		data.forms["voc_pl"] = stem .. "ua"
	end

	-- ubus
	if data.types.ubus then
		table.insert(data.subtitles, "dative/ablative plural in ''-ubus''")

		data.forms["dat_pl"] = stem .. "ubus"
		data.forms["abl_pl"] = stem .. "ubus"
	elseif data.types.not_ubus then
		table.insert(data.subtitles, "''-ibus''")
	end

	-- with locative
	if data.loc then
		data.forms["loc_sg"] = data.forms["abl_sg"]
		data.forms["loc_pl"] = data.forms["abl_pl"]
	end
end

decl["5"] = function(data, args)
	local stem = args[1]

	-- ies
	if data.types.i then
		stem = stem .. "i"
	end

	data.forms["nom_sg"] = stem .. "ēs"
	data.forms["gen_sg"] = stem .. "eī"
	data.forms["dat_sg"] = stem .. "eī"
	data.forms["acc_sg"] = stem .. "em"
	data.forms["abl_sg"] = stem .. "ē"
	data.forms["voc_sg"] = stem .. "ēs"

	data.forms["nom_pl"] = stem .. "ēs"
	data.forms["gen_pl"] = stem .. "ērum"
	data.forms["dat_pl"] = stem .. "ēbus"
	data.forms["acc_pl"] = stem .. "ēs"
	data.forms["abl_pl"] = stem .. "ēbus"
	data.forms["voc_pl"] = stem .. "ēs"

	-- ies
	if data.types.i then
		data.forms["gen_sg"] = stem .. "ēī"
		data.forms["dat_sg"] = stem .. "ēī"
	end

	--with locative
	if data.loc then
		data.forms["loc_sg"] = stem .. "ē"
		data.forms["loc_pl"] = stem .. "ēbus"
	end
end

decl["0"] = function(data, args)
	local stem = args[1]

	data.forms["nom_sg"] = stem
	data.forms["gen_sg"] = stem
	data.forms["dat_sg"] = stem
	data.forms["acc_sg"] = stem
	data.forms["abl_sg"] = stem
	data.forms["voc_sg"] = stem

	data.forms["nom_pl"] = stem
	data.forms["gen_pl"] = stem
	data.forms["dat_pl"] = stem
	data.forms["acc_pl"] = stem
	data.forms["abl_pl"] = stem
	data.forms["voc_pl"] = stem

	-- with locative
	if data.loc then
		data.forms["loc_sg"] = stem
		data.forms["loc_pl"] = stem
	end
end

decl["indecl"] = function(data, args)
	local title = {}
	data.title = "Not declined; used only in the nominative and accusative singular"

	local stem = args[1]

	data.forms["nom_sg"] = "-"
	data.forms["gen_sg"] = "-"
	data.forms["dat_sg"] = "-"
	data.forms["acc_sg"] = "-"
	data.forms["abl_sg"] = "-"
	data.forms["voc_sg"] = "-"

	data.forms["nom_pl"] = "-"
	data.forms["gen_pl"] = "-"
	data.forms["dat_pl"] = "-"
	data.forms["acc_pl"] = "-"
	data.forms["abl_pl"] = "-"
	data.forms["voc_pl"] = "-"

	data.forms["nom_sg"] = stem
	data.forms["acc_sg"] = stem
	data.num = "sg"
end

decl["irreg"] = function(data, args)
	local stem = args[1]

	data.forms["nom_sg"] = "-"
	data.forms["gen_sg"] = "-"
	data.forms["dat_sg"] = "-"
	data.forms["acc_sg"] = "-"
	data.forms["abl_sg"] = "-"
	data.forms["voc_sg"] = "-"

	data.forms["nom_pl"] = "-"
	data.forms["gen_pl"] = "-"
	data.forms["dat_pl"] = "-"
	data.forms["acc_pl"] = "-"
	data.forms["abl_pl"] = "-"
	data.forms["voc_pl"] = "-"

	if stem == "bōs" then
		data.forms["nom_sg"] = "bōs"
		data.forms["gen_sg"] = "bovis"
		data.forms["dat_sg"] = "bovī"
		data.forms["acc_sg"] = "bovem"
		data.forms["abl_sg"] = "bove"
		data.forms["voc_sg"] = "bōs"

		data.forms["nom_pl"] = "bovēs"
		data.forms["gen_pl"] = "boum"
		data.forms["dat_pl"] = {"bōbus", "būbus"}
		data.forms["acc_pl"] = "bovēs"
		data.forms["abl_pl"] = {"bōbus", "būbus"}
		data.forms["voc_pl"] = "bovēs"

	elseif stem == "cherub" then
		data.title = "mostly " .. glossary_link("indeclinable")
		table.insert(data.subtitles, "with a distinct plural")

		data.forms["nom_sg"] = "cherub"
		data.forms["gen_sg"] = "cherub"
		data.forms["dat_sg"] = "cherub"
		data.forms["acc_sg"] = "cherub"
		data.forms["abl_sg"] = "cherub"
		data.forms["voc_sg"] = "cherub"

		data.forms["nom_pl"] = {"cherubim", "cherubin"}
		data.forms["gen_pl"] = {"cherubim", "cherubin"}
		data.forms["dat_pl"] = {"cherubim", "cherubin"}
		data.forms["acc_pl"] = {"cherubim", "cherubin"}
		data.forms["abl_pl"] = {"cherubim", "cherubin"}
		data.forms["voc_pl"] = {"cherubim", "cherubin"}

	elseif stem == "deus" then
		data.forms["nom_sg"] = "deus"
		data.forms["gen_sg"] = "deī"
		data.forms["dat_sg"] = "deō"
		data.forms["acc_sg"] = "deum"
		data.forms["abl_sg"] = "deō"
		data.forms["voc_sg"] = {"dee", "deus"}

		data.forms["nom_pl"] = {"dī", "diī", "deī"}
		data.forms["gen_pl"] = {"deōrum", "deûm", "divom"}
		data.forms["dat_pl"] = {"dīs", "diīs", "deīs"}
		data.forms["acc_pl"] = "deōs"
		data.forms["abl_pl"] = {"dīs", "diīs", "deīs"}
		data.forms["voc_pl"] = {"dī", "diī", "deī"}

	elseif stem == "Deus" then
		data.forms["nom_sg"] = "Deus"
		data.forms["gen_sg"] = "Deī"
		data.forms["dat_sg"] = "Deō"
		data.forms["acc_sg"] = "Deum"
		data.forms["abl_sg"] = "Deō"
		data.forms["voc_sg"] = "Deus"
		data.num = "sg"

	elseif stem == "domus" then
		data.title = "[[Appendix:Latin fourth declension|fourth]]/[[Appendix:Latin second declension|second-declension]] noun"
		data.forms["nom_sg"] = "domus"
		data.forms["gen_sg"] = {"domūs", "domī"}
		data.forms["dat_sg"] = {"domuī", "domō", "domū"}
		data.forms["acc_sg"] = "domum"
		data.forms["abl_sg"] = {"domū", "domō"}
		data.forms["voc_sg"] = "domus"
		data.forms["loc_sg"] = "domī"

		data.forms["nom_pl"] = "domūs"
		data.forms["gen_pl"] = {"domuum", "domōrum"}
		data.forms["dat_pl"] = "domibus"
		data.forms["acc_pl"] = {"domūs", "domōs"}
		data.forms["abl_pl"] = "domibus"
		data.forms["voc_pl"] = "domūs"
		data.forms["loc_pl"] = "domibus"

		data.loc = true

	elseif stem == "Iēsus" or stem == "Iēsūs" then
		table.insert(data.subtitles, "highly " .. glossary_link("irregular"))
		ij = mw.ustring.sub(stem, 1, 1)

		data.forms["nom_sg"] = stem
		data.forms["gen_sg"] = ij .. "ēsū"
		data.forms["dat_sg"] = ij .. "ēsū"
		data.forms["acc_sg"] = ij .. "ēsum"
		data.forms["abl_sg"] = ij .. "ēsū"
		data.forms["voc_sg"] = ij .. "ēsū"
		data.num = "sg"
	elseif stem == "Jesus" then
		table.insert(data.subtitles, "highly " .. glossary_link("irregular"))
		ij = mw.ustring.sub(stem, 1, 1)

		data.forms["nom_sg"] = stem
		data.forms["gen_sg"] = ij .. "esu"
		data.forms["dat_sg"] = ij .. "esu"
		data.forms["acc_sg"] = ij .. "esum"
		data.forms["abl_sg"] = ij .. "esu"
		data.forms["voc_sg"] = ij .. "esu"
		data.num = "sg"
	elseif stem == "Jésus" then
		table.insert(data.subtitles, "highly " .. glossary_link("irregular"))
		ij = mw.ustring.sub(stem, 1, 1)

		data.forms["nom_sg"] = stem
		data.forms["gen_sg"] = ij .. "ésu"
		data.forms["dat_sg"] = ij .. "ésu"
		data.forms["acc_sg"] = ij .. "ésum"
		data.forms["abl_sg"] = ij .. "ésu"
		data.forms["voc_sg"] = ij .. "ésu"
		data.num = "sg"	
	elseif stem == "iūgerum" or stem == "jūgerum" then
		ij = stem == "iūgerum" and "i" or "j"
		data.title = "[[Appendix:Latin second declension|second]]–[[Appendix:Latin third declension|third-declension]] hybrid noun"
		table.insert(data.subtitles, "neuter")

		data.forms["nom_sg"] = ij .. "ūgerum"
		data.forms["gen_sg"] = ij .. "ūgerī"
		data.forms["dat_sg"] = ij .. "ūgerō"
		data.forms["acc_sg"] = ij .. "ūgerum"
		data.forms["abl_sg"] = ij .. "ūgerō"
		data.forms["voc_sg"] = ij .. "ūgerum"
		data.forms["nom_pl"] = ij .. "ūgera"
		data.forms["gen_pl"] = ij .. "ūgerum"
		data.forms["dat_pl"] = ij .. "ūgeribus"
		data.forms["acc_pl"] = ij .. "ūgera"
		data.forms["abl_pl"] = {ij .. "ūgeribus", ij .. "ūgerīs"}
		data.forms["voc_pl"] = ij .. "ūgera"

		data.notes["abl_pl2"] = "Once only, in:<br/>M. Terentius Varro, ''Res Rusticae'', bk I, ch. x"

	elseif stem == "sūs" then
		data.forms["nom_sg"] = "sūs"
		data.forms["gen_sg"] = "suis"
		data.forms["dat_sg"] = "suī"
		data.forms["acc_sg"] = "suem"
		data.forms["abl_sg"] = "sue"
		data.forms["voc_sg"] = "sūs"

		data.forms["nom_pl"] = "suēs"
		data.forms["gen_pl"] = "suum"
		data.forms["dat_pl"] = {"suibus", "sūbus", "subus"}
		data.forms["acc_pl"] = "suēs"
		data.forms["abl_pl"] = {"suibus", "sūbus", "subus"}
		data.forms["voc_pl"] = "suēs"

	elseif stem == "ēthos" then
		table.insert(data.subtitles, glossary_link("irregular"))
		table.insert(data.subtitles, "Greek-type")

		data.forms["nom_sg"] = "ēthos"
		data.forms["gen_sg"] = "ētheos"
		data.forms["acc_sg"] = "ēthos"
		data.forms["voc_sg"] = "ēthos"

		data.forms["nom_pl"] = {"ēthea", "ēthē"}
		data.forms["dat_pl"] = {"ēthesi", "ēthesin"}
		data.forms["acc_pl"] = {"ēthea", "ēthē"}
		data.forms["abl_pl"] = {"ēthesi", "ēthesin"}
		data.forms["voc_pl"] = {"ēthea", "ēthē"}

	elseif stem == "lexis" then
		table.insert(data.subtitles, glossary_link("irregular"))
		table.insert(data.subtitles, "Greek-type")

		data.forms["nom_sg"] = "lexis"
		data.forms["gen_sg"] = "lexeōs"
		data.forms["acc_pl"] = "lexeis"

	elseif stem == "Athōs" then
		table.insert(data.subtitles, "highly " .. glossary_link("irregular"))
		table.insert(data.subtitles, "Greek-type")

		data.forms["nom_sg"] = "Athōs"
		data.forms["gen_sg"] = "Athō"
		data.forms["dat_sg"] = "Athō"
		data.forms["acc_sg"] = {"Athō", "Athōn"}
		data.forms["abl_sg"] = "Athō"
		data.forms["voc_sg"] = "Athōs"
		data.num = "sg"
	
	elseif stem == "Pammenēs" then
		data.title = "Variably declined either according to [[Appendix:Latin third declension|Latin’s third declension]] or in a manner adapted from [[Appendix:Ancient Greek first declension|Ancient Greek’s first declension]]"
		
		data.forms["nom_sg"] = "Pammenēs"
		data.forms["gen_sg"] = {"Pammenis", "Pammenī"}
		data.forms["dat_sg"] = {"Pammenī", "Pammenē"}
		data.forms["acc_sg"] = {"Pammenem", "Pammenēn"}
		data.forms["abl_sg"] = "Pammenē̆"
		data.forms["voc_sg"] = {"Pammenēs", "Pammenē"}
		data.num = "sg"

	elseif stem == "vēnum" then
		data.title = "[[Appendix:Latin fourth declension|fourth]]/[[Appendix:Latin second declension|second-declension]] noun"
		table.insert(data.subtitles, glossary_link("defective"))

		data.forms["dat_sg"] = {"vēnuī", "vēnō"}
		data.forms["acc_sg"] = "vēnum"
		data.num = "sg"

	elseif stem == "vīs" then
		table.insert(data.subtitles, glossary_link("irregular"))
		table.insert(data.subtitles, glossary_link("defective"))

		data.forms["nom_sg"] = "vīs"
		data.forms["gen_sg"] = "*vīs"
		data.forms["dat_sg"] = "*vī"
		data.forms["acc_sg"] = "vim"
		data.forms["abl_sg"] = "vī"
		data.forms["voc_sg"] = "vīs"

		data.forms["nom_pl"] = "vīrēs"
		data.forms["gen_pl"] = "vīrium"
		data.forms["dat_pl"] = "vīribus"
		data.forms["acc_pl"] = {"vīrēs", "vīrīs"}
		data.forms["abl_pl"] = "vīribus"
		data.forms["voc_pl"] = "vīrēs"

	else
		error("Stem " .. stem .. " not recognized.")
	end
end

return decl

-- For Vim, so we get 4-space tabs
-- vim: set ts=4 sw=4 noet: