Indicacións de uso do módulo

Módulo que contén o código empregado polo modelo {{Control de autoridades}} para os identificadores médicos.

Os identificadores atópanse en Módulo:Medbar/conf

Esta documentación está transcluída desde Módulo:Medbar/uso. Os editores poden probar cambios no mesmo en Módulo:Medbar/probas.
Por favor, engade as categorías na subpáxina de documentación e os interwikis no Wikidata. Ver as subpáxinas deste módulo.

require('Module:No globals')

local conf = require( 'Module:Medbar/conf' ) -- configuration module

local function isNilOrEmpty( thing )
	if thing == nil or thing == '' then
		return true
	end
	return nil
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 getIdFromWikidata( item, property )
	local id = nil
	if item.claims[property] == nil then
		return id
	end
	for _, statement in pairs( item.claims[property] ) do
		if statement.mainsnak.datavalue then
			id = statement.mainsnak.datavalue.value
			break
		end
	end
	return id
end

local function getLink( property, val, mask )
	local link, returnVal = '', {}
	
	returnVal.isError = false
	
	if mw.ustring.find( val, '//' ) then
		link = val
	else
		if type(property) == 'number' and property > 0 then
			local entityObject = mw.wikibase.getEntity('P'..property)
			local dataType
			
			if entityObject then dataType = entityObject.datatype
			else returnVal.isError = true end
			
			if dataType == 'external-id' then
				local formatterURL = nil
				if property == 3746 then --Wildflowers of Israel ID's 2nd formatterURL is in English
					formatterURL = entityObject:getBestStatements('P1630')[2]
				end
				if formatterURL == nil then formatterURL = entityObject:getBestStatements('P1630')[1] end
				if formatterURL then
					if formatterURL.mainsnak.datavalue and formatterURL.mainsnak.datavalue.value then --nil check for ABA
						link = formatterURL.mainsnak.datavalue.value
					end
				end
			elseif dataType == 'url' then
				local subjectItem = entityObject:getBestStatements('P1629')[1]
				if subjectItem then
					local officialWebsite = mw.wikibase.getEntity(subjectItem.mainsnak.datavalue.value.id):getBestStatements('P856')[1]
					if officialWebsite then	link = officialWebsite.mainsnak.datavalue.value end
				end
			elseif dataType == 'string' then
				local formatterURL = entityObject:getBestStatements('P1630')[1]
				if formatterURL then
					link = formatterURL.mainsnak.datavalue.value
				else
					local subjectItem = entityObject:getBestStatements('P1629')[1]
					if subjectItem then
						local officialWebsite = mw.wikibase.getEntity(subjectItem.mainsnak.datavalue.value.id):getBestStatements('P856')[1]
						if officialWebsite then	link = officialWebsite.mainsnak.datavalue.value end
					end
				end
			else
				returnVal.isError = true
			end
		elseif type(property) == 'string' then
			link = property
		end
		
		local valurl = val
		valurl = mw.ustring.gsub(valurl,'%%','%%%%')
		link = mw.ustring.gsub(link, '$1', valurl)
	end
	
	link = mw.ustring.gsub(link, '^[Hh][Tt][Tt][Pp]([Ss]?)://', 'http%1://') -- fix wikidata URL
	link = mw.ustring.gsub(link, ' ' , '')
	val = mw.ustring.match(val, '([^=/]*)/?$') -- get display name from end of URL
	if mw.ustring.find( link, '//' ) then
		if mask == 'y' then
			returnVal.text = '<span class="plainlinks">['..link..' ID]</span>'
		else
			returnVal.text = '<span class="plainlinks">['..link..' '..mw.text.encode(mw.uri.decode(val, 'PATH'),'%[%]')..']</span>'
		end
	elseif link == '' then
		returnVal.text = val
	else
		returnVal.text = '[['..link..'|'..val..']]'
	end
	return returnVal
end

local function createRow( id, label, rawValue, link, withUid )
	if link then
		local outStr = '*<span style="white-space:nowrap;">' .. label .. ' <span'
		if withUid then outStr = outStr..' class="uid"' end
		return outStr..'>' .. link .. '</span></span>\n'
	else
		return '* ' .. mw.text.tag('span', {class='error'}, 'O identificador ' .. id .. ' ' .. rawValue .. ' non é válido.') .. '\n'
	end
end

local function copyTable(inTable)
	if type(inTable) ~= 'table' then return inTable end
	local outTable = setmetatable({}, getmetatable(inTable))
	for key, value in pairs (inTable) do outTable[copyTable(key)] = copyTable(value) end
	return outTable
end

local p = {}

function p.authorityControlMed( frame )
	local resolve = require( 'Module:ResolveEntityId' )
	local parentArgs = copyTable(frame:getParent().args)
	local currentTitle = mw.title.getCurrentTitle()
	local currentEntityId = mw.wikibase.getEntityIdForCurrentPage()
	
	local stringArgs = false
	local fromTitleCount, firstRow, rowCount = 1, 0, 0
	local outString, errors = '', ''
	local tFroms = {} --non-sequential table of unique froms
	local iFroms = 0 --integer size of tFroms, b/c Lua
	
	
	--Cleanup args
	for k, v in pairs( frame:getParent().args ) do
		if type(k) == 'string' then
			--make args case insensitive
			local lowerk = mw.ustring.lower(k)
			if isNilOrEmpty( parentArgs[lowerk] ) then
				parentArgs[k] = nil
				parentArgs[lowerk] = v
			end
			--remap abc to abc1
			if mw.ustring.find(lowerk,'%d$') == nil then --if no number at end of param
				if isNilOrEmpty( parentArgs[lowerk..'1'] ) then
					parentArgs[lowerk] = nil
					lowerk = lowerk..'1'
					parentArgs[lowerk] = v
				end
			end
			if v and v ~= '' then
				--remap 'for' to 'title'
				if mw.ustring.sub(lowerk,1,3) == 'for' then
					local forTitle = mw.ustring.gsub(lowerk,'^for','title',1)
					if isNilOrEmpty( parentArgs[forTitle] ) then
						parentArgs[lowerk] = nil
						lowerk = forTitle
						parentArgs[lowerk] = v
					end
				end
				--find highest from or title param
				if mw.ustring.sub(lowerk,1,4) == 'from' then
					local fromNumber = tonumber(mw.ustring.sub(lowerk,5,-1))
					if fromNumber and fromNumber >= fromTitleCount then fromTitleCount = fromNumber end
					--look for duplicate froms while we're here
					if mw.ustring.find(v, '^Q%d') then
						if tFroms[v] then

							tFroms[v] = tFroms[v] + 1
						else
							tFroms[v] = 1
							iFroms = iFroms + 1
						end
						if iFroms == 2 then

						end
					end
				elseif mw.ustring.sub(lowerk,1,5) == 'title' then
					local titleNumber = tonumber(mw.ustring.sub(lowerk,4,-1))
					if titleNumber and titleNumber >= fromTitleCount then fromTitleCount = titleNumber end
				elseif mw.ustring.lower(v) ~= 'no' then
					stringArgs = true

				end
			end
		end
	end
	
	--Check for unknown parameters
	--create knowns list
	local acceptableArgs = { from = true, } --master list of l/c acceptable args
	for _, d in pairs( conf.databases ) do
		if d[1] ~= 'Wikidata' then --made obsolete by from
			acceptableArgs[mw.ustring.lower(d[1])] = true
		end
	end
	for _, a in pairs( conf.aliases ) do
		acceptableArgs[mw.ustring.lower(a[1])] = true
	end
	--create trimmed parents list
	local baseParentArgs = {} --condensed list of l/c parent args w/o trailing #s
	for k, v in pairs( parentArgs ) do
		if type(k) == 'string' then --ignore unnamed params, which have keys of type 'number'
			local lowerk = mw.ustring.lower(k)
			local base = mw.ustring.gsub(lowerk, '[%d]*$', '')
			baseParentArgs[base] = true
		end
	end
	--compare lists and spit out unknowns
	local unknownParams = {}
	for k, v in pairs( baseParentArgs ) do
		if acceptableArgs[k] == nil then

			unknownParams[#unknownParams + 1] = k
		end
	end
	--warn if unknown(s) present
	if #unknownParams > 0 then
		if frame:preprocess( '{{REVISIONID}}' ) == '' then
			errors = errors..'<div class="hatnote" style="color:red">'..
				     '<strong>Atención:</strong> parámetros descoñecidos <strong>'..table.concat(unknownParams, ', ')..'</strong>.<br />'..
				     'Corríxaos ou considere engadilos a Wikidata.<br />'..
				     'Esta mensaxe só se amosa na vista previa.</div>'
		end
	end
	
	
	--Setup navbox
local navboxParams = {
		name  = 'Control de autoridades',
		bodyclass = 'hlist',
		listclass = 'plainlinks',
		groupstyle = 'width: 12%; text-align:center;',
	}
	
	for f = 1, fromTitleCount, 1
	do
		local elements, title = {}, nil
		--cleanup parameters
		if parentArgs['from'..f] == '' then parentArgs['from'..f] = nil end
		if parentArgs['title'..f] == '' then parentArgs['title'..f] = nil end
		--remap aliases
		for _, a in pairs( conf.aliases ) do
			local alias, name = mw.ustring.lower(a[1]), mw.ustring.lower(a[2])
			if parentArgs[alias..f] and parentArgs[name..f] == nil then
				parentArgs[name..f] = parentArgs[alias..f]
				parentArgs[alias..f] = nil
			end
		end
		--Fetch Wikidata item
		local from = resolve._entityid(frame, parentArgs['from'..f])
		local item = mw.wikibase.getEntity(from)
		local label = nil
		if type(item) == 'table' then
			local statements = item:getBestStatements('P225')[1] --taxon name
			if statements then
				local datavalue = statements.mainsnak.datavalue
				if datavalue then
					label = datavalue.value
				end
			end
			label = label or item:getLabel()
		else
			if parentArgs['from'..f] then

				errors = errors .. mw.text.tag('strong', {class='error'}, 'Erro: "' .. 
				         parentArgs['from'..f] .. '" non é un ID de entidade Wikidata válido.<br />')				
			end
		end
		if label and label ~= '' then
			title = mw.title.new(label)
		end
		if title == nil and parentArgs['title'..f] then
			title = mw.title.new(parentArgs['title'..f])
		end
		if title == nil and f == 1 then
			title = currentTitle
		end
		
		if title then
			if isNilOrEmpty( parentArgs['wikidata'..f] ) and 
			   (title.namespace == 0) then
				if parentArgs['from'..f] then
					parentArgs['wikidata'..f] = parentArgs['from'..f]
				elseif item then
					parentArgs['wikidata'..f] = item.id
				end
			end
			if title.namespace == 0 or stringArgs then --only in mainspace or if manual overrides exist
				local sourceCount = 0
				for _, params in pairs( conf.databases ) do
					params[1] = mw.ustring.lower(params[1])
					local propId = params[3]
					--Wikidata fallback if requested
					if (item and item.claims) and
					   (type(propId) == 'string' or (type(propId) == 'number' and propId > 0)) then
						local wikidataId = getIdFromWikidata( item, 'P' .. propId )
						local v = parentArgs[params[1]..f]
						if wikidataId then
							if isNilOrEmpty(v) then
								parentArgs[params[1]..f] = wikidataId
							else
								if v and v ~= 'no' and v ~= wikidataId then

								elseif v and v == wikidataId then

								end
							end
						end
					end
					local val = parentArgs[params[1]..f]
					if val and val ~= '' and mw.ustring.lower(val) ~= 'no' then
						
						if params[1] == 'issn' and parentArgs['worldcatid'..f] and parentArgs['worldcatid'..f] ~= '' then -- 'issn' is the first element following the 'wikidata' item
							table.insert( elements, createRow( params[1], '', parentArgs['worldcatid'..f], '[//www.worldcat.org/identities/' .. parentArgs['worldcatid'..f] .. ' WorldCat]', false ) ) --Validation?
						elseif params[1] == 'viaf' and parentArgs[params[1]..f] and string.match( parentArgs[params[1]..f], '^%d+$' ) and not parentArgs['worldcatid'..f] then -- Hackishly copy the validation code; this should go away when we move to using P1793 and P1630
							table.insert( elements, createRow( params[1], '', parentArgs[params[1]], '[//www.worldcat.org/identities/containsVIAFID/' .. parentArgs[params[1]..f] .. ' WorldCat]', false ) )
						elseif params[1] == 'lccn' and parentArgs[params[1]..f] and parentArgs[params[1]..f] ~= '' and not parentArgs['viaf'..f] and not parentArgs['worldcatid'..f] then
							local lccnParts = splitLccn( parentArgs[params[1]..f] )
								if lccnParts and lccnParts[1] ~= 'sh' then
								table.insert( elements, createRow( params[1], '', parentArgs[params[1]..f], '[//www.worldcat.org/identities/lccn-' .. lccnParts[1] .. lccnParts[2] .. '-' .. lccnParts[3] .. ' WorldCat]', false ) )
								end
						end
						
						if type(propId) == 'number' then
							if propId < 0 then propId = -propId end --allow link
							if propId > 0 then --link
								table.insert( elements, createRow( params[1], params[2]..':', val, getLink( propId, val, params[4] ).text, true ) )
							else --propId == 0; no link
								table.insert( elements, createRow( params[1], params[2]..':', val, val, true ) )
							end
						else
							table.insert( elements, createRow( params[1], params[2]..':', val, getLink( propId, val, params[4] ).text, true ) )
						end
						if params[1] ~= 'wikidata' and params[1] ~= 'wikispecies' then
							sourceCount = sourceCount + 1
						end
					end
				end
				

				
				--Generate navbox title
				if sourceCount > 0 then --TODO: don't count Wikispecies towards 'taxon ID count'
					rowCount = rowCount + 1
					if firstRow == 0 then firstRow = f end
					--set title from wikidata if it doesn't exist
					if isNilOrEmpty( parentArgs['title'..f] ) then
						parentArgs['noTitle'..f] = true
						parentArgs['title'..f] = title.text
					end
					--if it exists now, set row heading to title
					if not isNilOrEmpty( parentArgs['title'..f] ) then

					else
						navboxParams['group'..f] = ''
					end
					navboxParams['list'..f] = table.concat( elements )
				elseif currentEntityId then

				end
				
				--Categorize
				
			end
		end
	end --for f = 1, fromTitleCount, 1
	
	if rowCount > 0 then
		local Navbox = require('Module:Navbox')
		if rowCount > 1 then
			--remove duplicates and move page title to top
			local rowIDs = {}
			for f = 1,fromTitleCount,1
			do
				if not isNilOrEmpty( parentArgs['title'..f] ) then
					if rowIDs[parentArgs['wikidata'..f]] then --remove duplicate
						navboxParams['group'..f] = nil
						navboxParams['list'..f] = nil
					else
						rowIDs[parentArgs['wikidata'..f]] = true
						if f > firstRow and (parentArgs['title'..f] == currentTitle.text or 
						   parentArgs['wikidata'..f] == currentEntityId) then --move item linked to page to top
							if navboxParams['group'..f] and 
							   navboxParams['group'..f] ~= '' and 
							   navboxParams['list'..f] and 
							   navboxParams['list'..f] ~= '' then
								local tempGroup, tempList = navboxParams['group'..f], navboxParams['list'..f]
								navboxParams['group'..f], navboxParams['list'..f] = navboxParams['group'..firstRow], navboxParams['list'..firstRow]
								navboxParams['group'..firstRow], navboxParams['list'..firstRow] = tempGroup, tempList
							end
						end
					end
				end
			end
			--adjust navbox for number of rows
			navboxParams['title'] = 'Identificadores'
			if rowCount > 2 then
				navboxParams['navbar'] = 'plain'
			else
				navboxParams['state'] = 'off'
				navboxParams['navbar'] = 'off'
			end
		elseif parentArgs['noTitle'..firstRow] then
			navboxParams['group'..firstRow] = 'Identificadores'
		else
			navboxParams['group'..firstRow] = 'Identificadores<br />' .. navboxParams['group'..firstRow]
		end
		
		--return navbox
		outString = Navbox._navbox(navboxParams)
	end --if rowCount > 0
	
	--Add categories
	if string.sub(currentTitle.subpageText,1,9) == 'testcases' then parentArgs['demo'] = true end

	return outString .. errors
end

return p