Die Dokumentation für dieses Modul kann unter Modul:Normdaten/Doku erstellt werden

require('Module:No globals')

local function viafLink( id )
    if not string.match( id, '^%d+$' ) then
        return false
    end
    return '[https://viaf.org/viaf/' .. 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 '[http://www.idref.fr/' .. id .. ' ' .. 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 '[http://id.loc.gov/authorities/' .. lccnType .. '/' .. id .. ' ' .. id .. ']'
end

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

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

local function getIdsFromWikidata( item, property )
    local ids = {}
    if not item.claims[property] then
        return ids
    end
    for _, statement in pairs( item.claims[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>'
        else
            return label .. ' ' .. link .. ''
        end
    else
        return '<span class="error">Der ' .. id .. ' parameter ' .. rawValue .. ' ist ungültig</span>'
    end
end

--In this order: name of the parameter, label, propertyId in Wikidata, formatting function
local conf = {
    { 'GND', '[[Gemeinsame Normdatei|GND]]', 227, gndLink },
    { 'LCCN', 'LCCN', 244, lccnLink },
    { 'SUDOC', 'SUDOC/IdRef', 269, sudocLink },
    { 'SELIBR', 'SELIBR', 906, selibrLink },
    { 'VIAF', 'VIAF', 214, viafLink }
}

-- 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 withLocalArgs = false
    for _,_ in pairs( parentArgs ) do
    	withLocalArgs = true
    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
    
    --redirect GKD to GND
    if (parentArgs.GND == nil or parentArgs.GND == '') and parentArgs.GKD ~= nil and parentArgs.GKD ~= '' then
        parentArgs.GND = parentArgs.GKD
    end
    
    --redirect SWD to GND
    if (parentArgs.GND == nil or parentArgs.GND == '') and parentArgs.SWD ~= nil and parentArgs.SWD ~= '' then
        parentArgs.GND = parentArgs.SWD
    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
        	local strich = ''
        	if rct > 0 then
        		strich = ' &#124; '
        	end
            table.insert( elements, strich .. createRow( params[1], params[2] .. ':', val, params[4]( val ), true ) )
            rct = rct + 1
        end
    end
	
	local str = ''

    if withLocalArgs then
        str = str .. '[[Kategorie:Wikipedia:Artikel mit lokaler Normdateneinbindung]]\n'
    end   
	
	if #elements ~= 0 then
		return '<div id="normdaten" class="catlinks">\'\'\'Normdate\'\'\': ' .. table.concat( elements ) .. '</div>' .. str
	else
		return ""
	end
end

return p