Module:Authority control

This module contains the code for the {{Authority control}} template.

Please see Template:Authority control/doc.


require('strict')

local function getCatForId( id )
	return ""
end

local function viafLink( id )
    if not string.match( id, '^%d+$' ) then
        return false
    end
    return '[https://viaf.org/viaf/' .. id .. ' ' .. id .. ']' .. getCatForId( 'VIAF' )
end

local function kulturnavLink( id )
    return '[https://kulturnav.org/language/en/' .. id .. ' id]' 
end

local function sikartLink( id )
    return '[https://www.sikart.ch/KuenstlerInnen.aspx?id=' .. id .. '&lng=en ' .. id .. ']' 
end

local function tlsLink( id )
	local id2 = mw.ustring.gsub(id, '%s', function(s) return mw.uri.encode(s, 'WIKI') end)
    return '[http://tls.theaterwissenschaft.ch/wiki/' .. id2 .. ' ' .. id .. ']' 
end

local function ciniiLink( id )
    return '[https://ci.nii.ac.jp/author/' .. id .. '?l=en ' .. id .. ']' 
end

local function bneLink( id )
    return '[http://catalogo.bne.es/uhtbin/authoritybrowse.cgi?action=display&authority_id=' .. id .. ' ' .. id .. ']' 
end


local function uscongressLink( id )
    return '[https://bioguide.congress.gov/scripts/biodisplay.pl?index=' .. id .. ' ' .. id .. ']' 
end

local function narapersonLink( id )
    return '[https://research.archives.gov/person/' .. id .. ' ' .. id .. ']' 
end

local function naraorganizationLink( id )
    return '[https://research.archives.gov/organization/' .. id .. ' ' .. id .. ']' 
end

local function harvardBotanistLink( id )
    return '[https://kiki.huh.harvard.edu/databases/botanist_search.php?id=' .. id .. ' ' .. id .. ']' 
end

local function botanistLink( id )
	local id2 = mw.ustring.gsub(id, '%s', function(s) return mw.uri.encode(s, 'PATH') end)
    return '[https://www.ipni.org/ipni/advAuthorSearch.do?find_abbreviation=' .. id2 .. ' ' .. id .. ']' 
end

local function mgpLink( id )
    -- TODO Implement some sanity checking regex
    return '[https://www.genealogy.ams.org/id.php?id=' .. id .. ' ' .. id .. ']' 
end

local function rslLink( id )
    -- TODO Implement some sanity checking regex
    return '[http://aleph.rsl.ru/F?func=find-b&find_code=SYS&adjacent=Y&local_base=RSL11&request=' .. id .. '&CON_LNG=ENG ' .. id .. ']'
end

local function leonoreLink( id )
-- Identifiants allant de LH/1/1 à LH/2794/54 (légionnaires)
-- Identifiants allant de C/0/1 à C/0/84 (84 légionnaires célèbres)
-- Identifiants allant de 19800035/1/1 à 19800035/385/51670 (légionnaires décédés entre 1954 et 1977, et quelques dossiers de légionnaires décédés avant 1954)
    if not string.match( id, '^LH/%d%d?%d?%d?/%d%d?%d?$' ) and
       not string.match( id, '^C/0/%d%d?$' ) and
	   not string.match( id, '^19800035/%d%d?%d?%d?/%d%d?%d?%d?%d?$' ) then
        return false
    end
    return '[//www.culture.gouv.fr/public/mistral/leonore_fr?ACTION=CHERCHER&FIELD_1=COTE&VALUE_1=' .. id .. ' ' .. id .. ']' 
end

local function iccuLink( id )
	--P396's format regex: \D{2}[A-Z0-3]V\d{6} (e.g. CFIV000163)
	if not id:match( '^%u%u[%u0-3]V%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/nome/'..id..' ' .. id .. ']' .. getCatForId( 'ICCU' )
end

local function nkcLink( id )
	return '[https://aleph.nkp.cz/F/?func=find-c&local_base=aut&ccl_term=ica=' .. id .. '&CON_LNG=ENG ' .. id .. ']' 
end

local function nclLink( id )
    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 .. ']' 
end

local function ndlLink( id )
	return '[https://id.ndl.go.jp/auth/ndlna/' .. id .. ' ' .. id .. ']' 
end

local function sudocLink( id )
    if not string.match( id, '^%d%d%d%d%d%d%d%d[%dxX]$' ) then
        return false
    end
    return '[https://www.idref.fr/' .. id .. ' ' .. id .. ']' 
end

local function hlsLink( id )
    if not string.match( id, '^%d+$' ) then
        return false
    end
    return '[http://www.hls-dhs-dss.ch/textes/f/F' .. id .. '.php ' .. id .. ']'
end

local function lirLink( id )
    if not string.match( id, '^%d+$' ) then
        return false
    end
    return '[http://www.e-lir.ch/e-LIR___Lexicon.' .. id .. '.450.0.html ' .. id .. ']'
end

local function splitLccn( id )
    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

local function append(str, c, length)
    while str:len() < length do
        str = c .. str
    end
    return str
end

local function lccnLink( id )
    local parts = splitLccn( id )
    if not parts then
        return false
    end
    local lccnType = parts[1] ~= 'sh' and 'names' or 'subjects'
    id = parts[1] .. parts[2] .. append( parts[3], '0', 6 )
    return '[https://id.loc.gov/authorities/' .. lccnType .. '/' .. id .. ' ' .. id .. ']' .. getCatForId( 'LCCN' )
end

local function mbLink( id )
    -- TODO Implement some sanity checking regex
    return '[//musicbrainz.org/artist/' .. id .. ' ' .. id .. ']' .. getCatForId( 'MusicBrainz' )
end

--Returns the ISNI check digit isni must be a string where the 15 first elements are digits
local function 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 https://support.orcid.org/knowledgebase/articles/116780-structure-of-the-orcid-identifier
local function validateIsni( id )
    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 getIsniCheckDigit( id ) ~= string.char( id:byte( 16 ) ) then
        return false
    end
    return id
end

local function isniLink( id )
    id = validateIsni( id )
    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 ) .. ']' .. getCatForId( 'ISNI' )
end

local function orcidLink( id )
    id = validateIsni( id )
    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 .. ']' .. getCatForId( 'ORCID' )
end

local function gndLink( id )
    return '[https://d-nb.info/gnd/' .. id .. ' ' .. id .. ']' .. getCatForId( 'GND' )
end

local function selibrLink( id )
	if not string.match( id, '^%d+$' ) then
        return false
    end
    return '[https://libris.kb.se/auth/' .. id .. ' ' .. id .. ']' .. getCatForId( 'SELIBR' )
end

local function bnfLink( id )
    --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 .. '] [https://data.bnf.fr/ark:/12148/' .. id .. ' (data)]' .. getCatForId( 'BNF' )
end

local function bpnLink( id )
    if not string.match( id, '^%d+$' ) then
        return false
    end
    return '[http://www.biografischportaal.nl/en/persoon/' .. id .. ' ' .. id .. ']' .. getCatForId( 'BPN' )
end

local function ridLink( id )
    return '[https://www.researcherid.com/rid/' .. id .. ' ' .. id .. ']' .. getCatForId( 'RID' )
end

local function bibsysLink( id )
    return '[https://authority.bibsys.no/authority/rest/authorities/html/' .. id .. ' ' .. id .. ']' .. getCatForId( 'BIBSYS' )
end

local function ulanLink( id )
    return '[//www.getty.edu/vow/ULANFullDisplay?find=&role=&nation=&subjectid=' .. id .. ' ' .. id .. ']' .. getCatForId( 'ULAN' )
end

local function nlaLink( id )
	return '[//nla.gov.au/anbd.aut-an' .. id .. ' ' .. id .. ']' .. getCatForId( 'NLA' )
end

local function rkdartistsLink( id )
	return '[https://rkd.nl/en/explore/artists/' .. id .. ' ' .. id .. ']' .. getCatForId( 'RKDartists' )
end

local function kidlink( id )
	return '[https://www.kulturarv.dk/kid/VisKunstner.do?kunstnerId=' .. id .. ' ' .. id .. ']' .. getCatForId( 'KID' )
end

local function BionomiaLink( id )
	return '[https://bionomia.net/' .. id .. ' ' .. id .. ']'
end

local function fotobibllink( id )
	return '[http://fotobiobibliografie.albertina.at/cgi-bin/such_ausgabe.pl?scid=' ..id .. '&lang={{langSwitch|de=de|en=en}} ' .. id .. ']' .. getCatForId( 'FotoBibl' )
end

local function mendeley( id )
	return '[https://mendeley.com/profiles/' ..id .. ' ' .. id .. ']' .. getCatForId( 'Mendeley' )
end

local function museofilelink( id )
	return '[https://www.culture.gouv.fr/public/mistral/museo_fr?ACTION=CHERCHER&FIELD_98=REF&VALUE_98=' ..id .. ' ' .. id .. ']' .. getCatForId( 'Museofile' )
end

local function nhm( id )
	return '[https://www.nhm.ac.uk/CalmView/Record.aspx?src=CalmView.Persons&id=' ..id .. ' ' .. id .. ']'
end

local function nlm( id )
	return '[https://locatorplus.gov/cgi-bin/Pwebrecon.cgi?DB=local&v1=1&ti=1,1&Search_Arg=' ..id .. '&Search_Code=0359&CNT=25&SID=1 ' .. id .. ']' .. getCatForId( 'Museofile' )
end

local function ipniAuthorLink( id )
    return '[https://www.ipni.org/ipni/idAuthorSearch.do?id=' .. id .. ' ' .. id .. ']'
end

local function zooBankAuthorsLink( id )
    return '[http://zoobank.org/Authors/' .. id .. ' ' .. id .. ']'
end

local function ifpniLink( id )
    return '[http://www.ifpni.org/author.htm?id=' .. id .. ' ' .. id .. ']'
end

local function googleScholarLink( id )
    return '[https://scholar.google.com/citations?user=' .. id .. ' ' .. id .. ']'
end

local function scopusLink( id )
    return '[https://www.scopus.com/authid/detail.uri?authorId=' .. id .. ' ' .. id .. ']'
end

local function researchGateLink( id )
    return '[https://www.researchgate.net/profile/' .. id .. ' ' .. id .. ']'
end

local function zooBankRefLink( id )
	return '[http://zoobank.org/References/' .. id .. ' ' .. id .. ']'
end

local function bioStorWorkLink( id )
	return '[https://biostor.org/reference/' .. id .. ' ' .. id .. ']'
end

local function researchGateRefLink( id )
	return '[https://www.researchgate.net/publication/' .. id .. ' ' .. id .. ']'
end

local function doiLink( id )
	return '[https://doi.org/' .. id .. ' ' .. id .. ']'
end

local function pubMedLink( id )
	return '[https://www.ncbi.nlm.nih.gov/pmc/articles/PMC' .. id .. ' ' .. id .. ']'
end

local function plaziRefLink( id )
	return '[http://publication.plazi.org/id/' .. id .. ' ' .. id .. ']'
end

local function wormsRefLink( id )
	return '[https://www.marinespecies.org/aphia.php?p=sourcedetails&id=' .. id .. ' ' .. id .. ']'
end

local function bhlPageLink( id )
	return '[https://biodiversitylibrary.org/page/' .. id .. ' ' .. id .. ']'
end

local function bhlPartLink( id )
	return '[https://www.biodiversitylibrary.org/part/' .. id .. ' ' .. id .. ']'
end

local function internetArchiveLink( id )
	return '[https://archive.org/details/' .. id .. ' ' .. id .. ']'
end

local function zenodoLink( id )
	return '[https://zenodo.org/record/' .. id .. ' ' .. id .. ']'
end

local function academicTreeLink( id )
	return '[https://academictree.org/chemistry/peopleinfo.php?pid=' .. id .. ' ' .. id .. ']'
end

local function semanticScholar( id )
	return '[https://www.semanticscholar.org/author/' .. id .. ' ' .. id .. ']'
end

local function CiNiiBooksLink( id )
	return '[https://ci.nii.ac.jp/author/' .. id .. ' ' .. id .. ']'
end

local function CiNiiJournalsLink( id )
	return '[https://ci.nii.ac.jp/nrid/' .. id .. ' ' .. id .. ']'
end

local function ipniPubLink( id )
    return '[http://www.ipni.org/ipni/idPublicationSearch.do?id=' .. id .. ' ' .. id .. ']'
end

local function bphLink( id )
	return id
end

local function bhlBiblioLink( id )
    return '[https://www.biodiversitylibrary.org/bibliography/' .. id .. ' ' .. id .. ']'
end

local function bhlCreatorLink( id )
    return '[https://www.biodiversitylibrary.org/creator/' .. id .. ' ' .. id .. ']'
end

local function openCitationsLink( id )
    return '[https://w3id.org/oc/corpus/br/' .. id .. '.html ' .. id .. ']'
end

local function uniProtLink( id )
    return '[https://www.uniprot.org/journals/' .. id .. ' ' .. id .. ']'
end

local function entWorldLink( id )
    return '[http://sdei.senckenberg.de/biographies/information.php?id=' .. id .. ' ' .. id .. ']'
end

local function msAcadLink( id )
    return '[https://academic.microsoft.com/v2/detail/' .. id .. ' ' .. id .. ']'
end

local function trovePeopleLink( id )
    return '[https://trove.nla.gov.au/people/' .. id .. ' ' .. id .. ']'
end

local function troveWorkLink( id )
    return '[https://trove.nla.gov.au/work/' .. id .. ' ' .. id .. ']'
end

local function oclcLink( id )
    return '[https://www.worldcat.org/oclc/' .. id .. ' ' .. id .. ']'
end

local function worldCatEntLink( id )
    return '[https://id.oclc.org/worldcat/entity/' .. id .. ' ' .. id .. ']'
end

local function getIdsFromWikidata( item, property )
    local ids = {}
    if not item.claims[property] then
        return ids
    end
    for _, statement in pairs( item:getBestStatements( property )) do
		if statement.mainsnak.datavalue then
			table.insert( ids, statement.mainsnak.datavalue.value )
		end
    end
    return ids
end

local function matchesWikidataRequirements( item, reqs )
    for _, group in pairs( reqs ) do
        local property = 'p' .. group[1]
        local qid = group[2]
        if item.claims[property] ~= nil then
            for _, statement in pairs ( item.claims[property] ) do
            	if statement.mainsnak.datavalue ~= nil then
	                if statement.mainsnak.datavalue.value['numeric-id'] == qid then
    	                return true
        	        end
        	    end
            end
        end
    end
    return false
end

local function createRow( id, label, rawValue, link, withUid )
    if link then
        if withUid then
            return '* ' .. label .. ' <span class="uid">' .. link .. '</span>\n'
        else
            return '* ' .. label .. ' ' .. link .. '\n'
        end
    else
        return '* <span class="error">The ' .. id .. ' id ' .. rawValue .. ' is not valid.</span>[[Category:Wikipedia articles with faulty authority control identifiers (' .. id .. ')]]\n'
    end
end

--In this order: name of the parameter, label, propertyId in Wikidata, formatting function
local conf = {
    { 'WorldCatEnt', '[[w:WorldCat|WorldCat]] (entity)', 10832, worldCatEntLink},
    { 'VIAF', '[[:w:Virtual International Authority File|VIAF]]', 214, viafLink },
    { 'ISNI', '[[:w:International Standard Name Identifier|ISNI]]', 213, isniLink },
    { 'LCCN', '[[:w:Library of Congress Control Number|LCCN]]', 244, lccnLink },
    { 'GND', '[[:w:Integrated Authority File|GND]]', 227, gndLink },
    { 'ICCU', '[[:w:Istituto Centrale per il Catalogo Unico|ICCU]]', 396, iccuLink },
    { 'SELIBR', '[[:w:LIBRIS|SELIBR]]', 906, selibrLink },
    { 'SUDOC', '[[:w:Système universitaire de documentation|SUDOC]]', 269, sudocLink },    
    { 'BNF', '[[:w:Bibliothèque nationale de France|BNF]]', 268, bnfLink },
    { 'BPN', '[[:w:Biografisch Portaal|BPN]]', 651, bpnLink },
    { 'BIBSYS', '[[:w:BIBSYS|BIBSYS]]', 1015, bibsysLink },
    { 'ULAN', '[[:w:Union List of Artist Names|ULAN]]', 245, ulanLink },
    { 'ARC', '[[:w:National Archives and Records Administration|NARA]]', 1222, narapersonLink },
    { 'KID', '[[:w:Kulturarvsstyrelsen|Kulturarvsstyrelsen]]', 0, kidlink },
    { 'Bionomia', '[[:w:Bionomia|Bionomia]]', 6944, BionomiaLink },
    { 'FotoBibl', '[[:w:FotoBibl|FotoBibl]]', 0, fotobibllink },
    { 'Mendeley', '[[:w:Mendeley|Mendeley]]', 3835, mendeley },
    { 'Museofile', '[[:w:Museofile|Museofile]]', 539, museofilelink },
    { 'NHM', '[[:w:Natural History Museum, London|NHM (Lond.)]]', 10114, nhm },
    { 'NLM', '[[:w:United States National Library of Medicine|NLM (US)]]', 1055, nlm },
    { 'IPNIaut', '[[:w:International Plant Names Index|IPNI]]', 586, ipniAuthorLink },
    { 'IfpniAuthor', '[[:w:International Fossil Plant Names Index|IFPNI]]', 9738, ifpniLink },
    { 'ZooBankAuthor', '[[:w:ZooBank|ZooBank]]', 2006, zooBankAuthorsLink },
    { 'ORCID', '[[:w:ORCID|ORCID]]', 496, orcidLink },
    { 'RID', '[[:w:ResearcherID|ResearcherID]]', 1053, ridLink },
    { 'GoogleScholar', '[[:w:Google Scholar|Google Scholar]]', 1960, googleScholarLink },
    { 'Scopus', '[[:w:Scopus|Scopus]]', 1153, scopusLink },
    { 'ResearchGate', '[[:w:ResearchGate|ResearchGate]]', 2038, researchGateLink },
    { 'BioStorWork', '[[:w:BioStor|BioStor]]', 5315, bioStorWorkLink },
    { 'ZooBankRef', '[[:w:ZooBank|ZooBank]]', 2007, zooBankRefLink },
    { 'BhlPage', '[[:w: Biodiversity Heritage Library|BHL (page)]]', 687, bhlPageLink },
    { 'BhlPart', '[[:w: Biodiversity Heritage Library|BHL (part)]]', 6535, bhlPartLink },
    { 'ZenodoLink', '[[:w: Zenodo|Zenodo]]', 4901, zenodoLink },
    { 'PubMedLink', '[[:w:PubMed Central|PubMed]]', 932, pubMedLink },
    { 'DoiLink', '[[:w:Digital Object Identifier|DOI]]', 356, doiLink },
    { 'plaziRefLink', '[[:w:Plazi|Plazi]]', 11409, plaziRefLink },
    { 'WormsRefLink', '[[:w:World Register of Marine Species|WoRMS]]', 6678, wormsRefLink },
    { 'InternetArchive', '[[:w:Internet Archive|Internet Archive]]', 724, internetArchiveLink },
    { 'ResearchGateRef', '[[:w:ResearchGate|ResearchGate]]', 5875, researchGateRefLink },
    { 'AcademicTree', '[[:w:Academic Tree|Academic Tree]]', 2381, academicTreeLink },
    { 'SemanticScholar', '[[:w:Semantic Scholar|Semantic Scholar]]', 4012, semanticScholar },
    { 'CiNiiBooks', '[[:w:CiNii|CiNii (books)]]', 271, CiNiiBooksLink },
    { 'CiNiiJournals', '[[:w:CiNii|CiNii (journals)]]', 4787, CiNiiJournalsLink },
    { 'IPNIpub', '[[:w:International Plant Names Index|IPNI]]', 2008, ipniPubLink },
    { 'HarvardBotanist', '[[:w:Harvard Botanical Museum|HarvardBotanist]]', 6264, harvardBotanistLink },
    { 'BPH', 'BPH', 4569, bphLink},
    { 'BHL', '[[w:Biodiversity Heritage Library|Biodiversity Heritage Library]]', 4327, bhlBiblioLink},
    { 'BHLCreator', '[[w:Biodiversity Heritage Library|Biodiversity Heritage Library]] author', 4081, bhlCreatorLink},
    { 'OCLC', '[[w:OCLC|OCLC]]', 243, oclcLink},
    { 'OpenCitations', '[[w:Initiative for Open Citations|OpenCitations]]', 3181, openCitationsLink},
    { 'UniProt', '[[w:UniProt|UniProt]]', 4616, uniProtLink},
    { 'EntWorld', 'Entomologists of the World', 5370, entWorldLink},
    { 'MSAcad', '[[w:Microsoft Academic|Microsoft Academic]]', 6366, msAcadLink},
    { 'TrovePeople', '[[w:Trove|Trove]]', 1315, trovePeopleLink},
    { 'TroveWork', '[[w:Trove|Trove]]', 10044, troveWorkLink},
}

-- Check that the Wikidata item has this property-->value before adding it
local reqs = {}

local p = {}

function p.authorityControl( frame )
    local parentArgs = frame:getParent().args
    
     --Create rows
    local elements = {}
    
    local cats = ''
    
    for _,val in pairs( parentArgs ) do
    	if val ~= nil and val ~= '' then
    		cats = cats..'[[Category:Pages using authority control with parameters]]\n'
    		break
    	end
    end
    
	if parentArgs.GKD ~= nil or parentArgs.SWD ~= nil or parentArgs.EST ~= nil or parentArgs.PND ~= nil then
		cats = cats..'[[Category:Authority control templates with deprecated fields]]\n'
	end

    --redirect PND to GND
    if (parentArgs.GND == nil or parentArgs.GND == '') and parentArgs.PND ~= nil and parentArgs.PND ~= '' then
        parentArgs.GND = parentArgs.PND
    end

    --Wikidata fallback if requested
    local item = mw.wikibase.getEntityObject()
    if item ~= nil and item.claims ~= nil then
        for _, params in pairs( conf ) do
            if params[3] ~= 0 then
                local val = parentArgs[params[1]]
                if not val or val == '' then
                	local canUseWikidata = nil
                    if reqs[params[1]] ~= nil then
                        canUseWikidata = matchesWikidataRequirements( item, reqs[params[1]] )
                    else
                        canUseWikidata = true
                    end
                    if canUseWikidata then
                        local wikidataIds = getIdsFromWikidata( item, 'P' .. params[3] )
                        if wikidataIds[1] then
                            parentArgs[params[1]] = wikidataIds[1]
                        end
                    end
                end
            end
        end
    end

    --Configured rows
    local rct = 0
    for k, params in pairs( conf ) do
        local val = parentArgs[params[1]]
        if val and val ~= '' then
            table.insert( elements, createRow( params[1], params[2] .. ':', val, params[4]( val ), true ) )
            rct = rct + 1
        end
    end
    
	
	if #elements ~= 0 then
		table.insert(elements, cats)
		local title = mw.title.getCurrentTitle()
	    local namespace = title.namespace
	    if namespace == 0 then
	        table.insert( elements, '[[Category:Wikispecies articles with authority control information]]\n')
	    elseif namespace == 2 and not title.isSubpage then
	        table.insert( elements, '[[Category:User pages with authority control information]]\n')
	    else
	        table.insert( elements, '[[Category:Miscellaneous pages with authority control information]]\n')
	    end
		return '<table class="toccolours" style="width: 100%; direction: {{Dir|{{int:lang}} }};" cellpadding="4">' ..
			'<tr style="vertical-align: top">' ..
			'<td style="background: #ccf; text-align: right; padding-right: 0.4em; width: 15%; font-weight:bold">'..frame:expandTemplate{ title = 'Authority control tag'}..'</td>' ..
			'<td><div class="hlist">\n'.. table.concat( elements ) .. '</div></td></tr></table>'
	else
		local title = mw.title.getCurrentTitle()
	   	local namespace = title.namespace
	   	
	   	if namespace == 14 then
	   		return '[[Category:Categories with authority control data]]'
	   	end
		return ""
	end
end

return p