require "Амодуль:No globals"
local p = {}
local lib = require 'Амодуль:Wikidata/lib'
-- @const
local br_split = '%s*<[^<>%w]-br[^<>%w]->%s*'
local function in_array(value, array)
for _, val in ipairs(array) do
if val == value then
return true
end
end
return false
end
local function stripBrackets(text)
return mw.ustring.gsub(text, '%s*%([^%)]+%)', '')
end
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)
if value == '' then
return nil, nil
end
local title = mw.title.getCurrentTitle()
if title.namespace ~= 0 and title.namespace ~= 14 then
return nil, nil
end
if #Statements == 0 then
return markValue(value, 'not', options)
end
local datatype = Statements[math.random(#Statements)].mainsnak.datatype
local temp_value = mw.ustring.gsub(value, '<([a-z]+)%f[^%w][^>]->.-</%1>%s*', '')
if datatype == "commonsMedia" or datatype == "string" or datatype == "external-id" then
for _, statement in ipairs(Statements) do
if lib.IsSnakValue(statement.mainsnak) then
local temp_value = stripBrackets(temp_value)
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 == "monolingualtext" then
for _, statement in ipairs(Statements) do
if lib.IsSnakValue(statement.mainsnak) then
if statement.mainsnak.datavalue.value.text == mw.text.strip(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 ipairs(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 = stripBrackets(mw.ustring.lower(temp_value))
local Time = require 'Амодуль:Time'
local Months = {
["ажьырныҳәамза"] = 1,
["жәабранмза"] = 2,
["хәажәкырамза"] = 3,
["мшаԥымза"] = 4,
["лаҵарамза"] = 5,
["рашәарамза"] = 6,
["ԥхынгәымза"] = 7,
["нанҳәамза"] = 8,
["цәыббрамза"] = 9,
["жьҭаарамза"] = 10,
["абҵарамза"] = 11,
["ԥхынҷкәынмза"] = 12,
}
for _, statement in ipairs(Statements) do
if lib.IsSnakValue(statement.mainsnak) then
local timevalue = Time.newFromWikidataValue(statement.mainsnak.datavalue.value)
if timevalue then
for parsed in mw.text.gsplit(temp_value, br_split) do
parsed = mw.ustring.sub(parsed, 1, mw.ustring.match(parsed, '%d?%d%d()%d') or -1)
local parsedTable = {}
for _, value in ipairs(mw.text.split(parsed, '[^%w]+')) do
if tonumber(value) then
table.insert(parsedTable, tonumber(value))
else
if Months[value] then
table.insert(parsedTable, 2, Months[value])
else
parsedTable = {}
break
end
end
end
local Table
if #parsedTable == 1 then
Table = Time.new{
year = parsedTable[1]
}
elseif #parsedTable == 2 then
Table = Time.new{
year = parsedTable[1],
month = parsedTable[2]
}
elseif #parsedTable == 3 then
Table = Time.new{
year = math.max(parsedTable[1], parsedTable[3]),
month = parsedTable[2],
day = math.min(parsedTable[1], parsedTable[3])
}
end
if not Table then
mw.log('Аамҭарба аилыргара аманшәалахом ' .. parsed)
else
if timevalue == Table then
return markValue(value, 'same', options)
end
end
end
end
end
end
return markValue(value, 'diff', options)
elseif datatype == "url" then
if not mw.ustring.match(temp_value, 'https?://') then
return markValue(value, 'diff', options)
end
local WDValues = {}
for _, statement in ipairs(Statements) do
if lib.IsSnakValue(statement.mainsnak) then
table.insert(WDValues, statement.mainsnak.datavalue.value)
end
end
for url in mw.ustring.gmatch(temp_value, '(https?://[^%[%]%s]+)') do
if not in_array(url, WDValues) then
return markValue(value, 'diff', options)
end
end
return markValue(value, 'same', options)
elseif datatype == "wikibase-item" then
local WDValues, parsedValues = {}, {}
for _, statement in ipairs(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(WDValues, lib.common.firstToUpper(value))
end
end
end
local link_match = '%[%[[^%]%[]-%]%]'
local link_target = '%[%[%s*([^|%]]-)%s*[|%]]'
if mw.ustring.match(temp_value, br_split) then
for value in mw.text.gsplit(temp_value, br_split) do
local value = stripBrackets(value)
if mw.ustring.match(value, link_match) then
for page in mw.ustring.gmatch(value, link_target) do
table.insert(parsedValues, lib.common.firstToUpper(page))
end
else
table.insert(parsedValues, mw.text.trim(value))
end
end
elseif mw.ustring.match(temp_value, link_match) then
for value in mw.ustring.gmatch(temp_value, link_target) do
table.insert(parsedValues, lib.common.firstToUpper(value))
end
else
table.insert(parsedValues, mw.text.trim(temp_value))
end
if #parsedValues == 0 then
return markValue(value, 'diff', options)
end
for _, parsed in ipairs(parsedValues) do
if not in_array(parsed, WDValues) then
return markValue(value, 'diff', options)
end
end
return markValue(value, 'same', options)
end
--elseif datatype == "globecoordinate" then
return nil, nil
end
return p