require('Module:No globals')  
local p = {}
local title = mw.title.getCurrentTitle
local namespace = title.namespace
local testcases = (string.sub(title.subpageText,1,9) == 'testcases')  
--==========================================================================
-- Category functions
--==========================================================================  
function p.getCatForId( id )
local catName = ''
if namespace == 0 then
catName = 'Wikipedia articles with '..id..' identifiers'
elseif namespace == 2 and not title.isSubpage then
catName = 'User pages with '..id..' identifiers'
else
catName = 'Miscellaneous pages with '..id..' identifiers'
end
return ''..p.redCatLink(catName)
end  
function p.redCatLink( catName ) --catName == 'Blah', not 'Category:Blah', not ''
if catName and catName ~= '' and
testcases == false and
mw.title.new(catName, 14).exists == false
then
return ''
end
return ''
end  
--==========================================================================
-- Property formatting functions
--==========================================================================  
function p.aagLink( id )
--P3372's format regex: \d+ (e.g. 1)
if not id:match( '^%d+$' ) then
return false
end
return *..id..*..p.getCatForId( 'AAG' )
end  
function p.acmLink( id )
--P864's format regex: \d{11} (e.g. 12345678901)
if not id:match( '^%d%d%d%d%d%d%d%d%d%d%d$' ) then
return false
end
return *..id..*..p.getCatForId( 'ACM-DL' )
end  
function p.adbLink( id )
--P1907's format regex: [a-z][-a-z]+-([1-2]\d|[1-9])\d{0,3} (e.g. barton-sir-edmund-toby-71)
if not id:match( '^[a-z][-a-z]+-[1-2]%d%d?%d?%d?$' ) and
not id:match( '^[a-z][-a-z]+-[1-9]%d?%d?%d?$' ) then
return false
end
return *..id..*..p.getCatForId( 'ADB' )
end  
function p.agsaLink( id )
--P6804's format regex: [1-9]\d* (e.g. 3625)
if not id:match( '^[1-9]%d*$' ) then
return false
end
return *..id..*..p.getCatForId( 'AGSA' )
end  
function p.autoresuyLink( id )
--P2558's format regex: [1-9]\d{0,4} (e.g. 12345)
if not id:match( '^[1-9]%d?%d?%d?%d?$' ) then
return false
end
return *..id..*..p.getCatForId( 'autores.uy' )
end  
function p.awrLink( id )
--P4186's format regex: (([A-Z]{3}\d{4})|([A-Z]{2}\d{5}))[a-z] (e.g. PR00768b)
if not id:match( '^[A-Z][A-Z][A-Z]%d%d%d%d[a-z]$' ) and
not id:match( '^[A-Z][A-Z]%d%d%d%d%d[a-z]$' ) then
return false
end
return *..id..*..p.getCatForId( 'AWR' )
end  
function p.balatLink( id )
--P3293's format regex: \d+ (e.g. 1)
if not id:match( '^%d+$' ) then
return false
end
return *..id..*..p.getCatForId( 'BALaT' ) --no https as of 9/2019
end  
function p.bibsysLink( id )
--P1015's format regex: [1-9]\d* or [1-9](\d{0,8}|\d{12}) (e.g. 1234567890123)
--TODO: follow up @ d:Property talk:P1015#Discrepancy between the 2 regex constraints or escalate/investigate
if not id:match( '^[1-9]%d?%d?%d?%d?%d?%d?%d?%d?$' ) and
not id:match( '^[1-9]%d%d%d%d%d%d%d%d%d%d%d%d$' ) then
return false
end
return *..id..*..p.getCatForId( 'BIBSYS' )
end  
function p.bildLink( id )
--P2092's format regex: \d+ (e.g. 1)
if not id:match( '^%d+$' ) then
return false
end
return *..id..*..p.getCatForId( 'Bildindex' )
end  
function p.bncLink( id )
--P1890's format regex: \d{9} (e.g. 123456789)
if not id:match( '^%d%d%d%d%d%d%d%d%d$' ) then
return false
end
return *..id..*..p.getCatForId( 'BNC' )
end  
function p.bneLink( id )
--P950's format regex: (XX|FF|a)\d{4,7}|(bima|bimo|bica|bis[eo]|bivi|Mise|Mimo|Mima)\d{10} (e.g. XX1234567)
if not id:match( '^[XF][XF]%d%d%d%d%d?%d?%d?$' ) and
not id:match( '^a%d%d%d%d%d?%d?%d?$' ) and
not id:match( '^bi[mcsv][aoei]%d%d%d%d%d%d%d%d%d%d$' ) and
not id:match( '^Mi[sm][eoa]%d%d%d%d%d%d%d%d%d%d$' ) then
return false
end
return *..id..*..p.getCatForId( 'BNE' ) --no https as of 9/2019
end  
function p.bnfLink( id )
--P268's format regex: \d{8}[0-9bcdfghjkmnpqrstvwxz] (e.g. 123456789)
if not id:match( '^c?b?%d%d%d%d%d%d%d%d[0-9bcdfghjkmnpqrstvwxz]$' ) then
return false
end
--Add cb prefix if it has been removed
if not id:match( '^cb.+$' ) then
id = 'cb'..id
end
return ''..id..' (data)'..p.getCatForId( 'BNF' )
end  
function p.botanistLink( id )
--P428's format regex: ('t )?(d')?(de )?(la )?(van (der )?)?(Ma?c)?(De)?(Di)?\p{Lu}?C?['\p{Ll}]*([-'. ]*(van )?(y )?(d[ae][nr]?[- ])?(Ma?c)?[\p{Lu}bht]?C?['\p{Ll}]*)*\.? ?f?\.? (e.g. L.)
--not easily/meaningfully implementable in Lua's regex since "(this)?" is not allowed...
if not mw.ustring.match( id, "^[%u%l%d%. '-]+$" ) then --better than nothing
return false
end
local id2 = id:gsub(' +', '%%20')
return *..id..*..p.getCatForId( 'Botanist' )
end  
function p.bpnLink( id )
--P651's format regex: \d{6,8} (e.g. 00123456)
if not id:match( '^%d%d%d%d%d%d%d%d$' ) and --original format regex, changed 8/2019 to
not id:match( '^0?%d%d%d%d%d%d%d$' ) and --allow 1-2 leading 0s, allowed by the website
not id:match( '^0?0?%d%d%d%d%d%d$' ) then
return false
end
return *..id..*..p.getCatForId( 'BPN' ) --no https as of 9/2019
end  
function p.canticLink( id )
--P1273's format regex: a\d{7}[0-9x] (e.g. a10640745)
if not id:match( '^a%d%d%d%d%d%d%d[%dx]$' ) then
return false
end
return *..id..*..p.getCatForId( 'CANTIC' ) --no https as of 10/2019
end  
function p.ciniiLink( id )
--P271's format regex: DA\d{7}[\dX] (e.g. DA12345678)
if not id:match( '^DA%d%d%d%d%d%d%d[%dX]$' ) then
return false
end
return *..id..*..p.getCatForId( 'CINII' )
end  
function p.daaoLink( id )
--P1707's format regex: [a-z\-]+\d* (e.g. rolf-harris)
if not id:match( '^[a-z%-]+%d*$' ) then
return false
end
return *..id..*..p.getCatForId( 'DAAO' )
end  
function p.dblpLink( id )
--P2456's format regex: \d{2,3} /\d+(-\d+)?|[a-z] /[a-zA-Z][0-9A-Za-z]*(-\d+)? (e.g. 123/123)
if not id:match( '^%d%d%d?/%d+$' ) and
not id:match( '^%d%d%d?/%d+%-%d+$' ) and
not id:match( '^[a-z]/[a-zA-Z][0-9A-Za-z]*$' ) and
not id:match( '^[a-z]/[a-zA-Z][0-9A-Za-z]*%-%d+$' ) then
return false
end
return *..id..*..p.getCatForId( 'DBLP' )
end  
function p.dsiLink( id )
--P2349's format regex: [1-9]\d* (e.g. 1538)
if not id:match( '^[1-9]%d*$' ) then
return false
end
return *..id..*..p.getCatForId( 'DSI' )
end  
function p.fnzaLink( id )
--P6792's format regex: [1-9]\d* (e.g. 9785)
if not id:match( '^[1-9]%d*$' ) then
return false
end
return *..id..*..p.getCatForId( 'FNZA' )
end  
function p.gndLink( id )
--P227's format regex: 1[012]?\d{7}[0-9X]|[47]\d{6}-\d|[1-9]\d{0,7}-[0-9X]|3\d{7}[0-9X] (e.g. 4079154-3)
if not id:match( '^1[012]?%d%d%d%d%d%d%d[0-9X]$' ) and
not id:match( '^[47]%d%d%d%d%d%d%-%d$' ) and
not id:match( '^[1-9]%d?%d?%d?%d?%d?%d?%d?%-[0-9X]$' ) and
not id:match( '^3%d%d%d%d%d%d%d[0-9X]$' ) then
return false
end
return *..id..*..p.getCatForId( 'GND' )
end  
function p.hdsLink( id )
--P902's format regex: \d{6} (e.g. 050123)
if not id:match( '^%d%d%d%d%d%d$' ) then
return false
end
return *..id..*..p.getCatForId( 'HDS' )
end  
function p.iaafLink( id )
--P1146's format regex: [0-9][0-9]* (e.g. 012)
if not id:match( '^%d+$' ) then
return false
end
return *..id..*..p.getCatForId( 'IAAF' )
end  
function p.iciaLink( id )
--P1736's format regex: \d+ (e.g. 1)
if not id:match( '^%d+$' ) then
return false
end
return *..id..*..p.getCatForId( 'ICIA' )
end  
function p.isniLink( id )
id = p.validateIsni( id ) --e.g. 0000-0000-6653-4145
if not id then
return false
end
return *..id:sub( 1, 4 )..' '..id:sub( 5, 8 )..' '..id:sub( 9, 12 )..' '..id:sub( 13, 16 )..*..p.getCatForId( 'ISNI' ) --no https as of 9/2019
end  
function p.jocondeLink( id )
--P347's format regex: [\-0-9A-Za-z]{11} (e.g. 12345678901)
local regex = '^'..string.rep('[%-0-9A-Za-z]', 11)..'$'
if not id:match( regex ) then
return false
end
return *..id..*..p.getCatForId( 'Joconde' )
end  
function p.kulturnavLink( id )
--P1248's format regex: [0-9a-f]{8}\-[0-9a-f]{4}\-[0-9a-f]{4}\-[0-9a-f]{4}\-[0-9a-f]{12} (e.g. 12345678-1234-1234-1234-1234567890AB)
if not id:match( '^%x%x%x%x%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%x%x%x%x%x%x%x%x$' ) then
return false
end