Module:Wikidata
Харагдац
local i18n = {
["errors"] = {
["property-param-not-provided"] = "Не дан параметр свойства",
["entity-not-found"] = "Сущность не найдена.",
["unknown-claim-type"] = "Неизвестный тип заявления.",
["unknown-snak-type"] = "Неизвестный тип снэка.",
["unknown-datavalue-type"] = "Неизвестный тип значения данных.",
["unknown-entity-type"] = "Неизвестный тип сущности.",
["unknown-claim-module"] = "Вы должны установить и claim-module, и claim-function.",
["unknown-value-module"] = "Вы должны установить и value-module, и value-function.",
["claim-module-not-found"] = "Модуль, на который указывает утверждение, не найден.",
["claim-function-not-found"] = "Функция, на которую указывает утверждение, не найдена.",
["value-module-not-found"] = "Модуль, на который указывает значение, не найден.",
["value-function-not-found"] = "Функция, на которую указывает значение, не найдена."
},
["somevalue"] = "",
["novalue"] = ""
}
local moduleSources = require('Module:Wikidata/Sources')
local p = {}
function toBoolean( valueToParse, defaultValue )
if ( valueToParse ) then
if valueToParse == '' or valueToParse == 'false' or valueToParse == '0' then
return false
end
return true
end
return defaultValue;
end
function getEntityFromId( id )
if id then
return mw.wikibase.getEntity( id )
end
return mw.wikibase.getEntity()
end
function getEntityIdFromValue( value )
local prefix = ''
if value['entity-type'] == 'item' then
prefix = 'q'
elseif value['entity-type'] == 'property' then
prefix = 'p'
else
return formatError( 'unknown-entity-type' )
end
return prefix .. value['numeric-id']
end
function formatError( key )
return '<span class="error">' .. i18n.errors[key] .. '</span>'
end
function formatStatements( options )
if not options.property then
return formatError( 'property-param-not-provided' )
end
--Get entity
local entity = getEntityFromId( options.entityId )
if not entity then
return -- formatError( 'entity-not-found' )
end
if (entity.claims == nil) or (not entity.claims[string.lower(options.property)]) then
return '' --TODO error?
end
--Find if any statements are prefered
local rank = 'normal'
for i, statement in pairs( entity.claims[string.lower(options.property)] ) do
if (statement.rank == 'preferred') then
rank = 'preferred'
break
end
end
--Format statement and concat them cleanly
local formattedStatements = {}
for i, statement in pairs( entity.claims[string.lower(options.property)] ) do
if (statement.rank == rank) then
local formattedStatement = p.formatStatement( statement, options )
if (formattedStatement) then
if ( not options.plain ) then
formattedStatement = '<span class="wikidata-claim" data-wikidata-claim-id="' .. statement.id .. '">' .. formattedStatement .. '</span>'
end
table.insert( formattedStatements, formattedStatement )
end
end
end
return mw.text.listToText( formattedStatements, options.separator, options.conjunction )
end
function p.formatStatement( statement, options )
if not statement.type or statement.type ~= 'statement' then
return formatError( 'unknown-claim-type' )
end
local claim
--Use the customize handler if provided
if options['claim-module'] or options['claim-function'] then
if not options['claim-module'] or not options['claim-function'] then
return formatError( 'unknown-claim-module' )
end
local formatter = require ('Module:' .. options['claim-module'])
if formatter == nil then
return formatError( 'claim-module-not-found' )
end
local fun = formatter[options['claim-function']]
if fun == nil then
return formatError( 'claim-function-not-found' )
end
claim = fun( statement, options, formatSnak, p.formatRefs )
else
--Default formatter
claim = formatStatement( statement, options, formatSnak, p.formatRefs )
end
return claim
end
function formatStatement( statement, options, formatSnak, formatRefs )
if ( options.plain ) then
return formatSnak( statement.mainsnak, options );
end
if ( options.references ) then
return formatSnak( statement.mainsnak, options ) .. formatRefs( statement );
else
return formatSnak( statement.mainsnak, options );
end
end
function formatSnak( snak, options )
local hash = '';
local mainSnakClass = '';
if ( snak.hash ) then
hash = ' data-wikidata-hash="' .. snak.hash .. '"';
else
mainSnakClass = ' wikidata-main-snak';
end
local before = '<span class="wikidata-snak ' .. mainSnakClass .. '"' .. hash .. '>'
local after = '</span>'
if options.plain then
before = ''
after = ''
end
if snak.snaktype == 'somevalue' then
return before .. (options['somevalue'] or i18n['somevalue']) .. after;
elseif snak.snaktype == 'novalue' then
return before .. (options['novalue'] or i18n['novalue']) .. after;
elseif snak.snaktype == 'value' then
return before .. formatDatavalue( snak.datavalue, options ) .. after;
else
return before .. formatError( 'unknown-snak-type' ) .. after;
end
end
function formatGlobeCoordinate( value, options )
if ( options.plain ) then
return value['latitude'] .. ';' .. value['longitude']
end
if options['subvalue'] == 'latitude' then
return value['latitude']
elseif options['subvalue'] == 'longitude' then
return value['longitude']
else
local eps = 0.0000001 -- < 1/360000
local globe = '' -- TODO
local lat = {}
lat['abs'] = math.abs(value['latitude'])
lat['ns'] = value['latitude'] >= 0 and 'N' or 'S'
lat['d'] = math.floor(lat['abs'] + eps)
lat['m'] = math.floor((lat['abs'] - lat['d']) * 60 + eps)
lat['s'] = math.max(0, ((lat['abs'] - lat['d']) * 60 - lat['m']) * 60)
local lon = {}
lon['abs'] = math.abs(value['longitude'])
lon['ew'] = value['longitude'] >= 0 and 'E' or 'W'
lon['d'] = math.floor(lon['abs'] + eps)
lon['m'] = math.floor((lon['abs'] - lon['d']) * 60 + eps)
lon['s'] = math.max(0, ((lon['abs'] - lon['d']) * 60 - lon['m']) * 60)
local coord = '{{coord'
if (value['precision'] == nil) or (value['precision'] < 1/60) then -- по умолчанию с точностью до секунды
coord = coord .. '|' .. lat['d'] .. '|' .. lat['m'] .. '|' .. lat['s'] .. '|' .. lat['ns']
coord = coord .. '|' .. lon['d'] .. '|' .. lon['m'] .. '|' .. lon['s'] .. '|' .. lon['ew']
elseif value['precision'] < 1 then
coord = coord .. '|' .. lat['d'] .. '|' .. lat['m'] .. '|' .. lat['ns']
coord = coord .. '|' .. lon['d'] .. '|' .. lon['m'] .. '|' .. lon['ew']
else
coord = coord .. '|' .. lat['d'] .. '|' .. lat['ns']
coord = coord .. '|' .. lon['d'] .. '|' .. lon['ew']
end
coord = coord .. '|globe:' .. globe
if options['display'] then
coord = coord .. '|display=' .. options.display
else
coord = coord .. '|display=title'
end
coord = coord .. '}}'
return g_frame:preprocess(coord)
end
end
function formatDatavalue( datavalue, options )
--Use the customize handler if provided
if options['value-module'] or options['value-function'] then
if not options['value-module'] or not options['value-function'] then
return formatError( 'unknown-value-module' )
end
local formatter = require ('Module:' .. options['value-module'])
if formatter == nil then
return formatError( 'value-module-not-found' )
end
local fun = formatter[options['value-function']]
if fun == nil then
return formatError( 'value-function-not-found' )
end
return fun( datavalue.value, options )
end
--Default formatters
if datavalue.type == 'wikibase-entityid' then
return formatEntityId( getEntityIdFromValue( datavalue.value ), options )
elseif datavalue.type == 'string' then
return datavalue.value --TODO ids + media
elseif datavalue.type == 'globecoordinate' then
return formatGlobeCoordinate( datavalue.value, options )
elseif datavalue.type == 'quantity' then
return string.gsub(datavalue.value['amount'], '^%+', '')
else
return formatError( 'unknown-datavalue-type' )
end
end
function formatEntityId( entityId, options )
local label = mw.wikibase.label( entityId )
if ( options.text and options.text ~= '' ) then
label = options.text
end
if ( options.plain ) then
if ( label ) then
return label
else
return entityId
end
end
local link = mw.wikibase.sitelink( entityId )
if link then
if label then
return '[[' .. link .. '|' .. label .. ']]'
else
return '[[' .. link .. ']]'
end
end
if label then
return label
end
-- not good, but better than nothing
return '[[d:' .. entityId .. '|' .. entityId .. ']]<span style="border-bottom: 1px dotted; cursor: help; white-space: nowrap" title="На Викиданных нет русской подписи к элементу. Вы можете помочь, указав русский вариант подписи.">?</span>[[Категория:Википедия:Статьи со ссылками на элементы Викиданных без русской подписи]]';
end
function p.formatStatements( frame )
g_frame = frame
local args = frame.args
--If a value if already set, use it
if args.value and args.value ~= '' then
return args.value
end
frame.args.plain = toBoolean( frame.args.plain, false );
frame.args.references = toBoolean( frame.args.references, true );
return formatStatements( frame.args )
end
local haveReferences = false;
function p.formatRefs( statement )
local result = '';
if ( statement.references ) then
haveReferences = true;
for _, reference in pairs( statement.references ) do
result = result .. formatRef(reference);
end
end
return result
end
function formatRef( reference )
if ( not reference.snaks ) then
return ''
end
if ( reference.snaks.p248 ) then
local entityId = "Q" .. reference.snaks.p248[0].datavalue.value["numeric-id"];
local rendered;
if ( moduleSources['src' .. entityId] ) then
rendered = moduleSources['src' .. entityId]( reference );
else
rendered = moduleSources.srcDefault( reference );
end
return g_frame:extensionTag( 'ref', rendered.text, {name = rendered.code} ) .. '[[К:Википедия:Статьи с источниками из Викиданных]]';
end
local result = ''
if ( reference.snaks.p304 ) then
result = result .. ' — С. ' .. formatSnak( reference.snaks.p304[0], {} );
end
if ( string.len( result ) ~= 0 ) then
return g_frame:extensionTag( 'ref', result ) .. '[[К:Википедия:Статьи с неоформленными источниками из Викиданных]]';
end
return result;
end
function p.formatReferences( )
if ( haveReferences ) then
return g_frame:extensionTag( 'references' );
end
return '';
end
return p