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

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}