<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://twentyonewiki.info/index.php?action=history&amp;feed=atom&amp;title=Module%3ADetect_singular</id>
	<title>Module:Detect singular - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://twentyonewiki.info/index.php?action=history&amp;feed=atom&amp;title=Module%3ADetect_singular"/>
	<link rel="alternate" type="text/html" href="https://twentyonewiki.info/index.php?title=Module:Detect_singular&amp;action=history"/>
	<updated>2026-04-11T22:40:39Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.40.1</generator>
	<entry>
		<id>https://twentyonewiki.info/index.php?title=Module:Detect_singular&amp;diff=1944&amp;oldid=prev</id>
		<title>Buburka Rinderbuy: 1 revision imported</title>
		<link rel="alternate" type="text/html" href="https://twentyonewiki.info/index.php?title=Module:Detect_singular&amp;diff=1944&amp;oldid=prev"/>
		<updated>2024-01-27T01:34:57Z</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 21:34, 26 January 2024&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>Buburka Rinderbuy</name></author>
	</entry>
	<entry>
		<id>https://twentyonewiki.info/index.php?title=Module:Detect_singular&amp;diff=1943&amp;oldid=prev</id>
		<title>Module:Detect singular&gt;Hike395: decode HTML entities</title>
		<link rel="alternate" type="text/html" href="https://twentyonewiki.info/index.php?title=Module:Detect_singular&amp;diff=1943&amp;oldid=prev"/>
		<updated>2023-01-02T22:05:13Z</updated>

		<summary type="html">&lt;p&gt;decode HTML entities&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;local p = {}&lt;br /&gt;
local getArgs = require('Module:Arguments').getArgs&lt;br /&gt;
local yesNo = require('Module:Yesno')&lt;br /&gt;
local getPlain = require('Module:Text').Text().getPlain&lt;br /&gt;
&lt;br /&gt;
-- function to determine whether &amp;quot;sub&amp;quot; occurs in &amp;quot;s&amp;quot;&lt;br /&gt;
local function plainFind(s, sub)&lt;br /&gt;
	return mw.ustring.find(s, sub, 1, true)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- function to count the number of times &amp;quot;pattern&amp;quot; (a regex) occurs in &amp;quot;s&amp;quot;&lt;br /&gt;
local function countMatches(s, pattern)&lt;br /&gt;
	local _, count = mw.ustring.gsub(s, pattern, '')&lt;br /&gt;
	return count&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local singular = 1&lt;br /&gt;
local likelyPlural = 2&lt;br /&gt;
local plural = 3&lt;br /&gt;
&lt;br /&gt;
-- Determine whether a string is singular or plural (i.e., it represents one&lt;br /&gt;
-- item or many)&lt;br /&gt;
-- Arguments:&lt;br /&gt;
--   origArgs[1]: string to process&lt;br /&gt;
--   origArgs.no_comma:  if false, use commas to detect plural (default false)&lt;br /&gt;
--   origArgs.parse_links: if false, treat wikilinks as opaque singular objects (default false)&lt;br /&gt;
-- Returns:&lt;br /&gt;
--   singular, likelyPlural, or plural (see constants above), or nil for completely unknown&lt;br /&gt;
function p._main(origArgs)&lt;br /&gt;
	origArgs = type(origArgs) == 'table' and origArgs or {}&lt;br /&gt;
	local args = {}&lt;br /&gt;
	-- canonicalize boolean arguments&lt;br /&gt;
	for key, default in pairs({no_comma=false,parse_links=false,any_comma=false,no_and=false}) do&lt;br /&gt;
		if origArgs[key] == nil then&lt;br /&gt;
			args[key] = default&lt;br /&gt;
		else&lt;br /&gt;
			args[key] = yesNo(origArgs[key],default)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	local checkComma = not args.no_comma&lt;br /&gt;
	local checkAnd = not args.no_and&lt;br /&gt;
	local rewriteLinks = not args.parse_links&lt;br /&gt;
	local anyComma = args.any_comma&lt;br /&gt;
	local s = origArgs[1]  -- the input string&lt;br /&gt;
	if not s then&lt;br /&gt;
		return nil -- empty input returns nil&lt;br /&gt;
	end&lt;br /&gt;
	s = tostring(s)&lt;br /&gt;
	s = mw.text.decode(s,true)  --- replace HTML entities (to avoid spurious semicolons)&lt;br /&gt;
	if plainFind(s,'data-plural=&amp;quot;0&amp;quot;') then -- magic data string to return true&lt;br /&gt;
		return singular&lt;br /&gt;
	end&lt;br /&gt;
	if plainFind(s,'data-plural=&amp;quot;1&amp;quot;') then -- magic data string to return false&lt;br /&gt;
		return plural&lt;br /&gt;
	end&lt;br /&gt;
	-- count number of list items&lt;br /&gt;
	local numListItems = countMatches(s,'&amp;lt;%s*li')&lt;br /&gt;
	-- if exactly one, then singular, if more than one, then plural&lt;br /&gt;
	if numListItems == 1 then&lt;br /&gt;
		return singular&lt;br /&gt;
	end&lt;br /&gt;
	if numListItems &amp;gt; 1 then&lt;br /&gt;
		return plural&lt;br /&gt;
	end&lt;br /&gt;
	-- if &amp;quot;list of&amp;quot; occurs inside of wlink, then it's plural&lt;br /&gt;
	if mw.ustring.find(s:lower(), '%[%[[^%]]*list of[^%]]+%]%]') then&lt;br /&gt;
		return plural&lt;br /&gt;
	end&lt;br /&gt;
	-- fix for trailing br tags passed through [[template:marriage]]&lt;br /&gt;
	s = mw.ustring.gsub(s, '&amp;lt;%s*br[^&amp;gt;]*&amp;gt;%s*(&amp;lt;/div&amp;gt;)', '%1')&lt;br /&gt;
	-- replace all wikilinks with fixed string&lt;br /&gt;
	if rewriteLinks then&lt;br /&gt;
		s = mw.ustring.gsub(s,'%b[]','WIKILINK') &lt;br /&gt;
	end&lt;br /&gt;
	-- Five conditions: any one of them can make the string a likely plural or plural&lt;br /&gt;
	local hasBreak = mw.ustring.find(s,'&amp;lt;%s*br')&lt;br /&gt;
	-- For the last 4, evaluate on string stripped of wikimarkup&lt;br /&gt;
	s = getPlain(s)&lt;br /&gt;
	local hasBullets = countMatches(s,'%*+') &amp;gt; 1&lt;br /&gt;
	local multipleQids = mw.ustring.find(s,'Q%d+[%p%s]+Q%d+') -- has multiple QIDs in a row&lt;br /&gt;
	if hasBullets or multipleQids then&lt;br /&gt;
		return plural&lt;br /&gt;
	end&lt;br /&gt;
	local commaPattern = anyComma and '[,;]' or '%D[,;]%D'  -- semi-colon similar to comma&lt;br /&gt;
	local hasComma = checkComma and mw.ustring.find(s, commaPattern)&lt;br /&gt;
	local hasAnd = checkAnd and mw.ustring.find(s,'[,%s]and%s')&lt;br /&gt;
	if hasBreak or hasComma or hasAnd then&lt;br /&gt;
		return likelyPlural&lt;br /&gt;
	end&lt;br /&gt;
	return singular&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p._pluralize(args)&lt;br /&gt;
	args = type(args) == 'table' and args or {}&lt;br /&gt;
	local singularForm = args[3] or args.singular or &amp;quot;&amp;quot;&lt;br /&gt;
	local pluralForm = args[4] or args.plural or &amp;quot;&amp;quot;&lt;br /&gt;
	local likelyForm = args.likely or pluralForm&lt;br /&gt;
	local link = args[5] or args.link&lt;br /&gt;
	if link then&lt;br /&gt;
		link = tostring(link)&lt;br /&gt;
		singularForm = '[['..link..'|'..singularForm..']]'&lt;br /&gt;
		pluralForm = '[['..link..'|'..pluralForm..']]'&lt;br /&gt;
		likelyForm = '[['..link..'|'..likelyForm..']]'&lt;br /&gt;
	end&lt;br /&gt;
	if args[2] then&lt;br /&gt;
		return pluralForm&lt;br /&gt;
	end&lt;br /&gt;
	local detect = p._main(args)&lt;br /&gt;
	if detect == nil then&lt;br /&gt;
		return &amp;quot;&amp;quot;   -- return blank on complete failure&lt;br /&gt;
	end&lt;br /&gt;
	if detect == singular then&lt;br /&gt;
		return singularForm&lt;br /&gt;
	elseif detect == likelyPlural then&lt;br /&gt;
		return likelyForm&lt;br /&gt;
	else&lt;br /&gt;
		return pluralForm&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.main(frame)&lt;br /&gt;
	local args = getArgs(frame)&lt;br /&gt;
	-- For template, return 1 if singular, blank if plural or empty&lt;br /&gt;
	local result = p._main(args)&lt;br /&gt;
	if result == nil then&lt;br /&gt;
		return 1&lt;br /&gt;
	end&lt;br /&gt;
	return result == singular and 1 or &amp;quot;&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.pluralize(frame)&lt;br /&gt;
	local args = getArgs(frame)&lt;br /&gt;
	return p._pluralize(args)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Module:Detect singular&gt;Hike395</name></author>
	</entry>
</feed>