Модуль:Wikidata — версиосыз куспын пӧртэмлык

п
Откат правок Putnik (обсуждение) к версии Kaganer
(обновление из ru:Модуль:Wikidata)
п (Откат правок Putnik (обсуждение) к версии Kaganer)
["somevalue"] = "''неизвестно''",
["novalue"] = "",
["circaapproximate"] = '<span style="border-bottom: 1px dotted; cursor: help;" title="около, приблизительно">прибл. </span>',
["presumably"] = '<span style="border-bottom: 1px dotted; cursor: help;" title="предположительно">предп. </span>',
}
end
 
local function splitISO8601parseISO8601(str)
if 'table' == type(str) then
if str.args and str.args[1] then
return tonumber(sign .. oh), tonumber(sign .. om);
end )(str)
return tonumber(os.time({year=Y, month=M, day=D, hour=(h+oh), min=(m+om), sec=s};))
end
 
local function parseTimeBoundaries( time, precision )
local s = splitISO8601( time );
if (not s) then return nil; end
 
if ( precision >= 0 and precision <= 8 ) then
local powers = { 1000000000 , 100000000, 10000000, 1000000, 100000, 10000, 1000, 100, 10 }
local power = powers[ precision + 1 ];
local left = s.year - ( s.year % power );
return { tonumber(os.time( {year=left, month=1, day=1, hour=0, min=0, sec=0} )) * 1000,
tonumber(os.time( {year=left + power - 1, month=12, day=31, hour=29, min=59, sec=58} )) * 1000 + 1999 };
end
 
if ( precision == 9 ) then
return { tonumber(os.time( {year=s.year, month=1, day=1, hour=0, min=0, sec=0} )) * 1000,
tonumber(os.time( {year=s.year, month=12, day=31, hour=23, min=59, sec=58} )) * 1000 + 1999 };
end
 
if ( precision == 10 ) then
local lastDays = {31, 28.25, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
local lastDay = lastDays[s.month];
return { tonumber(os.time( {year=s.year, month=s.month, day=1, hour=0, min=0, sec=0} )) * 1000,
tonumber(os.time( {year=s.year, month=s.month, day=lastDay, hour=23, min=59, sec=58} )) * 1000 + 1999 };
end
 
if ( precision == 11 ) then
return { tonumber(os.time( {year=s.year, month=s.month, day=s.day, hour=0, min=0, sec=0} )) * 1000,
tonumber(os.time( {year=s.year, month=s.month, day=s.day, hour=23, min=59, sec=58} )) * 1000 + 1999 };
end
 
if ( precision == 12 ) then
return { tonumber(os.time( {year=s.year, month=s.month, day=s.day, hour=s.hour, min=0, sec=0} )) * 1000,
tonumber(os.time( {year=s.year, month=s.month, day=s.day, hour=s.hour, min=59, sec=58} )) * 1000 + 19991999 };
end
 
if ( precision == 13 ) then
return { tonumber(os.time( {year=s.year, month=s.month, day=s.day, hour=s.hour, min=s.min, sec=0} )) * 1000,
tonumber(os.time( {year=s.year, month=s.month, day=s.day, hour=s.hour, min=s.min, sec=58} )) * 1000 + 1999 };
end
 
if ( precision == 14 ) then
local t = tonumber(os.time( {year=s.year, month=s.month, day=s.day, hour=s.hour, min=s.min, sec=0} ) );
return { t * 1000, t * 1000 + 999 };
end
 
error('Unsupported precision: ' .. precision );
end
 
 
-- Выбирает свойства по property id, дополнительно фильтруя их по рангу
local function selectClaims( context, options, propertySelectorpropertyId )
if ( not context ) then error( 'context not specified'); end;
if ( not options ) then error( 'options not specified'); end;
if ( not options.entity ) then error( 'options.entity is missing'); end;
if ( not propertySelectorpropertyId ) then error( 'propertySelectorpropertyId not specified'); end;
 
local allPropertyClaims = options.entity.claims[ string.upper( propertyId ) ];
local WDS = require('Module:WikidataSelectors')
if ( not allPropertyClaims ) then
result = WDS.filter(options.entity.claims, propertySelector)
return nil;
end
 
--Поиск предпочтительного ранга
local requiredRank = 'normal' -- ранг по умолчанию (deprecated не используем)
-- если есть хотя бы один preferred, используем только их
for i, statement in pairs( allPropertyClaims ) do
if (statement.rank == 'preferred') then
requiredRank = 'preferred';
break
end
end
local result = {};
if ( allPropertyClaims[0] ) then
for i = 0, #allPropertyClaims do
local statement = allPropertyClaims[i]
if (statement.rank == requiredRank) then
result[ #result + 1 ] = statement;
end
end
else
for i, statement in pairs( allPropertyClaims ) do
if (statement.rank == requiredRank) then
result[ #result + 1 ] = statement;
end
end
end
 
if ( not result or #result == 0 ) then
return nil;
end
 
-- create context
local context = { formatSnak = formatSnak, formatPropertyDefault = formatPropertyDefault, formatStatementDefault = formatStatementDefault }
local context = {
entity = options.entity,
formatSnak = formatSnak,
formatPropertyDefault = formatPropertyDefault,
formatStatementDefault = formatStatementDefault }
context.formatProperty = function( options )
local func = getUserFunction( options, 'property', context.formatPropertyDefault );
context.parseTimeFromSnak = function( snak )
if ( snak and snak.datavalue and snak.datavalue.value and snak.datavalue.value.time ) then
returnlocal tonumber(os.time(timeISO6801 splitISO8601(= tostring( snak.datavalue.value.time ) ) ) ) * 1000;
return parseISO8601( timeISO6801 );
end
return nil;
end
context.parseTimeBoundariesFromSnak = function( snak )
if ( snak and snak.datavalue and snak.datavalue.value and snak.datavalue.value.time and snak.datavalue.value.precision ) then
return parseTimeBoundaries( snak.datavalue.value.time, snak.datavalue.value.precision );
end
return nil;
 
-- создание текстовой строки со списком оформленых заявлений из таблицы
local out =return mw.text.listToText( formattedClaims, options.separator, options.conjunction )
if out ~= '' then
if options.before then
out = options.before .. out
end
if options.after then
out = out .. options.after
end
end
 
return out
end
 
and qualifier.datavalue.value["entity-type"] == 'item' ) then
local circumstance = 'Q' .. qualifier.datavalue.value["numeric-id"];
if ( 'Q5727902Q18086598' == circumstance ) then
circumstances.circaapproximate = true;
end
if ( 'Q18122778' == circumstance ) then
 
if snak.snaktype == 'somevalue' then
if ( options['somevalue'] and options['somevalue'] ~= '' ) then
return before .. options['somevalue'] .. after;
end
return before .. options.i18n['somevalue'] .. after;
elseif snak.snaktype == 'novalue' then
if ( options['novalue'] and options['novalue'] ~= '' ) then
return before .. options['novalue'] .. after;
end
return before .. options.i18n['novalue'] .. after;
elseif snak.snaktype == 'value' then
before = before .. options.i18n.presumably;
end
if ( circumstances.circaapproximate ) then
before = before .. options.i18n.circaapproximate;
end
 
return before .. formatDatavalue( context, options, snak.datavalue, snak.datatype ) .. after;
else
throwError( 'unknown-snak-type' );
end
 
local function getDefaultValueFunction( datavalue )
--[[
Функция для оформления объектов-значений с файлами с Викисклада
 
Принимает: объект-значение и таблицу параметров,
Возвращает: строку оформленного текста
]]
function formatCommonsMedia( value, options )
local image = '[[File:' .. value
if options['border'] and options['border'] ~= '' then
image = image .. '|border'
end
 
local size = options['size']
if size and size ~= '' then
if not string.match( size, 'px$' )
and not string.match( size, 'пкс$' ) -- TODO: использовать перевод для языка вики
then
size = size .. 'px'
end
else
size = '250x350px' -- TODO: вынести в настройки
end
image = image .. '|' .. size
 
if options['alt'] and options['alt'] ~= '' then
image = image .. '|' .. options['alt']
end
image = image .. ']]'
return image
end
 
local function getDefaultValueFunction( datavalue, datatype )
-- вызов обработчиков по умолчанию для известных типов значений
if datavalue.type == 'wikibase-entityid' then
elseif datavalue.type == 'string' then
-- строка
if datatype and datatype == 'commonsMedia' then
-- медиафайл
return function( context, options, value ) return formatCommonsMedia( value, options ) end;
end
return function( context, options, value ) return value end;
elseif datavalue.type == 'monolingualtext' then
-- моноязычный текст (строка с указанием языка)
return function( context, options, value ) return '<span class="lang" lang="' .. value.language .. '">' .. value.text .. '</span>' end;
if ( options.monolingualLangTemplate == 'lang' ) then
return options.frame:expandTemplate{ title = 'lang-' .. value.language, args = { value.text } };
elseif ( options.monolingualLangTemplate == 'ref' ) then
return '<span class="lang" lang="' .. value.language .. '">' .. value.text .. '</span>' .. options.frame:expandTemplate{ title = 'ref-' .. value.language };
else
return '<span class="lang" lang="' .. value.language .. '">' .. value.text .. '</span>';
end
end;
elseif datavalue.type == 'globecoordinate' then
-- географические координаты
-- диапазон значений
local amount = string.gsub(value['amount'], '^%+', '')
local lang = mw.language.getContentLanguagenew( 'ru' )
return lang:formatNum( tonumber( amount ) )
end;
Возвращает: строку оформленного текста
]]
function formatDatavalue( context, options, datavalue, datatype )
if ( not context ) then error( 'context not specified' ); end;
if ( not options ) then error( 'options not specified' ); end;
-- проверка на указание специализированных обработчиков в параметрах,
-- переданных при вызове
context.formatValueDefault = getDefaultValueFunction( datavalue, datatype );
local functionToCall = getUserFunction( options, 'value', context.formatValueDefault );
return functionToCall( context, options, datavalue.value );
 
-- Небольшой словарь упрощенного отображения (TODO: надо сделать расширенный с учётом даты)
local simpleReplaces = {}
Q30 = '[[Соединённые Штаты Америки|США]]',
Q148 = '[[Китайская Народная Республика|КНР]]',
Q183 = '[[Германия]]',
Q258 = '[[Южно-Африканская Республика|ЮАР]]',
Q423 = '[[Корейская Народно-Демократическая Республика|КНДР]]',
Q2184 = '[[Российская Советская Федеративная Социалистическая Республика|РСФСР]]',
Q2895 = '[[Белорусская Советская Социалистическая Республика|Белорусская ССР]]',
Q15180 = '[[Союз Советских Социалистических Республик|СССР]]',
Q16957 = '[[Германская Демократическая Республика|ГДР]]',
Q130229 = '[[Грузинская Советская Социалистическая Республика|Грузинская ССР]]',
Q130280 = '[[Эстонская Советская Социалистическая Республика|Эстонская ССР]]',
Q131337 = '[[Азербайджанская Советская Социалистическая Республика|Азербайджанская ССР]]',
Q132856 = '[[Армянская Советская Социалистическая Республика|Армянская ССР]]',
Q133356 = '[[Украинская Советская Социалистическая Республика|Украинская ССР]]',
Q168811 = '[[Казахская Советская Социалистическая Республика|Казахская ССР]]',
Q170895 = '[[Молдавская Советская Социалистическая Республика|Молдавская ССР]]',
Q173761 = '[[Литовская Советская Социалистическая Республика|Литовская ССР]]',
Q192180 = '[[Латвийская Советская Социалистическая Республика|Латвийская ССР]]',
Q199707 = '[[Туркменская Советская Социалистическая Республика|Туркменская ССР]]',
Q199711 = '[[Таджикская Советская Социалистическая Республика|Таджикская ССР]]',
Q484578 = '[[Узбекская Советская Социалистическая Республика|Узбекская ССР]]',
Q809806 = '[[Башкирская Автономная Советская Социалистическая Республика|Башкирская АССР]]',
Q1157215 = '[[Дагестанская Автономная Советская Социалистическая Республика|Дагестанская АССР]]',
}
 
--[[
 
if label then
--return красная ссылкаlabel
if not mw.title.new( label ).exists then
return options.frame:expandTemplate{
title = 'не переведено 5',
args = { label, '', 'd', entityId }
}
end
 
-- TODO: перенести до проверки на существование статьи
local sup = '';
if ( not options.format or options.format ~= 'text' )
and entityId ~= 'Q6581072' and entityId ~= 'Q6581097' -- TODO: переписать на format=text
then
local lang = mw.language.getContentLanguage()
sup = '<sup class="plainlinks noprint">[//www.wikidata.org/wiki/' .. entityId .. '?uselang=' .. lang:getCode() .. ' [d]]</sup>'
end
 
-- одноимённая статья уже существует - выводится текст и ссылка на ВД
return '<span class="iw" data-title="' .. label .. '">' .. label
.. sup
.. '</span>'
end
-- сообщение об отсутвии локализованного названия
-- not good, but better than nothing
return '[[:d:' .. entityId .. '|' .. entityId .. ']]<span style="border-bottom: 1px dotted; cursor: help; white-space: nowrap" title="В Викиданных нет русской подписи к элементу. Вы можете помочь, указав русский вариант подписи.">?</span>' .. categoryLinksToEntitiesWithMissingLabel;
end
 
 
function p.formatProperty( frame )
local args = frame.args
local plain = toBoolean( frame.args.plain, false );
frame.args.nocat = toBoolean( frame.args.nocat, false );
frame.args.references = toBoolean( frame.args.references, true );
local args = frame.args
 
-- проверка на отсутствие обязательного параметра property
if not frame.args.property then
throwError( 'property-param-not-provided' )
end
local propertyId = mw.language.getContentLanguage():ucfirst( string.gsub( args.property, '%[.*$', '' ) )
 
-- если значение передано в параметрах вызова то выводим только его
if frame.args.value and frame.args.value ~= '' then
if plain or frame.args.nocat or frame:callParserFunction( '#property', frame.args.property )=='' then
-- специальное значение для скрытия Викиданных
-- опция, запрещающая оформление значения, поэтому никак не трогаем
if args.value == '-' then
return ''frame.args.value
else
-- если трогать всё-таки можно, добавляем категорию-маркер
return args.value .. categoryLocalValuePresent;
end
local value = args.value
 
-- опция, запрещающая оформление значения, поэтому никак не трогаем
if plain then
return value
end
 
-- обработчики по типу значения
-- TODO: переписать на запрос свойства из Викиданных
if ( propertyId == 'P18' or propertyId == 'P41' or propertyId == 'P94'
or propertyId == 'P109' or propertyId == 'P117'
or propertyId == 'P154' or propertyId == 'P242'
or propertyId == 'P1543' or propertyId == 'P1621'
or propertyId == 'P2425' or propertyId == 'P2910' )
and not string.find( value, '[%[%]%{%}]' ) then
value = formatCommonsMedia( value, args )
end
 
-- если трогать всё-таки можно, добавляем категорию-маркер
if not args.nocat then
value = value .. categoryLocalValuePresent;
end
 
return value
end
 
if ( plain ) then -- вызова стандартного обработчика без оформления, если передана опция plain
return frame:callParserFunction( '#property', propertyIdframe.args.property );
end
 
g_frame = frame
-- после проверки всех аргументов -- вызов функции оформления для свойства (набора утверждений)
return formatProperty( frame.args )
end