Модуль:Wikidata2: юрамалар арасында аерма
Контент бетерелгән Контент өстәлгән
Marat-avgust (бәхәс | кертем) Төзәтмә аңлатмасы юк |
Marat-avgust (бәхәс | кертем) Marat-avgust кулланучысының (бәхәс) 2141789 үзгәртүеннән баш тарту |
||
Юл номеры - 1: | Юл номеры - 1: | ||
local i18n = { |
|||
-- vim: set noexpandtab ft=lua ts=4 sw=4: |
|||
["errors"] = { |
|||
require('Module:No globals') |
|||
["property-param-not-provided"] = "Не дан параметр свойства", |
|||
["entity-not-found"] = "Сущность не найдена.", |
|||
["unknown-claim-type"] = "Неизвестный тип заявления.", |
|||
["unknown-snak-type"] = "Неизвестный тип снэка.", |
|||
["unknown-datavalue-type"] = "Неизвестный тип значения данных.", |
|||
["unknown-entity-type"] = "Неизвестный тип сущности.", |
|||
["unknown-property-module"] = "Вы должны установить и property-module, и property-function.", |
|||
["unknown-claim-module"] = "Вы должны установить и claim-module, и claim-function.", |
|||
["unknown-value-module"] = "Вы должны установить и value-module, и value-function.", |
|||
["property-module-not-found"] = "Модуль для отображения свойства не найден", |
|||
["property-function-not-found"] = "Функция для отображения свойства не найдена", |
|||
["claim-module-not-found"] = "Модуль для отображения утверждения не найден.", |
|||
["claim-function-not-found"] = "Функция для отображения утверждения не найдена.", |
|||
["value-module-not-found"] = "Модуль для отображения значения не найден.", |
|||
["value-function-not-found"] = "Функция для отображения значения не найдена." |
|||
}, |
|||
["somevalue"] = "''неизвестно''", |
|||
["novalue"] = "", |
|||
["approximate"] = '<span style="border-bottom: 1px dotted; cursor: help;" title="якынча">як. </span>', |
|||
["presumably"] = '<span style="border-bottom: 1px dotted; cursor: help;" title="предположительно">предп. </span>', |
|||
} |
|||
-- settings, may differ from project to project |
|||
local p = {} |
|||
local categoryLinksToEntitiesWithMissingLabel = '[[Төркем:Википедия:Статьи со ссылками на элементы Викиданных без русской подписи]]'; |
|||
local debug = false |
|||
local categoryLocalValuePresent = '[[Төркем:Википедия:Статьи с переопределением значения из Викиданных]]'; |
|||
local outputReferences = true; |
|||
-- sources that shall be omitted if any preffered sources exists |
|||
local deprecatedSources = { |
|||
Q36578 = true, -- Gemeinsame Normdatei |
|||
Q63056 = true, -- Find a Grave |
|||
Q15222191 = true, -- BNF |
|||
}; |
|||
local preferredSources = { |
|||
Q5375741 = true, -- Encyclopædia Britannica Online |
|||
Q17378135 = true, -- Great Soviet Encyclopedia (1969—1978) |
|||
}; |
|||
-- Ссылки на используемые модули, которые потребуются в 99% случаев загрузки страниц (чтобы иметь на виду при переименовании) |
|||
------------------------------------------------------------------------------ |
|||
local moduleSources = require('Module:Sources') |
|||
-- module local variables and functions |
|||
local |
local p = {} |
||
{ |
|||
langcode = mw.language.getContentLanguage().code |
|||
} |
|||
local formatDatavalue, formatEntityId, formatRefs, formatSnak, formatStatement, formatStatementDefault, formatProperty, getSourcingCircumstances, loadCacheSafe, throwError, toBoolean; |
|||
-- internationalisation |
|||
local i18n = |
|||
{ |
|||
["errors"] = |
|||
{ |
|||
["property-not-found"] = "Property not found.", |
|||
["entity-not-found"] = "Wikidata entity not found.", |
|||
["unknown-claim-type"] = "Unknown claim type.", |
|||
["unknown-entity-type"] = "Unknown entity type.", |
|||
["qualifier-not-found"] = "Qualifier not found.", |
|||
["site-not-found"] = "Wikimedia project not found.", |
|||
["unknown-datetime-format"] = "Unknown datetime format.", |
|||
["local-article-not-found"] = "Article is not yet available in this wiki." |
|||
}, |
|||
["datetime"] = |
|||
{ |
|||
-- $1 is a placeholder for the actual number |
|||
[0] = "$1 billion years", -- precision: billion years |
|||
[1] = "$100 million years", -- precision: hundred million years |
|||
[2] = "$10 million years", -- precision: ten million years |
|||
[3] = "$1 million years", -- precision: million years |
|||
[4] = "$100,000 years", -- precision: hundred thousand years |
|||
[5] = "$10,000 years", -- precision: ten thousand years |
|||
[6] = "$1 millennium", -- precision: millennium |
|||
[7] = "$1 century", -- precision: century |
|||
[8] = "$1s", -- precision: decade |
|||
-- the following use the format of #time parser function |
|||
[9] = "Y", -- precision: year, |
|||
[10] = "F Y", -- precision: month |
|||
[11] = "F j, Y", -- precision: day |
|||
[12] = "F j, Y ga", -- precision: hour |
|||
[13] = "F j, Y g:ia", -- precision: minute |
|||
[14] = "F j, Y g:i:sa", -- precision: second |
|||
["beforenow"] = "$1 BCE", -- how to format negative numbers for precisions 0 to 5 |
|||
["afternow"] = "$1 CE", -- how to format positive numbers for precisions 0 to 5 |
|||
["bc"] = '$1 "BCE"', -- how print negative years |
|||
["ad"] = "$1", -- how print positive years |
|||
-- the following are for function getDateValue() and getQualifierDateValue() |
|||
["default-format"] = "dmy", -- default value of the #3 (getDateValue) or |
|||
-- #4 (getQualifierDateValue) argument |
|||
["default-addon"] = "BC", -- default value of the #4 (getDateValue) or |
|||
-- #5 (getQualifierDateValue) argument |
|||
["prefix-addon"] = false, -- set to true for languages put "BC" in front of the |
|||
-- datetime string; or the addon will be suffixed |
|||
["addon-sep"] = " ", -- separator between datetime string and addon (or inverse) |
|||
["format"] = -- options of the 3rd argument |
|||
{ |
|||
["mdy"] = "F j, Y", |
|||
["my"] = "F Y", |
|||
["y"] = "Y", |
|||
["dmy"] = "j F Y", |
|||
["ymd"] = "Y-m-d", |
|||
["ym"] = "Y-m" |
|||
} |
|||
}, |
|||
["monolingualtext"] = '<span lang="%language">%text</span>', |
|||
["warnDump"] = "[[Category:Called function 'Dump' from module Wikidata]]", |
|||
["ordinal"] = |
|||
{ |
|||
[1] = "st", |
|||
[2] = "nd", |
|||
[3] = "rd", |
|||
["default"] = "th" |
|||
} |
|||
} |
|||
local function copyTo( obj, target ) |
|||
-- Credit to http://stackoverflow.com/a/1283608/2644759 |
|||
for k, v in pairs( obj ) do |
|||
-- cc-by-sa 3.0 |
|||
target[k] = v |
|||
local function tableMerge(t1, t2) |
|||
for k,v in pairs(t2) do |
|||
if type(v) == "table" then |
|||
if type(t1[k] or false) == "table" then |
|||
tableMerge(t1[k] or {}, t2[k] or {}) |
|||
else |
|||
t1[k] = v |
|||
end |
|||
else |
|||
t1[k] = v |
|||
end |
|||
end |
end |
||
return |
return target; |
||
end |
end |
||
local function |
local function loadCacheSafe( entityId ) |
||
local |
local status, result = pcall( function() return mw.loadData( 'Module:WikidataCache/' .. entityId ) end ); |
||
if |
if ( status == true ) then |
||
return result; |
|||
tableMerge(i18n, res.i18n) |
|||
end |
end |
||
return nil; |
|||
end |
end |
||
local function parseISO8601(str) |
|||
loadI18n() |
|||
if 'table' == type(str) then |
|||
if str.args and str.args[1] then |
|||
-- this function needs to be internationalised along with the above: |
|||
str = '' .. str.args[1] |
|||
-- takes cardinal numer as a numeric and returns the ordinal as a string |
|||
-- we need three exceptions in English for 1st, 2nd, 3rd, 21st, .. 31st, etc. |
|||
local function makeOrdinal (cardinal) |
|||
local ordsuffix = i18n.ordinal.default |
|||
if cardinal % 10 == 1 then |
|||
ordsuffix = i18n.ordinal[1] |
|||
elseif cardinal % 10 == 2 then |
|||
ordsuffix = i18n.ordinal[2] |
|||
elseif cardinal % 10 == 3 then |
|||
ordsuffix = i18n.ordinal[3] |
|||
end |
|||
-- In English, 1, 21, 31, etc. use 'st', but 11, 111, etc. use 'th' |
|||
-- similarly for 12 and 13, etc. |
|||
if (cardinal % 100 == 11) or (cardinal % 100 == 12) or (cardinal % 100 == 13) then |
|||
ordsuffix = i18n.ordinal.default |
|||
end |
|||
return tostring(cardinal) .. ordsuffix |
|||
end |
|||
local function printError(code) |
|||
return '<span class="error">' .. (i18n.errors[code] or code) .. '</span>' |
|||
end |
|||
local function parseDateValue(timestamp, date_format, date_addon) |
|||
local prefix_addon = i18n["datetime"]["prefix-addon"] |
|||
local addon_sep = i18n["datetime"]["addon-sep"] |
|||
local addon = "" |
|||
-- check for negative date |
|||
if string.sub(timestamp, 1, 1) == '-' then |
|||
timestamp = '+' .. string.sub(timestamp, 2) |
|||
addon = date_addon |
|||
end |
|||
local function d(f) |
|||
local year_suffix |
|||
local tstr = "" |
|||
local lang_obj = mw.language.new(wiki.langcode) |
|||
local f_parts = mw.text.split(f, 'Y', true) |
|||
for idx, f_part in pairs(f_parts) do |
|||
year_suffix = '' |
|||
if string.match(f_part, "x[mijkot]$") then |
|||
-- for non-Gregorian year |
|||
f_part = f_part .. 'Y' |
|||
elseif idx < #f_parts then |
|||
-- supress leading zeros in year |
|||
year_suffix = lang_obj:formatDate('Y', timestamp) |
|||
year_suffix = string.gsub(year_suffix, '^0+', '', 1) |
|||
end |
|||
tstr = tstr .. lang_obj:formatDate(f_part, timestamp) .. year_suffix |
|||
end |
|||
if addon ~= "" and prefix_addon then |
|||
return addon .. addon_sep .. tstr |
|||
elseif addon ~= "" then |
|||
return tstr .. addon_sep .. addon |
|||
else |
else |
||
return 'unknown argument type: ' .. type( str ) .. ': ' .. table.tostring( str ) |
|||
return tstr |
|||
end |
end |
||
end |
end |
||
local Y, M, D = (function(str) |
|||
local _date_format = i18n["datetime"]["format"][date_format] |
|||
local pattern = "(%-?%d+)%-(%d+)%-(%d+)T" |
|||
if _date_format ~= nil then |
|||
local Y, M, D = mw.ustring.match( str, pattern ) |
|||
return d(_date_format) |
|||
return tonumber(Y), tonumber(M), tonumber(D) |
|||
else |
|||
end) (str); |
|||
return printError("unknown-datetime-format") |
|||
local h, m, s = (function(str) |
|||
end |
|||
local pattern = "T(%d+):(%d+):(%d+)%Z"; |
|||
local H, M, S = mw.ustring.match( str, pattern); |
|||
return tonumber(H), tonumber(M), tonumber(S); |
|||
end) (str); |
|||
local oh,om = ( function(str) |
|||
if str:sub(-1)=="Z" then return 0,0 end; -- ends with Z, Zulu time |
|||
-- matches ±hh:mm, ±hhmm or ±hh; else returns nils |
|||
local pattern = "([-+])(%d%d):?(%d?%d?)$"; |
|||
local sign, oh, om = mw.ustring.match( str, pattern); |
|||
sign, oh, om = sign or "+", oh or "00", om or "00"; |
|||
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 |
end |
||
--[[ |
|||
-- This local function combines the year/month/day/BC/BCE handling of parseDateValue{} |
|||
Преобразует строку в булевое значение |
|||
-- with the millennium/century/decade handling of formatDate() |
|||
local function parseDateFull(timestamp, precision, date_format, date_addon) |
|||
local prefix_addon = i18n["datetime"]["prefix-addon"] |
|||
local addon_sep = i18n["datetime"]["addon-sep"] |
|||
local addon = "" |
|||
Принимает: строковое значение (может отсутствовать) |
|||
-- check for negative date |
|||
Возвращает: булевое значение true или false, если получается распознать значение, или defaultValue во всех остальных случаях |
|||
if string.sub(timestamp, 1, 1) == '-' then |
|||
]] |
|||
timestamp = '+' .. string.sub(timestamp, 2) |
|||
local function toBoolean( valueToParse, defaultValue ) |
|||
addon = date_addon |
|||
if ( valueToParse ) then |
|||
end |
|||
if valueToParse == '' or valueToParse == 'false' or valueToParse == '0' then |
|||
return false |
|||
-- get the next four characters after the + (should be the year now in all cases) |
|||
end |
|||
-- ok, so this is dirty, but let's get it working first |
|||
return true |
|||
local intyear = tonumber(string.sub(timestamp, 2, 5)) |
|||
end |
|||
if intyear == 0 and precision <= 9 then |
|||
return defaultValue; |
|||
end |
|||
-- precision is 10000 years or more |
|||
if precision <= 5 then |
|||
local factor = 10 ^ ((5 - precision) + 4) |
|||
local y2 = math.ceil(math.abs(intyear) / factor) |
|||
local relative = mw.ustring.gsub(i18n.datetime[precision], "$1", tostring(y2)) |
|||
if addon ~= "" then |
|||
-- negative date |
|||
relative = mw.ustring.gsub(i18n.datetime.beforenow, "$1", relative) |
|||
else |
|||
relative = mw.ustring.gsub(i18n.datetime.afternow, "$1", relative) |
|||
end |
|||
return relative |
|||
end |
|||
-- precision is decades (8), centuries (7) and millennia (6) |
|||
local era, card |
|||
if precision == 6 then |
|||
card = math.floor((intyear - 1) / 1000) + 1 |
|||
era = mw.ustring.gsub(i18n.datetime[6], "$1", makeOrdinal(card)) |
|||
end |
|||
if precision == 7 then |
|||
card = math.floor((intyear - 1) / 100) + 1 |
|||
era = mw.ustring.gsub(i18n.datetime[7], "$1", makeOrdinal(card)) |
|||
end |
|||
if precision == 8 then |
|||
era = mw.ustring.gsub(i18n.datetime[8], "$1", tostring(math.floor(math.abs(intyear) / 10) * 10)) |
|||
end |
|||
if era then |
|||
if addon ~= "" then |
|||
era = mw.ustring.gsub(mw.ustring.gsub(i18n.datetime.bc, '"', ""), "$1", era) |
|||
else |
|||
era = mw.ustring.gsub(mw.ustring.gsub(i18n.datetime.ad, '"', ""), "$1", era) |
|||
end |
|||
return era |
|||
end |
|||
local _date_format = i18n["datetime"]["format"][date_format] |
|||
if _date_format ~= nil then |
|||
-- check for precision is year and override supplied date_format |
|||
if precision == 9 then |
|||
_date_format = i18n["datetime"][9] |
|||
end |
|||
local year_suffix |
|||
local tstr = "" |
|||
local lang_obj = mw.language.new(wiki.langcode) |
|||
local f_parts = mw.text.split(_date_format, 'Y', true) |
|||
for idx, f_part in pairs(f_parts) do |
|||
year_suffix = '' |
|||
if string.match(f_part, "x[mijkot]$") then |
|||
-- for non-Gregorian year |
|||
f_part = f_part .. 'Y' |
|||
elseif idx < #f_parts then |
|||
-- supress leading zeros in year |
|||
year_suffix = lang_obj:formatDate('Y', timestamp) |
|||
year_suffix = string.gsub(year_suffix, '^0+', '', 1) |
|||
end |
|||
tstr = tstr .. lang_obj:formatDate(f_part, timestamp) .. year_suffix |
|||
end |
|||
local fdate |
|||
if addon ~= "" and prefix_addon then |
|||
fdate = addon .. addon_sep .. tstr |
|||
elseif addon ~= "" then |
|||
fdate = tstr .. addon_sep .. addon |
|||
else |
|||
fdate = tstr |
|||
end |
|||
return fdate |
|||
else |
|||
return printError("unknown-datetime-format") |
|||
end |
|||
end |
end |
||
--[[ |
|||
-- the "qualifiers" and "snaks" field have a respective "qualifiers-order" and "snaks-order" field |
|||
Функция для получения сущности (еntity) для текущей страницы |
|||
-- use these as the second parameter and this function instead of the built-in "pairs" function |
|||
Подробнее о сущностях см. d:Wikidata:Glossary/ru |
|||
-- to iterate over all qualifiers and snaks in the intended order. |
|||
local function orderedpairs(array, order) |
|||
if not order then return pairs(array) end |
|||
Принимает: строковый индентификатор (типа P18, Q42) |
|||
-- return iterator function |
|||
Возвращает: объект таблицу, элементы которой индексируются с нуля |
|||
local i = 0 |
|||
]] |
|||
return function() |
|||
local function getEntityFromId( id ) |
|||
i = i + 1 |
|||
if id then |
|||
local cached = loadCacheSafe( id ); |
|||
return order[i], array[order[i]] |
|||
if ( cached ) then |
|||
end |
|||
return cached; |
|||
end |
|||
return mw.wikibase.getEntityObject( id ) |
|||
end |
|||
local entity = mw.wikibase.getEntityObject(); |
|||
if ( entity ) then |
|||
local cached = loadCacheSafe( entity.id ); |
|||
if ( cached ) then |
|||
return cached; |
|||
end |
|||
end |
end |
||
return entity; |
|||
end |
end |
||
--[[ |
|||
-- precision: 0 - billion years, 1 - hundred million years, ..., 6 - millennia, 7 - century, 8 - decade, 9 - year, 10 - month, 11 - day, 12 - hour, 13 - minute, 14 - second |
|||
Внутрення функция для формирования сообщения об ошибке |
|||
local function normalizeDate(date) |
|||
date = mw.text.trim(date, "+") |
|||
Принимает: ключ элемента в таблице i18n (например entity-not-found) |
|||
-- extract year |
|||
Возвращает: строку сообщения |
|||
local yearstr = mw.ustring.match(date, "^\-?%d+") |
|||
]] |
|||
local year = tonumber(yearstr) |
|||
local function throwError( key ) |
|||
-- remove leading zeros of year |
|||
error( i18n.errors[key] ); |
|||
return year .. mw.ustring.sub(date, #yearstr + 1), year |
|||
end |
end |
||
--[[ |
|||
local function formatDate(date, precision, timezone) |
|||
Функция для получения идентификатора сущностей |
|||
precision = precision or 11 |
|||
local date, year = normalizeDate(date) |
|||
if year == 0 and precision <= 9 then return "" end |
|||
Принимает: объект таблицу сущности |
|||
-- precision is 10000 years or more |
|||
Возвращает: строковый индентификатор (типа P18, Q42) |
|||
if precision <= 5 then |
|||
]] |
|||
local factor = 10 ^ ((5 - precision) + 4) |
|||
local function getEntityIdFromValue( value ) |
|||
local y2 = math.ceil(math.abs(year) / factor) |
|||
local prefix = '' |
|||
local relative = mw.ustring.gsub(i18n.datetime[precision], "$1", tostring(y2)) |
|||
if value['entity-type'] == 'item' then |
|||
prefix = 'Q' |
|||
relative = mw.ustring.gsub(i18n.datetime.beforenow, "$1", relative) |
|||
elseif value['entity-type'] == 'property' then |
|||
else |
|||
prefix = 'P' |
|||
relative = mw.ustring.gsub(i18n.datetime.afternow, "$1", relative) |
|||
else |
|||
end |
|||
throwError( 'unknown-entity-type' ) |
|||
return relative |
|||
end |
|||
return prefix .. value['numeric-id'] |
|||
end |
|||
-- проверка на наличие специилизированной функции в опциях |
|||
-- precision is decades, centuries and millennia |
|||
local function getUserFunction( options, prefix, defaultFunction ) |
|||
local era |
|||
-- проверка на указание специализированных обработчиков в параметрах, |
|||
if precision == 6 then era = mw.ustring.gsub(i18n.datetime[6], "$1", tostring(math.floor((math.abs(year) - 1) / 1000) + 1)) end |
|||
-- переданных при вызове |
|||
if precision == 7 then era = mw.ustring.gsub(i18n.datetime[7], "$1", tostring(math.floor((math.abs(year) - 1) / 100) + 1)) end |
|||
if options[ prefix .. '-module' ] or options[ prefix .. '-function' ] then |
|||
if precision == 8 then era = mw.ustring.gsub(i18n.datetime[8], "$1", tostring(math.floor(math.abs(year) / 10) * 10)) end |
|||
-- проверка на пустые строки в параметрах или их отсутствие |
|||
if era then |
|||
if not options[ prefix .. '-module' ] or not options[ prefix .. '-function' ] then |
|||
if year < 0 then era = mw.ustring.gsub(mw.ustring.gsub(i18n.datetime.bc, '"', ""), "$1", era) |
|||
throwError( 'unknown-' .. prefix .. '-module' ); |
|||
elseif year > 0 then era = mw.ustring.gsub(mw.ustring.gsub(i18n.datetime.ad, '"', ""), "$1", era) end |
|||
end |
|||
return era |
|||
-- динамическая загруза модуля с обработчиком указанным в параметре |
|||
end |
|||
local formatter = require ('Module:' .. options[ prefix .. '-module' ]); |
|||
if formatter == nil then |
|||
throwError( prefix .. '-module-not-found' ) |
|||
end |
|||
local fun = formatter[ options[ prefix .. '-function' ] ] |
|||
if fun == nil then |
|||
throwError( prefix .. '-function-not-found' ) |
|||
end |
|||
return fun; |
|||
end |
|||
return defaultFunction; |
|||
-- precision is year |
|||
if precision == 9 then |
|||
return year |
|||
end |
|||
-- precision is less than years |
|||
if precision > 9 then |
|||
--[[ the following code replaces the UTC suffix with the given negated timezone to convert the global time to the given local time |
|||
timezone = tonumber(timezone) |
|||
if timezone and timezone ~= 0 then |
|||
timezone = -timezone |
|||
timezone = string.format("%.2d%.2d", timezone / 60, timezone % 60) |
|||
if timezone[1] ~= '-' then timezone = "+" .. timezone end |
|||
date = mw.text.trim(date, "Z") .. " " .. timezone |
|||
end |
|||
]]-- |
|||
local formatstr = i18n.datetime[precision] |
|||
if year == 0 then formatstr = mw.ustring.gsub(formatstr, i18n.datetime[9], "") |
|||
elseif year < 0 then |
|||
-- Mediawiki formatDate doesn't support negative years |
|||
date = mw.ustring.sub(date, 2) |
|||
formatstr = mw.ustring.gsub(formatstr, i18n.datetime[9], mw.ustring.gsub(i18n.datetime.bc, "$1", i18n.datetime[9])) |
|||
elseif year > 0 and i18n.datetime.ad ~= "$1" then |
|||
formatstr = mw.ustring.gsub(formatstr, i18n.datetime[9], mw.ustring.gsub(i18n.datetime.ad, "$1", i18n.datetime[9])) |
|||
end |
|||
return mw.language.new(wiki.langcode):formatDate(formatstr, date) |
|||
end |
|||
end |
end |
||
-- Выбирает свойства по property id, дополнительно фильтруя их по рангу |
|||
local function printDatavalueEntity(data, parameter) |
|||
local function selectClaims( context, options, propertyId ) |
|||
-- data fields: entity-type [string], numeric-id [int, Wikidata id] |
|||
if ( not context ) then error( 'context not specified'); end; |
|||
local id |
|||
if ( not options ) then error( 'options not specified'); end; |
|||
if ( not options.entity ) then error( 'options.entity is missing'); end; |
|||
if ( not propertyId ) then error( 'propertyId not specified'); end; |
|||
local allPropertyClaims = options.entity.claims[ string.upper( propertyId ) ]; |
|||
if data["entity-type"] == "item" then id = "Q" .. data["numeric-id"] |
|||
if ( not allPropertyClaims ) then |
|||
elseif data["entity-type"] == "property" then id = "P" .. data["numeric-id"] |
|||
return nil; |
|||
else return printError("unknown-entity-type") |
|||
end |
|||
--Поиск предпочтительного ранга |
|||
if parameter then |
|||
local requiredRank = 'normal' -- ранг по умолчанию (deprecated не используем) |
|||
if parameter == "link" then |
|||
-- если есть хотя бы один preferred, используем только их |
|||
local linkTarget = mw.wikibase.sitelink(id) |
|||
for i, statement in pairs( allPropertyClaims ) do |
|||
local linkName = mw.wikibase.label(id) |
|||
if (statement.rank == 'preferred') then |
|||
requiredRank = 'preferred'; |
|||
-- if there is a local Wikipedia article link to it using the label or the article title |
|||
break |
|||
return "[[" .. linkTarget .. "|" .. (linkName or linkTarget) .. "]]" |
|||
else |
|||
-- if there is no local Wikipedia article output the label or link to the Wikidata object to let the user input a proper label |
|||
if linkName then return linkName else return "[[:d:" .. id .. "|" .. id .. "]]" end |
|||
end |
|||
else |
|||
return data[parameter] |
|||
end |
end |
||
else |
|||
return mw.wikibase.label(id) or id |
|||
end |
end |
||
local result = {}; |
|||
end |
|||
if ( allPropertyClaims[0] ) then |
|||
for i = 0, #allPropertyClaims do |
|||
local function printDatavalueTime(data, parameter) |
|||
local statement = allPropertyClaims[i] |
|||
-- data fields: time [ISO 8601 time], timezone [int in minutes], before [int], after [int], precision [int], calendarmodel [wikidata URI] |
|||
if (statement.rank == requiredRank) then |
|||
-- precision: 0 - billion years, 1 - hundred million years, ..., 6 - millennia, 7 - century, 8 - decade, 9 - year, 10 - month, 11 - day, 12 - hour, 13 - minute, 14 - second |
|||
result[ #result + 1 ] = statement; |
|||
-- calendarmodel: e.g. http://www.wikidata.org/entity/Q1985727 for the proleptic Gregorian calendar or http://www.wikidata.org/wiki/Q11184 for the Julian calendar] |
|||
end |
|||
if parameter then |
|||
end |
|||
if parameter == "calendarmodel" then data.calendarmodel = mw.ustring.match(data.calendarmodel, "Q%d+") -- extract entity id from the calendar model URI |
|||
elseif parameter == "time" then data.time = normalizeDate(data.time) end |
|||
return data[parameter] |
|||
else |
else |
||
for i, statement in pairs( allPropertyClaims ) do |
|||
return formatDate(data.time, data.precision, data.timezone) |
|||
if (statement.rank == requiredRank) then |
|||
result[ #result + 1 ] = statement; |
|||
end |
|||
end |
|||
end |
end |
||
end |
|||
if ( #result == 0 ) then |
|||
local function printDatavalueMonolingualText(data, parameter) |
|||
return nil; |
|||
-- data fields: language [string], text [string] |
|||
end |
|||
if parameter then |
|||
return data[parameter] |
|||
return result; |
|||
else |
|||
local result = mw.ustring.gsub(mw.ustring.gsub(i18n.monolingualtext, "%%language", data["language"]), "%%text", data["text"]) |
|||
return result |
|||
end |
|||
end |
end |
||
--[[ |
|||
local function findClaims(entity, property) |
|||
Функция для оформления утверждений (statement) |
|||
if not property or not entity or not entity.claims then return end |
|||
Подробнее о утверждениях см. d:Wikidata:Glossary/ru |
|||
Принимает: таблицу параметров |
|||
if mw.ustring.match(property, "^P%d+$") then |
|||
Возвращает: строку оформленного текста, предназначенного для отображения в статье |
|||
-- if the property is given by an id (P..) access the claim list by this id |
|||
]] |
|||
return entity.claims[property] |
|||
local function formatProperty( options ) |
|||
else |
|||
-- Получение сущности по идентификатору |
|||
-- otherwise, iterate over all properties, fetch their labels and compare this to the given property name |
|||
local entity = getEntityFromId( options.entityId ) |
|||
for k, v in pairs(entity.claims) do |
|||
if not entity then |
|||
if mw.wikibase.label(k) == property then return v end |
|||
return -- throwError( 'entity-not-found' ) |
|||
end |
|||
end |
|||
return |
|||
-- проверка на присутсвие у сущности заявлений (claim) |
|||
end |
|||
-- подробнее о заявлениях см. d:Викиданные:Глоссарий |
|||
end |
|||
if (entity.claims == nil) then |
|||
return '' --TODO error? |
|||
end |
|||
-- improve options |
|||
local function getSnakValue(snak, parameter) |
|||
options.frame = g_frame; |
|||
if snak.snaktype == "value" then |
|||
options.entity = entity; |
|||
-- call the respective snak parser |
|||
options.extends = function( self, newOptions ) |
|||
if snak.datavalue.type == "string" then return snak.datavalue.value |
|||
return copyTo( newOptions, copyTo( self, {} ) ) |
|||
elseif snak.datavalue.type == "globecoordinate" then return printDatavalueCoordinate(snak.datavalue.value, parameter) |
|||
elseif snak.datavalue.type == "quantity" then return printDatavalueQuantity(snak.datavalue.value, parameter) |
|||
elseif snak.datavalue.type == "time" then return printDatavalueTime(snak.datavalue.value, parameter) |
|||
elseif snak.datavalue.type == "wikibase-entityid" then return printDatavalueEntity(snak.datavalue.value, parameter) |
|||
elseif snak.datavalue.type == "monolingualtext" then return printDatavalueMonolingualText(snak.datavalue.value, parameter) |
|||
end |
|||
end |
end |
||
return mw.wikibase.renderSnak(snak) |
|||
end |
|||
if ( options.i18n ) then |
|||
local function getQualifierSnak(claim, qualifierId) |
|||
options.i18n = copyTo( options.i18n, copyTo( i18n, {} ) ); |
|||
-- a "snak" is Wikidata terminology for a typed key/value pair |
|||
-- a claim consists of a main snak holding the main information of this claim, |
|||
-- as well as a list of attribute snaks and a list of references snaks |
|||
if qualifierId then |
|||
-- search the attribute snak with the given qualifier as key |
|||
if claim.qualifiers then |
|||
local qualifier = claim.qualifiers[qualifierId] |
|||
if qualifier then return qualifier[1] end |
|||
end |
|||
return nil, printError("qualifier-not-found") |
|||
else |
else |
||
options.i18n = i18n; |
|||
-- otherwise return the main snak |
|||
return claim.mainsnak |
|||
end |
end |
||
end |
|||
local function getValueOfClaim(claim, qualifierId, parameter) |
|||
local error |
|||
local snak |
|||
snak, error = getQualifierSnak(claim, qualifierId) |
|||
if snak then |
|||
return getSnakValue(snak, parameter) |
|||
else |
|||
return nil, error |
|||
end |
|||
end |
|||
-- create context |
|||
local function getReferences(frame, claim) |
|||
local context = { formatSnak = formatSnak, formatPropertyDefault = formatPropertyDefault, formatStatementDefault = formatStatementDefault } |
|||
local result = "" |
|||
context.formatProperty = function( options ) |
|||
-- traverse through all references |
|||
local func = getUserFunction( options, 'property', context.formatPropertyDefault ); |
|||
for ref in pairs(claim.references or {}) do |
|||
return func( context, options ) |
|||
local refparts |
|||
end; |
|||
-- traverse through all parts of the current reference |
|||
context.formatStatement = function( options, statement ) return formatStatement( context, options, statement ) end; |
|||
for snakkey, snakval in orderedpairs(claim.references[ref].snaks or {}, claim.references[ref]["snaks-order"]) do |
|||
context.formatSnak = function( options, snak, circumstances ) return formatSnak( context, options, snak, circumstances ) end; |
|||
if refparts then refparts = refparts .. ", " else refparts = "" end |
|||
context.formatRefs = function( options, statement ) return formatRefs( context, options, statement ) end; |
|||
-- output the label of the property of the reference part, e.g. "imported from" for P143 |
|||
refparts = refparts .. tostring(mw.wikibase.label(snakkey)) .. ": " |
|||
context.parseTimeFromSnak = function( snak ) |
|||
-- output all values of this reference part, e.g. "German Wikipedia" and "English Wikipedia" if the referenced claim was imported from both sites |
|||
if ( snak and snak.datavalue and snak.datavalue.value and snak.datavalue.value.time ) then |
|||
for snakidx = 1, #snakval do |
|||
local timeISO6801 = tostring( snak.datavalue.value.time ) |
|||
if snakidx > 1 then refparts = refparts .. ", " end |
|||
return parseISO8601( timeISO6801 ); |
|||
refparts = refparts .. getSnakValue(snakval[snakidx]) |
|||
end |
end |
||
return nil; |
|||
end |
end |
||
context.getSourcingCircumstances = function( statement ) return getSourcingCircumstances( statement ) end; |
|||
if refparts then result = result .. frame:extensionTag("ref", refparts) end |
|||
context.selectClaims = function( options, propertyId ) return selectClaims( context, options, propertyId ) end; |
|||
end |
|||
return result |
|||
return context.formatProperty( options ); |
|||
end |
end |
||
function formatPropertyDefault( context, options ) |
|||
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 missing' ); end; |
|||
local claims = context.selectClaims( options, options.property ); |
|||
------------------------------------------------------------------------------ |
|||
if (claims == nil) then |
|||
-- module global functions |
|||
return '' --TODO error? |
|||
end |
|||
-- Обход всех заявлений утверждения и с накоплением оформленых предпочтительных |
|||
if debug then |
|||
-- заявлений в таблице |
|||
function p.inspectI18n(frame) |
|||
local formattedClaims = {} |
|||
for _, key in pairs(frame.args) do |
|||
key = mw.text.trim(key) |
|||
val = val[key] |
|||
end |
|||
return val |
|||
end |
|||
end |
|||
for i, claim in ipairs(claims) do |
|||
function p.descriptionIn(frame) |
|||
local formattedStatement = context.formatStatement( options, claim ) |
|||
local langcode = frame.args[1] |
|||
-- здесь может вернуться либо оформленный текст заявления |
|||
local id = frame.args[2] -- "id" must be nil, as access to other Wikidata objects is disabled in Mediawiki configuration |
|||
-- либо строка ошибки nil похоже никогда не возвращается |
|||
-- return description of a Wikidata entity in the given language or the default language of this Wikipedia site |
|||
if (formattedStatement) then |
|||
return mw.wikibase.getEntityObject(id).descriptions[langcode or wiki.langcode].value |
|||
formattedStatement = '<span class="wikidata-claim" data-wikidata-property-id="' .. string.upper( options.property ) .. '" data-wikidata-claim-id="' .. claim.id .. '">' .. formattedStatement .. '</span>' |
|||
end |
|||
table.insert( formattedClaims, formattedStatement ) |
|||
end |
|||
end |
|||
-- создание текстовой строки со списком оформленых заявлений из таблицы |
|||
function p.labelIn(frame) |
|||
return mw.text.listToText( formattedClaims, options.separator, options.conjunction ) |
|||
local langcode = frame.args[1] |
|||
local id = frame.args[2] -- "id" must be nil, as access to other Wikidata objects is disabled in Mediawiki configuration |
|||
-- return label of a Wikidata entity in the given language or the default language of this Wikipedia site |
|||
return mw.wikibase.getEntityObject(id).labels[langcode or wiki.langcode].value |
|||
end |
end |
||
--[[ |
|||
-- This is used to get a value, or a comma separated list of them if multiple values exist |
|||
Функция для оформления одного утверждения (statement) |
|||
p.getValue = function(frame) |
|||
local propertyID = mw.text.trim(frame.args[1] or "") |
|||
local input_parm = mw.text.trim(frame.args[2] or "") |
|||
if input_parm == "FETCH_WIKIDATA" then |
|||
local entity = mw.wikibase.getEntityObject() |
|||
local claims |
|||
if entity and entity.claims then |
|||
claims = entity.claims[propertyID] |
|||
end |
|||
if claims then |
|||
-- if wiki-linked value output as link if possible |
|||
if (claims[1] and claims[1].mainsnak.snaktype == "value" and claims[1].mainsnak.datavalue.type == "wikibase-entityid") then |
|||
local out = {} |
|||
for k, v in pairs(claims) do |
|||
local sitelink = mw.wikibase.sitelink("Q" .. v.mainsnak.datavalue.value["numeric-id"]) |
|||
local label = mw.wikibase.label("Q" .. v.mainsnak.datavalue.value["numeric-id"]) |
|||
if label == nil then label = "Q" .. v.mainsnak.datavalue.value["numeric-id"] end |
|||
Принимает: объект-таблицу утверждение и таблицу параметров |
|||
if sitelink then |
|||
Возвращает: строку оформленного текста с заявлением (claim) |
|||
out[#out + 1] = "[[" .. sitelink .. "|" .. label .. "]]" |
|||
]] |
|||
else |
|||
function formatStatement( context, options, statement ) |
|||
out[#out + 1] = "[[:d:Q" .. v.mainsnak.datavalue.value["numeric-id"] .. "|" .. label .. "]]<abbr title='" .. i18n["errors"]["local-article-not-found"] .. "'>[*]</abbr>" |
|||
if ( not statement ) then |
|||
end |
|||
error( 'statement is not specified or nil' ); |
|||
end |
|||
return table.concat(out, ", ") |
|||
else |
|||
-- just return best values |
|||
return entity:formatPropertyValues(propertyID).value |
|||
end |
|||
else |
|||
return "" |
|||
end |
|||
else |
|||
return input_parm |
|||
end |
end |
||
if not statement.type or statement.type ~= 'statement' then |
|||
throwError( 'unknown-claim-type' ) |
|||
end |
|||
local functionToCall = getUserFunction( options, 'claim', context.formatStatementDefault ); |
|||
return functionToCall( context, options, statement ); |
|||
end |
end |
||
function getSourcingCircumstances( statement ) |
|||
-- Same as above, but uses the short name property for label if available. |
|||
if (not statement) then error('statement is not specified') end; |
|||
p.getValueShortName = function(frame) |
|||
local propertyID = mw.text.trim(frame.args[1] or "") |
|||
local input_parm = mw.text.trim(frame.args[2] or "") |
|||
if input_parm == "FETCH_WIKIDATA" then |
|||
local entity = mw.wikibase.getEntityObject() |
|||
local claims |
|||
if entity and entity.claims then |
|||
claims = entity.claims[propertyID] |
|||
end |
|||
if claims then |
|||
-- if wiki-linked value output as link if possible |
|||
if (claims[1] and claims[1].mainsnak.snaktype == "value" and claims[1].mainsnak.datavalue.type == "wikibase-entityid") then |
|||
local out = {} |
|||
for k, v in pairs(claims) do |
|||
local sitelink = mw.wikibase.sitelink("Q" .. v.mainsnak.datavalue.value["numeric-id"]) |
|||
local label |
|||
local claimEntity = mw.wikibase.getEntity("Q" .. v.mainsnak.datavalue.value["numeric-id"]) |
|||
if claimEntity ~= nil then |
|||
if claimEntity.claims.P1813 then |
|||
for k2, v2 in pairs(claimEntity.claims.P1813) do |
|||
if v2.mainsnak.datavalue.value.language == "en" then |
|||
label = v2.mainsnak.datavalue.value.text |
|||
end |
|||
end |
|||
end |
|||
end |
|||
if label == nil or label == "" then label = mw.wikibase.label("Q" .. v.mainsnak.datavalue.value["numeric-id"]) end |
|||
if label == nil then label = "Q" .. v.mainsnak.datavalue.value["numeric-id"] end |
|||
local circumstances = {}; |
|||
if sitelink then |
|||
if ( statement.qualifiers |
|||
out[#out + 1] = "[[" .. sitelink .. "|" .. label .. "]]" |
|||
and statement.qualifiers.P1480 ) then |
|||
else |
|||
for i, qualifier in pairs( statement.qualifiers.P1480 ) do |
|||
out[#out + 1] = "[[:d:Q" .. v.mainsnak.datavalue.value["numeric-id"] .. "|" .. label .. "]]<abbr title='" .. i18n["errors"]["local-article-not-found"] .. "'>[*]</abbr>" |
|||
if ( qualifier |
|||
end |
|||
and qualifier.datavalue |
|||
and qualifier.datavalue.type == 'wikibase-entityid' |
|||
and qualifier.datavalue.value |
|||
and qualifier.datavalue.value["entity-type"] == 'item' ) then |
|||
local circumstance = 'Q' .. qualifier.datavalue.value["numeric-id"]; |
|||
if ( 'Q18086598' == circumstance ) then |
|||
circumstances.approximate = true; |
|||
end |
|||
if ( 'Q18122778' == circumstance ) then |
|||
circumstances.presumably = true; |
|||
end |
end |
||
return table.concat(out, ", ") |
|||
else |
|||
-- just return best vakues |
|||
return entity:formatPropertyValues(propertyID).value |
|||
end |
end |
||
else |
|||
return "" |
|||
end |
end |
||
else |
|||
return input_parm |
|||
end |
end |
||
return circumstances; |
|||
end |
end |
||
--[[ |
|||
-- This is used to get a value, or a comma separated list of them if multiple values exist |
|||
Функция для оформления одного утверждения (statement) |
|||
-- from an arbitrary entry by using its QID. |
|||
-- Use : {{#invoke:Wikidata|getValueFromID|<ID>|<Property>|FETCH_WIKIDATA}} |
|||
-- E.g.: {{#invoke:Wikidata|getValueFromID|Q151973|P26|FETCH_WIKIDATA}} - to fetch value of 'spouse' (P26) from 'Richard Burton' (Q151973) |
|||
-- Please use sparingly - this is an *expensive call*. |
|||
p.getValueFromID = function(frame) |
|||
local itemID = mw.text.trim(frame.args[1] or "") |
|||
local propertyID = mw.text.trim(frame.args[2] or "") |
|||
local input_parm = mw.text.trim(frame.args[3] or "") |
|||
if input_parm == "FETCH_WIKIDATA" then |
|||
local entity = mw.wikibase.getEntity(itemID) |
|||
local claims = entity.claims[propertyID] |
|||
if claims then |
|||
-- if wiki-linked value output as link if possible |
|||
if (claims[1] and claims[1].mainsnak.snaktype == "value" and claims[1].mainsnak.datavalue.type == "wikibase-entityid") then |
|||
local out = {} |
|||
for k, v in pairs(claims) do |
|||
local sitelink = mw.wikibase.sitelink("Q" .. v.mainsnak.datavalue.value["numeric-id"]) |
|||
local label = mw.wikibase.label("Q" .. v.mainsnak.datavalue.value["numeric-id"]) |
|||
if label == nil then label = "Q" .. v.mainsnak.datavalue.value["numeric-id"] end |
|||
Принимает: объект-таблицу утверждение, таблицу параметров, |
|||
if sitelink then |
|||
объект-функцию оформления внутренних структур утверждения (snak) и |
|||
out[#out + 1] = "[[" .. sitelink .. "|" .. label .. "]]" |
|||
объект-функцию оформления ссылки на источники (reference) |
|||
else |
|||
Возвращает: строку оформленного текста с заявлением (claim) |
|||
out[#out + 1] = "[[:d:Q" .. v.mainsnak.datavalue.value["numeric-id"] .. "|" .. label .. "]]<abbr title='" .. i18n["errors"]["local-article-not-found"] .. "'>[*]</abbr>" |
|||
]] |
|||
end |
|||
function formatStatementDefault( context, options, statement ) |
|||
end |
|||
if (not context) then error('context is not specified') end; |
|||
return table.concat(out, ", ") |
|||
if (not options) then error('options is not specified') end; |
|||
else |
|||
if (not statement) then error('statement is not specified') end; |
|||
return entity:formatPropertyValues(propertyID).value |
|||
end |
|||
local circumstances = context.getSourcingCircumstances( statement ); |
|||
else |
|||
return "" |
|||
end |
|||
else |
|||
return input_parm |
|||
end |
|||
end |
|||
if ( options.references ) then |
|||
p.getQualifierValue = function(frame) |
|||
return context.formatSnak( options, statement.mainsnak, circumstances ) .. context.formatRefs( options, statement ); |
|||
local propertyID = mw.text.trim(frame.args[1] or "") |
|||
else |
|||
local qualifierID = mw.text.trim(frame.args[2] or "") |
|||
return context.formatSnak( options, statement.mainsnak, circumstances ); |
|||
local input_parm = mw.text.trim(frame.args[3] or "") |
|||
end |
|||
if input_parm == "FETCH_WIKIDATA" then |
|||
local entity = mw.wikibase.getEntityObject() |
|||
if entity.claims[propertyID] ~= nil then |
|||
local out = {} |
|||
for k, v in pairs(entity.claims[propertyID]) do |
|||
for k2, v2 in pairs(v.qualifiers[qualifierID]) do |
|||
if v2.snaktype == 'value' then |
|||
if (mw.wikibase.sitelink("Q" .. v2.datavalue.value["numeric-id"])) then |
|||
out[#out + 1] = "[[" .. mw.wikibase.sitelink("Q" .. v2.datavalue.value["numeric-id"]) .. "]]" |
|||
else |
|||
out[#out + 1] = "[[:d:Q" .. v2.datavalue.value["numeric-id"] .. "|" .. mw.wikibase.label("Q" .. v2.datavalue.value["numeric-id"]) .. "]]<abbr title='" .. i18n["errors"]["local-article-not-found"] .. "'>[*]</abbr>" |
|||
end |
|||
end |
|||
end |
|||
end |
|||
return table.concat(out, ", ") |
|||
else |
|||
return "" |
|||
end |
|||
else |
|||
return input_parm |
|||
end |
|||
end |
end |
||
--[[ |
|||
-- This is used to get a value like 'male' (for property p21) which won't be linked and numbers without the thousand separators |
|||
Функция для оформления части утверждения (snak) |
|||
p.getRawValue = function(frame) |
|||
Подробнее о snak см. d:Викиданные:Глоссарий |
|||
local propertyID = mw.text.trim(frame.args[1] or "") |
|||
local input_parm = mw.text.trim(frame.args[2] or "") |
|||
if input_parm == "FETCH_WIKIDATA" then |
|||
local entity = mw.wikibase.getEntityObject() |
|||
local claims |
|||
if entity and entity.claims then claims = entity.claims[propertyID] end |
|||
if claims then |
|||
local result = entity:formatPropertyValues(propertyID, mw.wikibase.entity.claimRanks).value |
|||
Принимает: таблицу snak объекта (main snak или же snak от квалификатора) и таблицу опций |
|||
-- if number type: remove thousand separators, bounds and units |
|||
Возвращает: строку оформленного викитекста |
|||
if (claims[1] and claims[1].mainsnak.snaktype == "value" and claims[1].mainsnak.datavalue.type == "quantity") then |
|||
]] |
|||
result = mw.ustring.gsub(result, "(%d),(%d)", "%1%2") |
|||
function formatSnak( context, options, snak, circumstances ) |
|||
result = mw.ustring.gsub(result, "(%d)±.*", "%1") |
|||
circumstances = circumstances or {}; |
|||
end |
|||
local hash = ''; |
|||
return result |
|||
local mainSnakClass = ''; |
|||
else |
|||
if ( snak.hash ) then |
|||
return "" |
|||
hash = ' data-wikidata-hash="' .. snak.hash .. '"'; |
|||
end |
|||
else |
else |
||
mainSnakClass = ' wikidata-main-snak'; |
|||
return input_parm |
|||
end |
end |
||
end |
|||
local before = '<span class="wikidata-snak ' .. mainSnakClass .. '"' .. hash .. '>' |
|||
-- This is used to get the unit name for the numeric value returned by getRawValue |
|||
local after = '</span>' |
|||
p.getUnits = function(frame) |
|||
local propertyID = mw.text.trim(frame.args[1] or "") |
|||
local input_parm = mw.text.trim(frame.args[2] or "") |
|||
if input_parm == "FETCH_WIKIDATA" then |
|||
local entity = mw.wikibase.getEntityObject() |
|||
local claims |
|||
if entity and entity.claims then claims = entity.claims[propertyID] end |
|||
if claims then |
|||
local result = entity:formatPropertyValues(propertyID, mw.wikibase.entity.claimRanks).value |
|||
if (claims[1] and claims[1].mainsnak.snaktype == "value" and claims[1].mainsnak.datavalue.type == "quantity") then |
|||
result = mw.ustring.sub(result, mw.ustring.find(result, " ")+1, -1) |
|||
end |
|||
return result |
|||
else |
|||
return "" |
|||
end |
|||
else |
|||
return input_parm |
|||
end |
|||
end |
|||
if snak.snaktype == 'somevalue' then |
|||
-- This is used to get the unit's QID to use with the numeric value returned by getRawValue |
|||
return before .. options.i18n['somevalue'] .. after; |
|||
p.getUnitID = function(frame) |
|||
elseif snak.snaktype == 'novalue' then |
|||
local propertyID = mw.text.trim(frame.args[1] or "") |
|||
return before .. options.i18n['novalue'] .. after; |
|||
local input_parm = mw.text.trim(frame.args[2] or "") |
|||
elseif snak.snaktype == 'value' then |
|||
if input_parm == "FETCH_WIKIDATA" then |
|||
if ( circumstances.presumably ) then |
|||
local entity = mw.wikibase.getEntityObject() |
|||
before = before .. options.i18n.presumably; |
|||
local claims |
|||
if entity and entity.claims then claims = entity.claims[propertyID] end |
|||
if claims then |
|||
local result |
|||
if (claims[1] and claims[1].mainsnak.snaktype == "value" and claims[1].mainsnak.datavalue.type == "quantity") then |
|||
-- get the url for the unit entry on Wikidata: |
|||
result = claims[1].mainsnak.datavalue.value.unit |
|||
-- and just reurn the last bit from "Q" to the end (which is the QID): |
|||
result = mw.ustring.sub(result, mw.ustring.find(result, "Q"), -1) |
|||
end |
|||
return result |
|||
else |
|||
return "" |
|||
end |
end |
||
if ( circumstances.approximate ) then |
|||
else |
|||
before = before .. options.i18n.approximate; |
|||
return input_parm |
|||
end |
|||
end |
|||
p.getRawQualifierValue = function(frame) |
|||
local propertyID = mw.text.trim(frame.args[1] or "") |
|||
local qualifierID = mw.text.trim(frame.args[2] or "") |
|||
local input_parm = mw.text.trim(frame.args[3] or "") |
|||
if input_parm == "FETCH_WIKIDATA" then |
|||
local entity = mw.wikibase.getEntityObject() |
|||
if entity.claims[propertyID] ~= nil then |
|||
local out = {} |
|||
for k, v in pairs(entity.claims[propertyID]) do |
|||
for k2, v2 in pairs(v.qualifiers[qualifierID]) do |
|||
if v2.snaktype == 'value' then |
|||
if v2.datavalue.value["numeric-id"] then |
|||
out[#out + 1] = mw.wikibase.label("Q" .. v2.datavalue.value["numeric-id"]) |
|||
else |
|||
out[#out + 1] = v2.datavalue.value |
|||
end |
|||
end |
|||
end |
|||
end |
|||
local ret = table.concat(out, ", ") |
|||
return string.upper(string.sub(ret, 1, 1)) .. string.sub(ret, 2) |
|||
else |
|||
return "" |
|||
end |
end |
||
else |
|||
return input_parm |
|||
end |
|||
end |
|||
return before .. formatDatavalue( context, options, snak.datavalue ) .. after; |
|||
-- This is used to get a date value for date_of_birth (P569), etc. which won't be linked |
|||
else |
|||
-- Dates and times are stored in ISO 8601 format (sort of). |
|||
throwError( 'unknown-snak-type' ); |
|||
-- At present the local formatDate(date, precision, timezone) function doesn't handle timezone |
|||
end |
|||
-- So I'll just supply "Z" in the call to formatDate below: |
|||
p.getDateValue = function(frame) |
|||
local propertyID = mw.text.trim(frame.args[1] or "") |
|||
local input_parm = mw.text.trim(frame.args[2] or "") |
|||
local date_format = mw.text.trim(frame.args[3] or i18n["datetime"]["default-format"]) |
|||
local date_addon = mw.text.trim(frame.args[4] or i18n["datetime"]["default-addon"]) |
|||
if input_parm == "FETCH_WIKIDATA" then |
|||
local entity = mw.wikibase.getEntityObject() |
|||
if entity.claims[propertyID] ~= nil then |
|||
local out = {} |
|||
for k, v in pairs(entity.claims[propertyID]) do |
|||
if v.mainsnak.datavalue.type == 'time' then |
|||
local timestamp = v.mainsnak.datavalue.value.time |
|||
local dateprecision = v.mainsnak.datavalue.value.precision |
|||
out[#out + 1] = parseDateFull(timestamp, dateprecision, date_format, date_addon) |
|||
end |
|||
end |
|||
return table.concat(out, ", ") |
|||
else |
|||
return "" |
|||
end |
|||
else |
|||
return input_parm |
|||
end |
|||
end |
end |
||
--[[ |
|||
p.getQualifierDateValue = function(frame) |
|||
Функция для оформления объектов-значений с географическими координатами |
|||
local propertyID = mw.text.trim(frame.args[1] or "") |
|||
local qualifierID = mw.text.trim(frame.args[2] or "") |
|||
local input_parm = mw.text.trim(frame.args[3] or "") |
|||
local date_format = mw.text.trim(frame.args[4] or i18n["datetime"]["default-format"]) |
|||
local date_addon = mw.text.trim(frame.args[5] or i18n["datetime"]["default-addon"]) |
|||
if input_parm == "FETCH_WIKIDATA" then |
|||
local entity = mw.wikibase.getEntityObject() |
|||
if entity.claims[propertyID] ~= nil then |
|||
local out = {} |
|||
for k, v in pairs(entity.claims[propertyID]) do |
|||
for k2, v2 in pairs(v.qualifiers[qualifierID]) do |
|||
if v2.snaktype == 'value' then |
|||
local timestamp = v2.datavalue.value.time |
|||
out[#out + 1] = parseDateValue(timestamp, date_format, date_addon) |
|||
end |
|||
end |
|||
end |
|||
return table.concat(out, ", ") |
|||
else |
|||
return "" |
|||
end |
|||
else |
|||
return input_parm |
|||
end |
|||
end |
|||
Принимает: объект-значение и таблицу параметров, |
|||
-- This is used to fetch all of the images with a particular property, e.g. image (P18), Gene Atlas Image (P692), etc. |
|||
Возвращает: строку оформленного текста |
|||
-- Parameters are | propertyID | value / FETCH_WIKIDATA / nil | separator (default=space) | size (default=frameless) |
|||
]] |
|||
-- It will return a standard wiki-markup [[File:Filename | size]] for each image with a selectable size and separator (which may be html) |
|||
function formatGlobeCoordinate( value, options ) |
|||
-- e.g. {{#invoke:Wikidata|getImages|P18|FETCH_WIKIDATA}} |
|||
-- проверка на требование в параметрах вызова на возврат сырого значения |
|||
-- e.g. {{#invoke:Wikidata|getImages|P18|FETCH_WIKIDATA|<br>|250px}} |
|||
if options['subvalue'] == 'latitude' then -- широты |
|||
-- If a property is chosen that is not of type "commonsMedia", it will return empty text. |
|||
return value['latitude'] |
|||
p.getImages = function(frame) |
|||
elseif options['subvalue'] == 'longitude' then -- долготы |
|||
local propertyID = mw.text.trim(frame.args[1] or "") |
|||
return value['longitude'] |
|||
local input_parm = mw.text.trim(frame.args[2] or "") |
|||
else |
|||
local sep = mw.text.trim(frame.args[3] or " ") |
|||
-- в противном случае формируются параметры для вызова шаблона {{coord}} |
|||
local imgsize = mw.text.trim(frame.args[4] or "frameless") |
|||
-- нужно дописать в документации шаблона, что он отсюда вызывается, и что |
|||
if input_parm == "FETCH_WIKIDATA" then |
|||
-- любое изменние его парамеров должно быть согласовано с кодом тут |
|||
local entity = mw.wikibase.getEntityObject() |
|||
local eps = 0.0000001 -- < 1/360000 |
|||
local claims |
|||
local globe = '' -- TODO |
|||
if entity and entity.claims then |
|||
local lat = {} |
|||
claims = entity.claims[propertyID] |
|||
lat['abs'] = math.abs(value['latitude']) |
|||
end |
|||
lat['ns'] = value['latitude'] >= 0 and 'N' or 'S' |
|||
if claims then |
|||
lat['d'] = math.floor(lat['abs'] + eps) |
|||
if (claims[1] and claims[1].mainsnak.datatype == "commonsMedia") then |
|||
lat['m'] = math.floor((lat['abs'] - lat['d']) * 60 + eps) |
|||
local out = {} |
|||
lat['s'] = math.max(0, ((lat['abs'] - lat['d']) * 60 - lat['m']) * 60) |
|||
for k, v in pairs(claims) do |
|||
local lon = {} |
|||
local filename = v.mainsnak.datavalue.value |
|||
lon['abs'] = math.abs(value['longitude']) |
|||
out[#out + 1] = "[[File:" .. filename .. "|" .. imgsize .. "]]" |
|||
lon['ew'] = value['longitude'] >= 0 and 'E' or 'W' |
|||
end |
|||
lon['d'] = math.floor(lon['abs'] + eps) |
|||
return table.concat(out, sep) |
|||
lon['m'] = math.floor((lon['abs'] - lon['d']) * 60 + eps) |
|||
else |
|||
lon['s'] = math.max(0, ((lon['abs'] - lon['d']) * 60 - lon['m']) * 60) |
|||
return "" |
|||
local coord = '{{coord' |
|||
end |
|||
if (value['precision'] == nil) or (value['precision'] < 1/60) then -- по умолчанию с точностью до секунды |
|||
else |
|||
coord = coord .. '|' .. lat['d'] .. '|' .. lat['m'] .. '|' .. lat['s'] .. '|' .. lat['ns'] |
|||
return "" |
|||
coord = coord .. '|' .. lon['d'] .. '|' .. lon['m'] .. '|' .. lon['s'] .. '|' .. lon['ew'] |
|||
end |
|||
elseif value['precision'] < 1 then |
|||
else |
|||
coord = coord .. '|' .. lat['d'] .. '|' .. lat['m'] .. '|' .. lat['ns'] |
|||
return input_parm |
|||
coord = coord .. '|' .. lon['d'] .. '|' .. lon['m'] .. '|' .. lon['ew'] |
|||
end |
|||
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 |
end |
||
local function getDefaultValueFunction( datavalue ) |
|||
-- This is used to get the TA98 (Terminologia Anatomica first edition 1998) values like 'A01.1.00.005' (property P1323) |
|||
-- вызов обработчиков по умолчанию для известных типов значений |
|||
-- which are then linked to http://www.unifr.ch/ifaa/Public/EntryPage/TA98%20Tree/Entity%20TA98%20EN/01.1.00.005%20Entity%20TA98%20EN.htm |
|||
if datavalue.type == 'wikibase-entityid' then |
|||
-- uses the newer mw.wikibase calls instead of directly using the snaks |
|||
-- идентификатор сущности |
|||
-- formatPropertyValues returns a table with the P1323 values concatenated with ", " so we have to split them out into a table in order to construct the return string |
|||
return function( context, options, value ) return formatEntityId( getEntityIdFromValue( value ), options ) end; |
|||
p.getTAValue = function(frame) |
|||
elseif datavalue.type == 'string' then |
|||
local ent = mw.wikibase.getEntityObject() |
|||
-- строка |
|||
local props = ent:formatPropertyValues('P1323') |
|||
return function( context, options, value ) return value end; |
|||
local out = {} |
|||
elseif datavalue.type == 'monolingualtext' then |
|||
local t = {} |
|||
-- моноязычный текст (строка с указанием языка) |
|||
for k, v in pairs(props) do |
|||
return function( context, options, value ) return '<span class="lang" lang="' .. value.language .. '">' .. value.text .. '</span>' end; |
|||
if k == 'value' then |
|||
elseif datavalue.type == 'globecoordinate' then |
|||
t = mw.text.split( v, ", ") |
|||
-- географические координаты |
|||
for k2, v2 in pairs(t) do |
|||
return function( context, options, value ) return formatGlobeCoordinate( value, options ) end; |
|||
out[#out + 1] = "[http://www.unifr.ch/ifaa/Public/EntryPage/TA98%20Tree/Entity%20TA98%20EN/" .. string.sub(v2, 2) .. "%20Entity%20TA98%20EN.htm " .. v2 .. "]" |
|||
elseif datavalue.type == 'quantity' then |
|||
end |
|||
return function( context, options, value ) |
|||
end |
|||
-- диапазон значений |
|||
end |
|||
local amount = string.gsub(value['amount'], '^%+', '') |
|||
local lang = mw.language.new( 'tt' ) |
|||
if #ret == 0 then |
|||
return lang:formatNum( tonumber( amount ) ) |
|||
ret = "Invalid TA" |
|||
end; |
|||
elseif datavalue.type == 'time' then |
|||
return ret |
|||
return function( context, options, value ) |
|||
local moduleDate = require('Module:Wikidata/date') |
|||
return moduleDate.formatDate( context, options, value ); |
|||
end; |
|||
else |
|||
-- во всех стальных случаях возвращаем ошибку |
|||
throwError( 'unknown-datavalue-type' ) |
|||
end |
|||
end |
end |
||
--[[ |
--[[ |
||
Функция для оформления значений (value) |
|||
This is used to return an image legend from Wikidata |
|||
Подробнее о значениях см. d:Wikidata:Glossary/ru |
|||
image is property P18 |
|||
image legend is property P2096 |
|||
Call as {{#invoke:Wikidata |getImageLegend | <PARAMETER> | lang=<ISO-639code> |id=<QID>}} |
|||
Returns PARAMETER, unless it is equal to "FETCH_WIKIDATA", from Item QID (expensive call) |
|||
If QID is omitted or blank, the current article is used (not an expensive call) |
|||
If lang is omitted, it uses the local wiki language, otherwise it uses the provided ISO-639 language code |
|||
ISO-639: https://docs.oracle.com/cd/E13214_01/wli/docs92/xref/xqisocodes.html#wp1252447 |
|||
Принимает: объект-значение и таблицу параметров, |
|||
Ranks are: 'preferred' > 'normal' |
|||
Возвращает: строку оформленного текста |
|||
This returns the label from the first image with 'preferred' rank |
|||
Or the label from the first image with 'normal' rank if preferred returns nothing |
|||
Ranks: https://www.mediawiki.org/wiki/Extension:Wikibase_Client/Lua |
|||
]] |
]] |
||
function formatDatavalue( context, options, datavalue ) |
|||
if ( not context ) then error( 'context not specified' ); end; |
|||
if ( not options ) then error( 'options not specified' ); end; |
|||
if ( not datavalue ) then error( 'datavalue not specified' ); end; |
|||
if ( not datavalue.value ) then error( 'datavalue.value is missng' ); end; |
|||
-- проверка на указание специализированных обработчиков в параметрах, |
|||
p.getImageLegend = function(frame) |
|||
-- переданных при вызове |
|||
-- look for named parameter id; if it's blank make it nil |
|||
context.formatValueDefault = getDefaultValueFunction( datavalue ); |
|||
local id = frame.args.id |
|||
local functionToCall = getUserFunction( options, 'value', context.formatValueDefault ); |
|||
if id and (#id == 0) then |
|||
return functionToCall( context, options, datavalue.value ); |
|||
id = nil |
|||
end |
|||
-- Небольшой словарь упрощенного отображения (TODO: надо сделать расширенный с учётом даты) |
|||
-- look for named parameter lang |
|||
local simpleReplaces = { |
|||
-- it should contain a two-character ISO-639 language code |
|||
Q30 = '[[Америка Кушма Штатлары|АКШ]]', |
|||
-- if it's blank fetch the language of the local wiki |
|||
Q148 = '[[Кытай Халык Җөмһүрияте|КХҖ]]', |
|||
local lang = frame.args.lang |
|||
Q183 = '[[Алмания]]', |
|||
if (not lang) or (#lang < 2) then |
|||
Q258 = '[[КАҖ]]', |
|||
lang = mw.language.getContentLanguage().code |
|||
Q423 = '[[КХДҖ]]', |
|||
end |
|||
Q2184 = '[[Российская Советская Федеративная Социалистическая Республика|РСФСР]]', |
|||
Q2895 = '[[Белорусская Советская Социалистическая Республика|Белорусская ССР]]', |
|||
Q15180 = '[[Союз Советских Социалистических Республик|СССР]]', |
|||
Q16957 = '[[Германская Демократическая Республика|ГДР]]', |
|||
Q130229 = '[[Грузинская Советская Социалистическая Республика|Грузинская ССР]]', |
|||
Q130280 = '[[Эстонская Советская Социалистическая Республика|Эстонская ССР]]', |
|||
Q131337 = '[[Азербайджанская Советская Социалистическая Республика|Азербайджанская ССР]]', |
|||
Q132856 = '[[Армянская Советская Социалистическая Республика|Армянская ССР]]', |
|||
Q133356 = '[[Украинская Советская Социалистическая Республика|Украинская ССР]]', |
|||
Q168811 = '[[Казахская Советская Социалистическая Республика|Казахская ССР]]', |
|||
Q170895 = '[[Молдавская Советская Социалистическая Республика|Молдавская ССР]]', |
|||
Q173761 = '[[Литовская Советская Социалистическая Республика|Литовская ССР]]', |
|||
Q192180 = '[[Латвийская Советская Социалистическая Республика|Латвийская ССР]]', |
|||
Q199707 = '[[Туркменская Советская Социалистическая Республика|Туркменская ССР]]', |
|||
Q199711 = '[[Таджикская Советская Социалистическая Республика|Таджикская ССР]]', |
|||
Q484578 = '[[Узбекская Советская Социалистическая Республика|Узбекская ССР]]', |
|||
Q809806 = '[[Башкирская Автономная Советская Социалистическая Республика|Башкирская АССР]]', |
|||
Q1157215 = '[[Дагестанская Автономная Советская Социалистическая Республика|Дагестанская АССР]]', |
|||
} |
|||
--[[ |
|||
-- first unnamed parameter is the local parameter, if supplied |
|||
Функция для оформления идентификатора сущности |
|||
local input_parm = mw.text.trim(frame.args[1] or "") |
|||
if input_parm == "FETCH_WIKIDATA" then |
|||
Принимает: строку индентификатора (типа Q42) и таблицу параметров, |
|||
local ent = mw.wikibase.getEntityObject(id) |
|||
Возвращает: строку оформленного текста |
|||
local imgs |
|||
]] |
|||
if ent and ent.claims then |
|||
function formatEntityId( entityId, options ) |
|||
imgs = ent.claims.P18 |
|||
-- получение локализованного названия |
|||
local label = nil; |
|||
if ( options.text and options.text ~= '' ) then |
|||
label = options.text |
|||
else |
|||
if ( simpleReplaces[entityId] ) then |
|||
return simpleReplaces[entityId]; |
|||
end |
end |
||
label = mw.wikibase.label( entityId ); |
|||
local imglbl |
|||
end |
|||
if imgs then |
|||
-- look for an image with 'preferred' rank |
|||
for k1, v1 in pairs(imgs) do |
|||
if v1.rank == "preferred" and v1.qualifiers and v1.qualifiers.P2096 then |
|||
local imglbls = v1.qualifiers.P2096 |
|||
for k2, v2 in pairs(imglbls) do |
|||
if v2.datavalue.value.language == lang then |
|||
imglbl = v2.datavalue.value.text |
|||
break |
|||
end |
|||
end |
|||
end |
|||
end |
|||
-- if we don't find one, look for an image with 'normal' rank |
|||
if (not imglbl) then |
|||
for k1, v1 in pairs(imgs) do |
|||
if v1.rank == "normal" and v1.qualifiers and v1.qualifiers.P2096 then |
|||
local imglbls = v1.qualifiers.P2096 |
|||
for k2, v2 in pairs(imglbls) do |
|||
if v2.datavalue.value.language == lang then |
|||
imglbl = v2.datavalue.value.text |
|||
break |
|||
end |
|||
end |
|||
end |
|||
end |
|||
end |
|||
end |
|||
return imglbl |
|||
else |
|||
return input_parm |
|||
end |
|||
end |
|||
-- получение ссылки по идентификатору |
|||
-- This is used to get the QIDs of all of the values of a property, as a comma separated list if multiple values exist |
|||
local link = mw.wikibase.sitelink( entityId ) |
|||
-- Usage: {{#invoke:Wikidata |getPropertyIDs |<PropertyID> |FETCH_WIKIDATA}} |
|||
if link then |
|||
-- Usage: {{#invoke:Wikidata |getPropertyIDs |<PropertyID> |<InputParameter> |qid=<QID>}} |
|||
if label then |
|||
return '[[' .. link .. '|' .. label .. ']]' |
|||
else |
|||
return '[[' .. link .. ']]' |
|||
end |
|||
end |
|||
if label then |
|||
p.getPropertyIDs = function(frame) |
|||
return label |
|||
local propertyID = mw.text.trim(frame.args[1] or "") |
|||
end |
|||
local input_parm = mw.text.trim(frame.args[2] or "") |
|||
-- сообщение об отсутвии локализованного названия |
|||
-- can take a named parameter |qid which is the Wikidata ID for the article. This will not normally be used. |
|||
-- not good, but better than nothing |
|||
local qid = frame.args.qid |
|||
return '[[d:' .. entityId .. '|' .. entityId .. ']]<span style="border-bottom: 1px dotted; cursor: help; white-space: nowrap" title="Викимәгълүматта бу элементның татарча атамасы юк. Сез аны язып, проектка булыша аласыз.">?</span>' .. categoryLinksToEntitiesWithMissingLabel; |
|||
if qid and (#qid == 0) then qid = nil end |
|||
if input_parm == "FETCH_WIKIDATA" then |
|||
local entity = mw.wikibase.getEntityObject(qid) |
|||
local propclaims |
|||
if entity and entity.claims then |
|||
propclaims = entity.claims[propertyID] |
|||
end |
|||
if propclaims then |
|||
-- if wiki-linked value collect the QID in a table |
|||
if (propclaims[1] and propclaims[1].mainsnak.snaktype == "value" and propclaims[1].mainsnak.datavalue.type == "wikibase-entityid") then |
|||
local out = {} |
|||
for k, v in pairs(propclaims) do |
|||
out[#out + 1] = "Q" .. v.mainsnak.datavalue.value["numeric-id"] |
|||
end |
|||
return table.concat(out, ", ") |
|||
else |
|||
-- not a wikibase-entityid, so return empty |
|||
return "" |
|||
end |
|||
else |
|||
-- no claim, so return empty |
|||
return "" |
|||
end |
|||
else |
|||
return input_parm |
|||
end |
|||
end |
end |
||
--[[ |
|||
-- returns the page id (Q...) of the current page or nothing of the page is not connected to Wikidata |
|||
Функция для оформления утверждений (statement) |
|||
function p.pageId(frame) |
|||
Подробнее о утверждениях см. d:Wikidata:Glossary/ru |
|||
local entity = mw.wikibase.getEntityObject() |
|||
if not entity then return nil else return entity.id end |
|||
Принимает: таблицу параметров |
|||
Возвращает: строку оформленного текста, предназначенного для отображения в статье |
|||
]] |
|||
-- устаревшее имя, не использовать |
|||
function p.formatStatements( frame ) |
|||
return p.formatProperty( frame ); |
|||
end |
end |
||
function p. |
function p.formatProperty( frame ) |
||
local args = frame.args |
|||
local plain = toBoolean( frame.args.plain, false ); |
|||
local id = frame.args["id"] -- "id" must be nil, as access to other Wikidata objects is disabled in Mediawiki configuration |
|||
frame.args.nocat = toBoolean( frame.args.nocat, false ); |
|||
frame.args.references = toBoolean( frame.args.references, true ); |
|||
local parameter = frame.args["parameter"] |
|||
local list = frame.args["list"] |
|||
local references = frame.args["references"] |
|||
local showerrors = frame.args["showerrors"] |
|||
local default = frame.args["default"] |
|||
if default then showerrors = nil end |
|||
-- проверка на отсутствие обязательного параметра property |
|||
-- get wikidata entity |
|||
if not frame.args.property then |
|||
local entity = mw.wikibase.getEntityObject(id) |
|||
throwError( 'property-param-not-provided' ) |
|||
if not entity then |
|||
end |
|||
if showerrors then return printError("entity-not-found") else return default end |
|||
end |
|||
-- fetch the first claim of satisfying the given property |
|||
local claims = findClaims(entity, property) |
|||
if not claims or not claims[1] then |
|||
if showerrors then return printError("property-not-found") else return default end |
|||
end |
|||
-- если значение передано в параметрах вызова то выводим только его |
|||
-- get initial sort indices |
|||
if frame.args.value and frame.args.value ~= '' then |
|||
local sortindices = {} |
|||
if plain or frame.args.nocat or frame:callParserFunction( '#property', frame.args.property )=='' then |
|||
for idx in pairs(claims) do |
|||
-- опция, запрещающая оформление значения, поэтому никак не трогаем |
|||
sortindices[#sortindices + 1] = idx |
|||
return frame.args.value |
|||
end |
|||
else |
|||
-- sort by claim rank |
|||
-- если трогать всё-таки можно, добавляем категорию-маркер |
|||
local comparator = function(a, b) |
|||
return args.value .. categoryLocalValuePresent; |
|||
local rankmap = { deprecated = 2, normal = 1, preferred = 0 } |
|||
end |
|||
local ranka = rankmap[claims[a].rank or "normal"] .. string.format("%08d", a) |
|||
end |
|||
local rankb = rankmap[claims[b].rank or "normal"] .. string.format("%08d", b) |
|||
return ranka < rankb |
|||
end |
|||
table.sort(sortindices, comparator) |
|||
if ( plain ) then -- вызова стандартного обработчика без оформления, если передана опция plain |
|||
local result |
|||
return frame:callParserFunction( '#property', frame.args.property ); |
|||
local error |
|||
end |
|||
if list then |
|||
local value |
|||
-- iterate over all elements and return their value (if existing) |
|||
result = {} |
|||
for idx in pairs(claims) do |
|||
local claim = claims[sortindices[idx]] |
|||
value, error = getValueOfClaim(claim, qualifierId, parameter) |
|||
if not value and showerrors then value = error end |
|||
if value and references then value = value .. getReferences(frame, claim) end |
|||
result[#result + 1] = value |
|||
end |
|||
result = table.concat(result, list) |
|||
else |
|||
-- return first element |
|||
local claim = claims[sortindices[1]] |
|||
result, error = getValueOfClaim(claim, qualifierId, parameter) |
|||
if result and references then result = result .. getReferences(frame, claim) end |
|||
end |
|||
g_frame = frame |
|||
if result then return result else |
|||
-- после проверки всех аргументов -- вызов функции оформления для свойства (набора утверждений) |
|||
if showerrors then return error else return default end |
|||
return formatProperty( frame.args ) |
|||
end |
|||
end |
end |
||
--[[ |
|||
-- look into entity object |
|||
Функция оформления ссылок на источники (reference) |
|||
function p.ViewSomething(frame) |
|||
Подробнее о ссылках на источники см. d:Wikidata:Glossary/ru |
|||
local f = (frame.args[1] or frame.args.id) and frame or frame:getParent() |
|||
local id = f.args.id |
|||
if id and (#id == 0) then |
|||
id = nil |
|||
end |
|||
local data = mw.wikibase.getEntityObject(id) |
|||
if not data then |
|||
return nil |
|||
end |
|||
Экспортируется в качестве зарезервированной точки для вызова из функций-расширения вида claim-module/claim-function через context |
|||
local i = 1 |
|||
Вызов из других модулей напрямую осуществляться не должен (используйте frame:expandTemplate вместе с одним из специлизированных шаблонов вывода значения свойства). |
|||
while true do |
|||
local index = f.args[i] |
|||
if not index then |
|||
if type(data) == "table" then |
|||
return mw.text.jsonEncode(data, mw.text.JSON_PRESERVE_KEYS + mw.text.JSON_PRETTY) |
|||
else |
|||
return tostring(data) |
|||
end |
|||
end |
|||
Принимает: объект-таблицу утверждение |
|||
data = data[index] or data[tonumber(index)] |
|||
Возвращает: строку оформленных ссылок для отображения в статье |
|||
if not data then |
|||
]] |
|||
return |
|||
function formatRefs( context, options, statement ) |
|||
end |
|||
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 missing' ); end; |
|||
if ( not statement ) then error( 'statement not specified' ); end; |
|||
if ( not outputReferences ) then |
|||
i = i + 1 |
|||
return ''; |
|||
end |
end |
||
end |
|||
local result = ''; |
|||
-- getting sitelink of a given wiki |
|||
if ( statement.references ) then |
|||
function p.getSiteLink(frame) |
|||
local f = frame.args[1] |
|||
local entity = mw.wikibase.getEntity() |
|||
if not entity then |
|||
return |
|||
end |
|||
local link = entity:getSitelink( f ) |
|||
if not link then |
|||
return |
|||
end |
|||
return link |
|||
end |
|||
local allReferences = statement.references; |
|||
function p.Dump(frame) |
|||
local hasPreferred = false; |
|||
local f = (frame.args[1] or frame.args.id) and frame or frame:getParent() |
|||
for _, reference in pairs( statement.references ) do |
|||
local data = mw.wikibase.getEntityObject(f.args.id) |
|||
if ( reference.snaks |
|||
if not data then |
|||
and reference.snaks.P248 |
|||
return i18n.warnDump |
|||
and reference.snaks.P248[1] |
|||
end |
|||
and reference.snaks.P248[1].datavalue |
|||
and reference.snaks.P248[1].datavalue.value["numeric-id"] ) then |
|||
local i = 1 |
|||
local entityId = "Q" .. reference.snaks.P248[1].datavalue.value["numeric-id"]; |
|||
while true do |
|||
if ( preferredSources[entityId] ) then |
|||
local index = f.args[i] |
|||
hasPreferred = true; |
|||
if not index then |
|||
end |
|||
return "<pre>"..mw.dumpObject(data).."</pre>".. i18n.warnDump |
|||
end |
|||
end |
end |
||
for _, reference in pairs( statement.references ) do |
|||
data = data[index] or data[tonumber(index)] |
|||
local display = true; |
|||
if not data then |
|||
if ( hasPreferred ) then |
|||
return i18n.warnDump |
|||
if ( reference.snaks |
|||
and reference.snaks.P248 |
|||
and reference.snaks.P248[1] |
|||
and reference.snaks.P248[1].datavalue |
|||
and reference.snaks.P248[1].datavalue.value["numeric-id"] ) then |
|||
local entityId = "Q" .. reference.snaks.P248[1].datavalue.value["numeric-id"]; |
|||
if ( deprecatedSources[entityId] ) then |
|||
display = false; |
|||
end |
|||
end |
|||
end |
|||
if ( display ) then |
|||
result = result .. moduleSources.renderReference( g_frame, options.entity, reference ); |
|||
end |
|||
end |
end |
||
i = i + 1 |
|||
end |
end |
||
return result |
|||
end |
end |
||
22 ноя 2016, 11:42 юрамасы
Игътибар! Бу иң еш кулланылган модульләрнең берсе. Аның һәр үзгәртелүе «Викимедиа Фондының» серверларына эш өсти. Зинһар, нәрсә эшләгәнегезне аңлагыз һәм махсус өйрәнү урыннарында татып карагыз.
|
{{Wikidata}} эчендә кулланыла (параметрлар тасвирламасын шунда ук карагыз). Модуль:Wikidata/config ярдәмендә көйләнелә
Башка телле бүлектә тулырак мәкалә бар: Модуль:Wikidata/doc (рус.) Сез тәрҗемә ярдәме белән бу мәкаләне язып бетереп проектка ярдәм итә аласыз.
|
Бу — мәкалә төпчеге. Сез мәкаләне үзгәртеп һәм мәгълүмат өстәп, Википедия проектына ярдәм итә аласыз. Мөмкинлек булса, бу искәрмәне төгәлрәккә алыштырырга кирәк.
|
local i18n = {
["errors"] = {
["property-param-not-provided"] = "Не дан параметр свойства",
["entity-not-found"] = "Сущность не найдена.",
["unknown-claim-type"] = "Неизвестный тип заявления.",
["unknown-snak-type"] = "Неизвестный тип снэка.",
["unknown-datavalue-type"] = "Неизвестный тип значения данных.",
["unknown-entity-type"] = "Неизвестный тип сущности.",
["unknown-property-module"] = "Вы должны установить и property-module, и property-function.",
["unknown-claim-module"] = "Вы должны установить и claim-module, и claim-function.",
["unknown-value-module"] = "Вы должны установить и value-module, и value-function.",
["property-module-not-found"] = "Модуль для отображения свойства не найден",
["property-function-not-found"] = "Функция для отображения свойства не найдена",
["claim-module-not-found"] = "Модуль для отображения утверждения не найден.",
["claim-function-not-found"] = "Функция для отображения утверждения не найдена.",
["value-module-not-found"] = "Модуль для отображения значения не найден.",
["value-function-not-found"] = "Функция для отображения значения не найдена."
},
["somevalue"] = "''неизвестно''",
["novalue"] = "",
["approximate"] = '<span style="border-bottom: 1px dotted; cursor: help;" title="якынча">як. </span>',
["presumably"] = '<span style="border-bottom: 1px dotted; cursor: help;" title="предположительно">предп. </span>',
}
-- settings, may differ from project to project
local categoryLinksToEntitiesWithMissingLabel = '[[Төркем:Википедия:Статьи со ссылками на элементы Викиданных без русской подписи]]';
local categoryLocalValuePresent = '[[Төркем:Википедия:Статьи с переопределением значения из Викиданных]]';
local outputReferences = true;
-- sources that shall be omitted if any preffered sources exists
local deprecatedSources = {
Q36578 = true, -- Gemeinsame Normdatei
Q63056 = true, -- Find a Grave
Q15222191 = true, -- BNF
};
local preferredSources = {
Q5375741 = true, -- Encyclopædia Britannica Online
Q17378135 = true, -- Great Soviet Encyclopedia (1969—1978)
};
-- Ссылки на используемые модули, которые потребуются в 99% случаев загрузки страниц (чтобы иметь на виду при переименовании)
local moduleSources = require('Module:Sources')
local p = {}
local formatDatavalue, formatEntityId, formatRefs, formatSnak, formatStatement, formatStatementDefault, formatProperty, getSourcingCircumstances, loadCacheSafe, throwError, toBoolean;
local function copyTo( obj, target )
for k, v in pairs( obj ) do
target[k] = v
end
return target;
end
local function loadCacheSafe( entityId )
local status, result = pcall( function() return mw.loadData( 'Module:WikidataCache/' .. entityId ) end );
if ( status == true ) then
return result;
end
return nil;
end
local function parseISO8601(str)
if 'table' == type(str) then
if str.args and str.args[1] then
str = '' .. str.args[1]
else
return 'unknown argument type: ' .. type( str ) .. ': ' .. table.tostring( str )
end
end
local Y, M, D = (function(str)
local pattern = "(%-?%d+)%-(%d+)%-(%d+)T"
local Y, M, D = mw.ustring.match( str, pattern )
return tonumber(Y), tonumber(M), tonumber(D)
end) (str);
local h, m, s = (function(str)
local pattern = "T(%d+):(%d+):(%d+)%Z";
local H, M, S = mw.ustring.match( str, pattern);
return tonumber(H), tonumber(M), tonumber(S);
end) (str);
local oh,om = ( function(str)
if str:sub(-1)=="Z" then return 0,0 end; -- ends with Z, Zulu time
-- matches ±hh:mm, ±hhmm or ±hh; else returns nils
local pattern = "([-+])(%d%d):?(%d?%d?)$";
local sign, oh, om = mw.ustring.match( str, pattern);
sign, oh, om = sign or "+", oh or "00", om or "00";
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
--[[
Преобразует строку в булевое значение
Принимает: строковое значение (может отсутствовать)
Возвращает: булевое значение true или false, если получается распознать значение, или defaultValue во всех остальных случаях
]]
local 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
--[[
Функция для получения сущности (еntity) для текущей страницы
Подробнее о сущностях см. d:Wikidata:Glossary/ru
Принимает: строковый индентификатор (типа P18, Q42)
Возвращает: объект таблицу, элементы которой индексируются с нуля
]]
local function getEntityFromId( id )
if id then
local cached = loadCacheSafe( id );
if ( cached ) then
return cached;
end
return mw.wikibase.getEntityObject( id )
end
local entity = mw.wikibase.getEntityObject();
if ( entity ) then
local cached = loadCacheSafe( entity.id );
if ( cached ) then
return cached;
end
end
return entity;
end
--[[
Внутрення функция для формирования сообщения об ошибке
Принимает: ключ элемента в таблице i18n (например entity-not-found)
Возвращает: строку сообщения
]]
local function throwError( key )
error( i18n.errors[key] );
end
--[[
Функция для получения идентификатора сущностей
Принимает: объект таблицу сущности
Возвращает: строковый индентификатор (типа P18, Q42)
]]
local function getEntityIdFromValue( value )
local prefix = ''
if value['entity-type'] == 'item' then
prefix = 'Q'
elseif value['entity-type'] == 'property' then
prefix = 'P'
else
throwError( 'unknown-entity-type' )
end
return prefix .. value['numeric-id']
end
-- проверка на наличие специилизированной функции в опциях
local function getUserFunction( options, prefix, defaultFunction )
-- проверка на указание специализированных обработчиков в параметрах,
-- переданных при вызове
if options[ prefix .. '-module' ] or options[ prefix .. '-function' ] then
-- проверка на пустые строки в параметрах или их отсутствие
if not options[ prefix .. '-module' ] or not options[ prefix .. '-function' ] then
throwError( 'unknown-' .. prefix .. '-module' );
end
-- динамическая загруза модуля с обработчиком указанным в параметре
local formatter = require ('Module:' .. options[ prefix .. '-module' ]);
if formatter == nil then
throwError( prefix .. '-module-not-found' )
end
local fun = formatter[ options[ prefix .. '-function' ] ]
if fun == nil then
throwError( prefix .. '-function-not-found' )
end
return fun;
end
return defaultFunction;
end
-- Выбирает свойства по property id, дополнительно фильтруя их по рангу
local function selectClaims( context, options, propertyId )
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 propertyId ) then error( 'propertyId not specified'); end;
local allPropertyClaims = options.entity.claims[ string.upper( propertyId ) ];
if ( not allPropertyClaims ) then
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 ( #result == 0 ) then
return nil;
end
return result;
end
--[[
Функция для оформления утверждений (statement)
Подробнее о утверждениях см. d:Wikidata:Glossary/ru
Принимает: таблицу параметров
Возвращает: строку оформленного текста, предназначенного для отображения в статье
]]
local function formatProperty( options )
-- Получение сущности по идентификатору
local entity = getEntityFromId( options.entityId )
if not entity then
return -- throwError( 'entity-not-found' )
end
-- проверка на присутсвие у сущности заявлений (claim)
-- подробнее о заявлениях см. d:Викиданные:Глоссарий
if (entity.claims == nil) then
return '' --TODO error?
end
-- improve options
options.frame = g_frame;
options.entity = entity;
options.extends = function( self, newOptions )
return copyTo( newOptions, copyTo( self, {} ) )
end
if ( options.i18n ) then
options.i18n = copyTo( options.i18n, copyTo( i18n, {} ) );
else
options.i18n = i18n;
end
-- create context
local context = { formatSnak = formatSnak, formatPropertyDefault = formatPropertyDefault, formatStatementDefault = formatStatementDefault }
context.formatProperty = function( options )
local func = getUserFunction( options, 'property', context.formatPropertyDefault );
return func( context, options )
end;
context.formatStatement = function( options, statement ) return formatStatement( context, options, statement ) end;
context.formatSnak = function( options, snak, circumstances ) return formatSnak( context, options, snak, circumstances ) end;
context.formatRefs = function( options, statement ) return formatRefs( context, options, statement ) end;
context.parseTimeFromSnak = function( snak )
if ( snak and snak.datavalue and snak.datavalue.value and snak.datavalue.value.time ) then
local timeISO6801 = tostring( snak.datavalue.value.time )
return parseISO8601( timeISO6801 );
end
return nil;
end
context.getSourcingCircumstances = function( statement ) return getSourcingCircumstances( statement ) end;
context.selectClaims = function( options, propertyId ) return selectClaims( context, options, propertyId ) end;
return context.formatProperty( options );
end
function formatPropertyDefault( context, options )
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 missing' ); end;
local claims = context.selectClaims( options, options.property );
if (claims == nil) then
return '' --TODO error?
end
-- Обход всех заявлений утверждения и с накоплением оформленых предпочтительных
-- заявлений в таблице
local formattedClaims = {}
for i, claim in ipairs(claims) do
local formattedStatement = context.formatStatement( options, claim )
-- здесь может вернуться либо оформленный текст заявления
-- либо строка ошибки nil похоже никогда не возвращается
if (formattedStatement) then
formattedStatement = '<span class="wikidata-claim" data-wikidata-property-id="' .. string.upper( options.property ) .. '" data-wikidata-claim-id="' .. claim.id .. '">' .. formattedStatement .. '</span>'
table.insert( formattedClaims, formattedStatement )
end
end
-- создание текстовой строки со списком оформленых заявлений из таблицы
return mw.text.listToText( formattedClaims, options.separator, options.conjunction )
end
--[[
Функция для оформления одного утверждения (statement)
Принимает: объект-таблицу утверждение и таблицу параметров
Возвращает: строку оформленного текста с заявлением (claim)
]]
function formatStatement( context, options, statement )
if ( not statement ) then
error( 'statement is not specified or nil' );
end
if not statement.type or statement.type ~= 'statement' then
throwError( 'unknown-claim-type' )
end
local functionToCall = getUserFunction( options, 'claim', context.formatStatementDefault );
return functionToCall( context, options, statement );
end
function getSourcingCircumstances( statement )
if (not statement) then error('statement is not specified') end;
local circumstances = {};
if ( statement.qualifiers
and statement.qualifiers.P1480 ) then
for i, qualifier in pairs( statement.qualifiers.P1480 ) do
if ( qualifier
and qualifier.datavalue
and qualifier.datavalue.type == 'wikibase-entityid'
and qualifier.datavalue.value
and qualifier.datavalue.value["entity-type"] == 'item' ) then
local circumstance = 'Q' .. qualifier.datavalue.value["numeric-id"];
if ( 'Q18086598' == circumstance ) then
circumstances.approximate = true;
end
if ( 'Q18122778' == circumstance ) then
circumstances.presumably = true;
end
end
end
end
return circumstances;
end
--[[
Функция для оформления одного утверждения (statement)
Принимает: объект-таблицу утверждение, таблицу параметров,
объект-функцию оформления внутренних структур утверждения (snak) и
объект-функцию оформления ссылки на источники (reference)
Возвращает: строку оформленного текста с заявлением (claim)
]]
function formatStatementDefault( context, options, statement )
if (not context) then error('context is not specified') end;
if (not options) then error('options is not specified') end;
if (not statement) then error('statement is not specified') end;
local circumstances = context.getSourcingCircumstances( statement );
if ( options.references ) then
return context.formatSnak( options, statement.mainsnak, circumstances ) .. context.formatRefs( options, statement );
else
return context.formatSnak( options, statement.mainsnak, circumstances );
end
end
--[[
Функция для оформления части утверждения (snak)
Подробнее о snak см. d:Викиданные:Глоссарий
Принимает: таблицу snak объекта (main snak или же snak от квалификатора) и таблицу опций
Возвращает: строку оформленного викитекста
]]
function formatSnak( context, options, snak, circumstances )
circumstances = circumstances or {};
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 snak.snaktype == 'somevalue' then
return before .. options.i18n['somevalue'] .. after;
elseif snak.snaktype == 'novalue' then
return before .. options.i18n['novalue'] .. after;
elseif snak.snaktype == 'value' then
if ( circumstances.presumably ) then
before = before .. options.i18n.presumably;
end
if ( circumstances.approximate ) then
before = before .. options.i18n.approximate;
end
return before .. formatDatavalue( context, options, snak.datavalue ) .. after;
else
throwError( 'unknown-snak-type' );
end
end
--[[
Функция для оформления объектов-значений с географическими координатами
Принимает: объект-значение и таблицу параметров,
Возвращает: строку оформленного текста
]]
function formatGlobeCoordinate( value, options )
-- проверка на требование в параметрах вызова на возврат сырого значения
if options['subvalue'] == 'latitude' then -- широты
return value['latitude']
elseif options['subvalue'] == 'longitude' then -- долготы
return value['longitude']
else
-- в противном случае формируются параметры для вызова шаблона {{coord}}
-- нужно дописать в документации шаблона, что он отсюда вызывается, и что
-- любое изменние его парамеров должно быть согласовано с кодом тут
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
local function getDefaultValueFunction( datavalue )
-- вызов обработчиков по умолчанию для известных типов значений
if datavalue.type == 'wikibase-entityid' then
-- идентификатор сущности
return function( context, options, value ) return formatEntityId( getEntityIdFromValue( value ), options ) end;
elseif datavalue.type == 'string' then
-- строка
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;
elseif datavalue.type == 'globecoordinate' then
-- географические координаты
return function( context, options, value ) return formatGlobeCoordinate( value, options ) end;
elseif datavalue.type == 'quantity' then
return function( context, options, value )
-- диапазон значений
local amount = string.gsub(value['amount'], '^%+', '')
local lang = mw.language.new( 'tt' )
return lang:formatNum( tonumber( amount ) )
end;
elseif datavalue.type == 'time' then
return function( context, options, value )
local moduleDate = require('Module:Wikidata/date')
return moduleDate.formatDate( context, options, value );
end;
else
-- во всех стальных случаях возвращаем ошибку
throwError( 'unknown-datavalue-type' )
end
end
--[[
Функция для оформления значений (value)
Подробнее о значениях см. d:Wikidata:Glossary/ru
Принимает: объект-значение и таблицу параметров,
Возвращает: строку оформленного текста
]]
function formatDatavalue( context, options, datavalue )
if ( not context ) then error( 'context not specified' ); end;
if ( not options ) then error( 'options not specified' ); end;
if ( not datavalue ) then error( 'datavalue not specified' ); end;
if ( not datavalue.value ) then error( 'datavalue.value is missng' ); end;
-- проверка на указание специализированных обработчиков в параметрах,
-- переданных при вызове
context.formatValueDefault = getDefaultValueFunction( datavalue );
local functionToCall = getUserFunction( options, 'value', context.formatValueDefault );
return functionToCall( context, options, datavalue.value );
end
-- Небольшой словарь упрощенного отображения (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 = '[[Дагестанская Автономная Советская Социалистическая Республика|Дагестанская АССР]]',
}
--[[
Функция для оформления идентификатора сущности
Принимает: строку индентификатора (типа Q42) и таблицу параметров,
Возвращает: строку оформленного текста
]]
function formatEntityId( entityId, options )
-- получение локализованного названия
local label = nil;
if ( options.text and options.text ~= '' ) then
label = options.text
else
if ( simpleReplaces[entityId] ) then
return simpleReplaces[entityId];
end
label = mw.wikibase.label( entityId );
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>' .. categoryLinksToEntitiesWithMissingLabel;
end
--[[
Функция для оформления утверждений (statement)
Подробнее о утверждениях см. d:Wikidata:Glossary/ru
Принимает: таблицу параметров
Возвращает: строку оформленного текста, предназначенного для отображения в статье
]]
-- устаревшее имя, не использовать
function p.formatStatements( frame )
return p.formatProperty( frame );
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 );
-- проверка на отсутствие обязательного параметра property
if not frame.args.property then
throwError( 'property-param-not-provided' )
end
-- если значение передано в параметрах вызова то выводим только его
if frame.args.value and frame.args.value ~= '' then
if plain or frame.args.nocat or frame:callParserFunction( '#property', frame.args.property )=='' then
-- опция, запрещающая оформление значения, поэтому никак не трогаем
return frame.args.value
else
-- если трогать всё-таки можно, добавляем категорию-маркер
return args.value .. categoryLocalValuePresent;
end
end
if ( plain ) then -- вызова стандартного обработчика без оформления, если передана опция plain
return frame:callParserFunction( '#property', frame.args.property );
end
g_frame = frame
-- после проверки всех аргументов -- вызов функции оформления для свойства (набора утверждений)
return formatProperty( frame.args )
end
--[[
Функция оформления ссылок на источники (reference)
Подробнее о ссылках на источники см. d:Wikidata:Glossary/ru
Экспортируется в качестве зарезервированной точки для вызова из функций-расширения вида claim-module/claim-function через context
Вызов из других модулей напрямую осуществляться не должен (используйте frame:expandTemplate вместе с одним из специлизированных шаблонов вывода значения свойства).
Принимает: объект-таблицу утверждение
Возвращает: строку оформленных ссылок для отображения в статье
]]
function formatRefs( context, options, statement )
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 missing' ); end;
if ( not statement ) then error( 'statement not specified' ); end;
if ( not outputReferences ) then
return '';
end
local result = '';
if ( statement.references ) then
local allReferences = statement.references;
local hasPreferred = false;
for _, reference in pairs( statement.references ) do
if ( reference.snaks
and reference.snaks.P248
and reference.snaks.P248[1]
and reference.snaks.P248[1].datavalue
and reference.snaks.P248[1].datavalue.value["numeric-id"] ) then
local entityId = "Q" .. reference.snaks.P248[1].datavalue.value["numeric-id"];
if ( preferredSources[entityId] ) then
hasPreferred = true;
end
end
end
for _, reference in pairs( statement.references ) do
local display = true;
if ( hasPreferred ) then
if ( reference.snaks
and reference.snaks.P248
and reference.snaks.P248[1]
and reference.snaks.P248[1].datavalue
and reference.snaks.P248[1].datavalue.value["numeric-id"] ) then
local entityId = "Q" .. reference.snaks.P248[1].datavalue.value["numeric-id"];
if ( deprecatedSources[entityId] ) then
display = false;
end
end
end
if ( display ) then
result = result .. moduleSources.renderReference( g_frame, options.entity, reference );
end
end
end
return result
end
return p