Module:User:Benwing2/la-headword

Hello, you have come here looking for the meaning of the word Module:User:Benwing2/la-headword. In DICTIOUS you will not only get to know all the dictionary meanings for the word Module:User:Benwing2/la-headword, but we will also tell you about its etymology, its characteristics and you will know how to say Module:User:Benwing2/la-headword in singular and plural. Everything you need to know about the word Module:User:Benwing2/la-headword you have here. The definition of the word Module:User:Benwing2/la-headword will help you to be more precise and correct when speaking or writing your texts. Knowing the definition ofModule:User:Benwing2/la-headword, as well as those of other words, enriches your vocabulary and provides you with more and better linguistic resources.


local export = {}
local pos_functions = {}

local m_table = require("Module:table")

local legal_gender = {
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
}

local declension_to_english = {
	 = "first",
	 = "second",
	 = "third",
	 = "fourth",
	 = "fifth",
}

local gender_names = {
	 = "masculine",
	 = "feminine",
	 = "neuter",
	 = "unknown gender",
	 = "unattested gender",
}

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

local u = mw.ustring.char
local rfind = mw.ustring.find
local rmatch = mw.ustring.match
local rsplit = mw.text.split
local rsubn = mw.ustring.gsub
local ulower = mw.ustring.lower

local MACRON = u(0x0304)
local BREVE = u(0x0306)
local DIAER = u(0x0308)
local DOUBLE_INV_BREVE = u(0x0361)
local accents = MACRON .. BREVE .. DIAER .. DOUBLE_INV_BREVE

-- 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 track(page)
	require("Module:debug").track("la-headword/" .. page)
	return true
end

local function format(array, concatenater)
	if #array == 0 then
		return ""
	else
		local concatenated = table.concat(array, concatenater)
		if concatenated == "" then
			return ""
		elseif rfind(concatenated, "'$") then
			concatenated = concatenated .. " "
		end
		return "; ''" .. concatenated .. "''"
	end
end

local function glossary_link(anchor, text)
	text = text or anchor
	return "]"
end

-- The main entry point.
-- This is the only function that can be invoked from a template.
function export.show(frame)
	local NAMESPACE = mw.title.getCurrentTitle().nsText
	local PAGENAME = mw.title.getCurrentTitle().text

	local iparams = {
		 = {required = true},
		 = {},
		 = {},
	}
	local iargs = require("Module:parameters").process(frame.args, iparams)
	local args = frame:getParent().args
	local poscat = iargs
	local def = iargs.def
	local suff_type = iargs.suff_type
	local postype = nil
	if suff_type then
		postype = poscat .. '-' .. suff_type
	else
		postype = poscat
	end

	local data = {lang = lang, categories = {}, heads = {}, genders = {}, inflections = {}}
	local infl_classes = {}
	local appendix = {}
	local postscript = {}

	if poscat == "suffixes" then
		table.insert(data.categories, "Latin " .. suff_type .. "-forming suffixes")
	end

	if pos_functions then
		local new_poscat = pos_functions(def, args, data, infl_classes, appendix, postscript)
		if new_poscat then
			poscat = new_poscat
		end
	end

	if (NAMESPACE == "Reconstruction") then
		data.pos_category = "reconstructed " .. poscat
		data.nolink = true
	else
		data.pos_category = poscat
	end

	postscript = table.concat(postscript, ", ")

	return
		require("Module:User:Benwing2/headword").full_headword(data)
		.. format(infl_classes, "/")
		.. format(appendix, ", ")
		.. (postscript ~= "" and " (" .. postscript .. ")" or "")
end

local function process_num_type(numtype, categories)
	if numtype == "card" then
		table.insert(categories, "Latin cardinal numbers")
	elseif numtype == "ord" then
		table.insert(categories, "Latin ordinal numbers")
	elseif numtype == "dist" then
		-- FIXME, should be named 'Latin distributive numbers'
		table.insert(categories, "la:Distributive numbers")
	elseif numtype == "mul" then
		-- FIXME, should be named 'Latin multiplicative numbers'
		table.insert(categories, "la:Multiplicative numbers")
	elseif numtype == "coll" then
		-- FIXME, should be named 'Latin collective numbers'
		table.insert(categories, "la:Collective numbers")
	elseif numtype then
		error("Unrecognized numeral type '" .. numtype .. "'")
	end
end

local function nouns(pos, def, args, data, infl_classes, appendix)
	local NAMESPACE = mw.title.getCurrentTitle().nsText
	local is_num = pos == "numerals"
	local is_pn = false
	if pos == "proper nouns" then
		is_pn = true
		pos = "nouns"
	end
	local decldata = require("Module:la-nominal").do_generate_noun_forms(
	  args, pos, true, def, is_num)
	local lemma = decldata.overriding_lemma
	local lemma_num = decldata.num == "pl" and "pl" or "sg"
	if not lemma or #lemma == 0 then
		lemma = decldata.forms
		if decldata.unattested then
			lemma = '*' .. lemma
		end
	end

	data.heads = lemma
	-- Since we always set data.heads to the lemma and specification of the lemma is mandatory in {{la-noun}}, there aren't
	-- really any redundant heads.
	data.no_redundant_head_cat = true
	data.id = decldata.id
	
	local genders = decldata.overriding_genders
	if #genders == 0 then
		if decldata.gender then
			genders = {ulower(decldata.gender)}
		elseif not is_num then
			error("No gender explicitly specified in headword template using g=, and can't infer gender from lemma spec")
		end
	end

	if is_num then
		process_num_type(decldata.num_type, data.categories)
	end

	if decldata.indecl then
		table.insert(data.inflections, {label = glossary_link("indeclinable")})
		table.insert(data.categories, "Latin indeclinable " .. decldata.pos)

		for _, g in ipairs(genders) do
			local gender, number = rmatch(g, "^(.)%-()$")
			if not gender then
				gender = g
			end
			if not legal_gender then
				error("Gender “" .. gender .. "” is not a valid Latin gender.")
			end
			table.insert(data.genders, g)
			local gender_name = gender_names
			table.insert(data.categories, "Latin " .. gender_name ..  " indeclinable " .. decldata.pos)
		end
	else
		local is_irreg = false
		local is_indecl = false
		local is_decl = false
		local has_multiple_decls = false
		local has_multiple_variants = false
		-- flatten declension specs
		local decls = {}

		for _, g in ipairs(genders) do
			if not legal_gender then
				error("Gender “" .. g .. "” is not a valid Latin gender.")
			end
			local gender_name = gender_names
			if decldata.num == "pl" then
				g = g .. "-p"
			elseif decldata.num == "sg" then
				g = g .. "-s"
			end
			table.insert(data.genders, g)
		end

		local function process_decl(decl_list, decl)
			-- skip adjectival declensions
			if not rfind(decl, "%+$") then
				local irreg_decl_spec = rmatch(decl, "^irreg/(.*)$")
				if irreg_decl_spec then
					is_irreg = true
					local irreg_decls = rsplit(irreg_decl_spec, ",")
					if #irreg_decls > 1 then
						has_multiple_decls = true
					end
					for _, d in ipairs(irreg_decls) do
						if d == "indecl" or decl == "0" then
							is_indecl = true
						else
							is_decl = true
						end
						m_table.insertIfNot(decl_list, d)
					end
				else
					if decl == "indecl" or decl == "0" then
						is_indecl = true
					else
						is_decl = true
					end
					m_table.insertIfNot(decl_list, decl)
				end
			end
		end

		for _, props in ipairs(decldata.propses) do
			if props.headword_decl then
				process_decl(decls, props.headword_decl)
			else
				local alternant_decls = {}
				for _, alternant in ipairs(props) do
					for _, single_props in ipairs(alternant) do
						process_decl(alternant_decls, single_props.headword_decl)
					end
				end
				if #alternant_decls > 1 then
					has_multiple_decls = true
				elseif #decls > 1 then
					has_multiple_variants = true
				end
				for _, d in ipairs(alternant_decls) do
					m_table.insertIfNot(decls, d)
				end
			end
		end

		if is_indecl and is_decl then
			has_multiple_decls = true
		end
		if has_multiple_decls then
			table.insert(data.categories, "Latin " .. decldata.pos .. " with multiple declensions")
		end
		if has_multiple_variants then
			table.insert(data.categories, "Latin " .. decldata.pos .. " with multiple variants of a single declension")
		end
		if is_irreg then
			table.insert(data.inflections, {label = glossary_link("irregular")})
			table.insert(data.categories, "Latin irregular " .. decldata.pos)
			for _, g in ipairs(genders) do
				table.insert(data.categories, "Latin " .. gender_names ..  " irregular " .. decldata.pos)
			end
		end

		if is_indecl then
			if is_decl then
				table.insert(appendix, glossary_link("indeclinable"))
			else
				table.insert(data.inflections, {label = glossary_link("indeclinable")})
			end
			table.insert(data.categories, "Latin indeclinable " .. decldata.pos)
			for _, g in ipairs(genders) do
				table.insert(data.categories, "Latin " .. gender_names ..  " indeclinable " .. decldata.pos)
			end
		end

		if #decls > 1 then
			table.insert(data.inflections, {label = 'variously declined'})
			--This causes multipart nouns composed of two nouns of different declensions
			--to go into the category. The above code only triggers if a given term has
			--multiple declensions.
			--table.insert(data.categories, "Latin " .. decldata.pos .. " with multiple declensions")
		end

		for _, decl in ipairs(decls) do
			if decl ~= "irreg" and decl ~= "indecl" and decl ~= "0" then
				local decl_class = declension_to_english
				if not decl_class then
					error("Something wrong with declension '" .. decl .. "', don't recognize it")
				end
				table.insert(appendix, "]")
				table.insert(data.categories, "Latin " .. decl_class .. " declension " .. decldata.pos)

				for _, g in ipairs(genders) do
					table.insert(data.categories, "Latin " .. gender_names ..  " " .. decldata.pos .. " in the " .. decl_class .. " declension")
				end
			end
		end

		if NAMESPACE == 'Reconstruction' then
			-- For reconstructed nouns:
			if data.genders == 'n' and lemma_num == 'sg' then
				-- singular neuter nouns give a plural
				local pl = decldata.forms
				if pl and pl ~= "" and #pl > 0 then
					pl.label = "plural"
					table.insert(data.inflections, pl)
				end
			else
				-- all others give an oblique
				local obl = decldata.forms
				if obl and obl ~= "" and #obl > 0 then
					obl.label = "oblique"
					table.insert(data.inflections, obl)
				end
			end
		else
			local gen = decldata.forms
			if (decldata.unattested) then
				gen = '*' .. gen
				data.nolink = true
			end
			if gen and gen ~= "" and gen ~= "—" and #gen > 0 then
				if is_decl then
					-- Skip displaying the genitive for nouns that are only
					-- indeclinable. But we do display it for nouns like Abrahām
					-- and Ādām that can be either indeclinable or declined.
					gen.label = "genitive"
					table.insert(data.inflections, gen)
				end
			else
				table.insert(data.inflections, {label = "no genitive"})
				table.insert(data.categories, "Latin " .. decldata.pos .. " without a genitive singular")
			end
		end
	end

	if #decldata.m > 0 then
		decldata.m.label = "masculine"
		table.insert(data.inflections, decldata.m)
	end

	if #decldata.f > 0 then
		decldata.f.label = "feminine"
		table.insert(data.inflections, decldata.f)
	end

	for _, cat in ipairs(decldata.categories) do
		m_table.insertIfNot(data.categories, cat)
	end

	for _, cat in ipairs(decldata.cat) do
		m_table.insertIfNot(data.categories, "Latin " .. cat)
	end
	
	return is_pn and decldata.pos == "nouns" and "proper nouns" or decldata.pos
end

pos_functions = function(def, args, data, infl_classes, appendix)
	return nouns("nouns", def, args, data, infl_classes, appendix)
end

pos_functions = function(def, args, data, infl_classes, appendix)
	return nouns("proper nouns", def, args, data, infl_classes, appendix)
end

pos_functions = function(def, args, data, infl_classes, appendix)
	return nouns("suffixes", def, args, data, infl_classes, appendix)
end

pos_functions = function(def, args, data, infl_classes, appendix)
	return nouns("numerals", def, args, data, infl_classes, appendix)
end

export.allowed_subtypes = {
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	-- can be specified manually in the headword to display "highly defective"
	-- in the title (e.g. aveō)
	 = true,
}

pos_functions = function(def, args, data, infl_classes, appendix)
	local m_la_verb = require("Module:la-verb")
	local NAMESPACE = mw.title.getCurrentTitle().nsText
	local def1, def2
	if def then
		def1, def2 = rmatch(def, "^(.*):(.*)$")
	end
	local conjdata, typeinfo = m_la_verb.make_data(args, true, def1, def2)
	local lemma_forms = conjdata.overriding_lemma
	if not lemma_forms or #lemma_forms == 0 then
		lemma_forms = m_la_verb.get_lemma_forms(conjdata, true)
	end
	local first_lemma = ""
	if #lemma_forms > 0 then
		first_lemma = require("Module:links").remove_links(lemma_forms)
	end
	data.heads = lemma_forms
	-- Since we always set data.heads to the lemma and specification of the lemma is mandatory in {{la-verb}}, there aren't
	-- really any redundant heads.
	data.no_redundant_head_cat = true
	data.id = conjdata.id
	local conj = typeinfo.conj_type
	local subconj = typeinfo.conj_subtype
	local subtypes = typeinfo.subtypes
	local perf_only = false

	local function insert_inflection(infl, label)
		for _, form in ipairs(infl) do
			if rsub(form, "^|%-a-zA-ZĀāĒēĪīŌōŪūȲȳÄäËëÏïÖöÜüŸÿĂăĔĕĬĭŎŏŬŭ " .. accents .. "]+$", "") ~= "" then
				table.insert(data.categories, "la-verb invalid parameters")
			end
		end
		infl.label = label
		table.insert(data.inflections, infl)
	end

	local inf = m_la_verb.get_valid_forms(conjdata.forms)
	if #inf > 0 then
		insert_inflection(inf, "present infinitive")
	else
		inf = m_la_verb.get_valid_forms(conjdata.forms)
		if #inf > 0 then
			perf_only = true
			insert_inflection(inf, "perfect infinitive")
		end
	end

	local depon = typeinfo.subtypes.depon or typeinfo.subtypes.semidepon
	if not perf_only then
		local perf
		if depon then
			local sup = m_la_verb.get_valid_forms(conjdata.forms)
			perf = {}
			for _, form in ipairs(sup) do
				if typeinfo.subtypes.impers then
					form = rsub(form, "^(.*)m$", "] est")
				elseif typeinfo.subtypes then
					form = rsub(form, "^(.*)m$", "] est")
				else
					form = rsub(form, "^(.*)m$", "] sum")
				end
				table.insert(perf, form)
			end
		else
			perf = m_la_verb.get_valid_forms(conjdata.forms)
			if #perf == 0 then
				perf = m_la_verb.get_valid_forms(conjdata.forms)
			end
		end
		if #perf > 0 then
			insert_inflection(perf, "perfect active")
		end
	end

	if not depon then
		local sup = m_la_verb.get_valid_forms(conjdata.forms)
		if #sup > 0 then
			insert_inflection(sup, "supine")
		else
			local fap = m_la_verb.get_valid_forms(conjdata.forms)
			if #fap > 0 then
				insert_inflection(fap, "future participle")
			end
		end
	end

	if conj == "1st" or subconj == "1st" then
		table.insert(appendix, "]")
	elseif conj == "2nd" or subconj == "2nd" then
		table.insert(appendix, "]")
	elseif conj == "3rd" or subconj == "3rd" then
		table.insert(appendix, "]")
	elseif conj == "3rd-io" or subconj == "3rd-io" then
		table.insert(appendix, "] iō-variant")
	elseif conj == "4th" or subconj == "4th" then
		table.insert(appendix, "]")
	elseif conj == "irreg" then --sum
		table.insert(appendix, "]")
	else
		if NAMESPACE == "Template" then
			table.insert(appendix, "? declension")
		else
			table.insert(data.categories, "Latin verbs without the conjugation in their headwords")
		end
	end

	if conj == "irreg" and subconj == "irreg" or subtypes.irreg then
		--sum, volō, ferō etc.
		table.insert(appendix, "]")
	end
	if subtypes.highlydef then
		-- āiō, inquam
		table.insert(appendix, "highly ]")
	end
	if subtypes.perfaspres then
		-- ōdī, meminī, commeminī
		table.insert(appendix, "] forms have ] meaning")
	end
	if subtypes.impers then
		-- decet
		-- advesperāscit (also nopass)
		table.insert(appendix, "]")
	end
	if subtypes.nopass then
		--coacēscō
		table.insert(appendix, "no ]")
	end
	if subtypes.depon then
		-- dēmōlior
		-- calvor (also noperf)
		table.insert(appendix, "]")
	end
	if subtypes.semidepon then
		-- fīdō, gaudeō
		table.insert(appendix, "]")
	end
	if subtypes.optsemidepon then
		-- audeō, placeō, soleō, pudeō
		table.insert(appendix, "optionally ]")
	end
	if subtypes.nosup and subtypes.noperf then
		-- many verbs
		table.insert(appendix, "no ] or ] stem")
	elseif subtypes.noperf then
		-- īnsolēscō etc.
		table.insert(appendix, "no ] stem")
	elseif subtypes.nosup then
		-- deeō etc.
		table.insert(appendix, "no ] stem")
	elseif subtypes.supfutractvonly then
		-- sum, dēpereō, etc.
		table.insert(appendix, "no ] stem except in the ] ] ]")
	end
	if typeinfo.subtypes.nopasvperf and not typeinfo.subtypes.nosup and
			not typeinfo.subtypes.supfutractvonly then
		table.insert(appendix, "no ] ] forms")
	end
	if subtypes.pass3only then
		--praefundō
		table.insert(appendix, "limited ]")
	end
	if subtypes.passimpers then
		--abambulō
		table.insert(appendix, "] in the passive")
	end
	if rfind(first_lemma, "faciō$") then
		--faciō
		table.insert(appendix, "irregular ]")
	end
	if subtypes then
		--decet
		table.insert(appendix,"] only")
	end
	if subtypes.noimp then
		--volō
		table.insert(appendix, "no ]")
	end
	if (conj == "3rd" or conj == "irreg") and rfind(first_lemma, "dcō$") then
		--dīcō
		table.insert(appendix, "irregular short ]")
	end
	if subtypes.nofut then
		--soleō
		table.insert(appendix, "no ]")
	end
	data.gloss = '<span class="ib-content qualifier-content"><abbr title="The first-singular present active indicative '
		.. 'is used as the lemma, rather than the infinitive.">first-singular present indicative</span></abbr>'
end

pos_functions = pos_functions

local function adjectives(pos, def, args, data, infl_classes, appendix)
	local is_num = pos == "numerals"
	local decldata = require("Module:la-nominal").do_generate_adj_forms(
	  args, pos, true, def, is_num)
	local lemma = decldata.overriding_lemma
	local lemma_num = decldata.num == "pl" and "pl" or "sg"
	if not lemma or #lemma == 0 then
		lemma = decldata.forms
		if decldata.unattested then
			lemma = '*' .. lemma
		end
	end

	data.heads = lemma
	-- Since we always set data.heads to the lemma and specification of the lemma is mandatory in {{la-noun}}, there aren't
	-- really any redundant heads.
	data.no_redundant_head_cat = true
	data.id = decldata.id

	if is_num then
		process_num_type(decldata.num_type, data.categories)
	end

	if decldata.num == "pl" then
		table.insert(data.categories, "Latin plural-only " .. decldata.pos)
	end

	if decldata.indecl then
		table.insert(data.inflections, {label = glossary_link("indeclinable")})

		if decldata.pos == "participles" then
			if rfind(lemma, "um$") then
				table.insert(data.categories, "Latin perfect participles")
			end
		end
	else

		local function attested_form(index)
			local form
			if (decldata.unattested) then
				form = { { term = '*' .. decldata.forms, nolink = true } }
			else
				form = decldata.forms
			end
			return form
		end

		local masc = decldata.forms
		local fem = attested_form("nom_" .. lemma_num .. "_f")
		local neut = attested_form("nom_" .. lemma_num .. "_n")
		local gen = attested_form("gen_" .. lemma_num .. "_m")
	
		if decldata.pos == "participles" then
			if rfind(masc, "ūrus$") then
				table.insert(data.categories, "Latin future participles")
			elseif rfind(masc, "ndus$") then
				-- FIXME, should rename to "Latin gerundives")
				table.insert(data.categories, "Latin future passive participles")
			elseif rfind(masc, "us$") then
				table.insert(data.categories, "Latin perfect participles")
			elseif rfind(masc, "ns$") then
				table.insert(data.categories, "Latin present participles")
			else
				error("Unrecognized participle ending: " .. masc)
			end
		end
	
		local function is_missing(form)
			return not form or form == "" or form == "—" or #form == 0
		end
		-- We display the inflections in three different ways to mimic the
		-- old way of doing things:
		--
		-- 1. If masc and fem are different, show masc, fem and neut.
		-- 2. Otherwise, if masc and neut are different, show masc and neut.
		-- 3. Otherwise, show masc nominative and masc genitive.
		if not is_missing(fem) and not m_table.deepEquals(masc, fem) then
			fem.label = "feminine"
			table.insert(data.inflections, fem)
			if not is_missing(neut) then
				neut.label = "neuter"
				table.insert(data.inflections, neut)
			end
		elseif not is_missing(neut) and not m_table.deepEquals(masc, neut) then
			neut.label = "neuter"
			table.insert(data.inflections, neut)
		elseif not is_missing(gen) then
			gen.label = "genitive"
			table.insert(data.inflections, gen)
		end

		table.insert(infl_classes, decldata.title)
	end

	if #decldata.comp > 0 then
		decldata.comp.label = "comparative"
		table.insert(data.inflections, decldata.comp)
	end
	if #decldata.sup > 0 then
		decldata.sup.label = "superlative"
		table.insert(data.inflections, decldata.sup)
	end
	if #decldata.adv > 0 then
		decldata.adv.label = "adverb"
		table.insert(data.inflections, decldata.adv)
	end

	for _, cat in ipairs(decldata.categories) do
		m_table.insertIfNot(data.categories, cat)
	end

	for _, cat in ipairs(decldata.cat) do
		m_table.insertIfNot(data.categories, "Latin " .. cat)
	end
	
	return decldata.pos
end

local function adjectives_comp(pos, def, args, data, infl_classes, appendix)
	local params = {
		 = {alias_of = 'head'},
		 = {alias_of = 'pos'},
		 = {list = true},
		 = {list = true},
		 = {type = "boolean"},
		 = {},
	}
	local args = require("Module:parameters").process(args, params)
	data.no_redundant_head_cat = #args.head == 0
	-- Set default manually so we can tell whether the user specified head=.
	if #args.head == 0 then
		args.head = {mw.title.getCurrentTitle().text}
	end
	data.heads = args.head
	data.id = args.id

	if args.is_lemma then
		-- See below. This happens automatically by virtue of the default POS
		-- unless we override it, which we do when is_lemma.
		table.insert(data.categories, "Latin comparative " .. pos)
	end
	table.insert(infl_classes, "]")

	local n = {label = "neuter"}
	for _, head in ipairs(args.head) do
		local neuter = mw.ustring.gsub(head, "or$", "us")
		table.insert(n, neuter)
	end

	table.insert(data.inflections, n)

	if #args.pos > 0 then
		args.pos.label = "positive"
		table.insert(data.inflections, args.pos)
	end
	if args.is_lemma then
		-- If is_lemma, we're a comparative adjective without positive form,
		-- so we're treated as a lemma. In that case, we return "adjectives" as
		-- the part of speech, which will automatically categorize into
		-- "Latin adjectives" and "Latin lemmas", otherwise we don't return
		-- anything, which defaults to the passed-in POS (usually
		-- "comparative adjectives"), which will automatically categorize into
		-- that POS (e.g. "Latin comparative adjectives") and into
		-- "Latin non-lemma forms".
		return pos
	end
end

local function adjectives_sup(pos, def, args, data, infl_classes, appendix)
	local params = {
		 = {alias_of = 'head'},
		 = {alias_of = 'pos'},
		 = {list = true},
		 = {list = true},
		 = {type = "boolean"},
		 = {},
	}
	local args = require("Module:parameters").process(args, params)
	data.no_redundant_head_cat = #args.head == 0
	-- Set default manually so we can tell whether the user specified head=.
	if #args.head == 0 then
		args.head = {mw.title.getCurrentTitle().text}
	end
	data.heads = args.head
	data.id = args.id

	if args.is_lemma then
		-- See below. This happens automatically by virtue of the default POS
		-- unless we overrride it, which we do when is_lemma.
		table.insert(data.categories, "Latin superlative " .. pos)
	end
	table.insert(infl_classes, "]")
	table.insert(infl_classes, "]")

	local f, n = {label = "feminine"}, {label = "neuter"}
	for _, head in ipairs(args.head) do
		local stem = mw.ustring.gsub(head, "us$", "")
		table.insert(f, stem .. "a")
		table.insert(n, stem .. "um")
	end

	table.insert(data.inflections, f)
	table.insert(data.inflections, n)

	if #args.pos > 0 then
		args.pos.label = "positive"
		table.insert(data.inflections, args.pos)
	end
	if args.is_lemma then
		-- If is_lemma, we're a superlative adjective without positive form,
		-- so we're treated as a lemma. In that case, we return "adjectives" as
		-- the part of speech, which will automatically categorize into
		-- "Latin adjectives" and "Latin lemmas", otherwise we don't return
		-- anything, which defaults to the passed-in POS (usually
		-- "superlative adjectives"), which will automatically categorize into
		-- that POS (e.g. "Latin superlative adjectives") and into
		-- "Latin non-lemma forms".
		return pos
	end
end

pos_functions = function(def, args, data, infl_classes, appendix)
	return adjectives("adjectives", def, args, data, infl_classes, appendix)
end

pos_functions = function(def, args, data, infl_classes, appendix)
	return adjectives_comp("adjectives", def, args, data, infl_classes, appendix)
end

pos_functions = function(def, args, data, infl_classes, appendix)
	return adjectives_sup("adjectives", def, args, data, infl_classes, appendix)
end

pos_functions = function(def, args, data, infl_classes, appendix)
	return adjectives("participles", def, args, data, infl_classes, appendix)
end

pos_functions = function(def, args, data, infl_classes, appendix)
	return adjectives("determiners", def, args, data, infl_classes, appendix)
end

pos_functions = function(def, args, data, infl_classes, appendix)
	return adjectives("pronouns", def, args, data, infl_classes, appendix)
end

pos_functions = function(def, args, data, infl_classes, appendix)
	return adjectives("suffixes", def, args, data, infl_classes, appendix)
end

pos_functions = function(def, args, data, infl_classes, appendix)
	return adjectives("numerals", def, args, data, infl_classes, appendix)
end

pos_functions = function(def, args, data, infl_classes, appendix)
	local params = {
		 = {alias_of = 'head'},
		 = {alias_of = 'comp'},
		 = {alias_of = 'sup'},
		 = {list = true, required = true},
		 = {list = true},
		 = {list = true},
		 = {},
	}

	local args = require("Module:parameters").process(args, params)
	data.heads = args.head
	data.no_redundant_head_cat = true -- since head= is required.
	data.id = args.id
	local comp, sup
	local irreg = false

	if args.comp == "-" then
		comp = "-"
	elseif #args.comp > 0 then
		args.comp.label = glossary_link("comparative")
		comp = args.comp
		irreg = true
	end
	if args.comp == "-" or args.sup == "-" then
		sup = "-"
	elseif #args.sup > 0 then
		args.sup.label = glossary_link("superlative")
		sup = args.sup
		irreg = true
	end
	if irreg then
		table.insert(data.categories, "Latin irregular adverbs")
	end

	if not comp or not sup then
		local default_comp = {label = glossary_link("comparative")}
		local default_sup = {label = glossary_link("superlative")}
		for _, head in ipairs(args.head) do
			local stem = nil
			for _, suff in ipairs({"iter", "nter", "ter", "er", "iē", "ē", "im", "ō"}) do
				stem = mw.ustring.match(head, "(.*)" .. suff .. "$")
				if stem ~= nil then
					if suff == "nter" then
						stem = stem .. "nt"
						suff = "er"
					end
					table.insert(default_comp, stem .. "ius")
					table.insert(default_sup, stem .. "issimē")
					break
				end
			end
			if not stem then
				error("Unrecognized adverb type, recognized types are “-ē”, “-er”, “-ter”, “-iter”, “-im”, or “-ō” or specify irregular forms or “-” if incomparable.")
			end
		end
		comp = comp or default_comp
		sup = sup or default_sup
	end

	if comp == "-" then
		table.insert(data.inflections, {label = "not ]"})
		table.insert(data.categories, "Latin uncomparable adverbs")
	else
		table.insert(data.inflections, comp)
	end
	if sup == "-" then
		if comp ~= "-" then
			table.insert(data.inflections, {label = "no ]"})
		end
	else
		table.insert(data.inflections, sup)
	end
end

pos_functions = pos_functions

local prepositional_cases = {
	genitive = true, accusative = true, ablative = true,
}

pos_functions = function(def, args, data, infl_classes, appendix, postscript)
	local params = {
		 = {list = true, required = true}, -- headword or cases
		 = {list = true},
		 = {},
	}

	local args = require("Module:parameters").process(args, params)

	-- Case names are supplied in numbered arguments, optionally preceded by
	-- headwords.
	local cases = {}
	while prepositional_cases]] do
		table.insert(cases, 1, table.remove(args))
	end

	for i = 1, #cases do
		for j = i + 1, #cases do
			if cases == cases then
				error("Duplicate case")
			end
		end
		local case = cases
		local appendix_link = glossary_link(case)
		if i == 1 then
			appendix_link = "+ " .. appendix_link
		end
		table.insert(postscript, appendix_link)
		table.insert(data.categories, "Latin " .. case .. " prepositions")
	end

	for _, v in ipairs(args) do
		table.insert(args.head, 1, v)
	end

	data.heads = args.head
	data.no_redundant_head_cat = true -- since 1= is required and goes into data.heads
	data.id = args.id
end

pos_functions = function(def, args, data, infl_classes, appendix, postscript)
	local params = {
		 = {required = true, default = "labōrandum"}, -- headword
		 = {}, -- gerundive
	}

	local args = require("Module:parameters").process(args, params)

	data.heads = {args}
	data.no_redundant_head_cat = true -- since 1= is required and goes into data.heads
	table.insert(data.inflections, {label = "]"})
	local stem = rmatch(args, "^(.*)um$")
	if not stem then
		error("Unrecognized gerund ending: " .. stem)
	end
	if args == "-" then
		table.insert(data.inflections, {label = "no ]"})
	else
		table.insert(data.inflections, { = args or stem .. "us", label = "]"})
	end
end

local function non_lemma_forms(def, args, data, infl_classes, appendix, postscript)
	local params = {
		 = {required = true, default = def}, -- headword or cases
		 = {list = true, require_index = true},
		 = {list = true},
		 = {},
	}

	local args = require("Module:parameters").process(args, params)

	local heads = {args}
	for _, head in ipairs(args.head) do
		table.insert(heads, head)
	end
	data.heads = heads
	data.no_redundant_head_cat = true -- since 1= is required and goes into data.heads
	data.genders = args.g
	data.id = args.id
end

pos_functions = non_lemma_forms
pos_functions = non_lemma_forms
pos_functions = non_lemma_forms
pos_functions = non_lemma_forms
pos_functions = non_lemma_forms
pos_functions = non_lemma_forms
pos_functions = non_lemma_forms
pos_functions = non_lemma_forms
pos_functions = non_lemma_forms
pos_functions = non_lemma_forms

return export