Module:Detect singular
Appearance
![]() | This Lua module is used on approximately 1,870,000 pages, or roughly 3% of all pages. To avoid major disruption and server load, any changes should be tested in the module's /sandbox or /testcases subpages, or in your own module sandbox. The tested changes can be added to this page in a single edit. Consider discussing changes on the talk page before implementing them. |
![]() | This module depends on the following other modules: |
Lua to determine whether a string is singular or plural. Designed for use in infoboxes, to determine whether labels should be singular or plural based on the corresponding data, e.g.
{{#invoke:Detect singular|pluralize|Wynken, Blynken, and Nod||singular|plural}}
→ plural
- See Template:Detect singular for main() usage. Test cases here.
- See Template:Pluralize from text for pluralize() usage (a wrapper around main()). Test cases here.
local p = {}
local getArgs = require('Module:Arguments').getArgs
local yesNo = require('Module:Yesno')
local function plainFind(s, sub)
return mw.ustring.find(s, sub, 1, true)
end
local function countMatches(s, pattern)
local _, count = mw.ustring.gsub(s, pattern, '')
return count
end
function p._main(origArgs)
local args = {}
-- canonicalize boolean arguments
for key, default in pairs({no_comma=false,bullets=true,ignore_links=true}) do
if origArgs[key] == nil then
args[key] = default
else
args[key] = yesNo(origArgs[key],default)
end
end
local checkComma = not args.no_comma
local checkBullets = args.bullets
local rewriteLinks = args.ignore_links
local s = origArgs[1] -- the input string
if not s then
return nil -- empty input returns nil
end
s = tostring(s)
if plainFind(s,'forcedetectsingular') then -- magic data string to return true
return true
end
if plainFind(s,'forcedetectplural') then -- magic data string to return false
return false
end
-- count number of list items
local numListItems = countMatches(s,'<%s*li')
-- if exactly one, then singular, if more than one, then plural
if numListItems == 1 then
return true
end
if numListItems > 1 then
return false
end
-- replace all wikilinks with fixed string
if rewriteLinks then
s = mw.ustring.gsub(s,'%b[]','WIKILINK')
end
local hasComma = checkComma and mw.ustring.find(s, '%D,%D')
local hasAnd = mw.ustring.find(s,'[,%s]and%s')
local hasBreak = mw.ustring.find(s,'<%s*br')
local hasBullets = checkBullets and countMatches(s,'%*+') > 1
local multipleQids = mw.ustring.find(s,'Q%d+[%p%s]+Q%d+') -- has multiple QIDs in a row
return not (hasComma or hasAnd or hasBreak or hasBullets or multipleQids)
end
function p._pluralize(args)
local singularForm = args[3] or ""
local pluralForm = args[4] or ""
if args[5] then
singularForm = '[['..args[5]..'|'..singularForm..']]'
pluralForm = '[['..args[5]..'|'..pluralForm..']]'
end
return args[2] and pluralForm or p._main(args) and singularForm or pluralForm
end
function p.main(frame)
local args = getArgs(frame)
if p._main(args) then
return 1
end
return ""
end
function p.pluralize(frame)
local args = getArgs(frame)
return p._pluralize(args)
end
return p