Module:category tree/poscatboiler/data/lang-specific/ru

From Wiktionary, the free dictionary
Jump to navigation Jump to search

This module handles generating the descriptions and categorization for Russian category pages of the format "Russian LABEL" where LABEL can be any text. Examples are Category:Bulgarian conjugation 2.1 verbs and Category:Russian velar-stem neuter-form nouns. This module is part of the poscatboiler system, which is a general framework for generating the descriptions and categorization of category pages.

For more information, see Module:category tree/poscatboiler/data/lang-specific/documentation.

NOTE: If you add a new language-specific module, you must add the language code to the list at the top of Module:category tree/poscatboiler/data/lang-specific in order for the module to be recognized.


local labels = {}
local handlers = {}

local lang = require("Module:languages").getByCode("ru")
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


--------------------------------- Verbs --------------------------------

labels["verbs by class"] = {
	description = "Russian verbs categorized by class.",
	parents = {{name = "verbs by inflection type", sort = "class"}},
}

labels["verbs by class and accent pattern"] = {
	description = "Russian verbs categorized by class and accent pattern.",
	parents = {{name = "verbs by inflection type", sort = "class and accent pattern"}},
}

table.insert(handlers, function(data)
	local cls, variant, pattern = rmatch(data.label, "^class ([0-9]*)(°?)([abc]?) verbs$")
	if cls then
		if pattern == "" then
			return {
				description = "Russian class " .. cls .. " verbs.",
				breadcrumb = cls,
				parents = {{name = "verbs by class", sort = cls .. variant}},
			}
		else
			return {
				description = "Russian class " .. cls .. " verbs of " ..
					"accent pattern " .. pattern .. (
					variant == "" and "" or " and variant " .. variant) .. ". " .. (
					pattern == "a" and "With this pattern, all forms are stem-stressed."
					or pattern == "b" and "With this pattern, all forms are ending-stressed."
					or "With this pattern, the first singular present indicative and all forms " ..
					"outside of the present indicative are ending-stressed, while the remaining " ..
					"forms of the present indicative are stem-stressed.") .. (
					variant == "" and "" or
					cls == "3" and " The variant code indicates that the -н of the stem " ..
					"is missing in most non-present-tense forms." or
					" The variant code indicates that the present tense is not " ..
					"[[Appendix:Glossary#iotation|iotated]]. (In most verbs of this class, " ..
					"the present tense is iotated, e.g. иска́ть with present tense " ..
					"ищу́, и́щешь, и́щет, etc.)"),
				breadcrumb = cls .. variant .. pattern,
				parents = {
					{name = "class " .. cls .. " verbs", sort = pattern},
					{name = "verbs by class and accent pattern", sort = cls .. pattern},
				},
			}
		end
	end
end)


--------------------------------- Adjectives --------------------------------

for _, plpos in ipairs { "adjectives", "surnames" } do
	labels[plpos .. " by stem type and stress"] = {
		description = "Russian " .. plpos .. " categorized by stem type and stress. " ..
			"Unlike for nouns, " .. plpos .. " are consistently either stem-stressed or ending-stressed.",
		breadcrumb = "by stem type and stress",
		parents = {{name = plpos .. " by inflection type", sort = "stem type and stress"}},
	}

	labels["ending-stressed " .. plpos] = {
		description = "Russian " .. plpos .. " where the ending is stressed. They end in " ..
			"{{lang|ru|-о́й}}, or in some cases {{lang|ru|-и́н}}, {{lang|ru|-о́в}}, or " ..
			"{{lang|ru|-ёв}}.",
		breadcrumb = "ending-stressed",
		parents = {{name = plpos .. " by inflection type", sort = "ending-stressed"}},
	}

	labels[plpos .. " by irregularity"] = {
		description = "Russian " .. plpos .. " categorized according to their irregularities.",
		breadcrumb = "by irregularity",
		parents = {{name = "irregular " .. plpos, sort = "irregularity"}},
	}
end

-- Should be no surnames like any of the following.
labels["adjectives with short forms"] = {
	description = "Russian " .. "adjectives that have short forms. Short forms are used " ..
		"[[Appendix:Glossary#predicative|predicatively]] and generally only for adjectives " ..
		"that are qualitative, i.e. can be modified with adverbs such as [[very]], [[completely]], " ..
		"[[somewhat]], [[more]], etc.",
	parents = {{name = "adjectives", sort = "short forms"}},
}

labels["adjectives with missing short forms"] = {
	description = "Russian adjectives that have short forms but where some of the short forms " ..
		"are missing. Short forms are used predicatively and generally only for adjectives that " ..
		"are qualitative, i.e. can be modified with adverbs such as [[very]], [[completely]], " ..
		"[[somewhat]], [[more]], etc.",
	parents = {{name = "adjectives", sort = "missing short forms"}},
}

labels["adjectives with irregular short stem"] = {
	description = "Russian adjectives where the stem of the short forms is irregular compared " ..
		"with the stem of the remaining forms. Examples are {{m|ru|солёный||[[salty]]}}" ..
		" (short forms {{lang|ru|со́лон, солона́, со́лоно, солоны́/со́лоны}}); " ..
		"{{m|ru|ма́ленький||[[small]]}} (short forms {{lang|ru|мал, мала́, мало́, малы́}}" ..
		"); and {{m|ru|большо́й||[[big]]}} (short forms " ..
		"{{lang|ru|вели́к, велика́, велико́, велики́}}. (In the latter two cases, the short forms " ..
		"come from the synonymous adjectives {{m|ru|ма́лый}} and {{m|ru|вели́кий}}" ..
		", respectively.)",
	parents = {{name = "irregular adjectives", sort = "short stem"}},
}

labels["adjectives with reducible short stem"] = {
	description = "Russian adjectives where the stem of the short forms is [[Appendix:Glossary#reducible|reducible]]; " ..
		"specifically, the short masculine singular has an extra vowel inserted before the final " ..
		"consonant, compared with all other forms. Examples are most adjectives in {{m|ru|-кий}}" ..
		" and {{m|ru|-ный}}, e.g. {{m|ru|лёгкий||[[light]], [[easy]]}}" ..
		" with short masculine singular {{m|ru|лёгок}} and " ..
		"{{m|ru|де́льный||[[efficient]], [[sensible]]}} with short masculine singular " ..
		"{{m|ru|де́лен}}.",
	parents = {{name = "adjectives", sort = "reducible short stem"}},
}

labels["adjectives by short accent pattern"] = {
	description = "Russian adjectives categorized according to their short accent pattern.",
	parents = {{name = "adjectives by inflection type", sort = "short accent pattern"}},
}

labels["adjectives with Zaliznyak short form special case 1"] = {
	description = "Russian adjectives where the lemma form ends in {{lang|ru|-нный}} or " ..
		"{{lang|ru|-нний}} (with two {{lang|ru|н}}'s) but the short masculine singular ends " ..
		"in simply {{lang|ru|-н}} (i.e. with only one {{lang|ru|н}}). Examples are " ..
		"{{m|ru|самоуве́ренный||[[self-confident]]}}, with short masculine singular " ..
		"{{m|ru|самоуве́рен}} (short feminine singular {{m|ru|самоуве́ренна}}, etc.); and " ..
		"{{m|ru|вы́спренний||[[grandiloquent]]}}, with short masculine singular " ..
		"{{m|ru|вы́спрен}} (short feminine singular {{m|ru|вы́спрення}}, etc.). Contrast " ..
		"[[:Category:Russian adjectives with Zaliznyak short form special case 2|special case 2]], where " ..
		"only one {{lang|ru|-н}} is present in '''all''' short forms.",
	parents = {{name = "adjectives", sort = "Zaliznyak short form special case 1"}},
}

-- Should be no surnames like the following.
labels["adjectives with Zaliznyak short form special case 2"] = {
	description = "Russian adjectives where the lemma form ends in {{lang|ru|-нный}} (with two " ..
		"{{lang|ru|н}}'s) but all short forms end in only one {{lang|ru|-н}}. An example is " ..
		"{{m|ru|подве́рженный||[[subject]] to, [[liable]] to, [[prone]] to}}, with short forms " ..
		"{{lang|ru|подве́ржен, подве́ржена, подве́ржено, подве́ржены}}. All past passive participles in " ..
		"{{lang|ru|-нный}} decline this way in their short forms, and most or all adjectives that " ..
		"decline this way are past passive participles in origin. Contrast " ..
		"[[:Category:Russian adjectives with Zaliznyak short form special case 1|special case 1]], where " ..
		"only the short masculine singular is irregular in having only a single {{lang|ru|-н}}. " ..
		"Note that many terms decline both ways, declining as special case 2 as a participle and as " ..
		"special case 1 as an adjective. An example is {{m|ru|отвлечённый}}, with short forms " ..
		"{{lang|ru|отвлечён, отвлечена́, отвлечено́, отвлечены́}} when functioning as the past passive " ..
		"participle of {{m|ru|отвле́чь||to [[distract]], to [[divert]]}} but with short forms " ..
		"{{lang|ru|отвлечён, отвлечённа, отвлечённо, отвлечённы}} when functioning as an adjective meaning " ..
		'"abstract". For yet other terms, there are three possibilities: special case 2 as a participle, and ' ..
		"either special case 1 or 2 as an adjective, depending on meaning. Often the meaning difference is " ..
		"between experiencing a given feeling and expressing that feeling; for example, " ..
		"{{m|ru|влюблённый}} has short forms {{lang|ru|влюблён, влюблена́, влюблено́, влюблены́}}" ..
		" when functioning as the past passive participle of {{m|ru|влюби́ть||to [[cause]] to [[fall in love]]}}" ..
		' and also when functioning as an adjective meaning "amorous (i.e. experiencing feelings of love, of a person)"' ..
		", but has short forms {{lang|ru|влюблён, влюблённа, влюблённо, влюблённы}} when functioning as " ..
		'an adjective meaning "amorous (i.e. expressing feelings of love, of a look, tone, etc.)".',
	parents = {{name = "adjectives", sort = "Zaliznyak short form special case 2"}},
}

-- Should be no surnames like the following.
labels["short-form-only adjectives"] = {
	description = "Russian adjectives that exist '''only''' as short forms. This means they function " ..
		"only as [[Appendix:Glossary#predicative|predicative]] adjectives. Examples are " ..
		"{{m|ru|рад||[[glad]]}}, {{m|ru|до́лжен||[[obligated]], [[must]], [[have to]], [[ought]]}}" ..
		", and {{m|ru|гора́зд||[[skillful]], [[capable]]}}.",
	parents = {{name = "adjectives", sort = "short-form-only"}},
}

-- Surnames and adjectives handled differently.
labels["proper-name adjectives"] = {
	description = "Russian proper names (normally, surnames) that decline as adjectives. These are similar " ..
		"to possessive adjectives and have the same endings, i.e. {{m|ru|-ин}}/{{m|ru|-ын}} or " ..
		"{{m|ru|-ов}}/{{m|ru|-ев}}/{{m|ru|-ёв}}, but lack the neuter gender and " ..
		"decline slightly differently from possessive adjectives. For example, the surname {{m|ru|По́пов}}" ..
		" has prepositional singular {{m|ru|По́пове}}, while the possessive adjective " ..
		"{{m|ru|сы́нов||[[son]]'s}} has prepositional singular {{m|ru|сы́новом}}.",
	parents = {{name = "adjectives", sort = "proper-name"}},
}

labels["possessive surnames"] = {
	description = "Russian surnames with a declension similar to possessive adjectives. These have the same endings " ..
		"as possessive adjectives, i.e. {{m|ru|-ин}}/{{m|ru|-ын}} or {{m|ru|-ов}}/{{m|ru|-ев}}/{{m|ru|-ёв}}, but lack " ..
		"the neuter gender and decline slightly differently. For example, the surname {{m|ru|По́пов}}" ..
		" has prepositional singular {{m|ru|По́пове}}, while the possessive adjective " ..
		"{{m|ru|сы́нов||[[son]]'s}} has prepositional singular {{m|ru|сы́новом}}.",
	parents = {{name = "surnames", sort = "possessive"}},
}

labels["surnames by inflection type"] = {
	description = "Russian surnames organized by the type of inflection they follow.",
	breadcrumb = "by inflection type",
	parents = {{name = "surnames", sort = "inflection type"}},
}

labels["irregular surnames"] = {
	description = "Russian surnames that follow non-standard patterns of inflection.",
	breadcrumb = "irregular",
	parents = {{name = "surnames by inflection type", sort = "irregular"}},
}

local stem_expl = {
	["velar-stem"] = "a velar (-к, -г or –x)",
	["sibilant-stem"] = "a sibilant (-ш, -ж, -ч or -щ)",
	["ц-stem"] = "-ц",
	["i-stem"] = "-и (old-style -і)",
	["vowel-stem"] = "a vowel other than -и or -і, or -й or -ь",
	["soft-stem"] = "a soft consonant",
	["hard-stem"] = "a hard consonant",
}

local zaliznyak_stem_type = {
	["velar-stem"] = "3",
	["sibilant-stem"] = "4",
	["ц-stem"] = "5",
	["i-stem"] = "7",
	["vowel-stem"] = "6",
	["soft-stem"] = "2",
	["hard-stem"] = "1",
	["3rd-declension"] = "8",
}

local adjective_stem_gender_endings = {
    masculine = {
		["hard-stem"]         = {"-ый", "-о́й"},
		["ц-stem"]            = {"-ый", "-о́й"},
		["velar-stem"]        = {"-ий", "-о́й"},
		["sibilant-stem"]     = {"-ий", "-о́й"},
		["long possessive"]   = {"-ий", "-и́й"},
		["short possessive"]  = {"a consonant (-ъ old-style)", "a consonant (-ъ old-style)"},
		["mixed possessive"]  = {"a consonant (-ъ old-style)", "a consonant (-ъ old-style)"},
		["proper possessive"] = {"a consonant (-ъ old-style)", "a consonant (-ъ old-style)"},
		["soft-stem"] = "-ий",
		["vowel-stem"] = "-ий",
	},
    feminine = {
		["hard-stem"]         = {"-ая", "-а́я"},
		["ц-stem"]            = {"-ая", "-а́я"},
		["velar-stem"]        = {"-ая", "-а́я"},
		["sibilant-stem"]     = {"-ая", "-а́я"},
		["long possessive"]   = {"-ья", "-ья́"},
		["short possessive"]  = {"-а", "-а́"},
		["mixed possessive"]  = {"-а", "-а́"},
		["proper possessive"] = {"-а", "-а́"},
		["soft-stem"] = "-яя",
		["vowel-stem"] = "-яя",
	},
    neuter = {
		["hard-stem"]         = {"-ое", "-о́е"},
		["ц-stem"]            = {"-ее", "-о́е"},
		["velar-stem"]        = {"-ое", "-о́е"},
		["sibilant-stem"]     = {"-ее", "-о́е"},
		["long possessive"]   = {"-ье", "-ье́"},
		["short possessive"]  = {"-о", "-о́"},
		["mixed possessive"]  = {"-о", "-о́"},
		["proper possessive"] = {"-о", "-о́"},
		["soft-stem"] = "-ее",
		["vowel-stem"] = "-ее",
	},
	plural = {
		["hard-stem"]         = {"-ые", "-ы́е"},
		["ц-stem"]            = {"-ые", "-ы́е"},
		["velar-stem"]        = {"-ие", "-и́е"},
		["sibilant-stem"]     = {"-ие", "-и́е"},
		["long possessive"]   = {"-ьи", "-ьи́"},
		["short possessive"]  = {"-ы", "-ы́"},
		["mixed possessive"]  = {"-ы", "-ы́"},
		["proper possessive"] = {"-ы", "-ы́"},
		["soft-stem"] = "-ие",
		["vowel-stem"] = "-ие",
	},
}

local adjective_numeral_stem_gender_endings = {
	plural = {
		["hard-stem"]         = {nil, "-еро"},
	}
}

local short_adjective_desc = {
	["a"] = "stem stress on all short forms",
	["aʹ"] = "stem or ending stress on the feminine singular, stem stress on the other forms",
	["b"] = "ending stress on all short forms (except the masculine singular)",
	["bʹ"] = "stem or ending stress on the plural, ending stress on the other forms (except the masculine singular)",
	["c"] = "ending stress on the feminine singular, stem stress on the other forms",
	["cʹ"] = "stem or ending stress on the plural, ending stress on the feminine singular and stem stress on the neuter singular",
	["cʺ"] = "stem or ending stress on the neuter singular and plural, ending stress on the feminine singular",
}

table.insert(handlers, function(data)
	local function pos_is_adjectival(pos)
		return pos == "adjective" or pos == "surname"
	end
	
	local function fetch_endings(gender, stem, stress)
		if not adjective_stem_gender_endings[gender] then
			return nil
		end
		if stress == "possessive" then
			stem = stem .. " possessive"
			stress = "stem"
		end
		local endings = adjective_stem_gender_endings[gender][stem]
		if endings then
			if type(endings) == "string" then
				return endings
			elseif stress == "stem" then
				return endings[1]
			elseif stress == "ending" then
				return endings[2]
			end
		end
		return nil
	end

	local breadcrumb, stem, stress, pos = rmatch(data.label, "^(([^ ]*) ([^ *]*)-stressed) (.*)s")
	if not stem then
		breadcrumb, stem, stress, pos = rmatch(data.label, "^(([^ ]*) (possessive)) (.*)s")
	end
	if not stem then
		breadcrumb, stem, pos = rmatch(data.label, "^(([^ ]*)) ([^ ]*)s")
		stress = ""
	end
	if stem and (stress == "possessive" or stem_expl[stem]) and pos_is_adjectival(pos) then
		local stresstext = stress == "stem" and
			"This " .. pos .. " has stress on the stem, corresponding to Zaliznyak's type a." or
			stress == "ending" and
			"This " .. pos .. " has stress on the endings, corresponding to Zaliznyak's type b." or
			"All " .. pos .. "s of this type have stress on the stem."
		local m = fetch_endings("masculine", stem, stress)
		local f = fetch_endings("feminine", stem, stress)
		local n = fetch_endings("neuter", stem, stress)
		local p = fetch_endings("plural", stem, stress)
		if not m or not f or not n or not p then
			return nil
		end
		local endingtext = "ending in the nominative in masculine singular " .. m ..
			", feminine singular " .. f .. ", neuter singular " .. n .. " and plural " .. p .. "."
		local stemtext, posstext
		if stress == "possessive" then
			posstext = " possessive"
			if stem == "long" then
				stemtext = " The stem ends in a yod, which disappears in the nominative singular but appears in all other forms as a soft sign ь followed by a vowel."
			else
				stemtext = ""
			end
		else
			posstext = ""
			stemtext = " The stem ends in " .. stem_expl[stem] .. " and is Zaliznyak's type " .. zaliznyak_stem_type[stem] .. "."
		end
		return {
			description = "Russian " .. stem .. posstext .. " " .. pos .. "s, " .. endingtext .. stemtext .. " " .. stresstext,
			breadcrumb = breadcrumb,
			parents = {pos .. "s by stem type and stress"},
		}
	end
	
	local pos, shortaccent = rmatch(data.label, "^([^ ]*)s with short accent pattern ([^ ]*)$")
	if shortaccent and short_adjective_desc[shortaccent] and pos_is_adjectival(pos) then
		local escaped_accent = rsub(shortaccent, "'", "'")
		return {
			description = "Russian " .. pos .. "s with short accent pattern " .. escaped_accent .. ", with " ..
				short_adjective_desc[shortaccent] .. ".",
			breadcrumb = { name = escaped_accent, nocap = true },
			parents = {{ name = pos .. "s by short accent pattern", sort = shortaccent }},
		}
	end

	local pos, irregularity = rmatch(data.label, "^([^ ]*)s with irregular (.*)$")
	if irregularity and pos_is_adjectival(pos) then
		return {
			description = "Russian " .. pos .. "s with irregular " .. irregularity .. " (possibly along with other cases).",
			breadcrumb = irregularity,
			parents = {{ name = pos .. "s by irregularity", sort = irregularity }},
		}
	end
end)


--------------------------------- Nouns/Pronouns/Numerals --------------------------------

for _, pos in ipairs({"nouns", "pronouns", "numerals"}) do
	local sgpos = pos:gsub("s$", "")
	labels[pos .. " by stem type and gender"] = {
		description = "Russian " .. pos .. " categorized by stem type and typical gender. " ..
			"Note that \"typical gender\" means the gender that is typical for the " .. sgpos .. "'s ending (e.g. most " .. pos .. " in ''-а'' are " ..
			"feminine, and hence all such " .. pos .. " are considered to be \"typically feminine\"; but some are in fact masculine).",
		parents = {{name = pos .. " by inflection type", sort = "stem type and gender"}},
	}

	labels[pos .. " by stem type, gender and accent pattern"] = {
		description = "Russian " .. pos .. " categorized by stem type, typical gender and " ..
			"accent pattern. Note that \"typical gender\" means the gender that is typical for the " .. sgpos .. "'s ending (e.g. most " ..
			pos .. " in ''-а'' are feminine, and hence all such " .. pos .. " are considered to be \"typically feminine\"; but some are in " ..
			"fact masculine). See [[Appendix:Russian stress patterns - nouns]] for further information on accent patterns.",
		parents = {{name = pos .. " by inflection type", sort = "stem type, gender and accent pattern"}},
	}

	labels[pos .. " by case form"] = {
		description = "Russian " .. pos .. " categorized according to the presence of " ..
			"an irregular case or an unusual case (locative, partitive or vocative).",
		parents = {{name = pos, sort = "case form"}},
	}

	labels[pos .. " by accent pattern"] = {
		description = "Russian " .. pos .. " categorized according to their accent pattern (see [[Appendix:Russian stress patterns - nouns]]).",
		parents = {{name = pos .. " by inflection type", sort = "accent pattern"}},
	}

	labels[pos .. " by singular ending"] = {
		description = "Russian " .. pos .. " categorized by the ending in the nominative " ..
			"singular. This is currently used only for certain exceptional types of endings.",
		parents = {{name = pos, sort = "singular ending"}},
	}

	labels[pos .. " by singular and plural ending"] = {
		description = "Russian " .. pos .. " categorized by nominative singular and " ..
			"plural ending. This is used only for " .. pos .. " where one one of the endings is either irregular or a declensional " ..
			"suffix such as ''-ёнок'' or ''-ин''.",
		parents = {{name = pos, sort = "singular and plural ending"}},
	}

	labels[pos .. " by plural ending"] = {
		description = "Russian " .. pos .. " categorized by the ending in the nominative " ..
			"plural. This is currently used only for certain exceptional types of endings.",
		parents = {{name = pos, sort = "plural ending"}},
	}

	labels[pos .. " with reducible stem"] = {
		description = "Russian " .. pos .. " with a reducible stem, where an extra vowel is inserted " ..
			"before the last stem consonant in the nominative singular and/or genitive plural.",
		parents = {{name = pos .. " by inflection type", sort = "reducible stem"}},
	}
	
	labels[pos .. " with soft final н in reduced stem"] = {
		description = "Russian " .. pos .. " in which the final {{lang|ru|н}} in the stem becomes {{lang|ru|нь}} when the stem is reduced.",
		breadcrumb = "soft final н in reduced stem",
		parents = {{name = pos .. " with reducible stem", sort = "soft final н in reduced stem"}},
	}

	labels[pos .. " with multiple argument sets"] = {
		description = "Russian " .. pos .. " with multiple argument sets (i.e. which can be declined according to multiple " ..
			"declensions that differ more than just in accent pattern).",
		parents = {{name = pos .. " by inflection type", sort = "multiple argument sets"}},
	}

	labels[pos .. " with multiple accent patterns"] = {
		description = "Russian " .. pos .. " with multiple accent patterns. See [[Appendix:Russian stress patterns - nouns]].",
		parents = {{name = pos .. " by inflection type", sort = "multiple accent patterns"}},
	}

	labels["adjectival " .. pos] = {
		description = "Russian " .. pos .. " with adjectival endings.",
		parents = {pos},
	}

	labels[pos .. " with irregular plural stem"] = {
		description = "Russian " .. pos .. " with an irregular plural stem, which occurs in all cases.",
		parents = {{name = "irregular " .. pos, sort = "plural stem"}},
	}

	labels[pos .. " with mixed declension"] = {
		description = "Russian " .. pos .. " with mixed declension (i.e. with a different declension in the plural as compared " ..
			"with the singular).",
		parents = {{name = "irregular " .. pos, sort = "mixed declension"}},
	}

	labels[pos .. " with alternative genitive plural"] = {
		description = "Russian " .. pos .. " using a specific alternative ending in the genitive plural: for masculine " ..
			pos .. ", no ending; for feminine " .. pos .. ", ''-ей'' (when this ending isn't otherwise expected); for neuter " ..
			pos .. ", ''-ев''. These " .. pos .. " are indicated by a ② in Zaliznyak's dictionary.",
		parents = {{name = "irregular " .. pos, sort = "alternative genitive plural"}},
	}
end

local noun_stem_gender_endings = {
    masculine = {
		["hard-stem"]      = {"a hard consonant (-ъ old-style)", "-ы"},
		["ц-stem"]         = {"-ц (-цъ old-style)", "-ы"},
		["velar-stem"]     = {"a velar (plus -ъ old-style)", "-и"},
		["sibilant-stem"]  = {"a sibilant (plus -ъ old-style)", "-и"},
		["soft-stem"]      = {"-ь", "-и"},
		["i-stem"]         = {"-й", "-и"},
		["vowel-stem"]     = {"-й", "-и"},
		["3rd-declension"] = {"-ь", "-и"},
	},
    feminine = {
		["hard-stem"]      = {"-а", "-ы"},
		["ц-stem"]         = {"-а", "-ы"},
		["velar-stem"]     = {"-а", "-и"},
		["sibilant-stem"]  = {"-а", "-и"},
		["soft-stem"]      = {"-я", "-и"},
		["i-stem"]         = {"-я", "-и"},
		["vowel-stem"]     = {"-я", "-и"},
		["3rd-declension"] = {"-ь", "-и"},
	},
    neuter = {
		["hard-stem"]      = {"-о", "-а"},
		["ц-stem"]         = {"-е", "-а"},
		["velar-stem"]     = {"-о", "-а"},
		["sibilant-stem"]  = {"-е", "-а"},
		["soft-stem"]      = {"-е", "-я"},
		["i-stem"]         = {"-е", "-я"},
		["vowel-stem"]     = {"-е", "-я"},
		["3rd-declension"] = {"-мя", "-мена"},
	},
}

table.insert(handlers, function(data)
	local function escape_accent(accent)
		return rsub(accent, "'", "'")
	end

	local function get_stem_gender_text(stem, gender, pos)
		if not noun_stem_gender_endings[gender] then
			return nil
		end
		local endings = noun_stem_gender_endings[gender][stem]
		if not endings then
			return nil
		end
		local sgending, plending = endings[1], endings[2]
		local stemtext =
			stem == "3rd-declension" and "" or
			" The stem ends in " .. stem_expl[stem] .. " and is Zaliznyak's type " .. zaliznyak_stem_type[stem] .. "."
		local decltext =
			stem == "3rd-declension" and "" or
			" This is traditionally considered to belong to the " .. (gender == "feminine" and "1st" or "2nd") .. " declension."
		return stem .. ", usually " .. gender .. " " .. pos .. "s, normally ending in " .. sgending .. " in the nominative singular " ..
			" and " .. plending .. " in the nominative plural." .. stemtext .. decltext
	end

	local stem, gender, accent, pos = rmatch(data.label, "^(.*) (.-) accent%-(.-) adjectival (.*)s$")
	if not stem then
		stem, gender, pos = rmatch(data.label, "^(.*) (.-) adjectival (.*)s$")
	end
	if stem then
		local possessive, stemtext
		local endings, sg, pl

		local function fetch_endings_1(endings_table, gender, stem, accent)
			if not endings_table[gender] then
				return nil
			end
			local endings = endings_table[gender][stem]
			if endings then
				if type(endings) == "string" then
					return endings
				elseif accent == "a" then
					return endings[1]
				elseif accent == "b" then
					return endings[2]
				end
			end
			return nil
		end

		local function fetch_endings(gender, stem, accent)
			if pos == "numeral" then
				local retval = fetch_endings_1(adjective_numeral_stem_gender_endings, gender, stem, accent)
				if retval then
					return retval
				end
			end
			return fetch_endings_1(adjective_stem_gender_endings, gender, stem, accent)
		end

		sg = fetch_endings(gender, stem, accent)
		pl = fetch_endings("plural", stem, accent)

		if rfind(stem, "possessive") then
			possessive = "possessive "
			stem = rsub(stem, " possessive", "")
			stemtext = ""
		elseif stem_expl[stem] then
			possessive = ""
			stemtext = " The stem ends in " .. stem_expl[stem] .. " and is Zaliznyak's type " .. zaliznyak_stem_type[stem] .. "."
		end

		if (sg or gender == "plural-only") and pl and stemtext then
			local accentdesc = accent == "a" and
				"This " .. pos .. " is stressed according to accent pattern a (stress on the stem)." or
				accent == "b" and
				"This " .. pos .. " is stressed according to accent pattern b (stress on the ending)." or
				"All " .. pos .. "s of this class are stressed according to accent pattern a (stress on the stem)."
			local accenttext = accent and " accent-" .. accent or ""
			return {
				description = "Russian " .. stem .. " " .. gender .. " " .. pos .. "s, with " .. possessive ..
					"adjectival endings, ending in " .. (
						gender == "plural-only" and "" or sg .. " in the nominative singular and ") ..
					pl .. " in the nominative plural." .. stemtext .. " " .. accentdesc,
				breadcrumb = stem .. " " .. gender .. accenttext,
				parents = {
					{name = "adjectival " .. pos .. "s", sort = stem .. " " .. gender .. accenttext},
					pos .. "s by stem type, gender and accent pattern",
				},
			}
		end
	end

	local stem, gender, accent, pos = rmatch(data.label, "^(.-) (.-)%-form accent%-(.-) (.*)s$")
	if stem then
		local stem_gender_text = get_stem_gender_text(stem, gender, pos)
		if stem_gender_text then
			local accent_text = " This " .. pos .. " is stressed according to accent pattern " .. escape_accent(accent) .. "."
			return {
				description = "Russian " .. stem_gender_text .. accent_text,
				breadcrumb = "Accent-" .. escape_accent(accent),
				parents = {
					{name = stem .. " " .. gender .. "-form " .. pos .. "s", sort = accent},
					pos .. "s by stem type, gender and accent pattern",
				}
			}
		end
	end

	local stem, gender, pos = rmatch(data.label, "^(.-) (.-)%-form (.*)s$")
	if stem then
		local stem_gender_text = get_stem_gender_text(stem, gender, pos)
		if stem_gender_text then
			return {
				description = "Russian " .. stem_gender_text,
				breadcrumb = stem .. " " .. gender .. "-form",
				parents = {pos .. "s by stem type and gender"},
			}
		end
	end

	local pos, sg, pl = rmatch(data.label, "^(.*)s ending in (.*) with plural (.*)$")
	if sg then
		return {
			description = "Russian " .. pos .. "s ending in " .. sg .. " in the nominative singular, and " .. pl .. " in the nominative plural.",
			breadcrumb = {name = "singular " .. sg .. ", plural " .. pl, nocap = true},
			parents = {{name = pos .. "s by singular and plural ending", sort = sg .. " " .. pl}},
		}
	end

	local pos, sg = rmatch(data.label, "^(.*)s ending in (.*)$")
	if sg then
		return {
			description = "Russian " .. pos .. "s ending in " .. sg .. " in the nominative singular.",
			breadcrumb = {name = sg, nocap = true},
			parents = {{name = pos .. "s by singular ending", sort = sg}},
		}
	end

	local pos, pl = rmatch(data.label, "^(.*)s with plural (.*)$")
	if pl then
		return {
			description = "Russian " .. pos .. "s ending in " .. pl .. " in the nominative plural.",
			breadcrumb = {name = pl, nocap = true},
			parents = {{name = pos .. "s by plural ending", sort = pl}},
		}
	end

	local pos, accent = rmatch(data.label, "^(.*)s with accent pattern (.*)$")
	if accent then
		return {
			description = "Russian " .. pos .. "s with accent pattern " .. escape_accent(accent) .. ".",
			breadcrumb = {name = escape_accent(accent), nocap = true},
			parents = {{name = pos .. "s by accent pattern", sort = accent}},
		}
	end

	for _, number in ipairs({"singular", "plural"}) do
		local pos, case = rmatch(data.label, "^(.*)s with ([a-z]+tive " .. number .. ")$")
		if case then
			-- partitive, locative, vocative
			return {
				description = "Russian " .. pos .. "s with a separate " .. case .. " case.",
				breadcrumb = case,
				parents = {{name = pos .. "s by case form", sort = case}},
			}
		end
	end

	for _, form in ipairs({"count form", "paucal form"}) do
		local pos = rmatch(data.label, "^(.*)s with " .. form .. "$")
		if pos then
			return {
				description = "Russian " .. pos .. "s with a separate " .. form .. ".",
				breadcrumb = form,
				parents = {{name = pos .. "s by case form", sort = form}},
			}
		end
	end

	local pos, case = rmatch(data.label, "^(.*)s with irregular (.*)$")
	if case then
		return {
			description = "Russian " .. pos .. "s with an irregular " .. case .. " case.",
			breadcrumb = case,
			parents = {{name = pos .. "s by case form", sort = case}},
		}
	end
end)

--------------------------------- Terms spelled with --------------------------------

labels["terms spelled with Е instead of Ё"] = {
	description = "Russian terms in which the letter {{lang|ru|Е}} has been substituted for {{lang|ru|Ё}}.",
	additional = "In normal running text (outside of educational or reference material), the letter {{m|ru|ё}} is seldom used by native speakers, and is instead written as {{m|ru|е}}. It is still pronounced as {{lang|ru|ё}}, however. For example, {{m|ru|лёгкий}} is commonly written {{m|ru|легкий|tr=-}}, but still pronounced as the former. Wiktionary follows the dictionary style with {{lang|ru|ё}}, but forms with {{lang|ru|е}} are also allowed as alternative spellings.\n\n" ..
	"Terms written with {{lang|ru|е}} instead of {{lang|ru|ё}} should only be given word stress if it is also required when spelled with {{lang|ru|ё}} (e.g. {{lang|ru|ё}} occurs more than once, or it is a foreign borrowing where the stress falls elsewhere).\n\n" ..
	"Entries for spellings of this sort should use {{temp|ru-noun-alt-ё}}, {{temp|ru-verb-alt-ё}}, {{temp|ru-adj-alt-ё}} or {{temp|ru-pos-alt-ё}} to format an entire entry.\n\n" ..
	"====See also====\n" ..
	"In {{w|Reforms of Russian orthography|pre-1918 orthography}}, two other rare variations also occurred in a similar fashion:\n" ..
	"* [[:Category:Russian terms spelled with Ѣ instead of Ѣ̈]]\n" ..
	"* [[:Category:Russian terms spelled with Я instead of Я̈]]\n\n" ..
	"Following the reform, an apostrophe was sometimes substituted for the hard sign {{lang|ru|ъ}}:\n" ..
	"* [[:Category:Russian terms spelled with ' instead of Ъ]]",
	breadcrumb = "Е instead of Ё",
	catfix = true,
	parents = {
		{name = "terms by their individual characters", sort = "Е instead of Ё"},
		{name = "terms with irregular pronunciations", sort = "Е instead of Ё"},
	},
}

return {LABELS = labels, HANDLERS = handlers}