Module:Authority control (arts)

require('strict')local p = {}local title = mw.title.getCurrentTitle()local namespace = title.namespacelocal testcases = (string.sub(title.subpageText,1,9) == 'testcases')--[[==========================================================================]]--[[                            Category functions                            ]]--[[==========================================================================]]function p.getCatForId( id )local catName = ''if namespace == 0 thencatName = 'Wikipedia articles with '..id..' identifiers'elseif namespace == 2 and not title.isSubpage thencatName = 'User pages with '..id..' identifiers'elsecatName = 'Miscellaneous pages with '..id..' identifiers'endreturn '[[Category:'..catName..']]'..p.redCatLink(catName)endfunction p.redCatLink( catName ) --catName == 'Blah' (not 'Category:Blah', not '[[Category:Blah]]')if catName and catName ~= '' and   testcases == false and   mw.title.new(catName, 14).exists == falsethenreturn '[[Category:Pages with red-linked authority control categories]]'endreturn ''endfunction p.createRow( id, rawValues, link, links, withUid, specialCat, prefix)local catName = 'Wikipedia articles with faulty '..(specialCat or id)..' identifiers'if links then -- all links[] use withUid = false; no check neededlocal row = ''if prefix then row = row .. '*' .. prefixendfor i, l in ipairs( links ) doif i == 1 and not prefix then row = row..'*'else           row = row..'\n**' endif l thenrow = row..'<span class="uid">'..l..'</span>'elserow = row..'<span class="error">The '..id..' id '..rawValues[i]..' is not valid.</span>[[Category:'..catName..']]'..p.redCatLink(catName)endendreturn row..'\n'elseif link then -- All IDs that have a prefix support multiple identifiers, so prefix is not neededif withUid thenreturn '*<span class="nowrap"><span class="uid">'..link..'</span></span>\n'endreturn '*<span class="nowrap">'..link..'</span>\n'endreturn '* <span class="error">The '..id..' id '..rawValues..' is not valid.</span>[[Category:'..catName..']]'..p.redCatLink(catName)..'\n'end--[[==========================================================================]]--[[                      Property formatting functions                       ]]--[[==========================================================================]]-- If a link has a suitable entry in the global inter-wiki prefix table at [[:m:Interwiki_map]], please consider routing through this prefix rather than as external link URL. This will ease future maintenance as necessary updates to the link can be centrally carried out there rather than by updating this module. The "external link" icon would disappear for such entries.function p.aagLink( id, label)--P3372's format regex: \d+ (e.g. 1)if not id:match( '^%d+$' ) thenreturn falseendreturn '[https://www.aucklandartgallery.com/explore-art-and-ideas/artist/'..id..'/ '..(label or 'Auckland')..']'..p.getCatForId( 'AAG' )endfunction p.acmLink( id, label )--P864's format regex: \d{11} (e.g. 12345678901)if not id:match( '^%d%d%d%d%d%d%d%d%d%d%d$' ) thenreturn falseendreturn '[https://dl.acm.org/profile/'..id..' '..(label or 'Association for Computing Machinery')..']'..p.getCatForId( 'ACM-DL' )endfunction p.adbLink( id, label )--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?$' ) thenreturn falseendreturn '[http://adb.anu.edu.au/biography/'..id..' '..(label or 'Australia')..']'..p.getCatForId( 'ADB' )endfunction p.agsaLink( id, label )--P6804's format regex: [1-9]\d* (e.g. 3625)if not id:match( '^[1-9]%d*$' ) thenreturn falseendreturn '[https://www.agsa.sa.gov.au/collection-publications/collection/creators/_/'..id..'/ '..(label or 'South Australia')..']'..p.getCatForId( 'AGSA' )endfunction p.autoresuyLink( id, label )--P2558's format regex: [1-9]\d{0,4} (e.g. 12345)if not id:match( '^[1-9]%d?%d?%d?%d?$' ) thenreturn falseendreturn '[https://autores.uy/autor/'..id..' '..(label or 'Uruguay')..']'..p.getCatForId( 'autores.uy' )endfunction p.awrLink( id, label )--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]$' ) thenreturn falseendreturn '[http://www.womenaustralia.info/biogs/'..id..'.htm '..(label or 'Australian Women\'s Register')..']'..p.getCatForId( 'AWR' )endfunction p.balatLink( id, label )--P3293's format regex: \d+ (e.g. 1)if not id:match( '^%d+$' ) thenreturn falseendreturn '[http://balat.kikirpa.be/object/104257'..id..' '..(label or 'BALaT (Belgium)')..']'..p.getCatForId( 'BALaT' ) --no https as of 9/2019endfunction p.bibsysLink( id, label )--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/investigateif 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$' ) thenreturn falseendreturn '[https://authority.bibsys.no/authority/rest/authorities/html/'..id..' '..(label or 'Norway')..']'..p.getCatForId( 'BIBSYS' )endfunction p.bildLink( id, label )--P2092's format regex: \d+ (e.g. 1)if not id:match( '^%d+$' ) thenreturn falseendreturn '[https://www.bildindex.de/document/obj'..id..' '..(label or 'Bildindex (Germany)')..']'..p.getCatForId( 'Bildindex' )endfunction p.bncLink( id, label )--P1890's format regex: \d{9} (e.g. 123456789)if not id:match( '^%d%d%d%d%d%d%d%d%d$' ) thenreturn falseendreturn '[http://www.bncatalogo.cl/F?func=direct&local_base=red10&doc_number='..id..' '..(label or 'Chile')..']'..p.getCatForId( 'BNC' )endfunction p.bneLink( id, label )--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$' ) thenreturn falseendreturn '[http://catalogo.bne.es/uhtbin/authoritybrowse.cgi?action=display&authority_id='..id..' '..(label or 'Spain')..']'..p.getCatForId( 'BNE' ) --no https as of 9/2019endfunction p.bnfLink( id, label )--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]$' ) thenreturn falseend--Add cb prefix if it has been removedif not id:match( '^cb.+$' ) thenid = 'cb'..idendreturn '[https://catalogue.bnf.fr/ark:/12148/'..id..' ' .. (label or 'France')..'] [https://data.bnf.fr/ark:/12148/'..id..' (data)]'..p.getCatForId( 'BNF' )endfunction p.botanistLink( id, label )--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 nothingreturn falseendid = id:gsub(' +', '%%20')return '[https://www.ipni.org/ipni/advAuthorSearch.do?find_abbreviation='..id..' '..(label or 'International Plant Names Index')..']'..p.getCatForId( 'Botanist' )endfunction p.bpnLink( id, label )--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$' ) thenreturn falseendreturn '[http://www.biografischportaal.nl/en/persoon/'..id..' '..(label or 'Netherlands')..']'..p.getCatForId( 'BPN' ) --no https as of 9/2019endfunction p.canticLink( id, label )--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]$' ) thenreturn falseendreturn '[http://cantic.bnc.cat/registres/CUCId/'..id..' '..(label or 'Catalonia')..']'..p.getCatForId( 'CANTIC' ) --no https as of 10/2019endfunction p.ciniiLink( id, label )--P271's format regex: DA\d{7}[\dX] (e.g. DA12345678)if not id:match( '^DA%d%d%d%d%d%d%d[%dX]$' ) thenreturn falseendreturn '[https://ci.nii.ac.jp/author/'..id..'?l=en '..(label or 'CiNii (Japan)')..']'..p.getCatForId( 'CINII' )endfunction p.cwgcLink( id, label )--P1908's format regex: [1-9]\d* (e.g. 75228351)if not id:match( '^[1-9]%d*$' ) thenreturn falseendreturn '[https://www.cwgc.org/find-war-dead/casualty/'..id..'/ '..(label or 'Commonwealth War Graves Commission')..']'..p.getCatForId( 'CWGC' )endfunction p.daaoLink( id, label )--P1707's format regex: [a-z\-]+\d* (e.g. rolf-harris)if not id:match( '^[a-z%-]+%d*$' ) thenreturn falseendreturn '[https://www.daao.org.au/bio/'..id..' '..(label or 'Australian Artists')..']'..p.getCatForId( 'DAAO' )endfunction p.dblpLink( id, label )--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+$' ) thenreturn falseendreturn '[https://dblp.org/pid/'..id..' '..(label or 'DBLP (computer science)')..']'..p.getCatForId( 'DBLP' )endfunction p.dibLink( id, label )--P6829's format regex: a\d{4}\d?(-[A-D])? (e.g. a1953)if not id:match( '^a%d%d%d%d%d?%-?[A-D]?$' ) thenreturn falseendreturn '[https://dib.cambridge.org/viewReadPage.do?articleId='..id..' '..(label or 'Ireland')..']'..p.getCatForId( 'DIB' )endfunction p.dsiLink( id, label )--P2349's format regex: [1-9]\d* (e.g. 1538)if not id:match( '^[1-9]%d*$' ) thenreturn falseendreturn '[http://www.uni-stuttgart.de/hi/gnt/dsi2/index.php?table_name=dsi&function=details&where_field=id&where_value='..id..' '..(label or 'Scientific illustrators')..']'..p.getCatForId( 'DSI' )endfunction p.fnzaLink( id, label )--P6792's format regex: [1-9]\d* (e.g. 9785)if not id:match( '^[1-9]%d*$' ) thenreturn falseendreturn '[https://findnzartists.org.nz/artist/'..id..'/ '..(label or 'New Zealand Artists')..']'..p.getCatForId( 'FNZA' )endfunction p.gndLink( id, label )--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]$' ) thenreturn falseendreturn '[https://d-nb.info/gnd/'..id..' '..(label or 'Germany')..']'..p.getCatForId( 'GND' )endfunction p.hdsLink( id, label )--P902's format regex: \d{6} (e.g. 050123)if not id:match( '^%d%d%d%d%d%d$' ) thenreturn falseendreturn '[https://hls-dhs-dss.ch/fr/articles/'..id..' '..(label or 'Historical Dictionary of Switzerland')..']'..p.getCatForId( 'HDS' )endfunction p.iaafLink( id, label )--P1146's format regex: [0-9][0-9]* (e.g. 012)if not id:match( '^%d+$' ) thenreturn falseendreturn '[https://www.iaaf.org/athletes/_/'..id..' '..(label or 'World Athletics')..']'..p.getCatForId( 'IAAF' )endfunction p.iccuLink( id, label )--P396's format regex: IT\\ICCU\\(\d{10}|\D\D[\D\d]\D\\\d{6}) (e.g. IT\ICCU\CFIV\000163)if not id:match( '^IT\\ICCU\\%d%d%d%d%d%d%d%d%d%d$' ) and   not id:match( '^IT\\ICCU\\%u%u[%u%d]%u\\%d%d%d%d%d%d$' ) then --legacy: %u used here instead of %D (but the faulty ID cat is empty, out of ~12k uses)return falseendreturn '[https://opac.sbn.it/opacsbn/opac/iccu/scheda_authority.jsp?bid='..id..' '..(label or 'Italy')..']'..p.getCatForId( 'ICCU' )endfunction p.iciaLink( id, label )--P1736's format regex: \d+ (e.g. 1)if not id:match( '^%d+$' ) thenreturn falseendreturn '[https://www.imj.org.il/artcenter/newsite/en/?artist='..id..' '..(label or 'ICIA (Israel)')..']'..p.getCatForId( 'ICIA' )endfunction p.ieuLink( id, label )--P9070's format regex: [A-Z]\\[A-Z]\\[A-Za-z0-9]+ (e.g. K\Y\Kyiv)if not id:match( '^[A-Z]\\[A-Z]\\%w+$' ) thenreturn falseendreturn '[http://www.encyclopediaofukraine.com/display.asp?linkpath=pages\\'..id..' '..(label or 'Internet Encyclopedia of Ukraine')..']'..p.getCatForId( 'IEU' )endfunction p.isniLink( id, label )id = p.validateIsni( id ) --e.g. 0000-0000-6653-4145if not id thenreturn falseendreturn '[https://isni.org/isni/'..id..' '..(label or 'ISNI')..']'..p.getCatForId( 'ISNI' )endfunction p.jocondeLink( id, label )--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 ) thenreturn falseendreturn '[https://www.pop.culture.gouv.fr/notice/joconde/'..id..' '..(label or 'Joconde (France)')..']'..p.getCatForId( 'Joconde' )endfunction p.kulturnavLink( id, label )--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$' ) thenreturn falseendreturn '[http://kulturnav.org/'..id..' '..(label or 'KulturNav (Norway)')..']'..p.getCatForId( 'KULTURNAV' ) --no https as of 9/2019endfunction p.lccnLink( id, label )local parts = p.splitLccn( id ) --e.g. n78039510if not parts thenreturn falseendlocal lccnType = parts[1] ~= 'sh' and 'names' or 'subjects'id = parts[1] .. parts[2] .. p.append( parts[3], '0', 6 )return '[https://id.loc.gov/authorities/'..lccnType..'/'..id..' '..(label or 'United States')..']'..p.getCatForId( 'LCCN' )endfunction p.lirLink( id, label )--P886's format regex: \d+ (e.g. 1)if not id:match( '^%d+$' ) thenreturn falseendreturn '[http://www.e-lir.ch/e-LIR___Lexicon.'..id..'.450.0.html '..(label or 'Lexicon Istoric Retic (Switzerland)')..']'..p.getCatForId( 'LIR' ) --no https as of 9/2019endfunction p.lnbLink( id, label )--P1368's format regex: \d{9} (e.g. 123456789)if not id:match( '^%d%d%d%d%d%d%d%d%d$' ) thenreturn falseendreturn '[https://kopkatalogs.lv/F?func=direct&local_base=lnc10&doc_number='..id..'&P_CON_LNG=ENG '..(label or 'Latvia')..']'..p.getCatForId( 'LNB' )endfunction p.leonoreLink( id, label )--P640's format regex: LH/\d{1,4}/\d{1,3}|19800035/\d{1,4}/\d{1,5}(Bis)?|C/0/\d{1,2} (e.g. LH/2064/18)if not id:match( '^LH/%d%d?%d?%d?/%d%d?%d?$' ) and             --IDs from       LH/1/1 to         LH/2794/54 (legionaries)   not id:match( '^19800035/%d%d?%d?%d?/%d%d?%d?%d?%d?$' ) and --IDs from 19800035/1/1 to 19800035/385/51670 (legionnaires who died 1954-1977 & some who died < 1954)   not id:match( '^C/0/%d%d?$' ) then                          --IDs from        C/0/1 to             C/0/84 (84 famous legionaries)return falseendreturn '[http://www.culture.gouv.fr/public/mistral/leonore_fr?ACTION=CHERCHER&FIELD_1=COTE&VALUE_1='..id..' '..(label or 'Léonore (France)')..']'..p.getCatForId( 'Léonore' ) --no https as of 9/2019endfunction p.maLink( id, label )--P6366's format regex: [1-9]\d{4,9} (e.g. 1498221862)if not id:match( '^[1-9]%d%d%d%d%d?%d?%d?%d?%d?$' ) thenreturn falseendreturn '[https://academic.microsoft.com/v2/detail/'..id..' '..(label or 'Microsoft Academic')..']'..p.getCatForId( 'MA' )endfunction p.mbaLink( id, label )--P434'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$' ) thenreturn falseendlocal url = 'https://musicbrainz.org/artist/'..idlocal cat = p.getCatForId( 'MusicBrainz' )--special category nameif label thenreturn '['..url..' '..label..']'..catelsereturn '[[MBA (identifier)|MusikBrainz]] [' .. url .. ' artist]' .. catendendfunction p.mbareaLink( id, label )--P982'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$' ) thenreturn falseendlocal url = 'https://musicbrainz.org/area/'..idlocal cat = p.getCatForId( 'MusicBrainz area' )--special category nameif label thenreturn '['..url..' '..label..']'..catelsereturn '[[MBAREA (identifier)|MusikBrainz]] [' .. url .. ' area]' .. catendendfunction p.mbiLink( id, label )--P1330'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$' ) thenreturn falseendlocal url = 'https://musicbrainz.org/instrument/'..idlocal cat = p.getCatForId( 'MusicBrainz instrument' )--special category nameif label thenreturn '['..url..' '..label..']'..catelsereturn '[[MBI (identifier)|MusikBrainz]] [' .. url .. ' instrument]' .. catendendfunction p.mblLink( id, label )--P966'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$' ) thenreturn falseendlocal url = 'https://musicbrainz.org/label/'..idlocal cat = p.getCatForId( 'MusicBrainz label' )--special category nameif label thenreturn '['..url..' '..label..']'..catelsereturn '[[MBL (identifier)|MusikBrainz]] [' .. url .. ' label]' .. catendendfunction p.mbpLink( id, label )--P1004'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$' ) thenreturn falseendlocal url = 'https://musicbrainz.org/place/'..idlocal cat = p.getCatForId( 'MusicBrainz place' )--special category nameif label thenreturn '['..url..' '..label..']'..catelsereturn '[[MBP (identifier)|MusikBrainz]] [' .. url .. ' place]' .. catendendfunction p.mbrgLink( id, label )--P436'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$' ) thenreturn falseendlocal url = 'https://musicbrainz.org/release-group/'..idlocal cat = p.getCatForId( 'MusicBrainz release group' )--special category nameif label thenreturn '['..url..' '..label..']'..catelsereturn '[[MBRG (identifier)|MusikBrainz]] [' .. url .. ' release group]' .. catendendfunction p.mbsLink( id, label )--P1407'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$' ) thenreturn falseendlocal url = 'https://musicbrainz.org/series/'..idlocal cat = p.getCatForId( 'MusicBrainz series' )--special category nameif label thenreturn '['..url..' '..label..']'..catelsereturn '[[MBS (identifier)|MusikBrainz]] [' .. url .. ' series]' .. catendendfunction p.mbwLink( id, label )--P435'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$' ) thenreturn falseendlocal url = 'https://musicbrainz.org/work/'..idlocal cat = p.getCatForId( 'MusicBrainz work' )--special category nameif label thenreturn '['..url..' '..label..']'..catelsereturn '[[MBW (identifier)|MusikBrainz]] [' .. url .. ' work]' .. catendendfunction p.mgpLink( id, label )--P549's format regex: \d{1,6} (e.g. 123456)if not id:match( '^%d%d?%d?%d?%d?%d?$' ) thenreturn falseendreturn '[https://genealogy.math.ndsu.nodak.edu/id.php?id='..id..' '..(label or 'Mathematics Genealogy Project')..']'..p.getCatForId( 'MGP' )endfunction p.naraLink( id, label )--P1225's format regex: ^([1-9]\d{0,8})$ (e.g. 123456789)if not id:match( '^[1-9]%d?%d?%d?%d?%d?%d?%d?%d?$' ) thenreturn falseendreturn '[https://catalog.archives.gov/id/'..id..' '..(label or 'National Archives (US)')..']'..p.getCatForId( 'NARA' )endfunction p.nclLink( id, label )--P1048's format regex: \d+ (e.g. 1081436)if not id:match( '^%d+$' ) thenreturn falseendreturn '[http://aleweb.ncl.edu.tw/F/?func=accref&acc_sequence='..id..'&CON_LNG=ENG '..(label or 'Taiwan')..']'..p.getCatForId( 'NCL' ) --no https as of 9/2019endfunction p.ndlLink( id, label )--P349's format regex: 0?\d{8} (e.g. 012345678)if not id:match( '^0?%d%d%d%d%d%d%d%d$' ) thenreturn falseendreturn '[https://id.ndl.go.jp/auth/ndlna/'..id..' '..(label or 'Japan')..']'..p.getCatForId( 'NDL' )endfunction p.ngvLink( id, label )--P2041's format regex: \d+ (e.g. 12354)if not id:match( '^%d+$' ) thenreturn falseendreturn '[https://www.ngv.vic.gov.au/explore/collection/artist/'..id..'/ '..(label or 'Victoria')..']'..p.getCatForId( 'NGV' )endfunction p.nkcLink( id, label )--P691's format regex: [a-z]{2,4}[0-9]{2,14} (e.g. abcd12345678901234)if not id:match( '^[a-z][a-z][a-z]?[a-z]?%d%d%d?%d?%d?%d?%d?%d?%d?%d?%d?%d?%d?%d?$' ) thenreturn falseendreturn '[https://aleph.nkp.cz/F/?func=find-c&local_base=aut&ccl_term=ica='..id..'&CON_LNG=ENG '..(label or 'Czech Republic')..']'..p.getCatForId( 'NKC' )endfunction p.nlaLink( id, label )--P409's format regex: [1-9][0-9]{0,11} (e.g. 123456789012)if not id:match( '^[1-9]%d?%d?%d?%d?%d?%d?%d?%d?%d?%d?%d?$' ) thenreturn falseendreturn '[https://nla.gov.au/anbd.aut-an'..id..' '..(label or 'Australia')..']'..p.getCatForId( 'NLA' )endfunction p.nlgLink( id, label )--P3348's format regex: [1-9]\d* (e.g. 1)if not id:match( '^[1-9]%d*$' ) thenreturn falseendreturn '[https://data.nlg.gr/resource/authority/record'..id..' '..(label or 'Greece')..']'..p.getCatForId( 'NLG' )endfunction p.nliLink( id, label )--P949's format regex: \d{9} (e.g. 123456789)if not id:match( '^%d%d%d%d%d%d%d%d%d$' ) thenreturn falseendreturn '[http://uli.nli.org.il/F/?func=direct&doc_number='..id..'&local_base=nlx10'..' '..(label or 'Israel')..']'..p.getCatForId( 'NLI' )endfunction p.nlkLink( id, label )--P5034's format regex: KA.(19|20).{7} (e.g. KAC201501465)if not id:match( '^KA.19.......$' ) and   not id:match( '^KA.20.......$' ) thenreturn falseendreturn '[https://nl.go.kr/authorities/resource/'..id..' '..(label or 'Korea')..']'..p.getCatForId( 'NLK' )endfunction p.nlpLink( id, label )--P1695's format regex: 9810[0-9]\d* or A[0-9]{7}[0-9X] (e.g. 9810123456789012345 or A10414836)if not id:match( '^9810%d+$' ) and   not id:match( '^A%d%d%d%d%d%d%d[%dX]$' ) thenreturn falseendreturn '[https://tools.wmflabs.org/wikidata-externalid-url?p=1695&id='..id..' '..(label or 'Poland')..']'..p.getCatForId( 'NLP' )endfunction p.nlrLink( id, label )--P1003's format regex: \d{9} (e.g. 123456789)if not id:match( '^%d%d%d%d%d%d%d%d%d$' ) thenreturn falseendreturn '[http://aleph.bibnat.ro:8991/F/?func=direct&local_base=NLR10&doc_number='..id..' '..(label or 'Romania')..']'..p.getCatForId( 'NLR' )endfunction p.nskLink( id, label )--P1375's format regex: \d{9} (e.g. 123456789)if not id:match( '^%d%d%d%d%d%d%d%d%d$' ) thenreturn falseendreturn '[http://katalog.nsk.hr/F/?func=direct&doc_number='..id..'&local_base=nsk10 '..(label or 'Croatia')..']'..p.getCatForId( 'NSK' ) --no https as of 9/2019endfunction p.ntaLink( id, label )--P1006's format regex: \d{8}[\dX] (e.g. 12345678X)if not id:match( '^%d%d%d%d%d%d%d%d[%dX]$' ) thenreturn falseendreturn '[http://data.bibliotheken.nl/id/thes/p'..id..' '..(label or 'Netherlands')..']'..p.getCatForId( 'NTA' )endfunction p.orcidLink( id, label )id = p.validateIsni( id ) --e.g. 0000-0002-7398-5483if not id thenreturn falseendid = id:sub( 1, 4 )..'-'..id:sub( 5, 8 )..'-'..id:sub( 9, 12 )..'-'..id:sub( 13, 16 )return '[https://orcid.org/'..id..' '..(label or 'ORCID')..']'..p.getCatForId( 'ORCID' )endfunction p.picLink( id, label )--P2750's format regex: [1-9]\d* (e.g. 1)if not id:match( '^[1-9]%d*$' ) thenreturn falseendreturn '[https://pic.nypl.org/constituents/'..id..' '..(label or 'Photographers\' Identities')..']'..p.getCatForId( 'PIC' )endfunction p.plwabnLink( id, label )--P7293's format regex: 981[0-9]{8}05606 (e.g. 9810696457305606)if not id:match( '^981%d%d%d%d%d%d%d%d05606*$' ) thenreturn falseendreturn '[http://mak.bn.org.pl/cgi-bin/KHW/makwww.exe?BM=1&NU=1&IM=4&WI='..id..' '..(label or 'Poland')..']'..p.getCatForId( 'PLWABN' )endfunction p.publonsLink( id, label )--P3829's format regex: \d+ (e.g. 654601)if not id:match( '^%d+$' ) thenreturn falseendreturn '[https://publons.com/author/'..id..'/ '..(label or 'Publons (researchers)')..']'..p.getCatForId( 'Publons' )endfunction p.ridLink( id, label )--P1053's format regex: [A-Z]{1,3}-\d{4}-(19|20)\d\d (e.g. AAS-5150-2020)if not id:match( '^[A-Z][A-Z]?[A-Z]?%-%d%d%d%d%-19%d%d$' ) and   not id:match( '^[A-Z][A-Z]?[A-Z]?%-%d%d%d%d%-20%d%d$' ) thenreturn falseendreturn '[https://www.researcherid.com/rid/'..id..' '..(label or 'ResearcherID')..']'..p.getCatForId( 'RID' )endfunction p.reroLink( id, label )--P3065's format regex: 0[1-2]-[A-Z0-9]{1,10} (e.g. 02-A012345678)if not id:match( '^0[1-2]%-[A-Z%d][A-Z%d]?[A-Z%d]?[A-Z%d]?[A-Z%d]?[A-Z%d]?[A-Z%d]?[A-Z%d]?[A-Z%d]?[A-Z%d]?$' ) thenreturn falseendreturn '[http://data.rero.ch/'..id..' '..(label or 'RERO (Switzerland)')..']'..p.getCatForId( 'RERO' )endfunction p.rkdartistsLink( id, label )--P650's format regex: [1-9]\d{0,5} (e.g. 123456)if not id:match( '^[1-9]%d?%d?%d?%d?%d?$' ) thenreturn falseendreturn '[https://rkd.nl/en/explore/artists/'..id..' '..(label or 'RKD Artists (Netherlands)')..']'..p.getCatForId( 'RKDartists' )endfunction p.rkdidLink( id, label )--P350's format regex: [1-9]\d{0,5} (e.g. 123456)if not id:match( '^[1-9]%d?%d?%d?%d?%d?$' ) thenreturn falseendreturn '[https://rkd.nl/nl/explore/images/'..id..' '..(label or 'RKD ID (Netherlands)')..']'..p.getCatForId( 'RKDID' )endfunction p.rslLink( id, label )--P947's format regex: \d{1,9} (e.g. 123456789)if not id:match( '^%d%d?%d?%d?%d?%d?%d?%d?%d?$' ) thenreturn falseendreturn '[http://aleph.rsl.ru/F?func=find-b&find_code=SYS&adjacent=Y&local_base=RSL11&request='..id..'&CON_LNG=ENG '..(label or 'Russia')..']'..p.getCatForId( 'RSL' ) --no https as of 9/2019endfunction p.selibrLink( id, label )--P906's format regex: [1-9]\d{4,5} (e.g. 123456)if not id:match( '^[1-9]%d%d%d%d%d?$' ) thenreturn falseendreturn '[https://libris.kb.se/auth/'..id..' '..(label or 'Sweden')..']'..p.getCatForId( 'SELIBR' )endfunction p.sikartLink( id, label )--P781's format regex: \d{7,9} (e.g. 123456789)if not id:match( '^%d%d%d%d%d%d%d%d?%d?$' ) thenreturn falseendreturn '[http://www.sikart.ch/KuenstlerInnen.aspx?id='..id..'&lng=en '..(label or 'SIKART (Switzerland)')..']'..p.getCatForId( 'SIKART' ) --no https as of 9/2019endfunction p.snacLink( id, label )--P3430's format regex: \d*[A-Za-z][0-9A-Za-z]* (e.g. A)if not id:match( '^%d*[A-Za-z][0-9A-Za-z]*$' ) thenreturn falseendreturn '[https://snaccooperative.org/ark:/99166/'..id..' '..(label or 'Social Networks and Archival Context')..']'..p.getCatForId( 'SNAC-ID' )endfunction p.sudocLink( id, label )--P269's format regex: (\d{8}[\dX]|) (e.g. 026927608)if not id:match( '^%d%d%d%d%d%d%d%d[%dxX]$' ) then --legacy: allow lowercase 'x'return falseendreturn '[https://www.idref.fr/'..id..' '..(label or 'SUDOC (France)')..']'..p.getCatForId( 'SUDOC' )endfunction p.s2authoridLink( id, label )--P4012's format regex: [1-9]\d* (e.g. 1796130)if not id:match( '^[1-9]%d*$' ) thenreturn falseendreturn '[https://www.semanticscholar.org/author/'..id..' '..(label or 'Semantic Scholar')..']'..p.getCatForId( 'Semantic Scholar author' ) --special category nameendfunction p.ta98Link( id, label )--P1323's format regex: A\d{2}\.\d\.\d{2}\.\d{3}[FM]? (e.g. A12.3.45.678)if not id:match( '^A%d%d%.%d%.%d%d%.%d%d%d[FM]?$' ) thenreturn falseendreturn '[http://tools.wmflabs.org/wikidata-externalid-url/?p=1323&url_prefix=https:%2F%2Fwww.unifr.ch%2Fifaa%2FPublic%2FEntryPage%2FTA98%20Tree%2FEntity%20TA98%20EN%2F&url_suffix=%20Entity%20TA98%20EN.htm&id='..id..' '..(label or 'Terminologia Anatomica')..']'..p.getCatForId( 'TA98' )endfunction p.tdviaLink( id, label )--P7314's format regex: [a-z/-]+] (e.g. barkan-omer-lutfi)if not id:match( '^[a-z/-]+$' ) thenreturn falseendreturn '[https://islamansiklopedisi.org.tr/'..id..' '..(label or 'Encyclopedia of Islam')..']'..p.getCatForId( 'TDVİA' )endfunction p.teLink( id, label )--P1693's format regex: E[1-8]\.\d{1,2}\.\d{1,2}\.\d{1,2}\.\d{1}\.\d{1}\.\d{1,3} (e.g. E1.23.45.67.8.9.0)local e1, e2 = id:match( '^E([1-8])%.(%d%d?)%.%d%d?%.%d%d?%.%d%.%d%.%d%d?%d?$' )if not e1 thenreturn falseendlocal TEnum = 'TEe0'..e1 --no formatter URL in WD, probably due to this complexityif e1 == '5' or e1 == '7' thenif #e2 == 1 then e2 = '0'..e2 endTEnum = TEnum..e2endreturn '[http://www.unifr.ch/ifaa/Public/EntryPage/ViewTE/'..TEnum..'.html '..(label or 'Terminologia Embryologica')..']'..p.getCatForId( 'TE' )endfunction p.tepapaLink( id, label )--P3544's format regex: \d+ (e.g. 1)if not id:match( '^%d+$' ) thenreturn falseendreturn '[https://collections.tepapa.govt.nz/agent/'..id..' '..(label or 'Te Papa (New Zealand)')..']'..p.getCatForId( 'TePapa' )endfunction p.thLink( id, label )--P1694's format regex: H\d\.\d{2}\.\d{2}\.\d\.\d{5} (e.g. H1.23.45.6.78901)local h1, h2 = id:match( '^H(%d)%.(%d%d)%.%d%d%.%d%.%d%d%d%d%d$' )if not h1 thenreturn falseendlocal THnum = 'THh'..h1..h2 --no formatter URL in WD, probably due to this complexityreturn '[http://www.unifr.ch/ifaa/Public/EntryPage/ViewTH/'..THnum..'.html '..(label or 'Terminologia Histologica')..']'..p.getCatForId( 'TH' )endfunction p.tlsLink( id, label )id = id:gsub(' +', '_')--P1362's format regex: \p{Lu}[\p{L}\d_',\.\-\(\)\*/–]{3,59} (e.g. Abcd)local class = "[%a%d_',%.%-%(%)%*/–]"local regex = "^%u"..string.rep(class, 3)..string.rep(class.."?", 56).."$"if not mw.ustring.match( id, regex ) thenreturn falseendreturn '[http://tls.theaterwissenschaft.ch/wiki/'..id..' '..(label or 'Theaterlexikon (Switzerland)')..']'..p.getCatForId( 'TLS' ) --no https as of 9/2019endfunction p.troveLink( id, label )--P1315's format regex: [1-9]\d{5,7} (e.g. 12345678)if not id:match( '^[1-9]%d%d%d%d%d%d?%d?$' ) thenreturn falseendreturn '[https://trove.nla.gov.au/people/'..id..' '..(label or 'Trove (Australia)')..']'..p.getCatForId( 'Trove' )endfunction p.ukparlLink( id, label )--P6213's format regex: [a-zA-Z\d]{8} (e.g. AQUupyiR)if not id:match( '^[a-zA-Z%d][a-zA-Z%d][a-zA-Z%d][a-zA-Z%d][a-zA-Z%d][a-zA-Z%d][a-zA-Z%d][a-zA-Z%d]$' ) thenreturn falseendreturn '[https://id.parliament.uk/'..id..' '..(label or 'UK Parliament')..']'..p.getCatForId( 'UKPARL' )endfunction p.ulanLink( id, label )--P245's format regex: 500\d{6} (e.g. 500123456)if not id:match( '^500%d%d%d%d%d%d$' ) thenreturn falseendreturn '[https://www.getty.edu/vow/ULANFullDisplay?find=&role=&nation=&subjectid='..id..' '..(label or 'Artist Names (Getty)')..']'..p.getCatForId( 'ULAN' )endfunction p.uscongressLink( id, label )--P1157's format regex: [A-Z]00[01]\d{3} (e.g. A000123)if not id:match( '^[A-Z]00[01]%d%d%d$' ) thenreturn falseendreturn '[http://bioguide.congress.gov/scripts/biodisplay.pl?index='..id..' '..(label or 'US Congress')..']'..p.getCatForId( 'USCongress' ) --no https as of 9/2019endfunction p.vcbaLink( id, label )--P8034's format regex: \d{3}\/[1-9]\d{0,5} (e.g. 494/9793)if not id:match( '^%d%d%d\/[1-9]%d?%d?%d?%d?%d?$' ) thenreturn falseendid = id:gsub('\/', '_')return '[https://opac.vatlib.it/auth/detail/'..id..' '..(label or 'Vatican')..']'..p.getCatForId( 'VcBA' )endfunction p.viafLink( id, label )--P214's format regex: [1-9]\d(\d{0,7}|\d{17,20}) (e.g. 123456789, 1234567890123456789012)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%d%d%d%d%d%d%d?%d?%d?$' ) thenreturn falseend-- If the "VIAF" entry at [[:m:Interwiki map]] would resolve to "https://viaf.org/viaf/$1" (rather than "http://viaf.org/viaf/$1", as it currently still does), the code below could change from '[https://viaf.org/viaf/'..id..' '..id..']' to '[[:VIAF:'..id..'|'..id..']]'.return '[https://viaf.org/viaf/'..id..' '..(label or 'VIAF')..']'..p.getCatForId( 'VIAF' )end--[[=========================== Helper functions =============================]]function p.append(str, c, length)while str:len() < length dostr = c .. strendreturn strend--Returns the ISNI check digit isni must be a string where the 15 first elements are digits, e.g. 0000000066534145function p.getIsniCheckDigit( isni )local total = 0for i = 1, 15 dolocal digit = isni:byte( i ) - 48 --Get integer valuetotal = (total + digit) * 2endlocal remainder = total % 11local result = (12 - remainder) % 11if result == 10 thenreturn "X"endreturn tostring( result )end--Validate ISNI (and ORCID) and retuns it as a 16 characters string or returns false if it's invalid--See http://support.orcid.org/knowledgebase/articles/116780-structure-of-the-orcid-identifierfunction p.validateIsni( id )--P213 (ISNI) format regex: [0-9]{4} [0-9]{4} [0-9]{4} [0-9]{3}[0-9X] (e.g. 0000-0000-6653-4145)--P496 (ORCID) format regex: 0000-000(1-[5-9]|2-[0-9]|3-[0-4])\d{3}-\d{3}[\dX] (e.g. 0000-0002-7398-5483)id = id:gsub( '[ %-]', '' ):upper()if not id:match( '^%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d[%dX]$' ) thenreturn falseendif p.getIsniCheckDigit( id ) ~= string.char( id:byte( 16 ) ) thenreturn falseendreturn idendfunction p.splitLccn( id )--P244's format regex: (n|nb|nr|no|ns|sh)([4-9][0-9]|00|20[0-1][0-9])[0-9]{6} (e.g. n78039510)if id:match( '^%l%l?%l?%d%d%d%d%d%d%d%d%d?%d?$' ) thenid = id:gsub( '^(%l+)(%d+)(%d%d%d%d%d%d)$', '%1/%2/%3' )endif id:match( '^%l%l?%l?/%d%d%d?%d?/%d+$' ) thenreturn mw.text.split( id, '/' )endreturn falseend--[[==========================================================================]]--[[                    Wikidata & documentation functions                    ]]--[[==========================================================================]]function p.getIdsFromWikidata( itemId, property )local ids = {}local statements = mw.wikibase.getBestStatements( itemId, property )if statements thenfor _, statement in ipairs( statements ) doif statement.mainsnak.datavalue thentable.insert( ids, statement.mainsnak.datavalue.value )endendendreturn idsendfunction p.matchesWikidataRequirements( itemId, reqs )for _, group in ipairs( reqs ) dolocal property = 'P'..group[1]local qid = group[2]local statements = mw.wikibase.getBestStatements( itemId, property )if statements thenfor _, statement in ipairs( statements ) doif statement.mainsnak.datavalue thenif statement.mainsnak.datavalue.value['numeric-id'] == qid thenreturn trueendendendendendreturn falseend-- Creates a human-readable standalone wikitable version of p.conf, and tracking categories with page counts, for use in the documentationfunction p.docConfTable( frame )local wikiTable = '{| class="wikitable sortable"\n'..  '! rowspan=2 | Parameter\n'..  '! rowspan=2 | Section\n'..  '! rowspan=2 | Appears as\n'..  '! rowspan=2; data-sort-type=number | Wikidata property\n'..  '! colspan=4 | Tracking categories and page counts\n'..  '|-\n'..  '! [[:Category:Wikipedia articles with authority control information|'..       'Articles]]\n'..  '! [[:Category:User pages with authority control information|'..               'User pages]]\n'..  '! [[:Category:Miscellaneous pages with authority control information|'..      'Misc. pages]]\n'..  '! [[:Category:Wikipedia articles with faulty authority control information|'..'Faulty IDs]]\n'..  '|-\n'local lang = mw.getContentLanguage()for _, conf in pairs( p.conf ) dolocal param, pid, section = conf[1], conf[2], conf[4]local appearsAs, linkif param == "WORLDCATID" then-- WorldCat is specialappearsAs = "[https://www.worldcat.org/identities/lccn-n78039510 WorldCat]"link = "WorldCat Identities (identifier)"elseif conf.prefix thenappearsAs = conf.prefixlink = conf.link or param .. ' (identifier)'elseappearsAs = conf[3](conf[5])link = conf.link or param .. ' (identifier)'endlocal category = conf.category or paramlocal args = { id = 'f', pid }local wpl = frame:expandTemplate{ title = 'Wikidata property link', args = args }--catslocal articleCat = 'Wikipedia articles with '..category..' identifiers'local userCat =    'User pages with '..category..' identifiers'local miscCat =    'Miscellaneous pages with '..category..' identifiers'local faultyCat =  'Wikipedia articles with faulty '..category..' identifiers'--countslocal articleCount = lang:formatNum( mw.site.stats.pagesInCategory(articleCat, 'pages') )local userCount =    lang:formatNum( mw.site.stats.pagesInCategory(userCat, 'pages') )local miscCount =    lang:formatNum( mw.site.stats.pagesInCategory(miscCat, 'pages') )local faultyCount =  lang:formatNum( mw.site.stats.pagesInCategory(faultyCat, 'pages') )--concatwikiTable = wikiTable..'\n'..'|-\n'..'||[['..link..'|'..param..']]'..'||'..section..'||'..appearsAs..'||data-sort-value='..pid..'|'..wpl..'||style="text-align: right;"|[[:Category:'..articleCat..'|'..articleCount..']]'..'||style="text-align: right;"|[[:Category:'..   userCat..'|'..   userCount..']]'..'||style="text-align: right;"|[[:Category:'..   miscCat..'|'..   miscCount..']]'..'||style="text-align: right;"|[[:Category:'.. faultyCat..'|'.. faultyCount..']]'end--append derivative WorldCat catslocal wcd = { 'WorldCat-LCCN', 'WorldCat-VIAF' }for _, w in pairs(wcd) dolocal articleCat = 'Wikipedia articles with '..w..' identifiers'local articleCount = lang:formatNum( mw.site.stats.pagesInCategory(articleCat, 'pages') )local appearsAs if w == "WorldCat-LCCN" thenappearsAs = "[https://www.worldcat.org/identities/lccn-n79-113947 WorldCat (via Library of Congress)]"elseappearsAs = "[https://www.worldcat.org/identities/containsVIAFID/12345789 WorldCat (via VIAF)]"endwikiTable = wikiTable..'\n'..'|-\n'..'||'..'—'..'||General'..'||'..appearsAs..'||data-sort-value='..w..'|'..'—'..'||style="text-align: right;"|[[:Category:'..articleCat..'|'..articleCount..']]'..'||style="text-align: right;"|—'..'||style="text-align: right;"|—'..'||style="text-align: right;"|—'endreturn require("Module:Suppress categories").main(wikiTable)..'\n|}'end--[[==========================================================================]]--[[                              Configuration                               ]]--[[==========================================================================]]-- If a specific "(identifier) redirect" exists for an identifier, please route through this particular redirect rather than linking directly to the target page. This reduces clutter in "What links here" and improves reverse lookup of articles where a manifestation of this particular identifier is used.-- Check that the Wikidata item has this property-->value before adding itlocal reqs = {}-- Parameter format: { 'parameter name', propertyId # in Wikidata, formatting/validation function, section, example ID for documentation }-- Optional named parameters: `link` to override the link in the documentation (defaults to parameter + (identifer)),-- category to override the ID in category names (defaults to parameter),-- prefix to include a prefix (usually a wikilink explaining what the identifier is) before the external link itselfp.conf = {{ 'AAG', 3372, p.aagLink, "Art galleries and museums", "1"},{ 'ACM-DL', 864, p.acmLink, "Scientific databases", "12345678901", link="ACM DL (identifier)"},{ 'ADB', 1907, p.adbLink,"Biographical dictionaries", "barton-sir-edmund-toby-71"},{ 'AGSA', 6804, p.agsaLink, "Art galleries and museums", "3625"},{ 'autores.uy', 2558, p.autoresuyLink, "Biographical dictionaries", "12345"},{ 'AWR', 4182, p.awrLink, "Biographical dictionaries", "PR00768b"},{ 'BALaT', 3293, p.balatLink, "Art research institutes", "1"},{ 'BIBSYS', 1015, p.bibsysLink, "National libraries", "1234567890123"},{ 'Bildindex', 2092, p.bildLink, "Art research institutes", "1"},{ 'BNC', 1890, p.bncLink, "National libraries", "123456789"},{ 'BNE', 950, p.bneLink, "National libraries", "XX1234567"},{ 'BNF', 268, p.bnfLink, "National libraries", "123456789"},{ 'Botanist', 428, p.botanistLink , "Scientific databases", "L."},{ 'BPN', 651, p.bpnLink , "Biographical dictionaries", "12345678"},{ 'CANTIC', 1273, p.canticLink, "National libraries", "a12345678"},{ 'CINII', 271, p.ciniiLink, "Scientific databases", "DA12345678", link = "CiNii (identifier)"},{ 'CWGC', 1908, p.cwgcLink, "Other", "1234567"},{ 'DAAO', 1707, p.daaoLink, "Art research institutes", "rolf-harris"},{ 'DBLP', 2456, p.dblpLink, "Scientific databases", "123/123"},{ 'DIB',  6829, p.dibLink, "Biographical dictionaries", "a1234"},{ 'DSI', 2349, p.dsiLink, "Art research institutes", "1538"},{ 'FNZA', 6792, p.fnzaLink, "Art research institutes", "12"},{ 'GND', 227, p.gndLink, "National libraries", "4079154-3"},{ 'HDS', 902, p.hdsLink, "Other", "050123"},{ 'IAAF', 1146, p.iaafLink, "Other", "123"},{ 'ICCU', 396, p.iccuLink, "National libraries", "IT\\ICCU\\CFIV\\000163"}, --formerly SBN{ 'ICIA', 1736, p.iciaLink, "Art research institutes", "1"},{ 'IEU', 9070, p.ieuLink, "Other", "N\\A\\NationalAcademyofArtandArchitecture"},{ 'ISNI', 213, p.isniLink, "General", "0000-0000-6653-4145", prefix = '[[ISNI (identifier)|ISNI]]'},{ 'Joconde', 347, p.jocondeLink, "Art research institutes", "12345678901"},{ 'KULTURNAV', 1248, p.kulturnavLink, "Art research institutes", "12345678-1234-1234-1234-1234567890AB", link="KulturNav (identifier)"},{ 'LCCN', 244, p.lccnLink, "National libraries", "n78039510"},{ 'LIR', 886, p.lirLink, "Other", "1"},{ 'LNB', 1368, p.lnbLink, "National libraries", "123456789"},{ 'Léonore', 640, p.leonoreLink, "Other", "LH/1/1", prefix = "[[Léonore (identifier)|Léonore (France)]]"},{ 'MA', 6366, p.maLink, "Other", "123456789"},{ 'MBA', 434, p.mbaLink, "Other", "12345678-1234-1234-1234-1234567890AB", category = 'MusicBrainz'}, --special category name{ 'MBAREA', 982, p.mbareaLink, "Other", "12345678-1234-1234-1234-1234567890AB", category = 'MusicBrainz area' }, --special category name{ 'MBI', 1330, p.mbiLink, "Other", "12345678-1234-1234-1234-1234567890AB", category = 'MusicBrainz instrument' }, --special category name{ 'MBL', 966, p.mblLink, "Other", "12345678-1234-1234-1234-1234567890AB", category = 'MusicBrainz label' }, --special category name{ 'MBP', 1004, p.mbpLink, "Other", "12345678-1234-1234-1234-1234567890AB", category = 'MusicBrainz place' }, --special category name{ 'MBRG', 436, p.mbrgLink, "Other", "12345678-1234-1234-1234-1234567890AB", category = 'MusicBrainz release group' }, --special category name{ 'MBS', 1407, p.mbsLink, "Other", "12345678-1234-1234-1234-1234567890AB", category = 'MusicBrainz series' }, --special category name{ 'MBW',  435, p.mbwLink, "Other", "12345678-1234-1234-1234-1234567890AB", category = 'MusicBrainz work' }, --special category name{ 'MGP', 549, p.mgpLink, "Scientific databases", "123456"},{ 'NARA', 1225, p.naraLink, "Other", "12345678"},{ 'NCL', 1048, p.nclLink, "National libraries", "1081436"},{ 'NDL', 349, p.ndlLink, "National libraries", "012345678"},{ 'NGV', 2041, p.ngvLink, "Art galleries and museums", "12354"},{ 'NKC', 691, p.nkcLink, "National libraries", "abcd12345678901234"},{ 'NLA', 409, p.nlaLink, "National libraries", "123456789012"},{ 'NLG', 3348, p.nlgLink, "National libraries", "12345678"},{ 'NLI', 949, p.nliLink, "National libraries", "123456789"},{ 'NLK', 5034, p.nlkLink, "National libraries", "KAB197000000"},{ 'NLP', 1695, p.nlpLink, "National libraries", "9810123456789012345"},{ 'NLR', 1003, p.nlrLink, "National libraries", "123456789"},{ 'NSK', 1375, p.nskLink, "National libraries", "123456789"},{ 'NTA', 1006, p.ntaLink, "National libraries", "12345678X"},{ 'ORCID', 496, p.orcidLink, "General", "0000-0002-7398-5483", prefix = '[[ORCID (identifier)|ORCID]]'},{ 'PIC', 2750, p.picLink, "Art research institutes", "1"},{ 'PLWABN',  7293, p.plwabnLink, "National libraries", "9812345678905606"},{ 'Publons', 3829, p.publonsLink, "Scientific databases", "2776255"},{ 'RID', 1053, p.ridLink, "Scientific databases", "A-1234-1934"},{ 'RERO', 3065, p.reroLink, "Other", "02-A012345678", prefix = '[[RERO (identifier)|RERO (Switzerland)]]'},{ 'RKDartists', 650, p.rkdartistsLink, "Art research institutes", "123456"},{ 'RKDID', 350, p.rkdidLink, "Art research institutes", "123456"},{ 'RSL', 947, p.rslLink, "National libraries", "123456789"},{ 'SELIBR', 906, p.selibrLink, "National libraries", "123456"},{ 'SIKART', 781, p.sikartLink, "Art research institutes", '123456789'},{ 'SNAC-ID', 3430, p.snacLink, "Other", "A"},{ 'SUDOC', 269, p.sudocLink, "Other", "026927608", prefix = '[[SUDOC (identifier)|SUDOC]]'},{ 'S2AuthorId', 4012, p.s2authoridLink, "Scientific databases", "1796130", category = 'Semantic Scholar author' }, --special category name{ 'TA98', 1323, p.ta98Link, "Scientific databases", "A12.3.45.678"},{ 'TDVİA', 7314, p.tdviaLink, "Other", "asim-b-behdele"},{ 'TE', 1693, p.teLink, "Scientific databases", "E1.23.45.67.8.9.0"},{ 'TePapa', 3544, p.tepapaLink, "Art galleries and museums", "1"},{ 'TH', 1694, p.thLink, "Scientific databases", "H1.23.45.6.78901"},{ 'TLS',  1362, p.tlsLink, "Other", "Abcd"},{ 'Trove', 1315, p.troveLink, "Other", "12345678", prefix = '[[Trove (identifier)|Trove (Australia)]]'}, --formerly NLA-person{ 'UKPARL', 6213, p.ukparlLink, "Other", "AQUupyiR"},{ 'ULAN', 245, p.ulanLink, "Art research institutes", "500123456"},{ 'USCongress', 1157, p.uscongressLink, "Other", "A000123", link = "US Congress (identifier)"},{ 'VcBA', 8034, p.vcbaLink, "National libraries", "494/9793"},{ 'VIAF', 214, p.viafLink, "General", "123456789", prefix = "[[VIAF (identifier)|VIAF]]"},{ 'WORLDCATID', 7859, nil, "General", nil},}-- Legitimate aliases to p.conf, for convenience-- Format: { 'alias', 'parameter name in p.conf' }p.aliases = {{ 'DNB', 'GND' }, --Deutsche Nationalbibliothek -> Gemeinsame Normdatei{ 'Leonore', 'Léonore' }, --alias name without diacritics{ 'leonore', 'Léonore' }, --lowercase variant without diacritics{ 'MusicBrainz', 'MBA' },{ 'MusicBrainz artist', 'MBA' },{ 'MusicBrainz label', 'MBL' },{ 'MusicBrainz release group', 'MBRG' },{ 'MusicBrainz work', 'MBW' },{ 'SBN', 'ICCU' }, --SBN alias to be deprecated at a later stage{ 'TDVIA', 'TDVİA' }, --alias name without diacritics{ 'tdvia', 'TDVİA' }, --lowercase variant without diacritics}-- Deprecated aliases to p.conf; tracked in [[Category:Wikipedia articles with deprecated authority control identifiers]]-- Format: { 'deprecated parameter name', 'replacement parameter name in p.conf' }p.deprecated = {{ 'GKD', 'GND' },{ 'PND', 'GND' },{ 'RLS', 'RSL' },{ 'SWD', 'GND' },{ 'NARA-organization', 'NARA' },{ 'NARA-person', 'NARA' },}--[[==========================================================================]]--[[                                   Main                                   ]]--[[==========================================================================]]function p.authorityControl( frame )local resolveEntity = require( "Module:ResolveEntityId" )local parentArgs = frame:getParent().args --WD IDs added here laterlocal iParentArgs = 0 --count original/manual parent args only laterlocal worldcatCat = ''local multipleIdCat = ''local suppressedIdCat = ''local deprecatedIdCat = ''local differentOnWDCat = ''local sameOnWDCat = ''--Redirect aliases to proper parameter namesfor _, a in pairs( p.aliases ) dolocal alias, param = a[1], a[2]if (parentArgs[param] == nil or parentArgs[param] == '') and parentArgs[alias] thenparentArgs[param] = parentArgs[alias]endend--Redirect deprecated parameters to proper parameter names, and assign tracking catfor _, d in pairs( p.deprecated ) dolocal dep, param = d[1], d[2]if (parentArgs[param] == nil or parentArgs[param] == '') and parentArgs[dep] thenparentArgs[param] = parentArgs[dep]if namespace == 0 thendeprecatedIdCat = '[[Category:Wikipedia articles with deprecated authority control identifiers|'..dep..']]'endendend--Use QID= parameter for testing/example purposes onlylocal itemId = nilif namespace ~= 0 thenlocal qid = parentArgs['qid'] or parentArgs['QID']if qid thenitemId = 'Q'..mw.ustring.gsub(qid, '^[Qq]', '')itemId = resolveEntity._id(itemId) --nil if unresolvableendelseitemId = mw.wikibase.getEntityIdForCurrentPage()end--Wikidata fallback if availableif itemId thenlocal iMatches = 0for _, params in ipairs( p.conf ) doif params[2] > 0 thenlocal val = parentArgs[mw.ustring.lower(params[1])] or parentArgs[params[1]]if val == nil or val == '' thenlocal canUseWikidata = nilif reqs[params[1]] then--since reqs{} has been nil afaicr, p.matchesWikidataRequirements will never be called--TODO: reqs{} doesn't seem useful/necessary; appendage of early WD incorporation?canUseWikidata = p.matchesWikidataRequirements( itemId, reqs[params[1]] )elsecanUseWikidata = trueendif canUseWikidata thenlocal wikidataIds = p.getIdsFromWikidata( itemId, 'P'..params[2] )if wikidataIds[1] thenif val == '' and (namespace == 0 or testcases) thensuppressedIdCat = '[[Category:Wikipedia articles with suppressed authority control identifiers|'..params[1]..']]'elseparentArgs[params[1]] = wikidataIds[1] --add ID from WDendendendelseiParentArgs = iParentArgs + 1local wikidataIds = p.getIdsFromWikidata( itemId, 'P'..params[3] )if wikidataIds[1] and differentOnWDCat == '' thenlocal bMatch = falsefor _, wd in pairs( wikidataIds ) doif val == wd theniMatches = iMatches + 1bMatch = trueendendif bMatch == false thendifferentOnWDCat = '[[Category:Pages using authority control with parameters different on Wikidata|'..params[1]..']]'endendendendendif iMatches > 0 and iMatches == iParentArgs thensameOnWDCat = '[[Category:Pages using authority control with parameters all matching Wikidata]]'endend--Configured rowslocal rct = 0local sectionOrder = {"General","National libraries","Art galleries and museums",  "Art research institutes","Biographical dictionaries","Scientific databases",  "Other"}local sections = {["General"] = {},["National libraries"] = {},["Art galleries and museums"] = {},["Art research institutes"] = {},["Biographical dictionaries"] = {},["Scientific databases"] = {},["Other"] = {}}-- Don't show NLP is PLWABN is present, since they both go to the National Library of Poland-- and the library has deprecated NLP IDs in favor of PLWABN IDsif parentArgs.PLWABN or parentArgs.plwabn thenparentArgs.NLP = nilparentArgs.nlp = nilendfor _, params in ipairs( p.conf ) dolocal val = parentArgs[mw.ustring.lower(params[1])] or parentArgs[params[1]]local tval, tlinks = {}, {} --init tablesif val and val ~= '' and type(params[3]) == 'function' thentable.insert( tval, val )if params.prefix then table.insert( tlinks, params[3]( val, "1" ) )elsetable.insert( tlinks, params[3]( val ) )endend--collect other unique vals (IDs) from WD, if presentif itemId and tval[1] thenlocal nextIdVal = 2local wikidataIds = p.getIdsFromWikidata( itemId, 'P'..params[2] )for _, v in pairs( wikidataIds ) dolocal bnew = truefor _, w in pairs( tval ) doif v == w then bnew = false endendif bnew thentable.insert( tval, v )table.insert( tlinks, params[3]( v, tostring(nextIdVal) ) )nextIdVal = nextIdVal + 1endendend--assembleif tval[1] thentable.insert( sections[params[4]], p.createRow( params[1], tval, nil, tlinks, true, params.category, params.prefix) )rct = rct + 1if tval[2] thenmultipleIdCat = p.getCatForId( 'multiple' )endendend--WorldCatlocal worldcatId = parentArgs['worldcatid'] or parentArgs['WORLDCATID']if worldcatId and worldcatId ~= '' then --if WORLDCATID present & unsuppressedtable.insert( sections["General"], p.createRow( 'WORLDCATID', worldcatId, '[https://www.worldcat.org/identities/'..mw.uri.encode(worldcatId, 'PATH')..' WorldCat]', nil, false ) ) --Validation?worldcatCat = p.getCatForId( 'WORLDCATID' )elseif worldcatId == nil then --if WORLDCATID absent but unsuppressedlocal viafId = parentArgs['viaf'] or parentArgs['VIAF']local lccnId = parentArgs['lccn'] or parentArgs['LCCN']if viafId and viafId ~= '' and p.viafLink( viafId ) then --VIAF must be present, unsuppressed, & validatedtable.insert( sections["General"], p.createRow( 'VIAF', viafId, '[https://www.worldcat.org/identities/containsVIAFID/'..viafId..' WorldCat (via VIAF)]', nil, false ) )if namespace == 0 then worldcatCat = '[[Category:Wikipedia articles with WorldCat-VIAF identifiers]]'endelseif lccnId and lccnId ~= '' and p.lccnLink( lccnId ) then --LCCN must be present, unsuppressed, & validatedlocal lccnParts = p.splitLccn( lccnId )if lccnParts and lccnParts[1] ~= 'sh' thenlocal lccnIdFmtd = lccnParts[1]..lccnParts[2]..'-'..lccnParts[3]table.insert( sections["General"], p.createRow( 'LCCN', lccnId, '[https://www.worldcat.org/identities/lccn-'..lccnIdFmtd..' WorldCat (via Library of Congress)]', nil, false ) )if namespace == 0 thenworldcatCat = '[[Category:Wikipedia articles with WorldCat-LCCN identifiers]]'endendendelseif worldcatId == '' then --if WORLDCATID suppressedsuppressedIdCat = '[[Category:Wikipedia articles with suppressed authority control identifiers|WORLDCATID]]'endlocal Navbox = require('Module:Navbox')local elementsCat = ''if rct == 0 or rct >= 25 thenlocal eCat = 'AC with '..rct..' elements'elementsCat  = '[[Category:'..eCat..']]'..p.redCatLink(eCat)endlocal outString = ''if rct > 0 thenlocal sectionID = 1local args = { pid = 'identifiers' } -- #target the list of identifiersif testcases and itemId then args = { pid = 'identifiers', qid = itemId } end --expensivelocal pencil = frame:expandTemplate{ title = 'EditAtWikidata', args = args}local navboxArgs = {name  = 'Authority control',navboxclass = 'authority-control',bodyclass = 'hlist',state = 'off',navbar = 'off'}for _, sectName in ipairs(sectionOrder) doif #sections[sectName] ~= 0 thennavboxArgs["group" .. sectionID] = sectNamenavboxArgs["list" .. sectionID] = table.concat(sections[sectName])sectionID = sectionID + 1endendif navboxArgs.group2 thenif rct >= 4 then navboxArgs.title = "[[Help:Authority control|Authority control]]" .. pencilelsenavboxArgs.border = "child"navboxArgs = {group1 = "[[Help:Authority control|Authority control]]" .. pencil,list1 = Navbox._navbox(navboxArgs)}endelselocal sect = navboxArgs.group1if sect == "General" or sect == "Other" then-- Just say "Authority control" with no label if only general or only other IDs are present-- since "general" is redundant and "other" is silly when there's nothing to contrast it withnavboxArgs.group1 = "[[Help:Authority control|Authority control]]" .. pencilelse navboxArgs.group1 = "[[Help:Authority control|Authority control: " .. sect .. "]] " .. pencilendendoutString = Navbox._navbox(navboxArgs)endlocal auxCats = worldcatCat .. elementsCat .. multipleIdCat .. suppressedIdCat .. deprecatedIdCat .. differentOnWDCat .. sameOnWDCatif testcases thenauxCats = mw.ustring.gsub(auxCats, '(%[%[)(Category)', '%1:%2') --for easier checkingendoutString = outString .. auxCatsif namespace ~= 0 thenoutString = mw.ustring.gsub(outString, '(%[%[)(Category:Wikipedia articles)', '%1:%2') --by definitionendreturn outStringendreturn p