Hopp til innhold

Modul:Wikibase

Fra Wikipedia, den frie encyklopedi
local function append( list, additions )
	for i,v in ipairs( additions ) do
		list[1+#list] = v
	end
	return list
end

local function copy( src )
    local copy
    if type(src) == 'table' then
        copy = {}
        for k,v in pairs( src ) do
            copy[k] = v
        end
    else
        copy = src
    end
    return copy
end

local reaper = {}

function reaper.find( path, set )
	local list = set or {}
	for v in reaper.fetch( path, set, chain ) do
	end
end

-- find neglects anchor, test on k?
-- set chain[1] = 
function reaper.fetch( p, s, c )
	--local path = p or ""
	local ptr = { path = p or "", index = 0 }
	local set = s or {}
	local chain = c or {}
	local value
	local entities = {}
	local statements = {}
	local length = path:len()
	--local i = 0
	local j = 0
	local epoch = 1
	if #chain == 0 then
		local entity = mw.wikibase.getEntity()
		chain[1] = entity and { entity } or {}
		entities = chain[1]:copy()
	end
	
	local function getEntities( ptr )
		local entities = {}
		
		local function getStatements( ptr )
		for i,entity in pairs( entities ) do 
			-- figure out if there are any request for specific statements
			-- exclamation used to trigger best statements
			local k,l,str,best = path:find( '^%s*%.(P%d+)(!?)', i+1 )
			if k then
				local entries = best == '!' and entity:getBestStatements( str ) or entity:getStatements( str )
				statements:append( entries )
			else
				k,l,str,best = path:find( '^%s*%.(%b{})(!?)', i+1 )
				if k then
					local entries = best == '!' and entity:getBestStatements( str ) or entity:getStatements( str )
					statements:append( entries )
				end
			end
			if #statements == 0 then
				return nil
			end
		end
		end

		local k,l,str = ptr.path:find( '^%s*([Q@]%.+)', ptr.index+1 )
		if k then
			local list = chain[str:len()-1]
			ptr.index = l
			return list and list:copy() or {}
		else
			k,l,str = ptr.path:find( '^%s*(Q%d+)', ptr.index+1 )
			if k then
				local entity = mw.wikibase.getEntity( str )
				ptr.index = l
				return entity and { entity } or {}
			else
				k,l,str = ptr.path:find( '^%s*@(%b{})', ptr.index+1 )
				if k then
					local entity = mw.wikibase.getEntity( mw.text.trim( str, '{}' ) )
					ptr.index = l
					return entity and { entity } or {}
				end
			end
		end
		return {}
	end
	

	repeat
		j = i -- track whether we have changes
		local attributes = nil
		
		do
			-- at the start we should have zero or one entity, but it can grow later on
			entities:append( getEntities( ptr ) )
			if #entities == 0 then
				return nil
			end
			chain[1] = entities:copy()
		end
	
		for i,entity in pairs( entities ) do 
			-- figure out if there are any request for specific statements
			-- exclamation used to trigger best statements
			local k,l,str,best = path:find( '^%s*%.(P%d+)(!?)', i+1 )
			if k then
				local entries = best == '!' and entity:getBestStatements( str ) or entity:getStatements( str )
				statements:append( entries )
			else
				k,l,str,best = path:find( '^%s*%.(%b{})(!?)', i+1 )
				if k then
					local entries = best == '!' and entity:getBestStatements( str ) or entity:getStatements( str )
					statements:append( entries )
				end
			end
			if #statements == 0 then
				return nil
			end
		end

		for i,entity in pairs( statements ) do
			-- figure out if there are any request for specific qualifiers
			local k,l,pid = path:find( '^%s*%:(P%d+)', i+1 )
			if k then
				-- we must define our own call here
			else
				k,l,label = path:find( '^%s*%:(%b{})', i+1 )
				if k then
				-- we must define our own call here
				end
			end
			if not qualifiers then
				return nil
			end
		end

		-- figure out if there are any sources, no matter ordinary statements
		-- it is possible to check sources for all available statements
		do
			local k,l,pid = path:find( '^%s*%.source%:(P%d+)', i+1 )
			if k then
				-- we must define our own call here
			else
				local k,l,label = path:find( '^%s*%.source%:(%b{})', i+1 )
				if k then
					-- we must define our own call here
				end
			end
			if not qualifiers then
				return nil
			end
		end

		-- figure out if there is a call for specific attribute or pseudo attribute value
		-- use the returned value as a implicit selector and store it for later use
		do
	--		for i,v in ipairs() do
	---			local k,l,access,attribute = path:find( '^%s*([%.%:]?)([^%-%.%:%s%{%}%[%]%(%)]+)', i+1 )
	--			if k then
	--				if access == '.' then
	--					for k,statement in pairs( statements ) do
	--						if statements[k] then
	--							statements[k] = nil
	--		end
		end
		do -- this finds the function
			local k,l,func,args = path:find( '^%s*%:([^-.%s%{%}%[%]%(%)]+)(%b())', i+1 )
			if k then
				fragments[epoch].func = { func, mw.text.trim( args, '%(%s%)' ) }
				i = l
			end
		end
		do -- this finds the selectors
			-- inside selectors this should not e allowed
			local k,l,selector = path:find( '^%s*(%b[])', i+1 )
			if k then
				fragments[epoch].selector = { func, mw.text.trim( selector, '%[%s%]' ) }
				i = l
			end
		end
		do -- this finds the end of this segment
			local k,l,_ = path:find( '^(/)', i+1 )
			if k then
				--unless there is an identified item this will fail
				-- ie., it needs a fail marker
				fragments[epoch].iterate = true
				epoch = 1+epoch
				i = l
			end
		end
		-- if no change then the path has an error
		if i == j then
			return nil
		end
	until i == 0 or i == length

	--return e or entity, v or value
	return mw.dumpObject(fragments)
end

function reaper.run()
	return ''
end

return reaper