Module:Authority control: திருத்தங்களுக்கு இடையிலான வேறுபாடு
Jump to navigation
Jump to search
உள்ளடக்கம் நீக்கப்பட்டது உள்ளடக்கம் சேர்க்கப்பட்டது
imported>Lingam No edit summary |
imported>Lingam No edit summary |
||
| வரிசை 1: | வரிசை 1: | ||
require(' |
require('Module:No globals') |
||
local p = {} |
local p = {} |
||
local arg = mw.getCurrentFrame().args.config |
|||
local configfile = 'Module:Authority control/config' .. (arg and arg~='' and ('/' .. arg) or '') |
|||
local config = mw.loadData(configfile) |
|||
local title = mw.title.getCurrentTitle() |
|||
local namespace = title.namespace |
|||
local testcases = title.subpageText == config.i18n.testcases |
|||
--[[==========================================================================]] |
|||
local function needsAttention(sortkey) |
|||
--[[ Category functions ]] |
|||
return '[[' .. config.i18n.category .. ':' .. config.i18n.attentioncat .. '|' .. sortkey .. title.text .. ']]' |
|||
--[[==========================================================================]] |
|||
end |
|||
function p.getCatForId( id ) |
|||
local title = mw.title.getCurrentTitle() |
|||
if cat and cat ~= '' and (namespace == 0 or namespace == 14 or testcases) then |
|||
local namespace = title.namespace |
|||
local catName = '' |
|||
if testcases == false then |
|||
if namespace == 0 then |
|||
local success, exists = pcall(function() return mw.title.new(cat, 14).exists end) |
|||
catName = 'Wikipedia articles with ' .. id .. ' identifiers' |
|||
if success and not exists then |
|||
elseif namespace == 2 and not title.isSubpage then |
|||
redlinkcat = needsAttention('N') |
|||
catName = 'User pages with ' .. id .. ' identifiers' |
|||
end |
|||
end |
|||
if sortkey then |
|||
cat = '[[' .. config.i18n.category .. ':'..cat..'|' .. sortkey .. title.text .. ']]' |
|||
else |
|||
cat = '[[' .. config.i18n.category .. ':'..cat..']]' |
|||
end |
|||
cat = cat .. redlinkcat |
|||
return cat |
|||
else |
else |
||
catName = 'Miscellaneous pages with ' .. id .. ' identifiers' |
|||
return '' |
|||
end |
end |
||
return '[[Category:' .. catName .. ']]' .. p.redCatLink(catName) |
|||
end |
end |
||
function p.redCatLink( catName ) --catName == 'Blah', not 'Category:Blah', not '[[Category:Blah]]' |
|||
local function getCatForId(id,faulty) |
|||
if catName and catName ~= '' and mw.title.new(catName, 14).exists == false then |
|||
local cat = string.format( |
|||
return '[[Category:Pages with red-linked authority control categories]]' |
|||
config.i18n.cat, |
|||
end |
|||
(faulty and config.i18n.faulty..' ' or '') .. id |
|||
return '' |
|||
) |
|||
return addCat(cat) |
|||
end |
end |
||
--[[==========================================================================]] |
|||
local function getIdsFromWikidata(qid,property) |
|||
--[[ Property formatting functions ]] |
|||
local function getquals(statement,qualid) |
|||
--[[==========================================================================]] |
|||
if statement.qualifiers and statement.qualifiers['P'..qualid] then |
|||
return mw.wikibase.renderSnak(statement.qualifiers['P'..qualid][1]) |
|||
function p.iaafLink( id ) |
|||
else |
|||
--P1146's format regex: [1-9][0-9]* (e.g. 123) |
|||
return false |
|||
if not string.match( id, '^[1-9]%d*$' ) then |
|||
end |
|||
return false |
|||
end |
end |
||
return '[https://www.iaaf.org/athletes/biographies/athcode='..id..' '..id..']'..p.getCatForId( 'IAAF' ) |
|||
local ids = {} |
|||
end |
|||
if qid then |
|||
for _, statement in ipairs(mw.wikibase.getBestStatements(qid,property)) do |
|||
function p.viafLink( id ) |
|||
if statement.mainsnak.datavalue then |
|||
--P214's format regex: [1-9]\d(\d{0,7}|\d{17,20}) (e.g. 123456789, 1234567890123456789012) |
|||
local val = statement.mainsnak.datavalue.value |
|||
if not string.match( id, '^[1-9]%d%d?%d?%d?%d?%d?%d?%d?$' ) and |
|||
if val then |
|||
not string.match( id, '^[1-9]%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d?%d?%d?$' ) then |
|||
local namedas = getquals(statement,1810) or getquals(statement,742) or '' |
|||
return false |
|||
table.insert(ids,{id=val,name=namedas}) |
|||
end |
|||
end |
|||
end |
|||
end |
end |
||
return '[https://viaf.org/viaf/'..id..' '..id..']'..p.getCatForId( 'VIAF' ) |
|||
return ids |
|||
end |
end |
||
function p.kulturnavLink( id ) |
|||
local _makelink = function(conf,val,nextid,qid) --validate values and create a link |
|||
--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) |
|||
local function tooltip(text,label) |
|||
if not string.match( id, '^%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 |
|||
if label and label~='' then |
|||
return false |
|||
return mw.getCurrentFrame():expandTemplate{title = "Tooltip", args = {text,label}} |
|||
else |
|||
return text |
|||
end |
|||
end |
end |
||
return '[http://kulturnav.org/'..id..' '..id..']'..p.getCatForId( 'KULTURNAV' ) --no https yet (10/2018) |
|||
local link |
|||
end |
|||
if nextid==1 then |
|||
if conf.prefix then |
|||
function p.sikartLink( id ) |
|||
link = '*' .. conf.prefix .. '\n**' |
|||
--P781's format regex: \d{7,9} (e.g. 123456789) |
|||
else |
|||
if not string.match( id, '^%d%d%d%d%d%d%d%d?%d?$' ) then |
|||
link = '*' |
|||
return false |
|||
end |
|||
else |
|||
link = '\n**' |
|||
end |
end |
||
return '[http://www.sikart.ch/KuenstlerInnen.aspx?id='..id..'&lng=en '..id..']'..p.getCatForId( 'SIKART' ) --no https yet (10/2018) |
|||
local valid_value = false |
|||
end |
|||
if conf.customlink then -- use function to validate and generate link |
|||
local label = nextid>1 and nextid |
|||
function p.tlsLink( id ) |
|||
local newlink= require(config.auxiliary)[conf.customlink](val.id,label) |
|||
local id2 = id:gsub(' +', '_') |
|||
if newlink then |
|||
--P1362's format regex: \p{Lu}[\p{L}\d_',\.\-\(\)\*/–]{3,59} (e.g. Abcd) |
|||
link = link .. newlink |
|||
local class = "[%a%d_',%.%-%(%)%*/–]" |
|||
valid_value = true |
|||
local regex = "^%u"..string.rep(class, 3)..string.rep(class.."?", 56).."$" |
|||
end |
|||
if not mw.ustring.match( id2, regex ) then |
|||
else |
|||
return false |
|||
if conf.pattern then -- use pattern to determine validity if defined |
|||
valid_value = string.match(val.id,'^'..conf.pattern..'$') |
|||
elseif conf.patterns then |
|||
for _,pattern in ipairs(conf.patterns) do |
|||
valid_value = val.id:match('^'..pattern..'$') |
|||
if valid_value then break end |
|||
end |
|||
elseif conf.valid then -- otherwise use function to determine validity |
|||
valid_value = require(config.auxiliary)[conf.valid](val.id) |
|||
else -- no validation possible |
|||
valid_value = val.id |
|||
end |
|||
if valid_value then |
|||
local newlink |
|||
local label = conf.label |
|||
if not label or nextid>1 then |
|||
label = tostring(nextid) |
|||
end |
|||
if conf.link then |
|||
valid_value = valid_value:gsub('%%', '%%%%') |
|||
newlink = '[' .. mw.ustring.gsub(conf.link,'%$1',valid_value) .. ' ' .. label .. ']' |
|||
else |
|||
newlink = valid_value |
|||
end |
|||
link = link .. '<span class="uid">'..tooltip(newlink,val.name)..'</span>' |
|||
end |
|||
end |
end |
||
return '[http://tls.theaterwissenschaft.ch/wiki/'..id2..' '..id..']'..p.getCatForId( 'TLS' ) --no https yet (10/2018) |
|||
if valid_value then |
|||
end |
|||
link = link .. getCatForId(conf.category or conf[1]) |
|||
else |
|||
function p.ciniiLink( id ) |
|||
--local preview = require("Module:If preview") |
|||
--P271's format regex: DA\d{7}[\dX] (e.g. DA12345678) |
|||
local wdlink = qid and '[[:wikidata:' .. qid .. '#P' .. conf.property .. ']]' or '' |
|||
if not string.match( id, '^DA%d%d%d%d%d%d%d[%dX]$' ) then |
|||
local tooltip = string.format( |
|||
return false |
|||
config.i18n.idnotvalid, |
|||
conf[1], |
|||
val.id |
|||
) |
|||
link = link .. '[[File:' .. config.i18n.warningicon .. '|20px|frameless|link=' .. wdlink .. '|' .. tooltip .. '.]]' |
|||
if conf.errorcat then |
|||
link = link .. addCat(conf.errorcat) |
|||
else |
|||
link = link .. getCatForId(conf.category or conf[1],true) |
|||
end |
|||
link = link .. addCat(config.i18n.allfaultycat,conf[1])-- .. preview._warning({'The '..conf[1]..' id '..val..' is not valid.'}) |
|||
end |
end |
||
return '[https://ci.nii.ac.jp/author/'..id..'?l=en '..id..']'..p.getCatForId( 'CINII' ) |
|||
return link |
|||
end |
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) |
|||
--[[ Main ]] |
|||
if not string.match( id, '^[XF][XF]%d%d%d%d%d?%d?%d?$' ) and |
|||
--[[==========================================================================]] |
|||
not string.match( id, '^a%d%d%d%d%d?%d?%d?$' ) and |
|||
function p.authorityControl(frame) |
|||
not string.match( id, '^bi[mcsv][aoei]%d%d%d%d%d%d%d%d%d%d$' ) and |
|||
local function resolveQID(qid) |
|||
not string.match( id, '^Mi[sm][eoa]%d%d%d%d%d%d%d%d%d%d$' ) then |
|||
if qid then |
|||
return false |
|||
qid = 'Q'..mw.ustring.gsub(qid, '^[Qq]', '') |
|||
if mw.wikibase.isValidEntityId(qid) and mw.wikibase.entityExists(qid) then |
|||
local sitelink = mw.wikibase.getSitelink(qid) |
|||
if sitelink then |
|||
return mw.wikibase.getEntityIdForTitle(sitelink) or mw.wikibase.getEntity(qid).id |
|||
end |
|||
return mw.wikibase.getEntity(qid).id |
|||
end |
|||
end |
|||
end |
end |
||
return '[http://catalogo.bne.es/uhtbin/authoritybrowse.cgi?action=display&authority_id='..id..' '..id..']'..p.getCatForId( 'BNE' ) --no https yet (10/2018) |
|||
local conf = config.config |
|||
end |
|||
local parentArgs = frame:getParent().args |
|||
local auxCats = '' |
|||
function p.uscongressLink( id ) |
|||
local rct = false -- boolean to track if there are any links to be returned |
|||
--P1157's format regex: [A-Z]00[01]\d{3} (e.g. A000123) |
|||
local qid,topic |
|||
if not string.match( id, '^[A-Z]00[01]%d%d%d$' ) then |
|||
local wikilink = function(qid,hideifequal) |
|||
return false |
|||
local label,sitelink = mw.wikibase.getLabel(qid),mw.wikibase.getSitelink(qid) |
|||
if label then |
|||
if sitelink then |
|||
local target = mw.title.new(sitelink) |
|||
if target==title or (target.isRedirect and target.redirectTarget==title) then -- do not link |
|||
return label |
|||
else -- make wikilink to article |
|||
return '[[' .. sitelink .. '|' .. label .. ']]' |
|||
end |
|||
else |
|||
return label |
|||
end |
|||
else |
|||
auxCats = auxCats .. needsAttention('L') |
|||
return qid |
|||
end |
|||
end |
end |
||
return '[http://bioguide.congress.gov/scripts/biodisplay.pl?index='..id..' '..id..']'..p.getCatForId( 'USCongress' ) --no https yet (10/2018) |
|||
if namespace == 0 then |
|||
end |
|||
qid = mw.wikibase.getEntityIdForCurrentPage() |
|||
function p.naraLink( id ) |
|||
--P1225's format regex: ^([1-9]\d{0,7})$ (e.g. 12345678) |
|||
if not string.match( id, '^[1-9]%d?%d?%d?%d?%d?%d?%d?$' ) then |
|||
return false |
|||
end |
end |
||
return '[https://catalog.archives.gov/id/'..id..' '..id..']'..p.getCatForId( 'NARA' ) |
|||
if qid then -- article is connected to Wikidata item |
|||
end |
|||
if parentArgs.qid and (resolveQID(parentArgs.qid) ~= qid) then -- non-matching qid parameter |
|||
auxCats = auxCats .. needsAttention('D') |
|||
function p.botanistLink( id ) |
|||
end |
|||
--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.) |
|||
else -- page is not connected to any Wikidata item |
|||
--not easily/meaningfully implementable in Lua's regex since "(this)?" is not allowed... |
|||
qid = resolveQID(parentArgs.qid) -- check qid parameter if no wikidata item is connected |
|||
if not mw.ustring.match( id, "^[%u%l%d%. '-]+$" ) then --better than nothing |
|||
if qid then -- qid parameter is valid, set topic to display |
|||
return false |
|||
topic = mw.wikibase.getLabel(qid) |
|||
end |
|||
if topic then |
|||
local id2 = id:gsub(' +', '%%20') |
|||
if mw.ustring.lower(title.subpageText) == mw.ustring.lower(topic) then -- suppress topic display if subpagename equals topic up to case change |
|||
return '[https://www.ipni.org/ipni/advAuthorSearch.do?find_abbreviation='..id2..' '..id..']'..p.getCatForId( 'Botanist' ) |
|||
topic = nil |
|||
end |
|||
if topic and mw.wikibase.getSitelink(qid) then -- make wikilink to article |
|||
function p.mgpLink( id ) |
|||
topic = '[[' .. mw.wikibase.getSitelink(qid) .. '|' .. topic .. ']]' |
|||
--P549's format regex: \d{1,6} (e.g. 123456) |
|||
end |
|||
if not string.match( id, '^%d%d?%d?%d?%d?%d?$' ) then |
|||
else |
|||
return false |
|||
auxCats = auxCats .. needsAttention('L') |
|||
end |
|||
return '[http://www.genealogy.ams.org/id.php?id='..id..' '..id..']'..p.getCatForId( 'MGP' ) --no https yet (10/2018) |
|||
end |
|||
function p.rslLink( id ) |
|||
--P947's format regex: \d{1,9} (e.g. 123456789) |
|||
if not string.match( id, '^%d%d?%d?%d?%d?%d?%d?%d?%d?$' ) then |
|||
return false |
|||
end |
|||
return '[http://aleph.rsl.ru/F?func=find-b&find_code=SYS&adjacent=Y&local_base=RSL11&request='..id..'&CON_LNG=ENG '..id..']'..p.getCatForId( 'RSL' ) --no https yet (10/2018) |
|||
end |
|||
function p.leonoreLink( id ) |
|||
--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 false |
|||
end |
|||
return '[http://www.culture.gouv.fr/public/mistral/leonore_fr?ACTION=CHERCHER&FIELD_1=COTE&VALUE_1='..id..' '..id..']'..p.getCatForId( 'Léonore' ) --no https yet (10/2018) |
|||
end |
|||
function p.sbnLink( id ) |
|||
--P396's format regex: IT\\ICCU\\(\d{10}|\D\D[\D\d]\D\\\d{6}) (e.g. IT\ICCU\CFIV\000163) |
|||
if not string.match( id, '^IT\\ICCU\\%d%d%d%d%d%d%d%d%d%d$' ) and |
|||
not string.match( id, '^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 false |
|||
end |
|||
return '[https://opac.sbn.it/opacsbn/opac/iccu/scheda_authority.jsp?bid='..id..' '..id..']'..p.getCatForId( 'SBN' ) |
|||
end |
|||
function p.nkcLink( id ) |
|||
--P691's format regex: [a-z]{2,4}[0-9]{2,14} (e.g. abcd12345678901234) |
|||
if not string.match( id, '^[a-z][a-z][a-z]?[a-z]?%d%d%d?%d?%d?%d?%d?%d?%d?%d?%d?%d?%d?%d?$' ) then |
|||
return false |
|||
end |
|||
return '[https://aleph.nkp.cz/F/?func=find-c&local_base=aut&ccl_term=ica='..id..'&CON_LNG=ENG '..id..']'..p.getCatForId( 'NKC' ) |
|||
end |
|||
function p.nclLink( id ) |
|||
--P1048's format regex: \d+ (e.g. 1081436) |
|||
if not string.match( id, '^%d+$' ) then |
|||
return false |
|||
end |
|||
return '[http://aleweb.ncl.edu.tw/F/?func=accref&acc_sequence='..id..'&CON_LNG=ENG '..id..']'..p.getCatForId( 'NCL' ) --no https yet (10/2018) |
|||
end |
|||
function p.ndlLink( id ) |
|||
--P349's format regex: 0?\d{8} (e.g. 012345678) |
|||
if not string.match( id, '^0?%d%d%d%d%d%d%d%d$' ) then |
|||
return false |
|||
end |
|||
return '[https://id.ndl.go.jp/auth/ndlna/'..id..' '..id..']'..p.getCatForId( 'NDL' ) |
|||
end |
|||
function p.sudocLink( id ) |
|||
--P269's format regex: (\d{8}[\dX]|) (e.g. 026927608) |
|||
if not string.match( id, '^%d%d%d%d%d%d%d%d[%dxX]$' ) then --legacy: allow lowercase 'x' |
|||
return false |
|||
end |
|||
return '[https://www.idref.fr/'..id..' '..id..']'..p.getCatForId( 'SUDOC' ) |
|||
end |
|||
function p.hdsLink( id ) |
|||
--P902's format regex: 50\d{3}|[1-4]\d{4}|[1-9]\d{0,3}| (e.g. 50123) |
|||
if not string.match( id, '^50%d%d%d$' ) and |
|||
not string.match( id, '^[1-4]%d%d%d%d$' ) and |
|||
not string.match( id, '^[1-9]%d?%d?%d?$' ) then |
|||
return false |
|||
end |
|||
return '[http://www.hls-dhs-dss.ch/textes/f/F'..id..'.php '..id..']'..p.getCatForId( 'HDS' ) --no https yet (10/2018) |
|||
end |
|||
function p.lirLink( id ) |
|||
--P886's format regex: \d+ (e.g. 1) |
|||
if not string.match( id, '^%d+$' ) then |
|||
return false |
|||
end |
|||
return '[http://www.e-lir.ch/e-LIR___Lexicon.'..id..'.450.0.html '..id..']'..p.getCatForId( 'LIR' ) --no https yet (10/2018) |
|||
end |
|||
function 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?$' ) then |
|||
id = id:gsub( '^(%l+)(%d+)(%d%d%d%d%d%d)$', '%1/%2/%3' ) |
|||
end |
|||
if id:match( '^%l%l?%l?/%d%d%d?%d?/%d+$' ) then |
|||
return mw.text.split( id, '/' ) |
|||
end |
|||
return false |
|||
end |
|||
function p.append(str, c, length) |
|||
while str:len() < length do |
|||
str = c .. str |
|||
end |
|||
return str |
|||
end |
|||
function p.lccnLink( id ) |
|||
local parts = p.splitLccn( id ) --e.g. n78039510 |
|||
if not parts then |
|||
return false |
|||
end |
|||
local 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..' '..id..']'..p.getCatForId( 'LCCN' ) |
|||
end |
|||
function p.mbaLink( id ) |
|||
--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 string.match( id, '^%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 |
|||
return '[https://musicbrainz.org/artist/'..id..' '..id..']'..p.getCatForId( 'MusicBrainz' ) |
|||
end |
|||
function p.mbareaLink( id ) |
|||
--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 string.match( id, '^%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 |
|||
return '[https://musicbrainz.org/area/'..id..' '..id..']'..p.getCatForId( 'MusicBrainz area' ) |
|||
end |
|||
function p.mbiLink( id ) |
|||
--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 string.match( id, '^%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 |
|||
return '[https://musicbrainz.org/instrument/'..id..' '..id..']'..p.getCatForId( 'MusicBrainz instrument' ) |
|||
end |
|||
function p.mblLink( id ) |
|||
--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 string.match( id, '^%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 |
|||
return '[https://musicbrainz.org/label/'..id..' '..id..']'..p.getCatForId( 'MusicBrainz label' ) |
|||
end |
|||
function p.mbpLink( id ) |
|||
--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 string.match( id, '^%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 |
|||
return '[https://musicbrainz.org/place/'..id..' '..id..']'..p.getCatForId( 'MusicBrainz place' ) |
|||
end |
|||
function p.mbrgLink( id ) |
|||
--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 string.match( id, '^%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 |
|||
return '[https://musicbrainz.org/release-group/'..id..' '..id..']'..p.getCatForId( 'MusicBrainz release group' ) |
|||
end |
|||
function p.mbsLink( id ) |
|||
--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 string.match( id, '^%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 |
|||
return '[https://musicbrainz.org/series/'..id..' '..id..']'..p.getCatForId( 'MusicBrainz series' ) |
|||
end |
|||
function p.mbwLink( id ) |
|||
--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 string.match( id, '^%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 |
|||
return '[https://musicbrainz.org/work/'..id..' '..id..']'..p.getCatForId( 'MusicBrainz work' ) |
|||
end |
|||
--Returns the ISNI check digit isni must be a string where the 15 first elements are digits, e.g. 0000000066534145 |
|||
function p.getIsniCheckDigit( isni ) |
|||
local total = 0 |
|||
for i = 1, 15 do |
|||
local digit = isni:byte( i ) - 48 --Get integer value |
|||
total = (total + digit) * 2 |
|||
end |
|||
local remainder = total % 11 |
|||
local result = (12 - remainder) % 11 |
|||
if result == 10 then |
|||
return "X" |
|||
end |
|||
return 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-identifier |
|||
function 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]$' ) then |
|||
return false |
|||
end |
|||
if p.getIsniCheckDigit( id ) ~= string.char( id:byte( 16 ) ) then |
|||
return false |
|||
end |
|||
return id |
|||
end |
|||
function p.isniLink( id ) |
|||
id = p.validateIsni( id ) --e.g. 0000-0000-6653-4145 |
|||
if not id then |
|||
return false |
|||
end |
|||
return '[http://isni.org/isni/'..id..' '..id:sub( 1, 4 )..' '..id:sub( 5, 8 )..' '..id:sub( 9, 12 )..' '..id:sub( 13, 16 )..']'..p.getCatForId( 'ISNI' ) --no https yet (10/2018) |
|||
end |
|||
function p.orcidLink( id ) |
|||
id = p.validateIsni( id ) --e.g. 0000-0002-7398-5483 |
|||
if not id then |
|||
return false |
|||
end |
|||
id = id:sub( 1, 4 )..'-'..id:sub( 5, 8 )..'-'..id:sub( 9, 12 )..'-'..id:sub( 13, 16 ) |
|||
return '[https://orcid.org/'..id..' '..id..']'..p.getCatForId( 'ORCID' ) |
|||
end |
|||
function p.gndLink( id ) |
|||
--P227's format regex: (1|1[01])\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 string.match( id, '^1[01]?%d%d%d%d%d%d%d[0-9X]$' ) and |
|||
not string.match( id, '^[47]%d%d%d%d%d%d%-%d$' ) and |
|||
not string.match( id, '^[1-9]%d?%d?%d?%d?%d?%d?%d?%-[0-9X]$' ) and |
|||
not string.match( id, '^3%d%d%d%d%d%d%d[0-9X]$' ) then |
|||
return false |
|||
end |
|||
return '[https://d-nb.info/gnd/'..id..' '..id..']'..p.getCatForId( 'GND' ) |
|||
end |
|||
function p.selibrLink( id ) |
|||
--P906's format regex: [1-9]\d{4,5} (e.g. 123456) |
|||
if not string.match( id, '^[1-9]%d%d%d%d%d?$' ) then |
|||
return false |
|||
end |
|||
return '[https://libris.kb.se/auth/'..id..' '..id..']'..p.getCatForId( 'SELIBR' ) |
|||
end |
|||
function p.bnfLink( id ) |
|||
--P268's format regex: \d{8}[0-9bcdfghjkmnpqrstvwxz] (e.g. 123456789) |
|||
if not string.match( id, '^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 string.match( id, '^cb.+$' ) then |
|||
id = 'cb'..id |
|||
end |
|||
return '[https://catalogue.bnf.fr/ark:/12148/'..id..' '..id..'] [http://data.bnf.fr/ark:/12148/'..id..' (data)]'..p.getCatForId( 'BNF' ) |
|||
end |
|||
function p.bpnLink( id ) |
|||
--P651's format regex: \d{8} (e.g. 12345678) |
|||
if not string.match( id, '^%d%d%d%d%d%d%d%d$' ) then |
|||
return false |
|||
end |
|||
return '[http://www.biografischportaal.nl/en/persoon/'..id..' '..id..']'..p.getCatForId( 'BPN' ) --no https yet (10/2018) |
|||
end |
|||
function p.ridLink( id ) |
|||
--P1053's format regex: [A-Z]-\d{4}-(19|20)\d\d (e.g. A-1234-1934) |
|||
if not string.match( id, '^[A-Z]%-%d%d%d%d%-19%d%d$' ) and |
|||
not string.match( id, '^[A-Z]%-%d%d%d%d%-20%d%d$' ) then |
|||
return false |
|||
end |
|||
return '[https://www.researcherid.com/rid/'..id..' '..id..']'..p.getCatForId( 'RID' ) |
|||
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 string.match( id, '^[1-9]%d?%d?%d?%d?%d?%d?%d?%d?$' ) and |
|||
not string.match( id, '^[1-9]%d%d%d%d%d%d%d%d%d%d%d%d$' ) then |
|||
return false |
|||
end |
|||
return '[https://authority.bibsys.no/authority/rest/authorities/html/'..id..' '..id..']'..p.getCatForId( 'BIBSYS' ) |
|||
end |
|||
function p.ulanLink( id ) |
|||
--P245's format regex: 500\d{6} (e.g. 500123456) |
|||
if not string.match( id, '^500%d%d%d%d%d%d$' ) then |
|||
return false |
|||
end |
|||
return '[https://www.getty.edu/vow/ULANFullDisplay?find=&role=&nation=&subjectid='..id..' '..id..']'..p.getCatForId( 'ULAN' ) |
|||
end |
|||
function p.nlaLink( id ) |
|||
--P409's format regex: [1-9][0-9]{0,11} (e.g. 123456789012) |
|||
if not string.match( id, '^[1-9]%d?%d?%d?%d?%d?%d?%d?%d?%d?%d?%d?$' ) then |
|||
return false |
|||
end |
|||
return '[https://nla.gov.au/anbd.aut-an'..id..' '..id..']'..p.getCatForId( 'NLA' ) |
|||
end |
|||
function p.rkdartistsLink( id ) |
|||
--P650's format regex: [1-9]\d{0,5} (e.g. 123456) |
|||
if not string.match( id, '^[1-9]%d?%d?%d?%d?%d?$' ) then |
|||
return false |
|||
end |
|||
return '[https://rkd.nl/en/explore/artists/'..id..' '..id..']'..p.getCatForId( 'RKDartists' ) |
|||
end |
|||
function p.snacLink( id ) |
|||
--P3430's format regex: \d*[A-Za-z][0-9A-Za-z]* (e.g. A) |
|||
if not string.match( id, '^%d*[A-Za-z][0-9A-Za-z]*$' ) then |
|||
return false |
|||
end |
|||
return '[http://socialarchive.iath.virginia.edu/ark:/99166/'..id..' '..id..']'..p.getCatForId( 'SNAC-ID' ) --no https yet (10/2018) |
|||
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 string.match( id, '^%d%d%d?/%d+$' ) and |
|||
not string.match( id, '^%d%d%d?/%d+%-%d+$' ) and |
|||
not string.match( id, '^[a-z]/[a-zA-Z][0-9A-Za-z]*$' ) and |
|||
not string.match( id, '^[a-z]/[a-zA-Z][0-9A-Za-z]*%-%d+$' ) then |
|||
return false |
|||
end |
|||
return '[https://dblp.org/pid/'..id..' '..id..']'..p.getCatForId( 'DBLP' ) |
|||
end |
|||
function p.acmLink( id ) |
|||
--P864's format regex: \d{11} (e.g. 12345678901) |
|||
if not string.match( id, '^%d%d%d%d%d%d%d%d%d%d%d$' ) then |
|||
return false |
|||
end |
|||
return '[https://dl.acm.org/author_page.cfm?id='..id..' '..id..']'..p.getCatForId( 'ACM-DL' ) |
|||
end |
|||
function p.autoresuyLink( id ) |
|||
--P2558's format regex: [1-9]\d{0,4} (e.g. 12345) |
|||
if not string.match( id, '^[1-9]%d?%d?%d?%d?$' ) then |
|||
return false |
|||
end |
|||
return '[https://autores.uy/autor/'..id..' '..id..']'..p.getCatForId( 'autores.uy' ) |
|||
end |
|||
function p.picLink( id ) |
|||
--P2750's format regex: [1-9]\d* (e.g. 1) |
|||
if not string.match( id, '^[1-9]%d*$' ) then |
|||
return false |
|||
end |
|||
return '[https://pic.nypl.org/constituents/'..id..' '..id..']'..p.getCatForId( 'PIC' ) |
|||
end |
|||
function p.bildLink( id ) |
|||
--P2092's format regex: \d+ (e.g. 1) |
|||
if not string.match( id, '^%d+$' ) then |
|||
return false |
|||
end |
|||
return '[https://www.bildindex.de/document/obj'..id..' '..id..']'..p.getCatForId( 'Bildindex' ) |
|||
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 string.match( id, regex ) then |
|||
return false |
|||
end |
|||
return '[http://www2.culture.gouv.fr/public/mistral/joconde_fr?ACTION=CHERCHER&FIELD_1=REF&VALUE_1='..id..' '..id..']'..p.getCatForId( 'Joconde' ) --no https yet (10/2018) |
|||
end |
|||
function p.rkdidLink( id ) |
|||
--P350's format regex: [1-9]\d{0,5} (e.g. 123456) |
|||
if not string.match( id, '^[1-9]%d?%d?%d?%d?%d?$' ) then |
|||
return false |
|||
end |
|||
return '[https://rkd.nl/nl/explore/images/'..id..' '..id..']'..p.getCatForId( 'RKDID' ) |
|||
end |
|||
function p.balatLink( id ) |
|||
--P3293's format regex: \d+ (e.g. 1) |
|||
if not string.match( id, '^%d+$' ) then |
|||
return false |
|||
end |
|||
return '[http://balat.kikirpa.be/object/104257'..id..' '..id..']'..p.getCatForId( 'BALaT' ) --no https yet (10/2018) |
|||
end |
|||
function p.lnbLink( id ) |
|||
--P1368's format regex: \d{9} (e.g. 123456789) |
|||
if not string.match( id, '^%d%d%d%d%d%d%d%d%d$' ) then |
|||
return false |
|||
end |
|||
return '[https://kopkatalogs.lv/F?func=direct&local_base=lnc10&doc_number='..id..'&P_CON_LNG=ENG '..id..']'..p.getCatForId( 'LNB' ) |
|||
end |
|||
function p.nskLink( id ) |
|||
--P1375's format regex: \d{9} (e.g. 123456789) |
|||
if not string.match( id, '^%d%d%d%d%d%d%d%d%d$' ) then |
|||
return false |
|||
end |
|||
return '[http://katalog.nsk.hr/F/?func=direct&doc_number='..id..'&local_base=nsk10 '..id..']'..p.getCatForId( 'NSK' ) --no https yet (10/2018) |
|||
end |
|||
function p.iciaLink( id ) |
|||
--P1736's format regex: \d+ (e.g. 1) |
|||
if not string.match( id, '^%d+$' ) then |
|||
return false |
|||
end |
|||
return '[https://www.imj.org.il/artcenter/newsite/en/?artist='..id..' '..id..']'..p.getCatForId( 'ICIA' ) |
|||
end |
|||
function p.ta98Link( id ) |
|||
--P1323's format regex: A\d{2}\.\d\.\d{2}\.\d{3}[FM]? (e.g. A12.3.45.678) |
|||
if not string.match( id, '^A%d%d%.%d%.%d%d%.%d%d%d[FM]?$' ) then |
|||
return false |
|||
end |
|||
return '[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..' '..id..']'..p.getCatForId( 'TA98' ) |
|||
end |
|||
function p.teLink( id ) |
|||
--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 = string.match( id, '^E([1-8])%.(%d%d?)%.%d%d?%.%d%d?%.%d%.%d%.%d%d?%d?$' ) |
|||
if not e1 then |
|||
return false |
|||
end |
|||
local TEnum = 'TEe0'..e1 --no formatter URL in WD, probably due to this complexity |
|||
if e1 == '5' or e1 == '7' then |
|||
if #e2 == 1 then e2 = '0'..e2 end |
|||
TEnum = TEnum..e2 |
|||
end |
|||
return '[http://www.unifr.ch/ifaa/Public/EntryPage/ViewTE/'..TEnum..'.html '..id..']'..p.getCatForId( 'TE' ) |
|||
end |
|||
function p.thLink( id ) |
|||
--P1694's format regex: H\d\.\d{2}\.\d{2}\.\d\.\d{5} (e.g. H1.23.45.6.78901) |
|||
local h1, h2 = string.match( id, '^H(%d)%.(%d%d)%.%d%d%.%d%.%d%d%d%d%d$' ) |
|||
if not h1 then |
|||
return false |
|||
end |
|||
local THnum = 'THh'..h1..h2 --no formatter URL in WD, probably due to this complexity |
|||
return '[http://www.unifr.ch/ifaa/Public/EntryPage/ViewTH/'..THnum..'.html '..id..']'..p.getCatForId( 'TH' ) |
|||
end |
|||
--[[==========================================================================]] |
|||
--[[ Wikidata, navigation bar, and documentation functions ]] |
|||
--[[==========================================================================]] |
|||
function p.getIdsFromWikidata( itemId, property ) |
|||
local ids = {} |
|||
local statements = mw.wikibase.getBestStatements( itemId, property ) |
|||
if statements then |
|||
for _, statement in ipairs( statements ) do |
|||
if statement.mainsnak.datavalue then |
|||
table.insert( ids, statement.mainsnak.datavalue.value ) |
|||
end |
end |
||
elseif parentArgs.qid and parentArgs.qid~='' then -- invalid qid has been supplied, add to tracking cat |
|||
auxCats = auxCats .. needsAttention('Q') |
|||
end |
end |
||
end |
end |
||
return ids |
|||
local qids = {} -- setup any additional QIDs |
|||
end |
|||
if parentArgs.additional=='auto' and qid then -- check P527 for parts to add additional qids |
|||
local checkparts = function(property) |
|||
function p.matchesWikidataRequirements( itemId, reqs ) |
|||
local parts = mw.wikibase.getBestStatements(qid,property) |
|||
for _, group in ipairs( reqs ) do |
|||
if parts then |
|||
local property = 'P' .. group[1] |
|||
for _,part in ipairs(parts) do |
|||
local qid = group[2] |
|||
if part.mainsnak.datavalue and part.mainsnak.datavalue.value.id then |
|||
local statements = mw.wikibase.getBestStatements( itemId, property ) |
|||
local resolvedqid = resolveQID(part.mainsnak.datavalue.value.id) |
|||
if statements then |
|||
for _, statement in ipairs( statements ) do |
|||
table.insert(qids,resolvedqid) |
|||
if statement.mainsnak.datavalue then |
|||
end end end end end |
|||
if statement.mainsnak.datavalue.value['numeric-id'] == qid then |
|||
for _,part in ipairs(config.auto_additional) do |
|||
return true |
|||
checkparts('P'..tostring(part)) |
|||
end |
end end end end end |
||
return false |
|||
elseif parentArgs.additional and parentArgs.additional ~= '' then |
|||
end |
|||
for _,v in ipairs(mw.text.split(parentArgs.additional,"%s*,%s*")) do |
|||
v = resolveQID(v) |
|||
function p.createRow( id, label, rawValue, link, withUid ) |
|||
if v then |
|||
if link then |
|||
if v == qid then -- duplicate of qid parameter |
|||
if withUid then |
|||
auxCats = auxCats .. needsAttention('R') |
|||
return '*<span class="nowrap">' .. label .. ' <span class="uid">' .. link .. '</span></span>\n' |
|||
end |
|||
table.insert(qids,v) |
|||
else -- invalid QID specified |
|||
auxCats = auxCats .. needsAttention('A') |
|||
end |
|||
end |
end |
||
return '*<span class="nowrap">' .. label .. ' ' .. link .. '</span>\n' |
|||
end |
end |
||
local catName = 'Wikipedia articles with faulty ' .. id .. ' identifiers' |
|||
local sections = {} |
|||
return '* <span class="error">The ' .. id .. ' id ' .. rawValue .. ' is not valid.</span>[[Category:' .. catName .. ']]' .. p.redCatLink(catName) .. '\n' |
|||
local localparams = false |
|||
end |
|||
local numsections = 0 |
|||
for _,_ in ipairs(config.sections) do numsections = numsections + 1 end |
|||
for _ = 1,#qids+numsections do table.insert(sections,{}) end |
|||
local qslink = '' -- setup link to add using QuickStatements |
|||
-- Creates a human-readable standalone wikitable version of p.conf, and tracking categories with page counts, for use in the documentation |
|||
-- check which identifiers to show/suppress in template |
|||
function p.docConfTable( frame ) |
|||
local show = {} -- setup list |
|||
local wikiTable = '{| class="wikitable sortable"\n' .. |
|||
local showall = true |
|||
'! rowspan=2 | Parameter\n' .. |
|||
local function stripP(pid) |
|||
'! rowspan=2 | Label\n' .. |
|||
if pid:match("^[Pp]%d+$") then |
|||
'! rowspan=2; data-sort-type=number | Wikidata property\n' .. |
|||
'! colspan=4 | Tracking categories and page counts\n' .. |
|||
end |
|||
'|-\n' .. |
|||
if pid:match("^%d+$") then |
|||
'! Articles\n' .. |
|||
return tonumber(pid) |
|||
'! User pages\n' .. |
|||
'! Misc. pages\n' .. |
|||
'! Faulty IDs\n' .. |
|||
'|-\n' |
|||
local lang = mw.getContentLanguage() |
|||
for _, conf in pairs( p.conf ) do |
|||
local param, link, pid = conf[1], conf[2], conf[3] |
|||
local category = conf.category or param |
|||
local args = { id = 'f', pid } |
|||
local wpl = frame:expandTemplate{ title = 'Wikidata property link', args = args } |
|||
--cats |
|||
local 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' |
|||
--counts |
|||
local 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') ) |
|||
--concat |
|||
wikiTable = wikiTable..'\n'.. |
|||
'|-\n'.. |
|||
'||'..param.. |
|||
'||'..link.. |
|||
'||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 |
|||
return wikiTable .. '\n|}' |
|||
end |
|||
--[[==========================================================================]] |
|||
--[[ Configuration ]] |
|||
--[[==========================================================================]] |
|||
-- Check that the Wikidata item has this property-->value before adding it |
|||
local reqs = {} |
|||
-- Parameter format: { name of the parameter, label, propertyId in Wikidata, formatting function } |
|||
p.conf = { |
|||
{ 'ACM-DL', '[[ACM Digital Library|ACM DL]]', 864, p.acmLink }, |
|||
{ 'autores.uy', '[[autores.uy]]', 2558, p.autoresuyLink }, |
|||
{ 'BALaT', '[[:d:Q2876688|BALaT]]', 3293, p.balatLink }, |
|||
{ 'BIBSYS', '[[Bibsys|BIBSYS]]', 1015, p.bibsysLink }, |
|||
{ 'Bildindex', '[[Marburg Picture Index|Bildindex]]', 2092, p.bildLink }, |
|||
{ 'BNE', '[[Biblioteca Nacional de España|BNE]]', 950, p.bneLink }, |
|||
{ 'BNF', '[[Bibliothèque nationale de France|BNF]]', 268, p.bnfLink }, |
|||
{ 'Botanist', '[[Author citation (botany)|Botanist]]', 428, p.botanistLink }, |
|||
{ 'BPN', '[[Biografisch Portaal|BPN]]', 651, p.bpnLink }, |
|||
{ 'CINII', '[[CiNii]]', 271, p.ciniiLink }, |
|||
{ 'DBLP', '[[DBLP]]', 2456, p.dblpLink }, |
|||
{ 'GND', '[[Integrated Authority File|GND]]', 227, p.gndLink }, |
|||
{ 'HDS', '[[Historical Dictionary of Switzerland|HDS]]', 902, p.hdsLink }, |
|||
{ 'IAAF', '[[International Association of Athletics Federations|IAAF]]', 1146, p.iaafLink }, |
|||
{ 'ICIA', '[[Information Center for Israeli Art|ICIA]]', 1736, p.iciaLink }, |
|||
{ 'ISNI', '[[International Standard Name Identifier|ISNI]]', 213, p.isniLink }, |
|||
{ 'Joconde', '[[Joconde|Joconde]]' , 347, p.jocondeLink }, |
|||
{ 'KULTURNAV', '[[KulturNav]]', 1248, p.kulturnavLink }, |
|||
{ 'LCCN', '[[Library of Congress Control Number|LCCN]]', 244, p.lccnLink }, |
|||
{ 'LIR', '[[Historical Dictionary of Switzerland#Lexicon_Istoric_Retic|LIR]]', 886, p.lirLink }, |
|||
{ 'LNB', '[[National Library of Latvia|LNB]]', 1368, p.lnbLink }, |
|||
{ 'Léonore', '[[Base Léonore|Léonore]]', 640, p.leonoreLink }, |
|||
{ 'MBA', '[[MusicBrainz]]', 434, p.mbaLink, category = 'MusicBrainz' }, |
|||
{ 'MBAREA', '[[MusicBrainz]]', 982, p.mbareaLink, category = 'MusicBrainz area' }, |
|||
{ 'MBI', '[[MusicBrainz]]', 1330, p.mbiLink, category = 'MusicBrainz instrument' }, |
|||
{ 'MBL', '[[MusicBrainz]]', 966, p.mblLink, category = 'MusicBrainz label' }, |
|||
{ 'MBP', '[[MusicBrainz]]', 1004, p.mbpLink, category = 'MusicBrainz place' }, |
|||
{ 'MBRG', '[[MusicBrainz]] release group', 436, p.mbrgLink, category = 'MusicBrainz release group' }, |
|||
{ 'MBS', '[[MusicBrainz]]', 1407, p.mbsLink, category = 'MusicBrainz series' }, |
|||
{ 'MBW', '[[MusicBrainz]] work', 435, p.mbwLink, category = 'MusicBrainz work' }, |
|||
{ 'MGP', '[[Mathematics Genealogy Project|MGP]]', 549, p.mgpLink }, |
|||
{ 'NARA', '[[National Archives and Records Administration|NARA]]', 1225, p.naraLink }, |
|||
{ 'NCL', '[[National Central Library|NCL]]', 1048, p.nclLink }, |
|||
{ 'NDL', '[[National Diet Library|NDL]]', 349, p.ndlLink }, |
|||
{ 'NKC', '[[National Library of the Czech Republic|NKC]]', 691, p.nkcLink }, |
|||
{ 'NLA', '[[National Library of Australia|NLA]]', 409, p.nlaLink }, |
|||
{ 'NSK', '[[National and University Library in Zagreb|NSK]]', 1375, p.nskLink }, |
|||
{ 'ORCID', '[[ORCID]]', 496, p.orcidLink }, |
|||
{ 'PIC', '[[:d:Q23892012|PIC]]', 2750, p.picLink }, |
|||
{ 'RID', '[[ResearcherID]]', 1053, p.ridLink }, |
|||
{ 'RKDartists', '[[Netherlands Institute for Art History#Online artist pages|RKD]]', 650, p.rkdartistsLink }, |
|||
{ 'RKDID', '[[:d:Q17299580|RKDimages ID]]', 350, p.rkdidLink }, |
|||
{ 'RSL', '[[Russian State Library|RSL]]', 947, p.rslLink }, |
|||
{ 'SBN', '[[Istituto Centrale per il Catalogo Unico|ICCU]]', 396, p.sbnLink }, |
|||
{ 'SELIBR', '[[LIBRIS|SELIBR]]', 906, p.selibrLink }, |
|||
{ 'SIKART', '[[SIKART]]', 781, p.sikartLink }, |
|||
{ 'SNAC-ID', '[[SNAC]]', 3430, p.snacLink }, |
|||
{ 'SUDOC', '[[Système universitaire de documentation|SUDOC]]', 269, p.sudocLink }, |
|||
{ 'TA98', '[[Terminologia Anatomica|TA98]]', 1323, p.ta98Link }, |
|||
{ 'TE', '[[Terminologia Embryologica|TE]]', 1693, p.teLink }, |
|||
{ 'TH', '[[Terminologia Histologica|TH]]', 1694, p.thLink }, |
|||
{ 'TLS', '[[Theaterlexikon der Schweiz|TLS]]', 1362, p.tlsLink }, |
|||
{ 'ULAN', '[[Union List of Artist Names|ULAN]]', 245, p.ulanLink }, |
|||
{ 'USCongress', '[[Biographical Directory of the United States Congress|US Congress]]', 1157, p.uscongressLink }, |
|||
{ 'VIAF', '[[Virtual International Authority File|VIAF]]', 214, p.viafLink }, |
|||
} |
|||
-- Legitimate aliases to p.conf, for convenience |
|||
-- Format: { alias, parameter name in p.conf } |
|||
p.aliases = { |
|||
{ 'RLS', 'RSL' }, |
|||
{ 'MusicBrainz', 'MBA' }, |
|||
{ 'MusicBrainz artist', 'MBA' }, |
|||
{ 'MusicBrainz label', 'MBL' }, |
|||
{ 'MusicBrainz release group', 'MBRG' }, |
|||
{ 'MusicBrainz work', 'MBW' }, |
|||
{ 'Leonore', 'Léonore' }, |
|||
} |
|||
-- Deprecated aliases to p.conf, which also get assigned to a tracking cat |
|||
-- Format: { deprecated parameter name, replacement parameter name in p.conf } |
|||
p.deprecated = { |
|||
{ 'GKD', 'GND' }, |
|||
{ 'PND', 'GND' }, |
|||
{ 'SWD', 'GND' }, |
|||
{ 'NARA-organization', 'NARA' }, |
|||
{ 'NARA-person', 'NARA' }, |
|||
} |
|||
--[[==========================================================================]] |
|||
--[[ Main ]] |
|||
--[[==========================================================================]] |
|||
function p.authorityControl( frame ) |
|||
local resolveEntity = require( "Module:ResolveEntityId" ) |
|||
local title = mw.title.getCurrentTitle() |
|||
local namespace = title.namespace |
|||
local talkspace = (mw.site.talkNamespaces[namespace] ~= nil) |
|||
local testcases = (string.sub(title.subpageText,1,9) == 'testcases') |
|||
local parentArgs = frame:getParent().args |
|||
local elements = {} --create/insert rows later |
|||
local worldcatCat = '' |
|||
local suppressedIdCat = '' |
|||
local deprecatedIdCat = '' |
|||
--Redirect aliases to proper parameter names |
|||
for _, a in pairs( p.aliases ) do |
|||
local alias, param = a[1], a[2] |
|||
if (parentArgs[param] == nil or parentArgs[param] == '') and parentArgs[alias] then |
|||
parentArgs[param] = parentArgs[alias] |
|||
end |
end |
||
end |
end |
||
local function addshowlist(list) |
|||
--Redirect deprecated parameters to proper parameter names, and assign tracking cat |
|||
if list and list ~= '' then |
|||
for _, d in pairs( p.deprecated ) do |
|||
local dep, param = d[1], d[2] |
|||
if (parentArgs[param] == nil or parentArgs[param] == '') and parentArgs[dep] then |
|||
if vprop then -- e.g. show=P214 to show one particular property |
|||
parentArgs[param] = parentArgs[dep] |
|||
if namespace == 0 then |
|||
else -- e.g. show=arts to use whitelist |
|||
deprecatedIdCat = '[[Category:Wikipedia articles with deprecated authority control identifiers|'..dep..']]' |
|||
if config.whitelists[v] then |
|||
for _,w in ipairs(config.whitelists[v].properties) do |
|||
show[w] = true |
|||
end |
|||
end |
|||
end |
|||
end |
end |
||
showall = false |
|||
end |
end |
||
end |
end |
||
addshowlist(frame.args.show) -- check show= parameter on wrapper template |
|||
--Use QID= parameter for testing/example purposes only |
|||
addshowlist(parentArgs.show or parentArgs.country) -- check show parameter on article template |
|||
local itemId = nil |
|||
if parentArgs.suppress then |
|||
if testcases or talkspace then |
|||
local suppresslist = mw.text.split(parentArgs.suppress,"%s*,%s*") -- split parameter by comma |
|||
if parentArgs['QID'] then |
|||
for _,v in ipairs(suppresslist) do |
|||
itemId = 'Q' .. mw.ustring.gsub(parentArgs['QID'], '^[Qq]', '') |
|||
v = stripP(string.upper(v)) |
|||
itemId = resolveEntity._id(itemId) --nil if unresolvable |
|||
if v then |
|||
show[v] = false |
|||
auxCats = auxCats .. '[[' .. config.i18n.category .. ':' .. config.i18n.suppressedcat .. ']]' |
|||
else |
|||
auxCats = auxCats .. needsAttention('P') |
|||
end |
|||
end |
end |
||
else |
|||
itemId = mw.wikibase.getEntityIdForCurrentPage() |
|||
end |
end |
||
--Wikidata fallback if requested |
|||
local function makeSections(qid,addit) |
|||
if itemId then |
|||
local tval = {} |
|||
for _, params in ipairs( p.conf ) do |
|||
local function parameter_is_used(property) |
|||
if params[3] > 0 then |
|||
local val = parentArgs[params[1]] |
|||
if property then |
|||
if |
if val == nil or val == '' then |
||
local canUseWikidata = nil |
|||
if reqs[params[1]] then |
|||
canUseWikidata = p.matchesWikidataRequirements( itemId, reqs[params[1]] ) |
|||
else |
|||
canUseWikidata = true |
|||
end |
end |
||
if canUseWikidata then |
|||
elseif tval[property] == false then -- property has been manually suppressed |
|||
local wikidataIds = p.getIdsFromWikidata( itemId, 'P' .. params[3] ) |
|||
used = true |
|||
if wikidataIds[1] then |
|||
end |
|||
if val == '' and (namespace == 0 or testcases) then |
|||
end |
|||
suppressedIdCat = '[[Category:Wikipedia articles with suppressed authority control identifiers|' .. params[1] .. ']]' |
|||
return used |
|||
else |
|||
parentArgs[params[1]] = wikidataIds[1] |
|||
end end end end end end end |
|||
--Configured rows |
|||
local rct = 0 |
|||
for _, params in ipairs( p.conf ) do |
|||
local val = parentArgs[params[1]] |
|||
if val and val ~= '' then |
|||
table.insert( elements, p.createRow( params[1], params[2] .. ':', val, params[4]( val ), true ) ) |
|||
rct = rct + 1 |
|||
end |
end |
||
end |
|||
for _, params in ipairs(conf) do |
|||
tval[params.property] = getIdsFromWikidata(qid, 'P' .. params.property) -- setup table for values with property number as key |
|||
--WorldCat |
|||
local showb = true |
|||
local worldcatId = parentArgs['WORLDCATID'] |
|||
if (show[params.property] == nil) and (show[string.upper(params[1])] == nil ) then |
|||
if worldcatId and worldcatId ~= '' then --if unsuppressed & present |
|||
showb = showall -- if not specified then depends on showall |
|||
table.insert( elements, p.createRow( 'WORLDCATID', '', worldcatId, '[[WorldCat Identities]]: [https://www.worldcat.org/identities/'..worldcatId..' '..worldcatId..']', false ) ) --Validation? |
|||
elseif (show[params.property] == false) or (show[string.upper(params[1])] == false) then -- if either are false then id will be suppressed |
|||
worldcatCat = '[[Category:Wikipedia articles with WorldCat identifiers]]' |
|||
showb = false |
|||
elseif worldcatId == nil then --if unsuppressed & absent |
|||
local viafId = parentArgs['VIAF'] |
|||
local lccnId = parentArgs['LCCN'] |
|||
if viafId and viafId ~= '' and p.viafLink( viafId ) then --VIAF must be unsuppressed & validated |
|||
table.insert( elements, p.createRow( 'VIAF', '', viafId, '[[WorldCat Identities]] (via VIAF): [https://www.worldcat.org/identities/containsVIAFID/'..viafId..' '..viafId..']', false ) ) |
|||
if (namespace == 0) then |
|||
worldcatCat = '[[Category:Wikipedia articles with WorldCat-VIAF identifiers]]' |
|||
end |
end |
||
elseif lccnId and lccnId ~= '' and p.lccnLink( lccnId ) then --LCCN must be unsuppressed & validated |
|||
if not showb then |
|||
local lccnParts = p.splitLccn( lccnId ) |
|||
tval[params.property] = false -- indicates the identifier is suppressed |
|||
if lccnParts and lccnParts[1] ~= 'sh' then |
|||
local |
local lccnIdFmtd = lccnParts[1] .. lccnParts[2] .. '-' .. lccnParts[3] |
||
table.insert( elements, p.createRow( 'LCCN', '', lccnId, '[[WorldCat Identities]] (via LCCN): [https://www.worldcat.org/identities/lccn-'..lccnIdFmtd..' '..lccnIdFmtd..']', false ) ) |
|||
if val and val~='' then -- add local parameter to list if not already in |
|||
if (namespace == 0) then |
|||
worldcatCat = '[[Category:Wikipedia articles with WorldCat-LCCN identifiers]]' |
|||
local bnew = true |
|||
for _, w in pairs(tval[params.property]) do |
|||
if val == w.id then |
|||
bnew = false |
|||
end |
|||
end |
|||
if bnew then -- add new value to table |
|||
if qid then |
|||
qslink = qslink .. '%7C%7C' .. qid .. '%7CP' .. params.property .. '%7C%22' .. mw.uri.encode(val,"PATH") .. '%22%7CS143%7CQ328' |
|||
end |
|||
table.insert(tval[params.property],{id=val,name=''}) |
|||
end |
|||
end |
|||
end |
|||
local suppress = false |
|||
if params.suppressedbyproperty then |
|||
for _,sc in ipairs(params.suppressedbyproperty) do |
|||
if parameter_is_used(sc) then |
|||
suppress = true |
|||
end |
|||
end |
|||
end |
|||
if tval[params.property] ~= false and not suppress then |
|||
local tlinks = {} -- setup table for links |
|||
local nextIdVal = 1 |
|||
local row = '' |
|||
for _,val in ipairs(tval[params.property]) do |
|||
local link = _makelink(params,val,nextIdVal,qid) |
|||
row = row .. link |
|||
table.insert(tlinks,link) |
|||
nextIdVal = nextIdVal + 1 |
|||
end |
|||
if nextIdVal>=2 then |
|||
row = row .. '\n' |
|||
table.insert(sections[addit or params.section],row) |
|||
rct = true |
|||
end |
end |
||
end |
end |
||
end |
end |
||
elseif worldcatId == '' then --if suppressed |
|||
suppressedIdCat = '[[Category:Wikipedia articles with suppressed authority control identifiers|WORLDCATID]]' |
|||
end |
end |
||
local function pencil(qid) |
|||
local Navbox = require('Module:Navbox') |
|||
if not qid then |
|||
local elementsCat = '' |
|||
return '' |
|||
if rct > 13 then |
|||
end |
|||
local |
local catName = 'AC with ' .. rct .. ' elements' |
||
elementsCat = '[[Category:' .. catName .. ']]' .. p.redCatLink(catName) |
|||
args.qid = qid |
|||
return require('Module:EditAtWikidata')._showMessage(args) |
|||
end |
end |
||
makeSections(qid,false) |
|||
for c = 1,#qids do |
|||
makeSections(qids[c],numsections+c) |
|||
end |
|||
--configure Navbox |
|||
local outString = '' |
local outString = '' |
||
if #elements > 0 then |
|||
if rct or localparams then -- there is at least one link to display |
|||
local |
local args = {} |
||
if testcases and itemId then args = { qid = itemId } end --expensive |
|||
local sect,lastsect = 0,0 |
|||
local pencil = frame:expandTemplate{ title = 'EditAtWikidata', args = args} |
|||
local navboxArgs = { |
|||
outString = Navbox._navbox( { |
|||
name = 'Authority control', |
name = 'Authority control', |
||
navboxclass = 'authority-control', |
|||
bodyclass = 'hlist', |
bodyclass = 'hlist', |
||
group1 = '[[Help:Authority control|Authority control]]' .. pencil, |
|||
state = parentArgs.state or config.i18n.autocollapse, |
|||
list1 = table.concat( elements ) |
|||
navbar = 'off' |
|||
} |
} ) |
||
local auxCats = worldcatCat .. elementsCat .. suppressedIdCat .. deprecatedIdCat |
|||
for c=1,numsections+#qids do |
|||
if testcases then |
|||
if #sections[c] ~= 0 then -- section is non-empty |
|||
auxCats = mw.ustring.gsub(auxCats, '(%[%[)(Category)', '%1:%2') --for easier checking |
|||
sect = sect + 1 |
|||
lastsect = c |
|||
local sectname |
|||
if c <= numsections then -- regular section |
|||
sectname = config.sections[c].name |
|||
else -- section from additional qid |
|||
local qid = qids[c-numsections] |
|||
sectname = wikilink(qid) .. pencil(qid) |
|||
end |
|||
navboxArgs['group' .. c] = sectname |
|||
navboxArgs['list' .. c] = table.concat(sections[c]) |
|||
end |
|||
end |
end |
||
outString = outString .. auxCats |
|||
if localparams then |
|||
if namespace ~= 0 then |
|||
lastsect = lastsect + 1 |
|||
outString = mw.ustring.gsub(outString, '(%[%[)(Category:Wikipedia articles)', '%1:%2') --by definition |
|||
sect = sect + 1 |
|||
navboxArgs['group' .. lastsect] = config.i18n.warning |
|||
local warning = frame:expandTemplate{title = config.i18n.errortemplate, args = {config.i18n.localparams}} |
|||
if qslink ~= '' then |
|||
warning = warning .. ' ' .. config.i18n.movetowd .. '<span class="qs autoconfirmed-show"> [[File:Commons to Wikidata QuickStatements.svg|20px|link=https://quickstatements.toolforge.org/#/v1=' .. qslink .. '|' .. config.i18n.addtowd .. ']]</span>' |
|||
elseif not qid then |
|||
if namespace == 0 then |
|||
warning = warning .. ' ' .. config.i18n.connecttowd |
|||
elseif namespace==14 or namespace==2 or namespace==118 then |
|||
warning = warning .. ' ' .. config.i18n.qidcode |
|||
end |
|||
end |
|||
navboxArgs['list' .. lastsect] = warning |
|||
end |
end |
||
if topic then -- display in expanded form with topic |
|||
navboxArgs.title = config.i18n.aclink .. ' – ' .. topic .. pencil(qid) |
|||
elseif sect == 1 then -- special display when only one section |
|||
if lastsect <= numsections then |
|||
if config.sections[lastsect].hidelabelwhenalone then -- no special label when only general or other IDs are present |
|||
navboxArgs['group' .. lastsect] = config.i18n.aclink .. pencil(qid) |
|||
else -- other regular section |
|||
navboxArgs['group' .. lastsect] = config.i18n.aclink .. ': ' .. navboxArgs['group' .. lastsect] .. pencil(qid) |
|||
end |
|||
else -- section from additional qid |
|||
navboxArgs['group' .. lastsect] = config.i18n.aclink .. ': ' .. navboxArgs['group' .. lastsect] |
|||
end |
|||
else -- add title to navbox |
|||
navboxArgs.title = config.i18n.aclink .. pencil(qid) |
|||
end |
|||
outString = Navbox._navbox(navboxArgs) |
|||
end |
end |
||
if parentArgs.state |
|||
and parentArgs.state~='' |
|||
and parentArgs.state~=config.i18n.collapsed |
|||
and parentArgs.state~=config.i18n.expanded |
|||
and parentArgs.state~=config.i18n.autocollapse then --invalid state parameter |
|||
auxCats = auxCats .. needsAttention('S') |
|||
end |
|||
if testcases then |
|||
auxCats = mw.ustring.gsub(auxCats, '(%[%[)(' .. config.i18n.category .. ')', '%1:%2') --for easier checking |
|||
end |
|||
--out |
|||
outString = outString..auxCats |
|||
if namespace ~= 0 then |
|||
outString = mw.ustring.gsub(outString,'(%[%[)(' .. config.i18n.category .. ':' .. config.i18n.Articles .. ')([^%|%]]+)%|?[^%|%]]*(%]%])','%1:%2%3%4') |
|||
outString = mw.ustring.gsub(outString,'(%[%[)(' .. config.i18n.category .. ':' .. config.i18n.All_articles .. ')([^%|%]]+)%|?[^%|%]]*(%]%])','%1:%2%3%4') |
|||
end |
|||
local check = require('Module:Check for unknown parameters')._check |
|||
local sortkey |
|||
if namespace == 0 then |
|||
sortkey = '*' .. title.text |
|||
else |
|||
sortkey = title.fullText |
|||
end |
|||
outString = outString .. check({ |
|||
['unknown'] = '[[' .. config.i18n.category .. ':' .. config.i18n.pageswithparams .. '|' .. sortkey .. ']]', |
|||
['preview'] = config.i18n.previewwarning, 'show', 'country', 'suppress', 'additional', 'qid', 'state' |
|||
}, parentArgs) |
|||
return outString |
return outString |
||
end |
|||
p.makelink = function(conf,val,nextid,qid) |
|||
return _makelink(conf,val,nextid,qid) |
|||
end |
end |
||
18:26, 27 மார்ச்சு 2024 இல் நிலவும் திருத்தம்
Documentation for this module may be created at Module:Authority control/doc
require('Module:No globals')
local p = {}
--[[==========================================================================]]
--[[ Category functions ]]
--[[==========================================================================]]
function p.getCatForId( id )
local title = mw.title.getCurrentTitle()
local namespace = title.namespace
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 '[[Category:' .. catName .. ']]' .. p.redCatLink(catName)
end
function p.redCatLink( catName ) --catName == 'Blah', not 'Category:Blah', not '[[Category:Blah]]'
if catName and catName ~= '' and mw.title.new(catName, 14).exists == false then
return '[[Category:Pages with red-linked authority control categories]]'
end
return ''
end
--[[==========================================================================]]
--[[ Property formatting functions ]]
--[[==========================================================================]]
function p.iaafLink( id )
--P1146's format regex: [1-9][0-9]* (e.g. 123)
if not string.match( id, '^[1-9]%d*$' ) then
return false
end
return '[https://www.iaaf.org/athletes/biographies/athcode='..id..' '..id..']'..p.getCatForId( 'IAAF' )
end
function p.viafLink( id )
--P214's format regex: [1-9]\d(\d{0,7}|\d{17,20}) (e.g. 123456789, 1234567890123456789012)
if not string.match( id, '^[1-9]%d%d?%d?%d?%d?%d?%d?%d?$' ) and
not string.match( id, '^[1-9]%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d?%d?%d?$' ) then
return false
end
return '[https://viaf.org/viaf/'..id..' '..id..']'..p.getCatForId( 'VIAF' )
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 string.match( id, '^%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
return '[http://kulturnav.org/'..id..' '..id..']'..p.getCatForId( 'KULTURNAV' ) --no https yet (10/2018)
end
function p.sikartLink( id )
--P781's format regex: \d{7,9} (e.g. 123456789)
if not string.match( id, '^%d%d%d%d%d%d%d%d?%d?$' ) then
return false
end
return '[http://www.sikart.ch/KuenstlerInnen.aspx?id='..id..'&lng=en '..id..']'..p.getCatForId( 'SIKART' ) --no https yet (10/2018)
end
function p.tlsLink( id )
local id2 = 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( id2, regex ) then
return false
end
return '[http://tls.theaterwissenschaft.ch/wiki/'..id2..' '..id..']'..p.getCatForId( 'TLS' ) --no https yet (10/2018)
end
function p.ciniiLink( id )
--P271's format regex: DA\d{7}[\dX] (e.g. DA12345678)
if not string.match( id, '^DA%d%d%d%d%d%d%d[%dX]$' ) then
return false
end
return '[https://ci.nii.ac.jp/author/'..id..'?l=en '..id..']'..p.getCatForId( 'CINII' )
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 string.match( id, '^[XF][XF]%d%d%d%d%d?%d?%d?$' ) and
not string.match( id, '^a%d%d%d%d%d?%d?%d?$' ) and
not string.match( id, '^bi[mcsv][aoei]%d%d%d%d%d%d%d%d%d%d$' ) and
not string.match( id, '^Mi[sm][eoa]%d%d%d%d%d%d%d%d%d%d$' ) then
return false
end
return '[http://catalogo.bne.es/uhtbin/authoritybrowse.cgi?action=display&authority_id='..id..' '..id..']'..p.getCatForId( 'BNE' ) --no https yet (10/2018)
end
function p.uscongressLink( id )
--P1157's format regex: [A-Z]00[01]\d{3} (e.g. A000123)
if not string.match( id, '^[A-Z]00[01]%d%d%d$' ) then
return false
end
return '[http://bioguide.congress.gov/scripts/biodisplay.pl?index='..id..' '..id..']'..p.getCatForId( 'USCongress' ) --no https yet (10/2018)
end
function p.naraLink( id )
--P1225's format regex: ^([1-9]\d{0,7})$ (e.g. 12345678)
if not string.match( id, '^[1-9]%d?%d?%d?%d?%d?%d?%d?$' ) then
return false
end
return '[https://catalog.archives.gov/id/'..id..' '..id..']'..p.getCatForId( 'NARA' )
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 '[https://www.ipni.org/ipni/advAuthorSearch.do?find_abbreviation='..id2..' '..id..']'..p.getCatForId( 'Botanist' )
end
function p.mgpLink( id )
--P549's format regex: \d{1,6} (e.g. 123456)
if not string.match( id, '^%d%d?%d?%d?%d?%d?$' ) then
return false
end
return '[http://www.genealogy.ams.org/id.php?id='..id..' '..id..']'..p.getCatForId( 'MGP' ) --no https yet (10/2018)
end
function p.rslLink( id )
--P947's format regex: \d{1,9} (e.g. 123456789)
if not string.match( id, '^%d%d?%d?%d?%d?%d?%d?%d?%d?$' ) then
return false
end
return '[http://aleph.rsl.ru/F?func=find-b&find_code=SYS&adjacent=Y&local_base=RSL11&request='..id..'&CON_LNG=ENG '..id..']'..p.getCatForId( 'RSL' ) --no https yet (10/2018)
end
function p.leonoreLink( id )
--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 false
end
return '[http://www.culture.gouv.fr/public/mistral/leonore_fr?ACTION=CHERCHER&FIELD_1=COTE&VALUE_1='..id..' '..id..']'..p.getCatForId( 'Léonore' ) --no https yet (10/2018)
end
function p.sbnLink( id )
--P396's format regex: IT\\ICCU\\(\d{10}|\D\D[\D\d]\D\\\d{6}) (e.g. IT\ICCU\CFIV\000163)
if not string.match( id, '^IT\\ICCU\\%d%d%d%d%d%d%d%d%d%d$' ) and
not string.match( id, '^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 false
end
return '[https://opac.sbn.it/opacsbn/opac/iccu/scheda_authority.jsp?bid='..id..' '..id..']'..p.getCatForId( 'SBN' )
end
function p.nkcLink( id )
--P691's format regex: [a-z]{2,4}[0-9]{2,14} (e.g. abcd12345678901234)
if not string.match( id, '^[a-z][a-z][a-z]?[a-z]?%d%d%d?%d?%d?%d?%d?%d?%d?%d?%d?%d?%d?%d?$' ) then
return false
end
return '[https://aleph.nkp.cz/F/?func=find-c&local_base=aut&ccl_term=ica='..id..'&CON_LNG=ENG '..id..']'..p.getCatForId( 'NKC' )
end
function p.nclLink( id )
--P1048's format regex: \d+ (e.g. 1081436)
if not string.match( id, '^%d+$' ) then
return false
end
return '[http://aleweb.ncl.edu.tw/F/?func=accref&acc_sequence='..id..'&CON_LNG=ENG '..id..']'..p.getCatForId( 'NCL' ) --no https yet (10/2018)
end
function p.ndlLink( id )
--P349's format regex: 0?\d{8} (e.g. 012345678)
if not string.match( id, '^0?%d%d%d%d%d%d%d%d$' ) then
return false
end
return '[https://id.ndl.go.jp/auth/ndlna/'..id..' '..id..']'..p.getCatForId( 'NDL' )
end
function p.sudocLink( id )
--P269's format regex: (\d{8}[\dX]|) (e.g. 026927608)
if not string.match( id, '^%d%d%d%d%d%d%d%d[%dxX]$' ) then --legacy: allow lowercase 'x'
return false
end
return '[https://www.idref.fr/'..id..' '..id..']'..p.getCatForId( 'SUDOC' )
end
function p.hdsLink( id )
--P902's format regex: 50\d{3}|[1-4]\d{4}|[1-9]\d{0,3}| (e.g. 50123)
if not string.match( id, '^50%d%d%d$' ) and
not string.match( id, '^[1-4]%d%d%d%d$' ) and
not string.match( id, '^[1-9]%d?%d?%d?$' ) then
return false
end
return '[http://www.hls-dhs-dss.ch/textes/f/F'..id..'.php '..id..']'..p.getCatForId( 'HDS' ) --no https yet (10/2018)
end
function p.lirLink( id )
--P886's format regex: \d+ (e.g. 1)
if not string.match( id, '^%d+$' ) then
return false
end
return '[http://www.e-lir.ch/e-LIR___Lexicon.'..id..'.450.0.html '..id..']'..p.getCatForId( 'LIR' ) --no https yet (10/2018)
end
function 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?$' ) then
id = id:gsub( '^(%l+)(%d+)(%d%d%d%d%d%d)$', '%1/%2/%3' )
end
if id:match( '^%l%l?%l?/%d%d%d?%d?/%d+$' ) then
return mw.text.split( id, '/' )
end
return false
end
function p.append(str, c, length)
while str:len() < length do
str = c .. str
end
return str
end
function p.lccnLink( id )
local parts = p.splitLccn( id ) --e.g. n78039510
if not parts then
return false
end
local 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..' '..id..']'..p.getCatForId( 'LCCN' )
end
function p.mbaLink( id )
--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 string.match( id, '^%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
return '[https://musicbrainz.org/artist/'..id..' '..id..']'..p.getCatForId( 'MusicBrainz' )
end
function p.mbareaLink( id )
--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 string.match( id, '^%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
return '[https://musicbrainz.org/area/'..id..' '..id..']'..p.getCatForId( 'MusicBrainz area' )
end
function p.mbiLink( id )
--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 string.match( id, '^%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
return '[https://musicbrainz.org/instrument/'..id..' '..id..']'..p.getCatForId( 'MusicBrainz instrument' )
end
function p.mblLink( id )
--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 string.match( id, '^%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
return '[https://musicbrainz.org/label/'..id..' '..id..']'..p.getCatForId( 'MusicBrainz label' )
end
function p.mbpLink( id )
--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 string.match( id, '^%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
return '[https://musicbrainz.org/place/'..id..' '..id..']'..p.getCatForId( 'MusicBrainz place' )
end
function p.mbrgLink( id )
--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 string.match( id, '^%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
return '[https://musicbrainz.org/release-group/'..id..' '..id..']'..p.getCatForId( 'MusicBrainz release group' )
end
function p.mbsLink( id )
--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 string.match( id, '^%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
return '[https://musicbrainz.org/series/'..id..' '..id..']'..p.getCatForId( 'MusicBrainz series' )
end
function p.mbwLink( id )
--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 string.match( id, '^%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
return '[https://musicbrainz.org/work/'..id..' '..id..']'..p.getCatForId( 'MusicBrainz work' )
end
--Returns the ISNI check digit isni must be a string where the 15 first elements are digits, e.g. 0000000066534145
function p.getIsniCheckDigit( isni )
local total = 0
for i = 1, 15 do
local digit = isni:byte( i ) - 48 --Get integer value
total = (total + digit) * 2
end
local remainder = total % 11
local result = (12 - remainder) % 11
if result == 10 then
return "X"
end
return 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-identifier
function 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]$' ) then
return false
end
if p.getIsniCheckDigit( id ) ~= string.char( id:byte( 16 ) ) then
return false
end
return id
end
function p.isniLink( id )
id = p.validateIsni( id ) --e.g. 0000-0000-6653-4145
if not id then
return false
end
return '[http://isni.org/isni/'..id..' '..id:sub( 1, 4 )..' '..id:sub( 5, 8 )..' '..id:sub( 9, 12 )..' '..id:sub( 13, 16 )..']'..p.getCatForId( 'ISNI' ) --no https yet (10/2018)
end
function p.orcidLink( id )
id = p.validateIsni( id ) --e.g. 0000-0002-7398-5483
if not id then
return false
end
id = id:sub( 1, 4 )..'-'..id:sub( 5, 8 )..'-'..id:sub( 9, 12 )..'-'..id:sub( 13, 16 )
return '[https://orcid.org/'..id..' '..id..']'..p.getCatForId( 'ORCID' )
end
function p.gndLink( id )
--P227's format regex: (1|1[01])\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 string.match( id, '^1[01]?%d%d%d%d%d%d%d[0-9X]$' ) and
not string.match( id, '^[47]%d%d%d%d%d%d%-%d$' ) and
not string.match( id, '^[1-9]%d?%d?%d?%d?%d?%d?%d?%-[0-9X]$' ) and
not string.match( id, '^3%d%d%d%d%d%d%d[0-9X]$' ) then
return false
end
return '[https://d-nb.info/gnd/'..id..' '..id..']'..p.getCatForId( 'GND' )
end
function p.selibrLink( id )
--P906's format regex: [1-9]\d{4,5} (e.g. 123456)
if not string.match( id, '^[1-9]%d%d%d%d%d?$' ) then
return false
end
return '[https://libris.kb.se/auth/'..id..' '..id..']'..p.getCatForId( 'SELIBR' )
end
function p.bnfLink( id )
--P268's format regex: \d{8}[0-9bcdfghjkmnpqrstvwxz] (e.g. 123456789)
if not string.match( id, '^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 string.match( id, '^cb.+$' ) then
id = 'cb'..id
end
return '[https://catalogue.bnf.fr/ark:/12148/'..id..' '..id..'] [http://data.bnf.fr/ark:/12148/'..id..' (data)]'..p.getCatForId( 'BNF' )
end
function p.bpnLink( id )
--P651's format regex: \d{8} (e.g. 12345678)
if not string.match( id, '^%d%d%d%d%d%d%d%d$' ) then
return false
end
return '[http://www.biografischportaal.nl/en/persoon/'..id..' '..id..']'..p.getCatForId( 'BPN' ) --no https yet (10/2018)
end
function p.ridLink( id )
--P1053's format regex: [A-Z]-\d{4}-(19|20)\d\d (e.g. A-1234-1934)
if not string.match( id, '^[A-Z]%-%d%d%d%d%-19%d%d$' ) and
not string.match( id, '^[A-Z]%-%d%d%d%d%-20%d%d$' ) then
return false
end
return '[https://www.researcherid.com/rid/'..id..' '..id..']'..p.getCatForId( 'RID' )
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 string.match( id, '^[1-9]%d?%d?%d?%d?%d?%d?%d?%d?$' ) and
not string.match( id, '^[1-9]%d%d%d%d%d%d%d%d%d%d%d%d$' ) then
return false
end
return '[https://authority.bibsys.no/authority/rest/authorities/html/'..id..' '..id..']'..p.getCatForId( 'BIBSYS' )
end
function p.ulanLink( id )
--P245's format regex: 500\d{6} (e.g. 500123456)
if not string.match( id, '^500%d%d%d%d%d%d$' ) then
return false
end
return '[https://www.getty.edu/vow/ULANFullDisplay?find=&role=&nation=&subjectid='..id..' '..id..']'..p.getCatForId( 'ULAN' )
end
function p.nlaLink( id )
--P409's format regex: [1-9][0-9]{0,11} (e.g. 123456789012)
if not string.match( id, '^[1-9]%d?%d?%d?%d?%d?%d?%d?%d?%d?%d?%d?$' ) then
return false
end
return '[https://nla.gov.au/anbd.aut-an'..id..' '..id..']'..p.getCatForId( 'NLA' )
end
function p.rkdartistsLink( id )
--P650's format regex: [1-9]\d{0,5} (e.g. 123456)
if not string.match( id, '^[1-9]%d?%d?%d?%d?%d?$' ) then
return false
end
return '[https://rkd.nl/en/explore/artists/'..id..' '..id..']'..p.getCatForId( 'RKDartists' )
end
function p.snacLink( id )
--P3430's format regex: \d*[A-Za-z][0-9A-Za-z]* (e.g. A)
if not string.match( id, '^%d*[A-Za-z][0-9A-Za-z]*$' ) then
return false
end
return '[http://socialarchive.iath.virginia.edu/ark:/99166/'..id..' '..id..']'..p.getCatForId( 'SNAC-ID' ) --no https yet (10/2018)
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 string.match( id, '^%d%d%d?/%d+$' ) and
not string.match( id, '^%d%d%d?/%d+%-%d+$' ) and
not string.match( id, '^[a-z]/[a-zA-Z][0-9A-Za-z]*$' ) and
not string.match( id, '^[a-z]/[a-zA-Z][0-9A-Za-z]*%-%d+$' ) then
return false
end
return '[https://dblp.org/pid/'..id..' '..id..']'..p.getCatForId( 'DBLP' )
end
function p.acmLink( id )
--P864's format regex: \d{11} (e.g. 12345678901)
if not string.match( id, '^%d%d%d%d%d%d%d%d%d%d%d$' ) then
return false
end
return '[https://dl.acm.org/author_page.cfm?id='..id..' '..id..']'..p.getCatForId( 'ACM-DL' )
end
function p.autoresuyLink( id )
--P2558's format regex: [1-9]\d{0,4} (e.g. 12345)
if not string.match( id, '^[1-9]%d?%d?%d?%d?$' ) then
return false
end
return '[https://autores.uy/autor/'..id..' '..id..']'..p.getCatForId( 'autores.uy' )
end
function p.picLink( id )
--P2750's format regex: [1-9]\d* (e.g. 1)
if not string.match( id, '^[1-9]%d*$' ) then
return false
end
return '[https://pic.nypl.org/constituents/'..id..' '..id..']'..p.getCatForId( 'PIC' )
end
function p.bildLink( id )
--P2092's format regex: \d+ (e.g. 1)
if not string.match( id, '^%d+$' ) then
return false
end
return '[https://www.bildindex.de/document/obj'..id..' '..id..']'..p.getCatForId( 'Bildindex' )
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 string.match( id, regex ) then
return false
end
return '[http://www2.culture.gouv.fr/public/mistral/joconde_fr?ACTION=CHERCHER&FIELD_1=REF&VALUE_1='..id..' '..id..']'..p.getCatForId( 'Joconde' ) --no https yet (10/2018)
end
function p.rkdidLink( id )
--P350's format regex: [1-9]\d{0,5} (e.g. 123456)
if not string.match( id, '^[1-9]%d?%d?%d?%d?%d?$' ) then
return false
end
return '[https://rkd.nl/nl/explore/images/'..id..' '..id..']'..p.getCatForId( 'RKDID' )
end
function p.balatLink( id )
--P3293's format regex: \d+ (e.g. 1)
if not string.match( id, '^%d+$' ) then
return false
end
return '[http://balat.kikirpa.be/object/104257'..id..' '..id..']'..p.getCatForId( 'BALaT' ) --no https yet (10/2018)
end
function p.lnbLink( id )
--P1368's format regex: \d{9} (e.g. 123456789)
if not string.match( id, '^%d%d%d%d%d%d%d%d%d$' ) then
return false
end
return '[https://kopkatalogs.lv/F?func=direct&local_base=lnc10&doc_number='..id..'&P_CON_LNG=ENG '..id..']'..p.getCatForId( 'LNB' )
end
function p.nskLink( id )
--P1375's format regex: \d{9} (e.g. 123456789)
if not string.match( id, '^%d%d%d%d%d%d%d%d%d$' ) then
return false
end
return '[http://katalog.nsk.hr/F/?func=direct&doc_number='..id..'&local_base=nsk10 '..id..']'..p.getCatForId( 'NSK' ) --no https yet (10/2018)
end
function p.iciaLink( id )
--P1736's format regex: \d+ (e.g. 1)
if not string.match( id, '^%d+$' ) then
return false
end
return '[https://www.imj.org.il/artcenter/newsite/en/?artist='..id..' '..id..']'..p.getCatForId( 'ICIA' )
end
function p.ta98Link( id )
--P1323's format regex: A\d{2}\.\d\.\d{2}\.\d{3}[FM]? (e.g. A12.3.45.678)
if not string.match( id, '^A%d%d%.%d%.%d%d%.%d%d%d[FM]?$' ) then
return false
end
return '[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..' '..id..']'..p.getCatForId( 'TA98' )
end
function p.teLink( id )
--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 = string.match( id, '^E([1-8])%.(%d%d?)%.%d%d?%.%d%d?%.%d%.%d%.%d%d?%d?$' )
if not e1 then
return false
end
local TEnum = 'TEe0'..e1 --no formatter URL in WD, probably due to this complexity
if e1 == '5' or e1 == '7' then
if #e2 == 1 then e2 = '0'..e2 end
TEnum = TEnum..e2
end
return '[http://www.unifr.ch/ifaa/Public/EntryPage/ViewTE/'..TEnum..'.html '..id..']'..p.getCatForId( 'TE' )
end
function p.thLink( id )
--P1694's format regex: H\d\.\d{2}\.\d{2}\.\d\.\d{5} (e.g. H1.23.45.6.78901)
local h1, h2 = string.match( id, '^H(%d)%.(%d%d)%.%d%d%.%d%.%d%d%d%d%d$' )
if not h1 then
return false
end
local THnum = 'THh'..h1..h2 --no formatter URL in WD, probably due to this complexity
return '[http://www.unifr.ch/ifaa/Public/EntryPage/ViewTH/'..THnum..'.html '..id..']'..p.getCatForId( 'TH' )
end
--[[==========================================================================]]
--[[ Wikidata, navigation bar, and documentation functions ]]
--[[==========================================================================]]
function p.getIdsFromWikidata( itemId, property )
local ids = {}
local statements = mw.wikibase.getBestStatements( itemId, property )
if statements then
for _, statement in ipairs( statements ) do
if statement.mainsnak.datavalue then
table.insert( ids, statement.mainsnak.datavalue.value )
end
end
end
return ids
end
function p.matchesWikidataRequirements( itemId, reqs )
for _, group in ipairs( reqs ) do
local property = 'P' .. group[1]
local qid = group[2]
local statements = mw.wikibase.getBestStatements( itemId, property )
if statements then
for _, statement in ipairs( statements ) do
if statement.mainsnak.datavalue then
if statement.mainsnak.datavalue.value['numeric-id'] == qid then
return true
end end end end end
return false
end
function p.createRow( id, label, rawValue, link, withUid )
if link then
if withUid then
return '*<span class="nowrap">' .. label .. ' <span class="uid">' .. link .. '</span></span>\n'
end
return '*<span class="nowrap">' .. label .. ' ' .. link .. '</span>\n'
end
local catName = 'Wikipedia articles with faulty ' .. id .. ' identifiers'
return '* <span class="error">The ' .. id .. ' id ' .. rawValue .. ' is not valid.</span>[[Category:' .. catName .. ']]' .. p.redCatLink(catName) .. '\n'
end
-- Creates a human-readable standalone wikitable version of p.conf, and tracking categories with page counts, for use in the documentation
function p.docConfTable( frame )
local wikiTable = '{| class="wikitable sortable"\n' ..
'! rowspan=2 | Parameter\n' ..
'! rowspan=2 | Label\n' ..
'! rowspan=2; data-sort-type=number | Wikidata property\n' ..
'! colspan=4 | Tracking categories and page counts\n' ..
'|-\n' ..
'! Articles\n' ..
'! User pages\n' ..
'! Misc. pages\n' ..
'! Faulty IDs\n' ..
'|-\n'
local lang = mw.getContentLanguage()
for _, conf in pairs( p.conf ) do
local param, link, pid = conf[1], conf[2], conf[3]
local category = conf.category or param
local args = { id = 'f', pid }
local wpl = frame:expandTemplate{ title = 'Wikidata property link', args = args }
--cats
local 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'
--counts
local 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') )
--concat
wikiTable = wikiTable..'\n'..
'|-\n'..
'||'..param..
'||'..link..
'||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
return wikiTable .. '\n|}'
end
--[[==========================================================================]]
--[[ Configuration ]]
--[[==========================================================================]]
-- Check that the Wikidata item has this property-->value before adding it
local reqs = {}
-- Parameter format: { name of the parameter, label, propertyId in Wikidata, formatting function }
p.conf = {
{ 'ACM-DL', '[[ACM Digital Library|ACM DL]]', 864, p.acmLink },
{ 'autores.uy', '[[autores.uy]]', 2558, p.autoresuyLink },
{ 'BALaT', '[[:d:Q2876688|BALaT]]', 3293, p.balatLink },
{ 'BIBSYS', '[[Bibsys|BIBSYS]]', 1015, p.bibsysLink },
{ 'Bildindex', '[[Marburg Picture Index|Bildindex]]', 2092, p.bildLink },
{ 'BNE', '[[Biblioteca Nacional de España|BNE]]', 950, p.bneLink },
{ 'BNF', '[[Bibliothèque nationale de France|BNF]]', 268, p.bnfLink },
{ 'Botanist', '[[Author citation (botany)|Botanist]]', 428, p.botanistLink },
{ 'BPN', '[[Biografisch Portaal|BPN]]', 651, p.bpnLink },
{ 'CINII', '[[CiNii]]', 271, p.ciniiLink },
{ 'DBLP', '[[DBLP]]', 2456, p.dblpLink },
{ 'GND', '[[Integrated Authority File|GND]]', 227, p.gndLink },
{ 'HDS', '[[Historical Dictionary of Switzerland|HDS]]', 902, p.hdsLink },
{ 'IAAF', '[[International Association of Athletics Federations|IAAF]]', 1146, p.iaafLink },
{ 'ICIA', '[[Information Center for Israeli Art|ICIA]]', 1736, p.iciaLink },
{ 'ISNI', '[[International Standard Name Identifier|ISNI]]', 213, p.isniLink },
{ 'Joconde', '[[Joconde|Joconde]]' , 347, p.jocondeLink },
{ 'KULTURNAV', '[[KulturNav]]', 1248, p.kulturnavLink },
{ 'LCCN', '[[Library of Congress Control Number|LCCN]]', 244, p.lccnLink },
{ 'LIR', '[[Historical Dictionary of Switzerland#Lexicon_Istoric_Retic|LIR]]', 886, p.lirLink },
{ 'LNB', '[[National Library of Latvia|LNB]]', 1368, p.lnbLink },
{ 'Léonore', '[[Base Léonore|Léonore]]', 640, p.leonoreLink },
{ 'MBA', '[[MusicBrainz]]', 434, p.mbaLink, category = 'MusicBrainz' },
{ 'MBAREA', '[[MusicBrainz]]', 982, p.mbareaLink, category = 'MusicBrainz area' },
{ 'MBI', '[[MusicBrainz]]', 1330, p.mbiLink, category = 'MusicBrainz instrument' },
{ 'MBL', '[[MusicBrainz]]', 966, p.mblLink, category = 'MusicBrainz label' },
{ 'MBP', '[[MusicBrainz]]', 1004, p.mbpLink, category = 'MusicBrainz place' },
{ 'MBRG', '[[MusicBrainz]] release group', 436, p.mbrgLink, category = 'MusicBrainz release group' },
{ 'MBS', '[[MusicBrainz]]', 1407, p.mbsLink, category = 'MusicBrainz series' },
{ 'MBW', '[[MusicBrainz]] work', 435, p.mbwLink, category = 'MusicBrainz work' },
{ 'MGP', '[[Mathematics Genealogy Project|MGP]]', 549, p.mgpLink },
{ 'NARA', '[[National Archives and Records Administration|NARA]]', 1225, p.naraLink },
{ 'NCL', '[[National Central Library|NCL]]', 1048, p.nclLink },
{ 'NDL', '[[National Diet Library|NDL]]', 349, p.ndlLink },
{ 'NKC', '[[National Library of the Czech Republic|NKC]]', 691, p.nkcLink },
{ 'NLA', '[[National Library of Australia|NLA]]', 409, p.nlaLink },
{ 'NSK', '[[National and University Library in Zagreb|NSK]]', 1375, p.nskLink },
{ 'ORCID', '[[ORCID]]', 496, p.orcidLink },
{ 'PIC', '[[:d:Q23892012|PIC]]', 2750, p.picLink },
{ 'RID', '[[ResearcherID]]', 1053, p.ridLink },
{ 'RKDartists', '[[Netherlands Institute for Art History#Online artist pages|RKD]]', 650, p.rkdartistsLink },
{ 'RKDID', '[[:d:Q17299580|RKDimages ID]]', 350, p.rkdidLink },
{ 'RSL', '[[Russian State Library|RSL]]', 947, p.rslLink },
{ 'SBN', '[[Istituto Centrale per il Catalogo Unico|ICCU]]', 396, p.sbnLink },
{ 'SELIBR', '[[LIBRIS|SELIBR]]', 906, p.selibrLink },
{ 'SIKART', '[[SIKART]]', 781, p.sikartLink },
{ 'SNAC-ID', '[[SNAC]]', 3430, p.snacLink },
{ 'SUDOC', '[[Système universitaire de documentation|SUDOC]]', 269, p.sudocLink },
{ 'TA98', '[[Terminologia Anatomica|TA98]]', 1323, p.ta98Link },
{ 'TE', '[[Terminologia Embryologica|TE]]', 1693, p.teLink },
{ 'TH', '[[Terminologia Histologica|TH]]', 1694, p.thLink },
{ 'TLS', '[[Theaterlexikon der Schweiz|TLS]]', 1362, p.tlsLink },
{ 'ULAN', '[[Union List of Artist Names|ULAN]]', 245, p.ulanLink },
{ 'USCongress', '[[Biographical Directory of the United States Congress|US Congress]]', 1157, p.uscongressLink },
{ 'VIAF', '[[Virtual International Authority File|VIAF]]', 214, p.viafLink },
}
-- Legitimate aliases to p.conf, for convenience
-- Format: { alias, parameter name in p.conf }
p.aliases = {
{ 'RLS', 'RSL' },
{ 'MusicBrainz', 'MBA' },
{ 'MusicBrainz artist', 'MBA' },
{ 'MusicBrainz label', 'MBL' },
{ 'MusicBrainz release group', 'MBRG' },
{ 'MusicBrainz work', 'MBW' },
{ 'Leonore', 'Léonore' },
}
-- Deprecated aliases to p.conf, which also get assigned to a tracking cat
-- Format: { deprecated parameter name, replacement parameter name in p.conf }
p.deprecated = {
{ 'GKD', 'GND' },
{ 'PND', 'GND' },
{ 'SWD', 'GND' },
{ 'NARA-organization', 'NARA' },
{ 'NARA-person', 'NARA' },
}
--[[==========================================================================]]
--[[ Main ]]
--[[==========================================================================]]
function p.authorityControl( frame )
local resolveEntity = require( "Module:ResolveEntityId" )
local title = mw.title.getCurrentTitle()
local namespace = title.namespace
local talkspace = (mw.site.talkNamespaces[namespace] ~= nil)
local testcases = (string.sub(title.subpageText,1,9) == 'testcases')
local parentArgs = frame:getParent().args
local elements = {} --create/insert rows later
local worldcatCat = ''
local suppressedIdCat = ''
local deprecatedIdCat = ''
--Redirect aliases to proper parameter names
for _, a in pairs( p.aliases ) do
local alias, param = a[1], a[2]
if (parentArgs[param] == nil or parentArgs[param] == '') and parentArgs[alias] then
parentArgs[param] = parentArgs[alias]
end
end
--Redirect deprecated parameters to proper parameter names, and assign tracking cat
for _, d in pairs( p.deprecated ) do
local dep, param = d[1], d[2]
if (parentArgs[param] == nil or parentArgs[param] == '') and parentArgs[dep] then
parentArgs[param] = parentArgs[dep]
if namespace == 0 then
deprecatedIdCat = '[[Category:Wikipedia articles with deprecated authority control identifiers|'..dep..']]'
end
end
end
--Use QID= parameter for testing/example purposes only
local itemId = nil
if testcases or talkspace then
if parentArgs['QID'] then
itemId = 'Q' .. mw.ustring.gsub(parentArgs['QID'], '^[Qq]', '')
itemId = resolveEntity._id(itemId) --nil if unresolvable
end
else
itemId = mw.wikibase.getEntityIdForCurrentPage()
end
--Wikidata fallback if requested
if itemId then
for _, params in ipairs( p.conf ) do
if params[3] > 0 then
local val = parentArgs[params[1]]
if val == nil or val == '' then
local canUseWikidata = nil
if reqs[params[1]] then
canUseWikidata = p.matchesWikidataRequirements( itemId, reqs[params[1]] )
else
canUseWikidata = true
end
if canUseWikidata then
local wikidataIds = p.getIdsFromWikidata( itemId, 'P' .. params[3] )
if wikidataIds[1] then
if val == '' and (namespace == 0 or testcases) then
suppressedIdCat = '[[Category:Wikipedia articles with suppressed authority control identifiers|' .. params[1] .. ']]'
else
parentArgs[params[1]] = wikidataIds[1]
end end end end end end end
--Configured rows
local rct = 0
for _, params in ipairs( p.conf ) do
local val = parentArgs[params[1]]
if val and val ~= '' then
table.insert( elements, p.createRow( params[1], params[2] .. ':', val, params[4]( val ), true ) )
rct = rct + 1
end
end
--WorldCat
local worldcatId = parentArgs['WORLDCATID']
if worldcatId and worldcatId ~= '' then --if unsuppressed & present
table.insert( elements, p.createRow( 'WORLDCATID', '', worldcatId, '[[WorldCat Identities]]: [https://www.worldcat.org/identities/'..worldcatId..' '..worldcatId..']', false ) ) --Validation?
worldcatCat = '[[Category:Wikipedia articles with WorldCat identifiers]]'
elseif worldcatId == nil then --if unsuppressed & absent
local viafId = parentArgs['VIAF']
local lccnId = parentArgs['LCCN']
if viafId and viafId ~= '' and p.viafLink( viafId ) then --VIAF must be unsuppressed & validated
table.insert( elements, p.createRow( 'VIAF', '', viafId, '[[WorldCat Identities]] (via VIAF): [https://www.worldcat.org/identities/containsVIAFID/'..viafId..' '..viafId..']', false ) )
if (namespace == 0) then
worldcatCat = '[[Category:Wikipedia articles with WorldCat-VIAF identifiers]]'
end
elseif lccnId and lccnId ~= '' and p.lccnLink( lccnId ) then --LCCN must be unsuppressed & validated
local lccnParts = p.splitLccn( lccnId )
if lccnParts and lccnParts[1] ~= 'sh' then
local lccnIdFmtd = lccnParts[1] .. lccnParts[2] .. '-' .. lccnParts[3]
table.insert( elements, p.createRow( 'LCCN', '', lccnId, '[[WorldCat Identities]] (via LCCN): [https://www.worldcat.org/identities/lccn-'..lccnIdFmtd..' '..lccnIdFmtd..']', false ) )
if (namespace == 0) then
worldcatCat = '[[Category:Wikipedia articles with WorldCat-LCCN identifiers]]'
end
end
end
elseif worldcatId == '' then --if suppressed
suppressedIdCat = '[[Category:Wikipedia articles with suppressed authority control identifiers|WORLDCATID]]'
end
local Navbox = require('Module:Navbox')
local elementsCat = ''
if rct > 13 then
local catName = 'AC with ' .. rct .. ' elements'
elementsCat = '[[Category:' .. catName .. ']]' .. p.redCatLink(catName)
end
local outString = ''
if #elements > 0 then
local args = {}
if testcases and itemId then args = { qid = itemId } end --expensive
local pencil = frame:expandTemplate{ title = 'EditAtWikidata', args = args}
outString = Navbox._navbox( {
name = 'Authority control',
bodyclass = 'hlist',
group1 = '[[Help:Authority control|Authority control]]' .. pencil,
list1 = table.concat( elements )
} )
local auxCats = worldcatCat .. elementsCat .. suppressedIdCat .. deprecatedIdCat
if testcases then
auxCats = mw.ustring.gsub(auxCats, '(%[%[)(Category)', '%1:%2') --for easier checking
end
outString = outString .. auxCats
if namespace ~= 0 then
outString = mw.ustring.gsub(outString, '(%[%[)(Category:Wikipedia articles)', '%1:%2') --by definition
end
end
return outString
end
return p