Přeskočit na obsah

Modul:Wikidata/compare

Tuto stránku mohou editovat jen zavedení uživatelé a správci.
Z Wikipedie, otevřené encyklopedie

require "Modul:No globals"

local p = {}

local lib = require 'Modul:Wikidata/lib'

local function markValue(value, as, options)
	return '<span class="wd-' .. as .. '">' .. value .. '</span>',
		lib.category(as, options.catbase or ('Vlastnost ' .. options.property))
end

function p.compareValues(value, Statements, options)
	local title = mw.title.getCurrentTitle()
	if title.namespace ~= 0 and title.namespace ~= 14 then
		return nil
	end

	if #Statements == 0 then
		return markValue(value, 'not', options)
	end

	local Values, Strings = {}, {}
	local datatype = Statements[math.random(1, #Statements)].mainsnak.datatype
	local temp_value = mw.ustring.gsub(value, '<([a-z]+)%f[^%w][^>]->.-</%1>%s*', '')
	if datatype == "commonsMedia" or datatype == "string" then
		for _, statement in pairs(Statements) do
			if lib.IsSnakValue(statement.mainsnak) then
				temp_value = mw.ustring.gsub(temp_value, '%s*%([^%)]+%)', '')
				if tostring(statement.mainsnak.datavalue.value) == tostring(temp_value) then --TODO: normalizing
					return markValue(value, 'same', options)
				end
			end
		end
		return markValue(value, 'diff', options)
	elseif datatype == "globecoordinate" or datatype == "wikibase-property" then
		return nil
	elseif datatype == "monolingualtext" then
		for _, statement in pairs(Statements) do
			if lib.IsSnakValue(statement.mainsnak) then
				if statement.mainsnak.datavalue.value.text == temp_value then
					return markValue(value, 'same', options)
				end
			end
		end
		return markValue(value, 'diff', options)
	elseif datatype == "quantity" then
		if mw.ustring.match(temp_value, '%d+') then
			for number in mw.ustring.gmatch(value, '(%-?%d+)') do
				for _, statement in pairs(Statements) do
					if lib.IsSnakValue(statement.mainsnak) then
						local lowerBound = tonumber(statement.mainsnak.datavalue.value.lowerBound)
						local upperBound = tonumber(statement.mainsnak.datavalue.value.upperBound)
						number = tonumber(number)
						if number >= lowerBound and number <= upperBound then
							return markValue(value, 'same', options)
						end
					end
				end
				break -- only the first one
			end
		end
		return markValue(value, 'diff', options)
	elseif datatype == "time" then
		temp_value = mw.ustring.gsub(temp_value, '%[%[%s*([^|%]]+)%s*[^%]]*%]%]', '%1')
		temp_value = mw.ustring.gsub(mw.ustring.lower(temp_value), '%s*%([^%)]+%)', '')
		local Time = require 'Modul:Time'
		local Date = require 'Modul:Wikidata/datum'
		for _, statement in pairs(Statements) do
			if lib.IsSnakValue(statement.mainsnak) then
				local timevalue = Time.newFromWikidataValue(statement.mainsnak.datavalue.value)
				if timevalue then
					for string in mw.text.gsplit(temp_value, '%s*<[^<>%w]-br[^<>%w]->%s*') do
						string = mw.ustring.sub(string, 1, mw.ustring.match(string, '%d?%d%d()%d') or -1)
						local Split = mw.text.split(string, '[^%w]+')
						local Table = {}
						local Months = {
							["leden"] = 1, ["ledna"] = 1,
							["únor"] = 2, ["února"] = 2,
							["březen"] = 3, ["března"] = 3,
							["duben"] = 4, ["dubna"] = 4,
							["květen"] = 5, ["května"] = 5,
							["červen"] = 6, ["června"] = 6,
							["červenec"] = 7, ["července"] = 7,
							["srpen"] = 8, ["srpna"] = 8,
							["září"] = 9,
							["říjen"] = 10, ["října"] = 10,
							["listopad"] = 11, ["listopadu"] = 11,
							["prosinec"] = 12, ["prosince"] = 12
						}
						for _, value in pairs(Split) do
							if tonumber(value) then
								table.insert(Table, tonumber(value))
							else
								if Months[value] then
									table.insert(Table, 2, Months[value])
								else
									Table = {}
									break
								end
							end
						end
						if #Table == 1 then
							Table = Time.new{
								year = Table[1]
							}
						elseif #Table == 2 then
							Table = Time.new{
								year = Table[1],
								month = Table[2]
							}
						elseif #Table == 3 then
							Table = Time.new{
								year = math.max(Table[1], Table[3]),
								month = Table[2],
								day = math.min(Table[1], Table[3])
							}
						else
							mw.log('Nepodařilo se zanalyzovat datum ' .. string)
						end
						if Table.precision then
							if Date.AreDatesSame(timevalue, Table) then
								return markValue(value, 'same', options)
							end
						end
					end
					return markValue(value, 'diff', options)
				end
			end
		end
		return nil
	elseif datatype == "url" then
		if mw.ustring.match(temp_value, 'https?://') then
			for url in mw.ustring.gmatch(temp_value, '(https?://[^%[%]%s]+)') do
				table.insert(Strings, url)
			end
			for _, statement in pairs(Statements) do
				if lib.IsSnakValue(statement.mainsnak) then
					table.insert(Values, statement.mainsnak.datavalue.value)
				end
			end
		else
			return markValue(value, 'diff', options)
		end
	elseif datatype == "wikibase-item" then
		for _, statement in pairs(Statements) do
			if lib.IsSnakValue(statement.mainsnak) then
				local id = lib.getEntityIdFromValue(statement.mainsnak.datavalue.value)
				local value = mw.wikibase.sitelink(id) or mw.wikibase.label(id)
				if value then
					table.insert(Values, lib.common.firstToUpper(value))
				end
			end
		end
		if mw.ustring.match(temp_value, '<[^<>%w]-br[^<>%w]->') then
			for string in mw.text.gsplit(temp_value, '<[^<>%w]-br[^<>%w]->') do
				string = mw.ustring.gsub(string, '%s*%([^%(%)]+%)', '')
				if mw.ustring.match(string, '%[%[[^%]%[]-%]%]') then
					for page in mw.ustring.gmatch(string, '%[%[%s*([^|%]]-)%s*[|%]]') do
						table.insert(Strings, lib.common.firstToUpper(page))
					end
				else
					table.insert(Strings, mw.text.trim(string))
				end
			end
		elseif mw.ustring.match(temp_value, '%[%[[^%]%[]-%]%]') then
			for string in mw.ustring.gmatch(temp_value, '%[%[%s*([^|%]]-)%s*[|%]]') do
				table.insert(Strings, lib.common.firstToUpper(string))
			end
		end
	end
	local i = 0
	for _, string in pairs(Strings) do
		for _, value in pairs(Values) do
			if string == value then
				i = i + 1
				break
			end
		end
	end
	if #Strings > 0 and #Values > 0 and i == #Strings then
		return markValue(value, 'same', options)
	end
	return markValue(value, 'diff', options)
end

function p.compareValuesFromOptions(value, options)
	local entity = mw.wikibase.getEntity()
	local Filterers = require 'Modul:Wikidata/Filterers'
	local Statements = Filterers.filterStatementsFromEntity(entity, optios)
	return p.compareValues(value, Statements, options)
end

return p