Module:gender and number

From Laenkea
Jump to navigation Jump to search

Gender and number is the (rather confusingly-named, honestly) module on Laenktionary that generates little snippets like m or f for nouns, or like pf for verbs.

Mostly, you'll see this on higher level templates where you might be able to specify multiple "genders" as a list of parameters. This might look like:

{{lfv-noun|m|or|f}}

to generate a Laefevian noun with the gender m or f.

There are specific genders/aspects/numbers defined, which can be seen in the script below. As in the example above, you can also specify "or" as a special one to create an option between two other "genders".


local export = {}

local available_genders = mw.loadData("Module:gender and number/data")
local combinations = {
	["mf"] = {"m", "or", "f"},
	["van"] = {"in", "or", "an"},
	["biasp"] = {"impf", "pf"}
}
local multiple_group_categories = {
	["gender"] = "% with multiple genders",
	["animacy"] = "% with multiple animacies",
	["aspect"] = "biaspectual %"
}

function export.show_list(frame)
	local args = frame.args
	local lang = require("Module:languages").get_by_code(args["lang"])
	local pos = args["pos"]
	local genders = {}
	local i = 1
	
	while args[i] and args[i] ~= "" do
		table.insert(genders, args[i])
		i = i + 1
	end

	local text, cats = export.format_genders(lang, pos, genders)
	return text .. (cats or "")
end

function export.format_genders(language, pos, genders)
	local parts = {}
	local groups = {}
	local cats = {}
	
	local function pluralize(word)
		local ending = mw.ustring.sub(word, -1)
		if ending == "h" and mw.ustring.sub(word, -2, -1) == "s" then ending = "sh" end
		if ending == "s" or ending == "z" or ending == "x" or ending == "sh" then
			return word .. "es"
		end
		return word .. "s"
	end

	for _, g_code in ipairs(genders) do
		local split_codes = combinations[g_code] or mw.text.split(g_code, "-")
		for _, split_code in ipairs(split_codes) do
			if split_code == "or" then
				table.insert(parts, "or")
			else
				local gender = available_genders[split_code]
				if gender ~= nil then
					table.insert(parts, '<abbr title="' .. gender.hint .. '">' .. gender.label .. "</abbr>")
					if pos ~= nil then
						if groups[gender.group] == nil then
							table.insert(cats, "[[Category:" .. language.name .. " " .. string.gsub(gender.category, "%%", pluralize(pos)) .. "]]")
							groups[gender.group] = 1
						else
							groups[gender.group] = groups[gender.group] + 1
						end
					end
				end
			end
		end
	end
	if pos ~= nil then
		for k, v in pairs(groups) do
			if type(v) == "number" and v > 1 and multiple_group_categories[k] ~= nil then
				table.insert(cats, "[[Category:" .. language.name .. " " .. string.gsub(multiple_group_categories[k], "%%", pluralize(pos)) .. "]]")
			end
		end
	end
	return '<span class="gender">' .. table.concat(parts, " ") .. "</span>", pos and table.concat(cats)
end

return export