「モジュール:Authority control」の版間の差分

提供:TDR Wiki
追加された内容 削除された内容
(en:Module:Authority control oldid=977413812 より更新)
 
(3人の利用者による、間の25版が非表示)
1行目: 1行目:
require('Module:No globals')
require('strict')

local p = {}
local p = {}
local configfile = 'Module:Authority control/config' -- default configuation module
local arg = mw.getCurrentFrame().args.config
if arg and arg~='' then
configfile = 'Module:Authority control/config/' .. arg
end
local config
if mw.title.new(configfile).exists then
config = mw.loadData(configfile)
else
return error('Invalid configuration file',0)
end
local title = mw.title.getCurrentTitle()
local title = mw.title.getCurrentTitle()
local namespace = title.namespace
local namespace = title.namespace
local testcases = (string.sub(title.subpageText,1,9) == 'testcases')
local testcases = title.subpageText == config.i18n.testcases


local function needsAttention(sortkey)
--[[==========================================================================]]
return '[[' .. config.i18n.category .. ':' .. config.i18n.attentioncat .. '|' .. sortkey .. title.text .. ']]'
--[[ Category functions ]]
end
--[[==========================================================================]]


function p.getCatForId( id )
local function addCat(cat,sortkey)
if cat and cat ~= '' and (namespace == 0 or namespace == 14 or testcases) then
local catName = ''
local redlinkcat = ''
if namespace == 0 then
if testcases == false and mw.title.new(cat, 14).exists == false then
catName = id..'識別子が指定されている記事'
redlinkcat = needsAttention('N')
elseif namespace == 2 and not title.isSubpage then
end
catName = id..'識別子が指定されている利用者ページ'
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
return ''
catName = id..'識別子が指定されているその他のページ'
end
end
return '[[Category:'..catName..']]'..p.redCatLink(catName)
end
end


local function getCatForId(id,faulty)
function p.redCatLink( catName ) --catName == 'Blah', not 'Category:Blah', not '[[Category:Blah]]'
local cat = string.format(
if catName and catName ~= '' and
config.i18n.cat,
testcases == false and
faulty and config.i18n.faulty..id or id
mw.title.new(catName, 14).exists == false
)
then
return addCat(cat)
return '[[Category:赤リンクの典拠情報カテゴリがあるページ]]'
end
return ''
end
end


local function getIdsFromWikidata(qid,property)
--[[==========================================================================]]
local function getquals(statement,qualid)
--[[ Property formatting functions ]]
if statement.qualifiers and statement.qualifiers['P'..qualid] then
--[[==========================================================================]]
return mw.wikibase.renderSnak(statement.qualifiers['P'..qualid][1])

else
function p.aagLink( id )
return false
--P3372's format regex: \d+ (e.g. 1)
end
if not id:match( '^%d+$' ) then
return false
end
end
local ids = {}
return '[https://www.aucklandartgallery.com/explore-art-and-ideas/artist/'..id..'/ '..id..']'..p.getCatForId( 'AAG' )
if qid then
end
for _, statement in ipairs(mw.wikibase.getBestStatements(qid,property)) do

if statement.mainsnak.datavalue then
function p.acmLink( id )
local val = statement.mainsnak.datavalue.value
--P864's format regex: \d{11} (e.g. 12345678901)
if val then
if not id:match( '^%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 ids
return '[https://dl.acm.org/profile/'..id..' '..id..']'..p.getCatForId( 'ACM-DL' )
end
end


local _makelink = function(conf,val,nextid,qid) --validate values and create a link
function p.adbLink( id )
local function tooltip(text,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 label and label~='' then
if not id:match( '^[a-z][-a-z]+-[1-2]%d%d?%d?%d?$' ) and
return mw.getCurrentFrame():expandTemplate{title = "Tooltip", args = {text,label}}
not id:match( '^[a-z][-a-z]+-[1-9]%d?%d?%d?$' ) then
else
return false
return text
end
end
end
local link
return '[http://adb.anu.edu.au/biography/'..id..' '..id..']'..p.getCatForId( 'ADB' )
if nextid==1 then
end
if conf.prefix then

link = '*' .. conf.prefix .. '\n**'
function p.agsaLink( id )
else
--P6804's format regex: [1-9]\d* (e.g. 3625)
link = '*'
if not id:match( '^[1-9]%d*$' ) then
end
return false
else
link = '\n**'
end
end
local valid_value = false
return '[https://www.agsa.sa.gov.au/collection-publications/collection/creators/_/'..id..'/ '..id..']'..p.getCatForId( 'AGSA' )
if conf.customlink then -- use function to validate and generate link
end
local label = nextid>1 and nextid

local newlink= require(config.auxiliary)[conf.customlink](val.id,label)
function p.autoresuyLink( id )
if newlink then
--P2558's format regex: [1-9]\d{0,4} (e.g. 12345)
link = link .. newlink
if not id:match( '^[1-9]%d?%d?%d?%d?$' ) then
valid_value = true
return false
end
else
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
if valid_value then
return '[https://autores.uy/autor/'..id..' '..id..']'..p.getCatForId( 'autores.uy' )
link = link .. getCatForId(conf.category or conf[1])
end
else

--local preview = require("Module:If preview")
function p.awrLink( id )
local wdlink = qid and '[[:wikidata:' .. qid .. '#P' .. conf.property .. ']]' or ''
--P4186's format regex: (([A-Z]{3}\d{4})|([A-Z]{2}\d{5}))[a-z] (e.g. PR00768b)
local tooltip = string.format(
if not id:match( '^[A-Z][A-Z][A-Z]%d%d%d%d[a-z]$' ) and
config.i18n.idnotvalid,
not id:match( '^[A-Z][A-Z]%d%d%d%d%d[a-z]$' ) then
conf[1],
return false
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 link
return '[http://www.womenaustralia.info/biogs/'..id..'.htm '..id..']'..p.getCatForId( 'AWR' )
end
end


--[[==========================================================================]]
function p.balatLink( id )
--[[ Main ]]
--P3293's format regex: \d+ (e.g. 1)
--[[==========================================================================]]
if not id:match( '^%d+$' ) then
function p.authorityControl(frame)
return false
local function resolveQID(qid)
if qid then
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
local conf = config.config
return '[http://balat.kikirpa.be/object/104257'..id..' '..id..']'..p.getCatForId( 'BALaT' ) --no https as of 9/2019
local parentArgs = frame:getParent().args
end
local auxCats = ''

local rct = false -- boolean to track if there are any links to be returned
function p.bibsysLink( id )
local qid,topic
--P1015's format regex: [1-9]\d* or [1-9](\d{0,8}|\d{12}) (e.g. 1234567890123)
local wikilink = function(qid,hideifequal)
--TODO: follow up @ [[d:Property talk:P1015#Discrepancy between the 2 regex constraints]] or escalate/investigate
local label,sitelink = mw.wikibase.getLabel(qid),mw.wikibase.getSitelink(qid)
if not id:match( '^[1-9]%d?%d?%d?%d?%d?%d?%d?%d?$' ) and
if label then
not id:match( '^[1-9]%d%d%d%d%d%d%d%d%d%d%d%d$' ) then
if sitelink then
return false
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
if namespace == 0 then
return '[https://authority.bibsys.no/authority/rest/authorities/html/'..id..' '..id..']'..p.getCatForId( 'BIBSYS' )
qid = mw.wikibase.getEntityIdForCurrentPage()
end

function p.bildLink( id )
--P2092's format regex: \d+ (e.g. 1)
if not id:match( '^%d+$' ) then
return false
end
end
if qid then -- article is connected to Wikidata item
return '[https://www.bildindex.de/document/obj'..id..' '..id..']'..p.getCatForId( 'Bildindex' )
if parentArgs.qid and (resolveQID(parentArgs.qid) ~= qid) then -- non-matching qid parameter
end
auxCats = auxCats .. needsAttention('D')

end
function p.bncLink( id )
else -- page is not connected to any Wikidata item
--P1890's format regex: \d{9} (e.g. 123456789)
qid = resolveQID(parentArgs.qid) -- check qid parameter if no wikidata item is connected
if not id:match( '^%d%d%d%d%d%d%d%d%d$' ) then
if qid then -- qid parameter is valid, set topic to display
return false
topic = mw.wikibase.getLabel(qid)
end
if topic then
return '[http://www.bncatalogo.cl/F?func=direct&local_base=red10&doc_number='..id..' '..id..']'..p.getCatForId( 'BNC' )
if mw.ustring.lower(title.subpageText) == mw.ustring.lower(topic) then -- suppress topic display if subpagename equals topic up to case change
end
topic = nil

end
function p.bneLink( id )
if topic and mw.wikibase.getSitelink(qid) then -- make wikilink to article
--P950's format regex: (XX|FF|a)\d{4,7}|(bima|bimo|bica|bis[eo]|bivi|Mise|Mimo|Mima)\d{10} (e.g. XX1234567)
topic = '[[' .. mw.wikibase.getSitelink(qid) .. '|' .. topic .. ']]'
if not id:match( '^[XF][XF]%d%d%d%d%d?%d?%d?$' ) and
end
not id:match( '^a%d%d%d%d%d?%d?%d?$' ) and
else
not id:match( '^bi[mcsv][aoei]%d%d%d%d%d%d%d%d%d%d$' ) and
auxCats = auxCats .. needsAttention('L')
not id:match( '^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 as of 9/2019
end

function p.bnfLink( id )
--P268's format regex: \d{8}[0-9bcdfghjkmnpqrstvwxz] (e.g. 123456789)
if not id:match( '^c?b?%d%d%d%d%d%d%d%d[0-9bcdfghjkmnpqrstvwxz]$' ) then
return false
end
--Add cb prefix if it has been removed
if not id:match( '^cb.+$' ) then
id = 'cb'..id
end
return '[https://catalogue.bnf.fr/ark:/12148/'..id..' '..id..'] [https://data.bnf.fr/ark:/12148/'..id..' (データ)]'..p.getCatForId( 'BNF' )
end

function p.botanistLink( id )
--P428's format regex: ('t )?(d')?(de )?(la )?(van (der )?)?(Ma?c)?(De)?(Di)?\p{Lu}?C?['\p{Ll}]*([-'. ]*(van )?(y )?(d[ae][nr]?[- ])?(Ma?c)?[\p{Lu}bht]?C?['\p{Ll}]*)*\.? ?f?\.? (e.g. L.)
--not easily/meaningfully implementable in Lua's regex since "(this)?" is not allowed...
if not mw.ustring.match( id, "^[%u%l%d%. '-]+$" ) then --better than nothing
return false
end
local id2 = id:gsub(' +', '%%20')
return '[https://www.ipni.org/ipni/advAuthorSearch.do?find_abbreviation='..id2..' '..id..']'..p.getCatForId( 'Botanist' )
end

function p.bpnLink( id )
--P651's format regex: \d{6,8} (e.g. 00123456)
if not id:match( '^%d%d%d%d%d%d%d%d$' ) and --original format regex, changed 8/2019 to
not id:match( '^0?%d%d%d%d%d%d%d$' ) and --allow 1-2 leading 0s, allowed by the website
not id:match( '^0?0?%d%d%d%d%d%d$' ) then
return false
end
return '[http://www.biografischportaal.nl/en/persoon/'..id..' '..id..']'..p.getCatForId( 'BPN' ) --no https as of 9/2019
end

function p.canticLink( id )
--P1273's format regex: a\d{7}[0-9x] (e.g. a10640745)
if not id:match( '^a%d%d%d%d%d%d%d[%dx]$' ) then
return false
end
return '[http://cantic.bnc.cat/registres/CUCId/'..id..' '..id..']'..p.getCatForId( 'CANTIC' ) --no https as of 10/2019
end

function p.ciniiLink( id )
--P271's format regex: DA\d{7}[\dX] (e.g. DA12345678)
if not id:match( '^DA%d%d%d%d%d%d%d[%dX]$' ) then
return false
end
return '[https://ci.nii.ac.jp/author/'..id..'?l=en '..id..']'..p.getCatForId( 'CINII' )
end

function p.daaoLink( id )
--P1707's format regex: [a-z\-]+\d* (e.g. rolf-harris)
if not id:match( '^[a-z%-]+%d*$' ) then
return false
end
return '[https://www.daao.org.au/bio/'..id..' '..id..']'..p.getCatForId( 'DAAO' )
end

function p.dblpLink( id )
--P2456's format regex: \d{2,3} /\d+(-\d+)?|[a-z] /[a-zA-Z][0-9A-Za-z]*(-\d+)? (e.g. 123/123)
if not id:match( '^%d%d%d?/%d+$' ) and
not id:match( '^%d%d%d?/%d+%-%d+$' ) and
not id:match( '^[a-z]/[a-zA-Z][0-9A-Za-z]*$' ) and
not id:match( '^[a-z]/[a-zA-Z][0-9A-Za-z]*%-%d+$' ) then
return false
end
return '[https://dblp.org/pid/'..id..' '..id..']'..p.getCatForId( 'DBLP' )
end

function p.dsiLink( id )
--P2349's format regex: [1-9]\d* (e.g. 1538)
if not id:match( '^[1-9]%d*$' ) then
return false
end
return '[http://www.uni-stuttgart.de/hi/gnt/dsi2/index.php?table_name=dsi&function=details&where_field=id&where_value='..id..' '..id..']'..p.getCatForId( 'DSI' )
end

function p.fnzaLink( id )
--P6792's format regex: [1-9]\d* (e.g. 9785)
if not id:match( '^[1-9]%d*$' ) then
return false
end
return '[https://findnzartists.org.nz/artist/'..id..'/ '..id..']'..p.getCatForId( 'FNZA' )
end

function p.gndLink( id )
--P227's format regex: 1[012]?\d{7}[0-9X]|[47]\d{6}-\d|[1-9]\d{0,7}-[0-9X]|3\d{7}[0-9X] (e.g. 4079154-3)
if not id:match( '^1[012]?%d%d%d%d%d%d%d[0-9X]$' ) and
not id:match( '^[47]%d%d%d%d%d%d%-%d$' ) and
not id:match( '^[1-9]%d?%d?%d?%d?%d?%d?%d?%-[0-9X]$' ) and
not id:match( '^3%d%d%d%d%d%d%d[0-9X]$' ) then
return false
end
return '[https://d-nb.info/gnd/'..id..' '..id..']'..p.getCatForId( 'GND' )
end

function p.hdsLink( id )
--P902's format regex: \d{6} (e.g. 050123)
if not id:match( '^%d%d%d%d%d%d$' ) then
return false
end
return '[https://hls-dhs-dss.ch/fr/articles/'..id..' '..id..']'..p.getCatForId( 'HDS' )
end

function p.iaafLink( id )
--P1146's format regex: [0-9][0-9]* (e.g. 012)
if not id:match( '^%d+$' ) then
return false
end
return '[https://www.iaaf.org/athletes/_/'..id..' '..id..']'..p.getCatForId( 'IAAF' )
end

function p.iciaLink( id )
--P1736's format regex: \d+ (e.g. 1)
if not id:match( '^%d+$' ) then
return false
end
return '[https://www.imj.org.il/artcenter/newsite/en/?artist='..id..' '..id..']'..p.getCatForId( 'ICIA' )
end

function p.isniLink( id )
id = p.validateIsni( id ) --e.g. 0000-0000-6653-4145
if not id then
return false
end
return '[https://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 as of 9/2019
end

function p.jocondeLink( id )
--P347's format regex: [\-0-9A-Za-z]{11} (e.g. 12345678901)
local regex = '^'..string.rep('[%-0-9A-Za-z]', 11)..'$'
if not id:match( regex ) then
return false
end
return '[https://www.pop.culture.gouv.fr/notice/joconde/'..id..' '..id..']'..p.getCatForId( 'Joconde' )
end

function p.kulturnavLink( id )
--P1248's format regex: [0-9a-f]{8}\-[0-9a-f]{4}\-[0-9a-f]{4}\-[0-9a-f]{4}\-[0-9a-f]{12} (e.g. 12345678-1234-1234-1234-1234567890AB)
if not id:match( '^%x%x%x%x%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%x%x%x%x%x%x%x%x$' ) then
return false
end
return '[http://kulturnav.org/'..id..' '..id..']'..p.getCatForId( 'KULTURNAV' ) --no https as of 9/2019
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.lirLink( id )
--P886's format regex: \d+ (e.g. 1)
if not id:match( '^%d+$' ) then
return false
end
return '[http://www.e-lir.ch/e-LIR___Lexicon.'..id..'.450.0.html '..id..']'..p.getCatForId( 'LIR' ) --no https as of 9/2019
end

function p.lnbLink( id )
--P1368's format regex: \d{9} (e.g. 123456789)
if not id:match( '^%d%d%d%d%d%d%d%d%d$' ) then
return false
end
return '[https://kopkatalogs.lv/F?func=direct&local_base=lnc10&doc_number='..id..'&P_CON_LNG=ENG '..id..']'..p.getCatForId( 'LNB' )
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 as of 9/2019
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 id:match( '^%x%x%x%x%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%x%x%x%x%x%x%x%x$' ) then
return false
end
return '[https://musicbrainz.org/artist/'..id..' '..id..']'..p.getCatForId( 'MusicBrainz' ) --special category name
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 id:match( '^%x%x%x%x%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%x%x%x%x%x%x%x%x$' ) then
return false
end
return '[https://musicbrainz.org/area/'..id..' '..id..']'..p.getCatForId( 'MusicBrainz地域' ) --special category name
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 id:match( '^%x%x%x%x%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%x%x%x%x%x%x%x%x$' ) then
return false
end
return '[https://musicbrainz.org/instrument/'..id..' '..id..']'..p.getCatForId( 'MusicBrainz楽器' ) --special category name
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 id:match( '^%x%x%x%x%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%x%x%x%x%x%x%x%x$' ) then
return false
end
return '[https://musicbrainz.org/label/'..id..' '..id..']'..p.getCatForId( 'MusicBrainzレーベル' ) --special category name
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 id:match( '^%x%x%x%x%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%x%x%x%x%x%x%x%x$' ) then
return false
end
return '[https://musicbrainz.org/place/'..id..' '..id..']'..p.getCatForId( 'MusicBrainz場所' ) --special category name
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 id:match( '^%x%x%x%x%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%x%x%x%x%x%x%x%x$' ) then
return false
end
return '[https://musicbrainz.org/release-group/'..id..' '..id..']'..p.getCatForId( 'MusicBrainzリリース・グループ' ) --special category name
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 id:match( '^%x%x%x%x%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%x%x%x%x%x%x%x%x$' ) then
return false
end
return '[https://musicbrainz.org/series/'..id..' '..id..']'..p.getCatForId( 'MusicBrainzシリーズ' ) --special category name
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 id:match( '^%x%x%x%x%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%x%x%x%x%x%x%x%x$' ) then
return false
end
return '[https://musicbrainz.org/work/'..id..' '..id..']'..p.getCatForId( 'MusicBrainz作品' ) --special category name
end

function p.mgpLink( id )
--P549's format regex: \d{1,6} (e.g. 123456)
if not id:match( '^%d%d?%d?%d?%d?%d?$' ) then
return false
end
return '[https://genealogy.math.ndsu.nodak.edu/id.php?id='..id..' '..id..']'..p.getCatForId( 'MGP' )
end

function p.naraLink( id )
--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?$' ) then
return false
end
return '[https://catalog.archives.gov/id/'..id..' '..id..']'..p.getCatForId( 'NARA' )
end

function p.nclLink( id )
--P1048's format regex: \d+ (e.g. 1081436)
if not id:match( '^%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 as of 9/2019
end

function p.ndlLink( id )
--P349's format regex: 0?\d{8} (e.g. 012345678)
if not id:match( '^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.ngvLink( id )
--P2041's format regex: \d+ (e.g. 12354)
if not id:match( '^%d+$' ) then
return false
end
return '[https://www.ngv.vic.gov.au/explore/collection/artist/'..id..'/ '..id..']'..p.getCatForId( 'NGV' )
end

function p.nkcLink( id )
--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?$' ) 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.nlaLink( id )
--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?$' ) then
return false
end
return '[https://nla.gov.au/anbd.aut-an'..id..' '..id..']'..p.getCatForId( 'NLA' )
end

function p.nlgLink( id )
--P3348's format regex: [1-9]\d* (e.g. 1)
if not id:match( '^[1-9]%d*$' ) then
return false
end
return '[https://data.nlg.gr/resource/authority/record'..id..' '..id..']'..p.getCatForId( 'NLG' )
end

function p.nliLink( id )
--P949's format regex: \d{9} (e.g. 123456789)
if not id:match( '^%d%d%d%d%d%d%d%d%d$' ) then
return false
end
return '[http://uli.nli.org.il/F/?func=direct&doc_number='..id..'&local_base=nlx10'..' '..id..']'..p.getCatForId( 'NLI' )
end

function p.nlkLink( id )
--P5034's format regex: KA.(19|20).{7} (e.g. KAC201501465)
if not id:match( '^KA.19.......$' ) and
not id:match( '^KA.20.......$' ) then
return false
end
return '[https://nl.go.kr/authorities/resource/'..id..' '..id..']'..p.getCatForId( 'NLK' )
end

function p.nlpLink( id )
--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]$' ) then
return false
end
return '[https://tools.wmflabs.org/wikidata-externalid-url?p=1695&id='..id..' '..id..']'..p.getCatForId( 'NLP' )
end

function p.nlrLink( id )
--P1003's format regex: \d{9} (e.g. 123456789)
if not id:match( '^%d%d%d%d%d%d%d%d%d$' ) then
return false
end
return '[http://alephnew.bibnat.ro:8991/F?func=find-b&request='..id..'&find_code=SYS&adjacent=Y&local_base=NLR10 '..id..']'..p.getCatForId( 'NLR' )
end

function p.nskLink( id )
--P1375's format regex: \d{9} (e.g. 123456789)
if not id:match( '^%d%d%d%d%d%d%d%d%d$' ) then
return false
end
return '[http://katalog.nsk.hr/F/?func=direct&doc_number='..id..'&local_base=nsk10 '..id..']'..p.getCatForId( 'NSK' ) --no https as of 9/2019
end

function p.ntaLink( id )
--P1006's format regex: \d{8}[\dX] (e.g. 12345678X)
if not id:match( '^%d%d%d%d%d%d%d%d[%dX]$' ) then
return false
end
return '[http://data.bibliotheken.nl/id/thes/p'..id..' '..id..']'..p.getCatForId( 'NTA' )
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.picLink( id )
--P2750's format regex: [1-9]\d* (e.g. 1)
if not id:match( '^[1-9]%d*$' ) then
return false
end
return '[https://pic.nypl.org/constituents/'..id..' '..id..']'..p.getCatForId( 'PIC' )
end

function p.ridLink( id )
--P1053's format regex: [A-Z]{1,3}-\d{4}-20[0-2]\d (e.g. AAS-5150-2020)
if not id:match( '^[A-Z][A-Z]?[A-Z]?%-%d%d%d%d%-20[0-2]%d$' ) then
return false
end
return '[https://www.researcherid.com/rid/'..id..' '..id..']'..p.getCatForId( 'RID' )
end

function p.reroLink( id )
--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]?$' ) then
return false
end
return '[http://data.rero.ch/'..id..' '..id..']'..p.getCatForId( 'RERO' )
end

function p.rkdartistsLink( id )
--P650's format regex: [1-9]\d{0,5} (e.g. 123456)
if not id:match( '^[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.rkdidLink( id )
--P350's format regex: [1-9]\d{0,5} (e.g. 123456)
if not id:match( '^[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.rslLink( id )
--P947's format regex: \d{1,9} (e.g. 123456789)
if not id:match( '^%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 as of 9/2019
end

function p.iccuLink( id )
--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 false
end
return '[https://opac.sbn.it/opacsbn/opac/iccu/scheda_authority.jsp?bid='..id..' '..id..']'..p.getCatForId( 'ICCU' )
end

function p.selibrLink( id )
--P906's format regex: [1-9]\d{4,5} (e.g. 123456)
if not id:match( '^[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.sikartLink( id )
--P781's format regex: \d{7,9} (e.g. 123456789)
if not id:match( '^%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 as of 9/2019
end

function p.snacLink( id )
--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]*$' ) then
return false
end
return '[https://snaccooperative.org/ark:/99166/'..id..' '..id..']'..p.getCatForId( 'SNAC-ID' )
end

function p.sudocLink( id )
--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 false
end
return '[https://www.idref.fr/'..id..' '..id..']'..p.getCatForId( 'SUDOC' )
end

function p.s2authoridLink( id )
--P4012's format regex: [1-9]\d* (e.g. 1796130)
if not id:match( '^[1-9]%d*$' ) then
return false
end
return '[https://www.semanticscholar.org/author/'..id..' '..id..']'..p.getCatForId( 'Semantic Scholar著者' ) --special category name
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 id:match( '^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.tdviaLink( id )
--P7314's format regex: [a-z/-]+] (e.g. barkan-omer-lutfi)
if not id:match( '^[a-z/-]+$' ) then
return false
end
return '[https://islamansiklopedisi.org.tr/'..id..' '..id..']'..p.getCatForId( 'TDVİA' )
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 = id:match( '^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.tepapaLink( id )
--P3544's format regex: \d+ (e.g. 1)
if not id:match( '^%d+$' ) then
return false
end
return '[https://collections.tepapa.govt.nz/agent/'..id..' '..id..']'..p.getCatForId( 'TePapa' )
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 = id:match( '^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

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 as of 9/2019
end

function p.troveLink( id )
--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?$' ) then
return false
end
return '[https://trove.nla.gov.au/people/'..id..' '..id..']'..p.getCatForId( 'Trove' )
end

function p.ukparlLink( id )
--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]$' ) then
return false
end
return '[https://id.parliament.uk/'..id..' '..id..']'..p.getCatForId( 'UKPARL' )
end

function p.ulanLink( id )
--P245's format regex: 500\d{6} (e.g. 500123456)
if not id:match( '^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.uscongressLink( id )
--P1157's format regex: [A-Z]00[01]\d{3} (e.g. A000123)
if not id:match( '^[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 as of 9/2019
end

function p.vcbaLink( id )
--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?$' ) then
return false
end
local id2 = id:gsub('\/', '_')
return '[https://opac.vatlib.it/auth/detail/'..id2..' '..id..']'..p.getCatForId( 'VcBA' )
end

function p.viafLink( id )
--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?$' ) then
return false
end
return '[https://viaf.org/viaf/'..id..' '..id..']'..p.getCatForId( 'VIAF' )
end

--[[=========================== Helper functions =============================]]

function p.append(str, c, length)
while str:len() < length do
str = c .. str
end
return str
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.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

--[[==========================================================================]]
--[[ 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
local qids = {} -- setup any additional QIDs
return ids
if parentArgs.additional=='auto' and qid then -- check P527 for parts to add additional qids
end
local checkparts = function(property)

local parts = mw.wikibase.getBestStatements(qid,property)
function p.matchesWikidataRequirements( itemId, reqs )
if parts then
for _, group in ipairs( reqs ) do
for _,part in ipairs(parts) do
local property = 'P'..group[1]
if part.mainsnak.datavalue and part.mainsnak.datavalue.value.id then
local qid = group[2]
local resolvedqid = resolveQID(part.mainsnak.datavalue.value.id)
local statements = mw.wikibase.getBestStatements( itemId, property )
if statements then
if resolvedqid then
table.insert(qids,resolvedqid)
for _, statement in ipairs( statements ) do
end end end end end
if statement.mainsnak.datavalue then
for _,part in ipairs(config.auto_additional) do
if statement.mainsnak.datavalue.value['numeric-id'] == qid then
checkparts('P'..tostring(part))
return true
end end end end end
end
elseif parentArgs.additional and parentArgs.additional ~= '' then
return false
for _,v in ipairs(mw.text.split(parentArgs.additional,"%s*,%s*")) do
end
v = resolveQID(v)

if v then
function p.createRow( id, label, rawValue, link, withUid, specialCat )
if v == qid then -- duplicate of qid parameter
if link then
auxCats = auxCats .. needsAttention('R')
if withUid then
end
return '*<span class="nowrap">'..label..' <span class="uid">'..link..'</span></span>\n'
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 sections = {}
local catName = '誤った'..(specialCat or id)..'識別子が指定されている記事';
local localparams = false
return '* <span class="error">'..id..'識別子の値'..rawValue..'は正しくありません。</span>[[Category:'..catName..']]'..p.redCatLink(catName)..'\n'
local numsections = 0
end
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


-- check which identifiers to show/suppress in template
-- Creates a human-readable standalone wikitable version of p.conf, and tracking categories with page counts, for use in the documentation
local show = {} -- setup list
function p.docConfTable( frame )
local showall = true
local wikiTable = '{| class="wikitable sortable"\n'..
local function stripP(pid)
'! rowspan=2 | 識別子\n'..
if pid:match("^[Pp]%d+$") then
'! rowspan=2 | 識別子表示名\n'..
pid = mw.ustring.gsub(pid,'[Pp]','') --strip P from property number
'! rowspan=2; data-sort-type=number | ウィキデータのプロパティ\n'..
end
'! colspan=4 | 追跡カテゴリのページ数\n'..
if pid:match("^%d+$") then
'|-\n'..
return tonumber(pid)
'! [[:Category:典拠管理情報がある記事|'.. '記事]]\n'..
'! [[:Category:典拠管理情報がある利用者ページ|'.. '利用者ページ]]\n'..
'! [[:Category:典拠管理情報があるその他のページ|'.. 'その他のページ]]\n'..
'! [[:Category:誤った典拠管理情報が指定されている記事|'..'誤った識別子]]\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 = category..'識別子が指定されている記事'
local userCat = category..'識別子が指定されている利用者ページ'
local miscCat = category..'識別子が指定されているその他のページ'
local faultyCat = '誤った'..category..'識別子が指定されている記事'
--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 ]]
--[[==========================================================================]]

-- 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 it
local reqs = {}

-- Parameter format: { 'parameter name', 'label', propertyId # in Wikidata, formatting/validation function }
p.conf = {
{ 'AAG', '[[:en:Auckland Art Gallery Toi o Tāmaki|AAG]]', 3372, p.aagLink },
{ 'ACM-DL', '[[Association for Computing Machinery|ACM DL]]', 864, p.acmLink },
{ 'ADB', '[[:en:Australian Dictionary of Biography|ADB]]', 1907, p.adbLink },
{ 'AGSA', '[[南オーストラリア美術館|AGSA]]', 6804, p.agsaLink },
{ 'autores.uy', '[[autores.uy]]', 2558, p.autoresuyLink },
{ 'AWR', '[[:en:Australian Women\'s Register|AWR]]', 4186, p.awrLink },
{ 'BALaT', '[[:en:Royal Institute for Cultural Heritage#Online artworks pages|BALaT]]', 3293, p.balatLink },
{ 'BIBSYS', '[[:en:BIBSYS|BIBSYS]]', 1015, p.bibsysLink },
{ 'Bildindex', '[[:en:Marburg Picture Index|Bildindex]]', 2092, p.bildLink },
{ 'BNC', '[[:en:National Library of Chile|BNC]]', 1890, p.bncLink },
{ 'BNE', '[[スペイン国立図書館|BNE]]', 950, p.bneLink },
{ 'BNF', '[[BNF (識別子)|BNF]]', 268, p.bnfLink },
{ 'Botanist', '[[:en:Author citation (botany)|植物学者]]', 428, p.botanistLink },
{ 'BPN', '[[:en:Biografisch Portaal|BPN]]', 651, p.bpnLink },
{ 'CANTIC', '[[:en:Name and Title Authority File of Catalonia|CANTIC]]', 1273, p.canticLink },
{ 'CINII', '[[CiNii (識別子)|CiNii]]', 271, p.ciniiLink },
{ 'DAAO', '[[:en:Dictionary of Australian Artists|DAAO]]', 1707, p.daaoLink },
{ 'DBLP', '[[DBLP]]', 2456, p.dblpLink },
{ 'DSI', '[[:en:Stuttgart Database of Scientific Illustrators 1450–1950|DSI]]', 2349, p.dsiLink },
{ 'FNZA', '[[:d:Property:P6792|FNZA]]', 6792, p.fnzaLink },
{ 'GND', '[[GND (識別子)|GND]]', 227, p.gndLink },
{ 'HDS', '[[スイス歴史事典|HDS]]', 902, p.hdsLink },
{ 'IAAF', '[[ワールドアスレティックス|IAAF]]', 1146, p.iaafLink },
{ 'ICCU', '[[:en:ICCU (identifier)|ICCU]]', 396, p.iccuLink }, --formerly SBN
{ 'ICIA', '[[:en:Information Center for Israeli Art|ICIA]]', 1736, p.iciaLink },
{ 'ISNI', '[[ISNI (識別子)|ISNI]]', 213, p.isniLink },
{ 'Joconde', '[[:en:Joconde|Joconde]]' , 347, p.jocondeLink },
{ 'KULTURNAV', '[[:en:KulturNav|KulturNav]]', 1248, p.kulturnavLink },
{ 'LCCN', '[[LCCN (識別子)|LCCN]]', 244, p.lccnLink },
{ 'LIR', '[[スイス歴史事典|LIR]]', 886, p.lirLink },
{ 'LNB', '[[:en:National Library of Latvia|LNB]]', 1368, p.lnbLink },
{ 'Léonore', '[[:en:Base Léonore|Léonore]]', 640, p.leonoreLink },
{ 'MBA', '[[MusicBrainz]]', 434, p.mbaLink, category = 'MusicBrainz' }, --special category name
{ 'MBAREA', '[[MusicBrainz]]', 982, p.mbareaLink, category = 'MusicBrainz地域' }, --special category name
{ 'MBI', '[[MusicBrainz]]', 1330, p.mbiLink, category = 'MusicBrainz楽器' }, --special category name
{ 'MBL', '[[MusicBrainz]]', 966, p.mblLink, category = 'MusicBrainzレーベル' }, --special category name
{ 'MBP', '[[MusicBrainz]]', 1004, p.mbpLink, category = 'MusicBrainz場所' }, --special category name
{ 'MBRG', '[[MusicBrainz]]リリース・グループ', 436, p.mbrgLink, category = 'MusicBrainzリリース・グループ' }, --special category name
{ 'MBS', '[[MusicBrainz]]', 1407, p.mbsLink, category = 'MusicBrainzシリーズ' }, --special category name
{ 'MBW', '[[MusicBrainz]]作品', 435, p.mbwLink, category = 'MusicBrainz作品' }, --special category name
{ 'MGP', '[[Mathematics Genealogy Project|MGP]]', 549, p.mgpLink },
{ 'NARA', '[[アメリカ国立公文書記録管理局|NARA]]', 1225, p.naraLink },
{ 'NCL', '[[国家図書館|NCL]]', 1048, p.nclLink },
{ 'NDL', '[[国立国会図書館|NDL]]', 349, p.ndlLink },
{ 'NGV', '[[ビクトリア国立美術館|NGV]]', 2041, p.ngvLink },
{ 'NKC', '[[:en:National Library of the Czech Republic|NKC]]', 691, p.nkcLink },
{ 'NLA', '[[オーストラリア国立図書館|NLA]]', 409, p.nlaLink },
{ 'NLG', '[[:en:National Library of Greece|NLG]]', 3348, p.nlgLink },
{ 'NLI', '[[イスラエル国立図書館|NLI]]', 949, p.nliLink },
{ 'NLK', '[[韓国国立中央図書館|NLK]]', 5034, p.nlkLink },
{ 'NLP', '[[ポーランド国立図書館|NLP]]', 1695, p.nlpLink },
{ 'NLR', '[[ルーマニア国立図書館|NLR]]', 1003, p.nlrLink },
{ 'NSK', '[[:en:National and University Library in Zagreb|NSK]]', 1375, p.nskLink },
{ 'NTA', '[[:en:Royal Library of the Netherlands|NTA]]', 1006, p.ntaLink },
{ 'ORCID', '[[ORCID (識別子)|ORCID]]', 496, p.orcidLink },
{ 'PIC', '[[:d:Q23892012|PIC]]', 2750, p.picLink },
{ 'RID', '[[ResearcherID]]', 1053, p.ridLink },
{ 'RERO', '[[:en:RERO (Library Network of Western Switzerland)|RERO]]', 3065, p.reroLink },
{ 'RKDartists', '[[オランダ美術史研究所#美術家ページ|RKD]]', 650, p.rkdartistsLink },
{ 'RKDID', '[[オランダ美術史研究所#作品ページ|RKDimages ID]]', 350, p.rkdidLink },
{ 'RSL', '[[ロシア国立図書館 (モスクワ)|RSL]]', 947, p.rslLink },
{ 'SELIBR', '[[:en:SELIBR (identifier)|SELIBR]]', 906, p.selibrLink },
{ 'SIKART', '[[:en:SIKART|SIKART]]', 781, p.sikartLink },
{ 'SNAC-ID', '[[SNAC]]', 3430, p.snacLink },
{ 'SUDOC', '[[SUDOC (識別子)|SUDOC]]', 269, p.sudocLink },
{ 'S2AuthorId', '[[:en:Semantic Scholar|S2AuthorId]]', 4012, p.s2authoridLink, category = 'Semantic Scholar著者' }, --special category name
{ 'TA98', '[[:en:Terminologia Anatomica|TA98]]', 1323, p.ta98Link },
{ 'TDVİA', '[[:en:İslâm Ansiklopedisi|TDVİA]]', 7314, p.tdviaLink },
{ 'TE', '[[:en:Terminologia Embryologica|TE]]', 1693, p.teLink },
{ 'TePapa', '[[ニュージーランド国立博物館テ・パパ・トンガレワ|TePapa]]', 3544, p.tepapaLink },
{ 'TH', '[[:en:Terminologia Histologica|TH]]', 1694, p.thLink },
{ 'TLS', '[[:en:Theaterlexikon der Schweiz|TLS]]', 1362, p.tlsLink },
{ 'Trove', '[[:en:Trove|Trove]]', 1315, p.troveLink }, --formerly NLA-person
{ 'UKPARL', '[[UKPARL (識別子)|英議会]]', 6213, p.ukparlLink },
{ 'ULAN', '[[:en:Union List of Artist Names|ULAN]]', 245, p.ulanLink },
{ 'USCongress', '[[:en:Biographical Directory of the United States Congress|米議会]]', 1157, p.uscongressLink },
{ 'VcBA', '[[VcBA (識別子)|VcBA]]', 8034, p.vcbaLink },
{ 'VIAF', '[[VIAF (識別子)|VIAF]]', 214, p.viafLink },
{ 'WORLDCATID', '[[WorldCat Identities (識別子)|WorldCat Identities]]', 7859, nil, category = 'WorldCat' },
}

-- Legitimate aliases to p.conf, for convenience
-- Format: { 'alias', 'parameter name in p.conf' }
p.aliases = {
{ 'MusicBrainz', 'MBA' },
{ 'MusicBrainz artist', 'MBA' },
{ 'MusicBrainz label', 'MBL' },
{ 'MusicBrainz release group', 'MBRG' },
{ 'MusicBrainz work', 'MBW' },
{ 'Leonore', 'Léonore' }, --alias name without diacritics
{ 'leonore', 'Léonore' }, --lowercase variant without diacritics
{ '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
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)
if list and list ~= '' then
--Redirect deprecated parameters to proper parameter names, and assign tracking cat
for _, d in pairs( p.deprecated ) do
for _,v in ipairs(mw.text.split(string.lower(list),"%s*,%s*")) do
local dep, param = d[1], d[2]
local vprop = stripP(v)
if vprop then -- e.g. show=P214 to show one particular property
if (parentArgs[param] == nil or parentArgs[param] == '') and parentArgs[dep] then
parentArgs[param] = parentArgs[dep]
show[vprop] = true
else -- e.g. show=arts to use whitelist
if namespace == 0 then
if config.whitelists[v] then
deprecatedIdCat = '[[Category:非推奨の典拠管理識別子が指定されている記事|'..dep..']]'
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
addshowlist(parentArgs.show or parentArgs.country) -- check show parameter on article template
--Use QID= parameter for testing/example purposes only
if parentArgs.suppress then
local itemId = nil
local suppresslist = mw.text.split(parentArgs.suppress,"%s*,%s*") -- split parameter by comma
if namespace ~= 0 then
for _,v in ipairs(suppresslist) do
local qid = parentArgs['qid'] or parentArgs['QID']
v = stripP(string.upper(v))
if qid then
if v then
itemId = 'Q'..mw.ustring.gsub(qid, '^[Qq]', '')
show[v] = false
itemId = resolveEntity._id(itemId) --nil if unresolvable
auxCats = auxCats .. '[[' .. config.i18n.category .. ':' .. config.i18n.suppressedcat .. ']]'
else
auxCats = auxCats .. needsAttention('P')
end
end
end
else
itemId = mw.wikibase.getEntityIdForCurrentPage()
end
end
local function makeSections(qid,addit)
--Wikidata fallback if requested
local tval = {}
if itemId then
local function parameter_is_used(property)
for _, params in ipairs( p.conf ) do
if params[3] > 0 then
local used = false
if property then
local val = parentArgs[mw.ustring.lower(params[1])] or parentArgs[params[1]]
if val == nil or val == '' then
if tval[property] then
local canUseWikidata = nil
if tval[property][1] then
if reqs[params[1]] then
used = true
canUseWikidata = p.matchesWikidataRequirements( itemId, reqs[params[1]] )
else
canUseWikidata = true
end
end
elseif tval[property] == false then -- property has been manually suppressed
if canUseWikidata then
used = true
local wikidataIds = p.getIdsFromWikidata( itemId, 'P'..params[3] )
end
if wikidataIds[1] then
end
if val == '' and (namespace == 0 or testcases) then
return used
suppressedIdCat = '[[Category:抑制された典拠管理識別子がある記事|'..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[mw.ustring.lower(params[1])] or parentArgs[params[1]]
if val and val ~= '' and type(params[4]) == 'function' then
table.insert( elements, p.createRow( params[1], params[2]..':', val, params[4]( val ), true, params.category ) )
rct = rct + 1
end
end
for _, params in ipairs(conf) do
end
tval[params.property] = getIdsFromWikidata(qid, 'P' .. params.property) -- setup table for values with property number as key
local showb = true
--WorldCat
if (show[params.property] == nil) and (show[string.upper(params[1])] == nil ) then
local worldcatId = parentArgs['worldcatid'] or parentArgs['WORLDCATID']
showb = showall -- if not specified then depends on showall
if worldcatId and worldcatId ~= '' then --if WORLDCATID present & unsuppressed
elseif (show[params.property] == false) or (show[string.upper(params[1])] == false) then -- if either are false then id will be suppressed
table.insert( elements, p.createRow( 'WORLDCATID', '', worldcatId, '[[WorldCat Identities (識別子)|WorldCat Identities]]: [https://www.worldcat.org/identities/'..worldcatId..' '..worldcatId..']', false ) ) --Validation?
showb = false
worldcatCat = '[[Category:WorldCat識別子が指定されている記事]]'
elseif worldcatId == nil then --if WORLDCATID absent but unsuppressed
local 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, & validated
table.insert( elements, p.createRow( 'VIAF', '', viafId, '[[WorldCat Identities (識別子)|WorldCat Identities]](VIAF経由): [https://www.worldcat.org/identities/containsVIAFID/'..viafId..' '..viafId..']', false ) )
if namespace == 0 then
worldcatCat = '[[Category:WorldCat-VIAF識別子が指定されている記事]]'
end
end
if not showb then
elseif lccnId and lccnId ~= '' and p.lccnLink( lccnId ) then --LCCN must be present, unsuppressed, & validated
tval[params.property] = false -- indicates the identifier is suppressed
local lccnParts = p.splitLccn( lccnId )
if lccnParts and lccnParts[1] ~= 'sh' then
elseif not addit then
local lccnIdFmtd = lccnParts[1]..lccnParts[2]..'-'..lccnParts[3]
local val = parentArgs[mw.ustring.lower(params[1])] or parentArgs[params[1]]
if val and val~='' then -- add local parameter to list if not already in
table.insert( elements, p.createRow( 'LCCN', '', lccnId, '[[WorldCat Identities (識別子)|WorldCat Identities]](LCCN経由): [https://www.worldcat.org/identities/lccn-'..lccnIdFmtd..' '..lccnIdFmtd..']', false ) )
if namespace == 0 then
localparams = true
local bnew = true
worldcatCat = '[[Category:WorldCat-LCCN識別子が指定されている記事]]'
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
-- 末尾はQ328(英語版ウィキペディア)ではなくQ177837(日本語版ウィキペディア)とする
qslink = qslink .. '%7C%7C' .. qid .. '%7CP' .. params.property .. '%7C%22' .. mw.uri.encode(val,"PATH") .. '%22%7CS143%7CQ177837'
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 WORLDCATID suppressed
suppressedIdCat = '[[Category:抑制された典拠管理識別子がある記事|WORLDCATID]]'
end
end
local function pencil(qid)
if not qid then
local Navbox = require('Module:Navbox')
return ''
local elementsCat = ''
end
if rct == 0 or rct >= 25 then
local args = { pid = 'identifiers' } -- #target the list of identifiers
--local eCat = rct..'種類以上の識別子があるページ'
args.qid = qid
--elementsCat = '[[Category:'..eCat..']]'..p.redCatLink(eCat)
return require('Module:EditAtWikidata')._showMessage(args)
elementsCat = '' --25種類以上の識別子が指定された場合、追跡カテゴリをつけるという機能は日本語版では導入されていない
end
end

makeSections(qid,false)
for c = 1,#qids do
makeSections(qids[c],numsections+c)
end

--configure Navbox
local outString = ''
local outString = ''
if rct or localparams then -- there is at least one link to display
if #elements > 0 then
local Navbox = require('Module:Navbox')
local args = { pid = 'identifiers' } -- #target the list of identifiers
local sect,lastsect = 0,0
if testcases and itemId then args = { pid = 'identifiers', qid = itemId } end --expensive
local navboxArgs = {
local pencil = frame:expandTemplate{ title = 'EditAtWikidata', args = args}
name = 'Authority control',
outString = Navbox._navbox( {
name = 'Normdaten',
navboxclass = 'authority-control',
navboxclass = 'authority-control',
bodyclass = 'hlist',
bodyclass = 'hlist',
state = parentArgs.state or config.i18n.autocollapse,
group1 = '[[Help:典拠管理|典拠管理]]'..pencil,
navbar = 'off'
list1 = table.concat( elements )
} )
}
for c=1,numsections+#qids do
if #sections[c] ~= 0 then -- section is non-empty
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
if localparams then
lastsect = lastsect + 1
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">&#32;[[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
if topic then -- display in expanded form with topic
navboxArgs.title = config.i18n.aclink .. ' &ndash; ' .. 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)
else -- 典拠管理識別子が1つもない
if namespace == 0 or testcases then
auxCats = auxCats .. addCat('典拠管理識別子が1つもない記事')
end
end
end
if parentArgs.state
local auxCats = worldcatCat .. elementsCat .. suppressedIdCat .. deprecatedIdCat
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
if testcases then
auxCats = mw.ustring.gsub(auxCats, '(%[%[)(Category)', '%1:%2') --for easier checking
auxCats = mw.ustring.gsub(auxCats, '(%[%[)(' .. config.i18n.category .. ')', '%1:%2') --for easier checking
end
end

outString = outString .. auxCats
--out
outString = outString..auxCats
if namespace ~= 0 then
if namespace ~= 0 then
-- 日本語版独自の変更あり
outString = mw.ustring.gsub(outString, '(%[%[)(Category:[^%]]*記事)', '%1:%2') --by definition
outString = mw.ustring.gsub(outString,'(%[%[)(' .. config.i18n.category .. ':)([^%|%]]+' .. config.i18n.Articles .. ')%|?[^%|%]]*(%]%])','%1:%2%3%4')
end
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



2023年8月31日 (木) 12:46時点における最新版

このモジュールについての説明文ページを モジュール:Authority control/doc に作成できます

require('strict')
local p = {}
local configfile = 'Module:Authority control/config' -- default configuation module
local arg = mw.getCurrentFrame().args.config
if arg and arg~='' then
	configfile = 'Module:Authority control/config/' .. arg
end
local config
if mw.title.new(configfile).exists then
	config = mw.loadData(configfile)
else
	return error('Invalid configuration file',0)
end
local title = mw.title.getCurrentTitle()
local namespace = title.namespace
local testcases = title.subpageText == config.i18n.testcases

local function needsAttention(sortkey)
	return '[[' .. config.i18n.category .. ':' .. config.i18n.attentioncat .. '|' .. sortkey .. title.text .. ']]'
end

local function addCat(cat,sortkey)
	if cat and cat ~= '' and (namespace == 0 or namespace == 14 or testcases) then
		local redlinkcat = ''
		if testcases == false and mw.title.new(cat, 14).exists == false then
			redlinkcat = needsAttention('N')
		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
		return ''
	end
end

local function getCatForId(id,faulty)
	local cat = string.format(
		config.i18n.cat,
		faulty and config.i18n.faulty..id or id
	)
	return addCat(cat)
end

local function getIdsFromWikidata(qid,property)
	local function getquals(statement,qualid)
		if statement.qualifiers and statement.qualifiers['P'..qualid] then
			return mw.wikibase.renderSnak(statement.qualifiers['P'..qualid][1])
		else
			return false
		end
	end
	local ids = {}
	if qid then
		for _, statement in ipairs(mw.wikibase.getBestStatements(qid,property)) do
			if statement.mainsnak.datavalue then
				local val = statement.mainsnak.datavalue.value
				if val then
					local namedas = getquals(statement,1810) or getquals(statement,742) or ''
					table.insert(ids,{id=val,name=namedas})
				end
			end
		end
	end
	return ids
end

local _makelink = function(conf,val,nextid,qid) --validate values and create a link
	local function tooltip(text,label)
		if label and label~='' then
			return mw.getCurrentFrame():expandTemplate{title = "Tooltip", args = {text,label}}
		else
			return text
		end
	end
	local link
	if nextid==1 then
		if conf.prefix then
			link = '*' .. conf.prefix .. '\n**'
		else
			link = '*'
		end
	else
		link = '\n**'
	end
	local valid_value = false
	if conf.customlink then -- use function to validate and generate link
		local label = nextid>1 and nextid
		local newlink= require(config.auxiliary)[conf.customlink](val.id,label)
		if newlink then
			link = link .. newlink
			valid_value = true
		end
	else
		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
	if valid_value then
		link = link .. getCatForId(conf.category or conf[1])
	else
		--local preview = require("Module:If preview")
		local wdlink = qid and '[[:wikidata:' .. qid .. '#P' .. conf.property .. ']]' or ''
		local tooltip = string.format(
			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
	return link
end

--[[==========================================================================]]
--[[                                   Main                                   ]]
--[[==========================================================================]]
function p.authorityControl(frame)
	local function resolveQID(qid)
		if qid then
			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
	local conf = config.config
	local parentArgs = frame:getParent().args
	local auxCats = ''
	local rct = false -- boolean to track if there are any links to be returned
	local qid,topic
	local wikilink = function(qid,hideifequal)
		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
	if namespace == 0 then
		qid = mw.wikibase.getEntityIdForCurrentPage()
	end
	if qid then -- article is connected to Wikidata item
		if parentArgs.qid and (resolveQID(parentArgs.qid) ~= qid) then -- non-matching qid parameter
			auxCats = auxCats .. needsAttention('D')
		end
	else -- page is not connected to any Wikidata item
		qid = resolveQID(parentArgs.qid) -- check qid parameter if no wikidata item is connected
		if qid then -- qid parameter is valid, set topic to display
			topic = mw.wikibase.getLabel(qid)
			if topic then
				if mw.ustring.lower(title.subpageText) == mw.ustring.lower(topic) then -- suppress topic display if subpagename equals topic up to case change
					topic = nil
				end
				if topic and mw.wikibase.getSitelink(qid) then -- make wikilink to article
					topic = '[[' .. mw.wikibase.getSitelink(qid) .. '|' .. topic .. ']]'
				end
			else
				auxCats = auxCats .. needsAttention('L')
			end
		elseif parentArgs.qid and parentArgs.qid~='' then -- invalid qid has been supplied, add to tracking cat
			auxCats = auxCats .. needsAttention('Q')
		end
	end
	local qids = {} -- setup any additional QIDs
	if parentArgs.additional=='auto' and qid then  -- check P527 for parts to add additional qids
		local checkparts = function(property)
			local parts = mw.wikibase.getBestStatements(qid,property)
			if parts then
				for _,part in ipairs(parts) do
					if part.mainsnak.datavalue and part.mainsnak.datavalue.value.id then
						local resolvedqid = resolveQID(part.mainsnak.datavalue.value.id)
						if resolvedqid then
							table.insert(qids,resolvedqid)
		end end end end end
		for _,part in ipairs(config.auto_additional) do
			checkparts('P'..tostring(part))
		end
	elseif parentArgs.additional and parentArgs.additional ~= '' then
		for _,v in ipairs(mw.text.split(parentArgs.additional,"%s*,%s*")) do
			v = resolveQID(v)
			if v then
				if v == qid then -- duplicate of qid parameter
					auxCats = auxCats .. needsAttention('R')
				end
				table.insert(qids,v)
			else -- invalid QID specified
				auxCats = auxCats .. needsAttention('A')
			end
		end
	end

	local sections = {}
	local localparams = false
	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

	-- check which identifiers to show/suppress in template
	local show = {} -- setup list
	local showall = true
	local function stripP(pid)
		if pid:match("^[Pp]%d+$") then
			pid = mw.ustring.gsub(pid,'[Pp]','') --strip P from property number
		end
		if pid:match("^%d+$") then
			return tonumber(pid)
		end
	end
	local function addshowlist(list)
		if list and list ~= '' then
			for _,v in ipairs(mw.text.split(string.lower(list),"%s*,%s*")) do
				local vprop = stripP(v)
				if vprop then -- e.g. show=P214 to show one particular property
					show[vprop] = true
				else -- e.g. show=arts to use whitelist
					if config.whitelists[v] then
						for _,w in ipairs(config.whitelists[v].properties) do
							show[w] = true
						end
					end
				end
			end
			showall = false
		end
	end
	addshowlist(frame.args.show) -- check show= parameter on wrapper template
	addshowlist(parentArgs.show or parentArgs.country) -- check show parameter on article template
	if parentArgs.suppress then
		local suppresslist = mw.text.split(parentArgs.suppress,"%s*,%s*") -- split parameter by comma
		for _,v in ipairs(suppresslist) do
			v = stripP(string.upper(v))
			if v then
				show[v] = false
				auxCats = auxCats .. '[[' .. config.i18n.category .. ':' .. config.i18n.suppressedcat .. ']]'
			else
				auxCats = auxCats .. needsAttention('P')
			end
		end
	end
	
	local function makeSections(qid,addit)
		local tval = {}
		local function parameter_is_used(property)
			local used = false
			if property then
				if tval[property] then
					if tval[property][1] then
						used = true
					end
				elseif tval[property] == false then -- property has been manually suppressed
					used = true
				end
			end
			return used
		end
		for _, params in ipairs(conf) do
			tval[params.property] = getIdsFromWikidata(qid, 'P' .. params.property) -- setup table for values with property number as key
			local showb = true
			if (show[params.property] == nil) and (show[string.upper(params[1])] == nil ) then
				showb = showall -- if not specified then depends on showall
			elseif (show[params.property] == false) or (show[string.upper(params[1])] == false) then -- if either are false then id will be suppressed
				showb = false
			end
			if not showb then
				tval[params.property] = false -- indicates the identifier is suppressed
			elseif not addit then
				local val = parentArgs[mw.ustring.lower(params[1])] or parentArgs[params[1]]
				if val and val~='' then -- add local parameter to list if not already in
					localparams = true
					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
							-- 末尾はQ328(英語版ウィキペディア)ではなくQ177837(日本語版ウィキペディア)とする
							qslink = qslink .. '%7C%7C' .. qid .. '%7CP' .. params.property .. '%7C%22' .. mw.uri.encode(val,"PATH") .. '%22%7CS143%7CQ177837'
						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
	local function pencil(qid)
		if not qid then
			return ''
		end
		local args = { pid = 'identifiers' } -- #target the list of identifiers
		args.qid = qid
		return require('Module:EditAtWikidata')._showMessage(args)
	end

	makeSections(qid,false)
	for c = 1,#qids do
		makeSections(qids[c],numsections+c)
	end

	--configure Navbox
	local outString = ''
	if rct or localparams then -- there is at least one link to display
		local Navbox = require('Module:Navbox')
		local sect,lastsect = 0,0
		local navboxArgs = {
			name  = 'Authority control',
			navboxclass = 'authority-control',
			bodyclass = 'hlist',
			state = parentArgs.state or config.i18n.autocollapse,
			navbar = 'off'
		}
		for c=1,numsections+#qids do
			if #sections[c] ~= 0 then -- section is non-empty
				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
		if localparams then
			lastsect = lastsect + 1
			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">&#32;[[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
		if topic then -- display in expanded form with topic
			navboxArgs.title = config.i18n.aclink .. ' &ndash; ' .. 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)
	else -- 典拠管理識別子が1つもない
		if namespace == 0 or testcases then
			auxCats = auxCats .. addCat('典拠管理識別子が1つもない記事')
		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')
	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
end

p.makelink = function(conf,val,nextid,qid)
	return _makelink(conf,val,nextid,qid)
end

return p