<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://odden.us:443/thadar/wiki/index.php?action=history&amp;feed=atom&amp;title=Module%3AGender_and_number</id>
	<title>Module:Gender and number - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://odden.us:443/thadar/wiki/index.php?action=history&amp;feed=atom&amp;title=Module%3AGender_and_number"/>
	<link rel="alternate" type="text/html" href="https://odden.us:443/thadar/wiki/index.php?title=Module:Gender_and_number&amp;action=history"/>
	<updated>2026-04-11T09:32:03Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://odden.us:443/thadar/wiki/index.php?title=Module:Gender_and_number&amp;diff=1264&amp;oldid=prev</id>
		<title>Oa10712: 1 revision imported</title>
		<link rel="alternate" type="text/html" href="https://odden.us:443/thadar/wiki/index.php?title=Module:Gender_and_number&amp;diff=1264&amp;oldid=prev"/>
		<updated>2022-09-06T03:58:07Z</updated>

		<summary type="html">&lt;p&gt;1 revision imported&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 22:58, 5 September 2022&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;en&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(No difference)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Oa10712</name></author>
	</entry>
	<entry>
		<id>https://odden.us:443/thadar/wiki/index.php?title=Module:Gender_and_number&amp;diff=1263&amp;oldid=prev</id>
		<title>en&gt;Benwing2: If a qualifier is attached to a spec like &#039;n-p&#039;, add the qualifier only before the first part</title>
		<link rel="alternate" type="text/html" href="https://odden.us:443/thadar/wiki/index.php?title=Module:Gender_and_number&amp;diff=1263&amp;oldid=prev"/>
		<updated>2022-02-20T22:06:49Z</updated>

		<summary type="html">&lt;p&gt;If a qualifier is attached to a spec like &amp;#039;n-p&amp;#039;, add the qualifier only before the first part&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;--[=[&lt;br /&gt;
	This module creates standardised displays for gender and number.&lt;br /&gt;
	It converts a gender specification into Wiki/HTML format.&lt;br /&gt;
	&lt;br /&gt;
	A gender/number specification consists of one or more gender/number elements, separated by hyphens.&lt;br /&gt;
	Examples are: &amp;quot;n&amp;quot; (neuter gender), &amp;quot;f-p&amp;quot; (feminine plural), &amp;quot;m-an-p&amp;quot; (masculine animate plural),&lt;br /&gt;
	&amp;quot;pf&amp;quot; (perfective aspect). Each gender/number element has the following properties:&lt;br /&gt;
	1. A code, as used in the spec, e.g. &amp;quot;f&amp;quot; for feminine, &amp;quot;p&amp;quot; for plural&amp;quot;.&lt;br /&gt;
	2. A type, e.g. &amp;quot;gender&amp;quot;, &amp;quot;number&amp;quot; or &amp;quot;animacy&amp;quot;. Each element in a given spec must be of a different type.&lt;br /&gt;
	3. A display form, which in turn consists of a display code and a tooltip gloss. The display code&lt;br /&gt;
	   may not be the same as the spec code, e.g. the spec code &amp;quot;an&amp;quot; has display code &amp;quot;anim&amp;quot; and tooltip&lt;br /&gt;
	   gloss &amp;quot;animate&amp;quot;.&lt;br /&gt;
    4. A category into which lemmas of the right part of speech are placed if they have a gender/number&lt;br /&gt;
	   spec containing the given element. For example, a noun with gender/number spec &amp;quot;m-an-p&amp;quot; is placed&lt;br /&gt;
	   into the categories &amp;quot;LANG masculine nouns&amp;quot;, &amp;quot;LANG animate nouns&amp;quot; and &amp;quot;LANG pluralia tantum&amp;quot;.&lt;br /&gt;
]=]--&lt;br /&gt;
&lt;br /&gt;
local export = {}&lt;br /&gt;
local data = mw.loadData(&amp;quot;Module:gender and number/data&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- Version of format_list that can be invoked from a template.&lt;br /&gt;
function export.show_list(frame)&lt;br /&gt;
	local args = frame.args&lt;br /&gt;
	local lang = args[&amp;quot;lang&amp;quot;]; if lang == &amp;quot;&amp;quot; then lang = nil end&lt;br /&gt;
	local list = {}&lt;br /&gt;
	local i = 1&lt;br /&gt;
	&lt;br /&gt;
	while args[i] and args[i] ~= &amp;quot;&amp;quot; do&lt;br /&gt;
		table.insert(list, args[i])&lt;br /&gt;
		i = i + 1&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return export.format_list(list, lang)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- Older entry point; equivalent to format_genders() except that it formats the&lt;br /&gt;
-- categories and returns them appended to the formatted gender text rather than&lt;br /&gt;
-- returning the formatted text and categories separately.&lt;br /&gt;
function export.format_list(specs, lang, pos_for_cat, sort_key)&lt;br /&gt;
	local text, cats = export.format_genders(specs, lang, pos_for_cat)&lt;br /&gt;
	if #cats == 0 then&lt;br /&gt;
		return text&lt;br /&gt;
	end&lt;br /&gt;
	return text .. require(&amp;quot;Module:utilities/format_categories&amp;quot;)(cats, lang, sort_key)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
-- Format one or more gender/number specifications. Each spec is either a string, e.g. &amp;quot;f-p&amp;quot;, or&lt;br /&gt;
-- a table of the form {spec = &amp;quot;SPEC&amp;quot;, qualifiers = {&amp;quot;QUALIFIER&amp;quot;, &amp;quot;QUALIFIER&amp;quot;, ...}} where `.spec`&lt;br /&gt;
-- is a gender/number spec such as &amp;quot;f-p&amp;quot; and `.qualifiers` is a list of qualifiers to display before&lt;br /&gt;
-- the formatted gender/number spec. `.spec` must be present but `.qualifiers` may be omitted.&lt;br /&gt;
-- The function returns two values:&lt;br /&gt;
-- (a) the formatted text;&lt;br /&gt;
-- (b) a list of the categories to add.&lt;br /&gt;
-- If `lang` and `pos_for_cat` are given, gender categories such as &amp;quot;German masculine nouns&amp;quot; or&lt;br /&gt;
-- &amp;quot;Russian imperfective verbs&amp;quot; are added to the categories. Otherwise, if only `lang` is given,&lt;br /&gt;
-- the only category that may be returned is &amp;quot;Requests for gender in LANG entries&amp;quot;. If both are&lt;br /&gt;
-- omitted, the returned list is empty.&lt;br /&gt;
function export.format_genders(specs, lang, pos_for_cat)&lt;br /&gt;
	local formatted_specs = {}&lt;br /&gt;
	local categories = {}&lt;br /&gt;
	local seen_types = {}&lt;br /&gt;
	local category_text = &amp;quot;&amp;quot;&lt;br /&gt;
	local all_is_nounclass = nil&lt;br /&gt;
&lt;br /&gt;
	local function do_gender_spec(spec, parts)&lt;br /&gt;
		local types = {}&lt;br /&gt;
		local codes = data.codes&lt;br /&gt;
&lt;br /&gt;
		for key, code in ipairs(parts) do&lt;br /&gt;
			-- Is this code valid?&lt;br /&gt;
			if not codes[code] then&lt;br /&gt;
				error(&amp;#039;The tag &amp;quot;&amp;#039; .. code .. &amp;#039;&amp;quot; in the gender specification &amp;quot;&amp;#039; .. spec.spec .. &amp;#039;&amp;quot; is not valid.&amp;#039;)&lt;br /&gt;
			end&lt;br /&gt;
			&lt;br /&gt;
			-- Check for multiple genders/numbers/animacies in a single spec.&lt;br /&gt;
			local typ = codes[code].type&lt;br /&gt;
			if typ ~= &amp;quot;other&amp;quot; and types[typ] then&lt;br /&gt;
				--require(&amp;quot;Module:debug&amp;quot;).track(&amp;quot;gender and number/multiple&amp;quot;)&lt;br /&gt;
				--require(&amp;quot;Module:debug&amp;quot;).track(&amp;quot;gender and number/multiple/&amp;quot; .. spec)&lt;br /&gt;
				error(&amp;#039;The gender specification &amp;quot;&amp;#039; .. spec.spec .. &amp;#039;&amp;quot; contains multiple tags of type &amp;quot;&amp;#039; .. typ .. &amp;#039;&amp;quot;.&amp;#039;)&lt;br /&gt;
			end&lt;br /&gt;
			types[typ] = true&lt;br /&gt;
				&lt;br /&gt;
			if key == 1 and spec.qualifiers and #spec.qualifiers &amp;gt; 0 then&lt;br /&gt;
				parts[key] = require(&amp;quot;Module:qualifier&amp;quot;).format_qualifier(spec.qualifiers) .. &amp;quot; &amp;quot; .. codes[code].display&lt;br /&gt;
			else&lt;br /&gt;
				parts[key] = codes[code].display&lt;br /&gt;
			end&lt;br /&gt;
		&lt;br /&gt;
			-- Generate categories if called for.&lt;br /&gt;
			if lang and pos_for_cat then&lt;br /&gt;
				local cat = codes[code].cat&lt;br /&gt;
				if cat then&lt;br /&gt;
					table.insert(categories, lang:getCanonicalName() .. &amp;quot; &amp;quot; .. cat)&lt;br /&gt;
				end&lt;br /&gt;
				if seen_types[typ] and seen_types[typ] ~= code then&lt;br /&gt;
					cat = data.codetype_cats[typ]&lt;br /&gt;
					if cat then&lt;br /&gt;
						table.insert(categories, lang:getCanonicalName() .. &amp;quot; &amp;quot; .. cat)&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
				seen_types[typ] = code&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		-- Add the processed codes together with non-breaking spaces&lt;br /&gt;
		if #parts == 1 then&lt;br /&gt;
			return parts[1]&lt;br /&gt;
		end&lt;br /&gt;
		return table.concat(parts, &amp;quot;&amp;amp;nbsp;&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	for _, spec in ipairs(specs) do&lt;br /&gt;
		if type(spec) ~= &amp;quot;table&amp;quot; then&lt;br /&gt;
			spec = {spec = spec}&lt;br /&gt;
		end&lt;br /&gt;
		local is_nounclass&lt;br /&gt;
		-- If the specification starts with cX, then it is a noun class specification.&lt;br /&gt;
		if spec.spec:find(&amp;quot;^[1-9]&amp;quot;) or spec.spec:find(&amp;quot;^c[^-]&amp;quot;) then&lt;br /&gt;
			is_nounclass = true&lt;br /&gt;
			code = spec.spec:gsub(&amp;quot;^c&amp;quot;, &amp;quot;&amp;quot;)&lt;br /&gt;
			&lt;br /&gt;
			local text&lt;br /&gt;
			if code == &amp;quot;?&amp;quot; then&lt;br /&gt;
				text = &amp;#039;&amp;lt;abbr class=&amp;quot;noun-class&amp;quot; title=&amp;quot;noun class missing&amp;quot;&amp;gt;?&amp;lt;/abbr&amp;gt;&amp;#039;&lt;br /&gt;
			else&lt;br /&gt;
				text = &amp;#039;&amp;lt;abbr class=&amp;quot;noun-class&amp;quot; title=&amp;quot;noun class &amp;#039; .. code .. &amp;#039;&amp;quot;&amp;gt;&amp;#039; .. code .. &amp;quot;&amp;lt;/abbr&amp;gt;&amp;quot;&lt;br /&gt;
				if lang and pos_for_cat then&lt;br /&gt;
					table.insert(categories, lang:getCanonicalName() .. &amp;quot; class &amp;quot; .. code .. &amp;quot; POS&amp;quot;)&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
			local text_with_qual&lt;br /&gt;
			if spec.qualifiers and #spec.qualifiers &amp;gt; 0 then&lt;br /&gt;
				text_with_qual = require(&amp;quot;Module:qualifier&amp;quot;).format_qualifier(spec.qualifiers) .. &amp;quot; &amp;quot; .. text&lt;br /&gt;
			else&lt;br /&gt;
				text_with_qual = text&lt;br /&gt;
			end&lt;br /&gt;
			table.insert(formatted_specs, text_with_qual)&lt;br /&gt;
		else&lt;br /&gt;
			-- Split the parts and iterate over each part, converting it into its display form&lt;br /&gt;
			local parts = mw.text.split(spec.spec, &amp;quot;%-&amp;quot;)&lt;br /&gt;
			local extra_cats = {}&lt;br /&gt;
			local combined_codes = data.combinations&lt;br /&gt;
&lt;br /&gt;
			local has_combined = false&lt;br /&gt;
			for _, code in ipairs(parts) do&lt;br /&gt;
				if combined_codes[code] then&lt;br /&gt;
					has_combined = true&lt;br /&gt;
					break&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			if not has_combined then&lt;br /&gt;
				table.insert(formatted_specs, do_gender_spec(spec, parts))&lt;br /&gt;
			else&lt;br /&gt;
				-- This logic is to handle combined gender specs like &amp;#039;mf&amp;#039; and &amp;#039;mfbysense&amp;#039;.&lt;br /&gt;
				local all_parts = {{}}&lt;br /&gt;
&lt;br /&gt;
				for i, code in ipairs(parts) do&lt;br /&gt;
					if combined_codes[code] then&lt;br /&gt;
						local new_all_parts = {}&lt;br /&gt;
						for _, one_parts in ipairs(all_parts) do&lt;br /&gt;
							for _, one_code in ipairs(combined_codes[code].codes) do&lt;br /&gt;
								local new_combined_parts = mw.clone(one_parts)&lt;br /&gt;
								table.insert(new_combined_parts, one_code)&lt;br /&gt;
								table.insert(new_all_parts, new_combined_parts)&lt;br /&gt;
							end&lt;br /&gt;
						end&lt;br /&gt;
						all_parts = new_all_parts&lt;br /&gt;
						if lang and pos_for_cat then&lt;br /&gt;
							local extra_cat = combined_codes[code].cat&lt;br /&gt;
							if extra_cat then&lt;br /&gt;
								table.insert(extra_cats, lang:getCanonicalName() .. &amp;quot; &amp;quot; .. extra_cat)&lt;br /&gt;
							end&lt;br /&gt;
						end&lt;br /&gt;
					else&lt;br /&gt;
						for _, one_parts in ipairs(all_parts) do&lt;br /&gt;
							table.insert(one_parts, code)&lt;br /&gt;
						end&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
&lt;br /&gt;
				for _, parts in ipairs(all_parts) do&lt;br /&gt;
					table.insert(formatted_specs, do_gender_spec(spec, parts))&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			if #extra_cats &amp;gt; 0 then&lt;br /&gt;
				for _, cat in ipairs(extra_cats) do&lt;br /&gt;
					table.insert(categories, cat)&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			if lang then&lt;br /&gt;
				-- Do some additional gender checks if a language was given&lt;br /&gt;
				-- Is this an incomplete gender?&lt;br /&gt;
				if spec.spec:find(&amp;quot;?&amp;quot;) then&lt;br /&gt;
					table.insert(categories, &amp;quot;Requests for gender in &amp;quot; .. lang:getCanonicalName() .. &amp;quot; entries&amp;quot;)&lt;br /&gt;
				end&lt;br /&gt;
				&lt;br /&gt;
				-- Check if the specification is valid&lt;br /&gt;
				--elseif langinfo.genders then&lt;br /&gt;
				--	local valid_genders = {}&lt;br /&gt;
				--	for _, g in ipairs(langinfo.genders) do valid_genders[g] = true end&lt;br /&gt;
				--	&lt;br /&gt;
				--	if not valid_genders[spec.spec] then&lt;br /&gt;
				--		local valid_string = {}&lt;br /&gt;
				--		for i, g in ipairs(langinfo.genders) do valid_string[i] = g end&lt;br /&gt;
				--		error(&amp;#039;The gender specification &amp;quot;&amp;#039; .. spec.spec .. &amp;#039;&amp;quot; is not valid for &amp;#039; .. langinfo.names[1] .. &amp;quot;. Valid are: &amp;quot; .. table.concat(valid_string, &amp;quot;, &amp;quot;))&lt;br /&gt;
				--	end&lt;br /&gt;
				--end&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			is_nounclass = false&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		-- Ensure that the specifications are either all noun classes, or none are.&lt;br /&gt;
		if all_is_nounclass == nil then&lt;br /&gt;
			all_is_nounclass = is_nounclass&lt;br /&gt;
		elseif all_is_nounclass ~= is_nounclass then&lt;br /&gt;
			error(&amp;quot;Noun classes and genders cannot be mixed. Please use either one or the other.&amp;quot;)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if lang and pos_for_cat then&lt;br /&gt;
		for i, cat in ipairs(categories) do&lt;br /&gt;
			categories[i] = cat:gsub(&amp;quot;POS&amp;quot;, pos_for_cat)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if is_nounclass then&lt;br /&gt;
		-- Add the processed codes together with slashes&lt;br /&gt;
		return &amp;#039;&amp;lt;span class=&amp;quot;gender&amp;quot;&amp;gt;class &amp;#039; .. table.concat(formatted_specs, &amp;quot;/&amp;quot;) .. &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;, categories&lt;br /&gt;
	else&lt;br /&gt;
		-- Add the processed codes together with &amp;quot; or &amp;quot;&lt;br /&gt;
		return &amp;#039;&amp;lt;span class=&amp;quot;gender&amp;quot;&amp;gt;&amp;#039; .. table.concat(formatted_specs, &amp;quot; or &amp;quot;) .. &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;, categories&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return export&lt;/div&gt;</summary>
		<author><name>en&gt;Benwing2</name></author>
	</entry>
</feed>