Moduuli:Cs:Wikidata/compare
Siirry navigaatioon
Siirry hakuun
[ muokkaa ] wikiprojekti:wikidata/cswiki
|
require "Module:No globals"
local p = {}
local lib = require 'Module:cs: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" 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 'Module:cs:Time'
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 _, 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('Nepodařilo se zanalyzovat datum ' .. 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
--elseif datatype == "wikibase-property" then
return nil, nil
end
function p.compareValuesFromOptions(value, options)
local entity = mw.wikibase.getEntity(options.id)
local Filterers = require 'Module:cs:Wikidata/Filterers'
local Statements = Filterers.filterStatementsFromEntity(entity, options)
return p.compareValues(value, Statements, options)
end
function p.compare(frame)
local args = frame.args
local value = args.value
local _, category = p.compareValuesFromOptions(value, { property = args.property, catbase = args.catbase })
return category
end
return p