Modul:Autocategories

Fra Wikipedia, den frie encyklopedi
Moduldokumentasjon
-- module for replicating categories listed at Wikidata
-- © John Erling Blad, Creative Commons by Attribution 3.0

-- don't pollute with globals
require('strict')

-- @var our exposed table
local Autocategories = {}

-- find the first entry that seems to be a Q-id
-- @param table args argument list from the frame
-- @return string first matching argument
function Autocategories._findQid( args )
	for key, value in ipairs( args ) do
		if value ~= '' and string.match(value, '^Q%d+$') then
			return value
		end
	end
	local entity = mw.wikibase.getEntity()
	if entity then
		return entity['id']
	end
	return nil
end

-- find id for all statements
-- @param table statement well-defined structure for a statement
-- @return values for the provided statements
function Autocategories._findId(statements)
	local ids = {}
	for _,statement in pairs(statements) do
		local mainsnak = statement["mainsnak"]
		if mainsnak then
			local datavalue = mainsnak['datavalue']
			if datavalue then
				local value = datavalue['value']
				if value then
					local entityType = value['entity-type']
					local numericId = value['numeric-id']
					if entityType and numericId and entityType == 'item' then
						ids[1+#ids] = numericId
					end
				end
			end
		end
	end
	return ids
end

-- find the P-ids from the argument lists
-- note that this maintain argument sequence
-- @param table vector forwarded from the method call
-- @return table hash of matching arguments
function Autocategories._findPidsInArgs( pids, args )
	for _,value in ipairs( args ) do
		local _,_,action,pid = string.find(value, '^%s*(!?)(P%d+)%s*$')
		if pid then
			pids[pid] =  action == '' and true or nil
		end
	end
	return pids
end

-- find the P-ids from the frame lists
-- note that this maintain argument sequence
-- @param table vector forwarded from the method call
-- @return table hash of matching arguments
function Autocategories._findPidsInFrames( ... )
	local pids = {}
	--pids[1+#pids] = arg.n
	for i = 1,arg.n do
		local frame = arg[i]
		if frame then
			local firstArg = frame.args[1]
			--do return mw.text.split( firstArg, ',', true ) end
			if firstArg then
				pids = Autocategories._findPidsInArgs( pids, mw.text.split( firstArg, ',', true ) )
			end
		end
	end
	return pids
end

-- find the P-ids from the frame lists
-- note that this does not maintain argument sequence
-- @param table frames forwarded from the method call
-- @return table hash of matching arguments
function Autocategories.findPids( ... )
	local pids = Autocategories._findPidsInFrames( ... )
	local keys = {}
	for key,_ in pairs( pids ) do
		keys[1+#keys] = key
	end
	return keys
end

-- do all allowable categorizations
-- @param table frame arguments from invoke
-- @return string status report during development, should be an empty string
function Autocategories.run( frame )
	--local qid = Autocategories._findQid( frame.args )
	--first call is when the call is encapsulated in a template
	local pids = frame:getParent() and Autocategories.findPids( frame, frame:getParent() ) or Autocategories.findPids( frame )
	if #pids == 0 then
		return ''
	end
	local entity = mw.wikibase.getEntity()
	if not entity then
		return ''
	end
	local categories = {}
	for _,pid in pairs(pids) do
		local statements = entity:getBestStatements( pid )
		if statements then
			for _,id in pairs( Autocategories._findId( statements ) ) do
				local sitelink = mw.wikibase.sitelink( 'Q'..id )
				if sitelink then
					categories[1+#categories] =
						(pid == 'P910' and '[['..sitelink..'| ]]' or '[['..sitelink..']]')
				end
			end
		end
	end
	return table.concat( categories, '\n' )
end

-- export the accesspoint
return Autocategories