Modul:Detect singular: Unterschied zwischen den Versionen
(handle empty input) |
K (52 Versionen von wpen:Module:Detect_singular importiert) |
||
(49 dazwischenliegende Versionen von 2 Benutzern werden nicht angezeigt) | |||
Zeile 2: | Zeile 2: | ||
local getArgs = require('Module:Arguments').getArgs | local getArgs = require('Module:Arguments').getArgs | ||
local yesNo = require('Module:Yesno') | local yesNo = require('Module:Yesno') | ||
local getPlain = require('Module:Text').Text().getPlain | |||
-- function to determine whether "sub" occurs in "s" | |||
local function plainFind(s, sub) | local function plainFind(s, sub) | ||
return mw.ustring.find(s, sub, 1, | return mw.ustring.find(s, sub, 1, true) | ||
end | end | ||
local function | -- function to count the number of times "pattern" (a regex) occurs in "s" | ||
local _, count = mw.ustring.gsub(s, | local function countMatches(s, pattern) | ||
local _, count = mw.ustring.gsub(s, pattern, '') | |||
return count | return count | ||
end | end | ||
function p._main(args) | local singular = 1 | ||
local checkComma = not | local likelyPlural = 2 | ||
local | local plural = 3 | ||
local s = | |||
-- Determine whether a string is singular or plural (i.e., it represents one | |||
-- item or many) | |||
-- Arguments: | |||
-- origArgs[1]: string to process | |||
-- origArgs.no_comma: if false, use commas to detect plural (default false) | |||
-- origArgs.parse_links: if false, treat wikilinks as opaque singular objects (default false) | |||
-- Returns: | |||
-- singular, likelyPlural, or plural (see constants above), or nil for completely unknown | |||
function p._main(origArgs) | |||
origArgs = type(origArgs) == 'table' and origArgs or {} | |||
local args = {} | |||
-- canonicalize boolean arguments | |||
for key, default in pairs({no_comma=false,parse_links=false,any_comma=false,no_and=false}) 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 checkAnd = not args.no_and | |||
local rewriteLinks = not args.parse_links | |||
local anyComma = args.any_comma | |||
local s = origArgs[1] -- the input string | |||
if not s then | if not s then | ||
return nil -- empty input returns nil | return nil -- empty input returns nil | ||
end | end | ||
s = tostring(s) | s = tostring(s) | ||
if plainFind(s,' | s = mw.text.decode(s,true) --- replace HTML entities (to avoid spurious semicolons) | ||
return | if plainFind(s,'data-plural="0"') then -- magic data string to return true | ||
return singular | |||
end | end | ||
if plainFind(s,' | if plainFind(s,'data-plural="1"') then -- magic data string to return false | ||
return | return plural | ||
end | end | ||
local | -- 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 singular | |||
end | |||
if numListItems > 1 then | |||
return plural | |||
end | |||
-- if "list of" occurs inside of wlink, then it's plural | |||
if mw.ustring.find(s:lower(), '%[%[[^%]]*list of[^%]]+%]%]') then | |||
return plural | |||
end | |||
-- fix for trailing br tags passed through [[template:marriage]] | |||
s = mw.ustring.gsub(s, '<%s*br[^>]*>%s*(</div>)', '%1') | |||
-- replace all wikilinks with fixed string | |||
if rewriteLinks then | |||
s = mw.ustring.gsub(s,'%b[]','WIKILINK') | |||
end | |||
-- Five conditions: any one of them can make the string a likely plural or plural | |||
local hasBreak = mw.ustring.find(s,'<%s*br') | local hasBreak = mw.ustring.find(s,'<%s*br') | ||
local hasBullets = | -- For the last 4, evaluate on string stripped of wikimarkup | ||
return | s = getPlain(s) | ||
local hasBullets = countMatches(s,'%*+') > 1 | |||
local multipleQids = mw.ustring.find(s,'Q%d+[%p%s]+Q%d+') -- has multiple QIDs in a row | |||
if hasBullets or multipleQids then | |||
return plural | |||
end | |||
local commaPattern = anyComma and '[,;]' or '%D[,;]%D' -- semi-colon similar to comma | |||
local hasComma = checkComma and mw.ustring.find(s, commaPattern) | |||
local hasAnd = checkAnd and mw.ustring.find(s,'[,%s]and%s') | |||
if hasBreak or hasComma or hasAnd then | |||
return likelyPlural | |||
end | |||
return singular | |||
end | |||
function p._pluralize(args) | |||
args = type(args) == 'table' and args or {} | |||
local singularForm = args[3] or args.singular or "" | |||
local pluralForm = args[4] or args.plural or "" | |||
local likelyForm = args.likely or pluralForm | |||
local link = args[5] or args.link | |||
if link then | |||
link = tostring(link) | |||
singularForm = '[['..link..'|'..singularForm..']]' | |||
pluralForm = '[['..link..'|'..pluralForm..']]' | |||
likelyForm = '[['..link..'|'..likelyForm..']]' | |||
end | |||
if args[2] then | |||
return pluralForm | |||
end | |||
local detect = p._main(args) | |||
if detect == nil then | |||
return "" -- return blank on complete failure | |||
end | |||
if detect == singular then | |||
return singularForm | |||
elseif detect == likelyPlural then | |||
return likelyForm | |||
else | |||
return pluralForm | |||
end | |||
end | end | ||
function p.main(frame) | function p.main(frame) | ||
local args = getArgs(frame) | local args = getArgs(frame) | ||
if p._main(args) then | -- For template, return 1 if singular, blank if plural or empty | ||
local result = p._main(args) | |||
if result == nil then | |||
return 1 | return 1 | ||
end | end | ||
return "" | return result == singular and 1 or "" | ||
end | |||
function p.pluralize(frame) | |||
local args = getArgs(frame) | |||
return p._pluralize(args) | |||
end | end | ||
return p | return p |
Aktuelle Version vom 17. Februar 2023, 00:33 Uhr
Die Dokumentation für dieses Modul kann unter Modul:Detect singular/doc erstellt werden
local p = {} local getArgs = require('Module:Arguments').getArgs local yesNo = require('Module:Yesno') local getPlain = require('Module:Text').Text().getPlain -- function to determine whether "sub" occurs in "s" local function plainFind(s, sub) return mw.ustring.find(s, sub, 1, true) end -- function to count the number of times "pattern" (a regex) occurs in "s" local function countMatches(s, pattern) local _, count = mw.ustring.gsub(s, pattern, '') return count end local singular = 1 local likelyPlural = 2 local plural = 3 -- Determine whether a string is singular or plural (i.e., it represents one -- item or many) -- Arguments: -- origArgs[1]: string to process -- origArgs.no_comma: if false, use commas to detect plural (default false) -- origArgs.parse_links: if false, treat wikilinks as opaque singular objects (default false) -- Returns: -- singular, likelyPlural, or plural (see constants above), or nil for completely unknown function p._main(origArgs) origArgs = type(origArgs) == 'table' and origArgs or {} local args = {} -- canonicalize boolean arguments for key, default in pairs({no_comma=false,parse_links=false,any_comma=false,no_and=false}) 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 checkAnd = not args.no_and local rewriteLinks = not args.parse_links local anyComma = args.any_comma local s = origArgs[1] -- the input string if not s then return nil -- empty input returns nil end s = tostring(s) s = mw.text.decode(s,true) --- replace HTML entities (to avoid spurious semicolons) if plainFind(s,'data-plural="0"') then -- magic data string to return true return singular end if plainFind(s,'data-plural="1"') then -- magic data string to return false return plural 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 singular end if numListItems > 1 then return plural end -- if "list of" occurs inside of wlink, then it's plural if mw.ustring.find(s:lower(), '%[%[[^%]]*list of[^%]]+%]%]') then return plural end -- fix for trailing br tags passed through [[template:marriage]] s = mw.ustring.gsub(s, '<%s*br[^>]*>%s*(</div>)', '%1') -- replace all wikilinks with fixed string if rewriteLinks then s = mw.ustring.gsub(s,'%b[]','WIKILINK') end -- Five conditions: any one of them can make the string a likely plural or plural local hasBreak = mw.ustring.find(s,'<%s*br') -- For the last 4, evaluate on string stripped of wikimarkup s = getPlain(s) local hasBullets = countMatches(s,'%*+') > 1 local multipleQids = mw.ustring.find(s,'Q%d+[%p%s]+Q%d+') -- has multiple QIDs in a row if hasBullets or multipleQids then return plural end local commaPattern = anyComma and '[,;]' or '%D[,;]%D' -- semi-colon similar to comma local hasComma = checkComma and mw.ustring.find(s, commaPattern) local hasAnd = checkAnd and mw.ustring.find(s,'[,%s]and%s') if hasBreak or hasComma or hasAnd then return likelyPlural end return singular end function p._pluralize(args) args = type(args) == 'table' and args or {} local singularForm = args[3] or args.singular or "" local pluralForm = args[4] or args.plural or "" local likelyForm = args.likely or pluralForm local link = args[5] or args.link if link then link = tostring(link) singularForm = '[['..link..'|'..singularForm..']]' pluralForm = '[['..link..'|'..pluralForm..']]' likelyForm = '[['..link..'|'..likelyForm..']]' end if args[2] then return pluralForm end local detect = p._main(args) if detect == nil then return "" -- return blank on complete failure end if detect == singular then return singularForm elseif detect == likelyPlural then return likelyForm else return pluralForm end end function p.main(frame) local args = getArgs(frame) -- For template, return 1 if singular, blank if plural or empty local result = p._main(args) if result == nil then return 1 end return result == singular and 1 or "" end function p.pluralize(frame) local args = getArgs(frame) return p._pluralize(args) end return p