local moduleDate = require('Module:Wikidata/date')
local moduleWikidata = require('Module:Wikidata')
local p = {}
local refs = {}
local refcount = 0
local function renderStatement(frame, args)
return moduleWikidata.formatProperty(frame:newChild{args = args})
end
-- "cite web"-based reference formatter
local function renderReference(frame, entity, reference)
local url = nil
local title = nil
local lang = nil
local date = nil
local publisher = nil
local archiveurl = nil
local archivedate = nil
local accessdate = nil
if reference.snaks.P854 ~= nil then
url = reference.snaks.P854[1].datavalue.value
end
if reference.snaks.P1476 ~= nil then
title = reference.snaks.P1476[1].datavalue.value.text
lang = reference.snaks.P1476[1].datavalue.value.language
end
if reference.snaks.P1065 ~= nil then
archiveurl = reference.snaks.P1065[1].datavalue.value
end
if reference.snaks.P2960 ~= nil then
archivedate = reference.snaks.P2960[1].datavalue.value.time
end
if url == nil and archiveurl ~= nil then
url = archiveurl
archiveurl = nil
archivedate = nil
end
if archiveurl ~= nil and archivedate == nil then
archivedate = ' '
end
if title == nil and url ~= nil then
title = url
end
local ref = ''
if url == nil then
ref = 'Unsupported reference (no URL provided)'
else
if reference.snaks.P813 ~= nil then
accessdate = string.sub(reference.snaks.P813[1].datavalue.value.time, 2, 11)
end
if reference.snaks.P577 ~= nil then
date = string.sub(reference.snaks.P577[1].datavalue.value.time, 2, 5)
end
if reference.snaks.P123 ~= nil then
publisher = mw.wikibase.label(reference.snaks.P123[1].datavalue.value.id)
end
ref = '{{cite web'
ref = ref .. '|url=' .. url
ref = ref .. '|title=' .. title
ref = ref .. '|lang=' .. lang
if date ~= nil then ref = ref .. '|date=' .. date end
if publisher ~= nil then ref = ref .. '|publisher=' .. publisher end
if accessdate ~= nil then ref = ref .. '|accessdate=' .. accessdate end
if archiveurl ~= nil then ref = ref .. '|archiveurl=' .. archiveurl .. '|archivedate=' .. archivedate end
ref = ref .. '}}'
end
hash = mw.hash.hashValue('md5', ref)
local refidx = refs[hash]
if refidx ~= nil then
return frame:extensionTag('ref', '', {name ='ref' .. refs[hash]})
else
refcount = refcount + 1
refs[hash] = refcount
return frame:extensionTag('ref', ref, {name ='ref' .. refcount})
end
end
local function formatSchool( name )
name = mw.ustring.gsub(name, "Старш", "старш")
name = mw.ustring.gsub(name, "ая ", "ую ")
name = mw.ustring.gsub(name, "[Шш]кола", "школу")
name = mw.ustring.gsub(name, "[Аа]кадемия", "академию")
return name
end
local function formatName( frame, name )
return frame:preprocess("{{safesubst:#ifexpr: {{safesubst:str find|{{safesubst:До символа|" .. name .. "|(}}|,}} = -1 " ..
"|{{safesubst:#invoke:string2|bs|" .. name .. "|(|1}}" ..
"|{{safesubst:#invoke:string2|as|{{safesubst:#invoke:string2|bs|" .. name .. "|(|1}}|,}} {{safesubst:#if:1|{{safesubst:#invoke:string2|bs|{{safesubst:#invoke:string2|bs|" .. name .. "|(|1}}|,|1}}}}" ..
"}}")
end
local function formatCitizenship( claims, is_female )
if claims == nil then return end
local qid = claims[1].mainsnak.datavalue.value.id
local tbl = {
Q17='японск',
Q30='американск',
Q159='российск',
Q183='немецк',
Q7318='немецк',
Q41304='немецк',
Q43287='немецк',
}
local word = tbl[qid]
if word == nil then return end
word = word .. (is_female and 'ая' or 'ий')
return '[[' .. mw.wikibase.sitelink( qid ) .. '|' .. word .. ']]'
end
-- plain replacement routine
local function replace(text, from, to)
local pattern = from:gsub('[%^%$%(%)%%%.%[%]%*%+%-%?]','%%%1')
local replacement = to:gsub('[%^%$%(%)%%%.%[%]%*%+%-%?]','%%%1')
return text:gsub(pattern, replacement)
end
local function cleanup( text )
-- simplify names for reused refs, remove names for single-used refs
refs = {}
for s in text:gsub('<ref name=".-"','\0%0\0'):gsub('%z%z','\0 \0'):gmatch'%z<ref name="(.-)"%z' do
refs[s] = (refs[s] or 0) + 1
end
refindex = 1
for ref, count in pairs(refs) do
if count == 1 then
text = replace(text, ' name="' .. ref .. '"', '')
else
text = replace(text, ref, 'ref' .. refindex)
refindex = refindex + 1
end
end
-- move categories to bottom (for subst)
cats = {}
for s in text:gsub('%[%[Category:[^]]+%]%]','\0%0\0'):gsub('%z%z','\0 \0'):gmatch'%z%[%[Category:(.-)%]%]%z' do
cats[s] = true
end
for s in text:gsub('%[%[Категория:[^]]+%]%]','\0%0\0'):gsub('%z%z','\0 \0'):gmatch'%z%[%[Категория:(.-)%]%]%z' do
cats[s] = true
end
cats['Википедия:Статьи с источниками из Викиданных'] = nil -- we don't need this category in substitution
text = text:gsub('%[%[Category:[^]]+%]%]',''):gsub('%[%[Категория:[^]]+%]%]','') .. '\n\n'
for cat, _ in pairs(cats) do
text = text .. '[[Категория:' .. cat .. ']]\n'
end
text = text:gsub('<img style="display:none">\(.?<img class=".-</img>.?\)</img>', '')
text = text:gsub('<img.->', '')
text = text:gsub('</img>', '')
text = text:gsub('(%d)]] год', '%1 год]]')
text = text:gsub('\n\n\n+', '\n\n')
text = text:gsub('<div style="display:none"></div>', '')
-- text = text:gsub('<', '<')
return text
end
local function formatPreferredAwards( frame, entity )
local r = ''
local awards = entity.claims.P166
local lst = {}
for k, v in pairs( awards ) do
if v.rank == 'preferred' then
local o = {}
local qid = v.mainsnak.datavalue.value.id
local sitelink = mw.wikibase.sitelink( qid )
local label = mw.wikibase.label( qid )
label = mw.ustring.gsub(label, "[Пп]ремия", "премии")
label = mw.ustring.gsub(label, "[Нн]аграда", "награды")
label = mw.ustring.gsub(label, "[Оо]рден", "ордена")
label = mw.ustring.gsub(label, "[Мм]едаль", "медали")
if sitelink ~= nil then
o.link = '[[' .. sitelink .. '|' .. label .. ']]'
else
o.link = label
end
o.refs = v.references
table.insert(lst, o)
end
end
local function formatRefs(references)
local out = ''
if references then
for _, reference in pairs(references) do
out = out .. renderReference(frame, entity, reference)
end
end
return out
end
for i = 1, #lst do
r = r .. lst[i].link .. formatRefs(lst[i].refs)
if i < #lst - 1 then
r = r .. ', '
elseif i == #lst - 1 then
r = r .. ' и '
end
end
return r
end
local function hasPreferredAwards( entity )
local awards = entity.claims.P166
for k, v in pairs( awards ) do
if v.rank == 'preferred' then
return true
end
end
return false
end
local function formatExtraSources( entity )
for _, v in pairs( entity.claims.P973 ) do
local r = ''
local url = v.mainsnak.datavalue.value
if url ~= nil then
if v.qualifiers ~= nil and v.qualifiers.P1476 ~= nil then
local title = v.qualifiers.P1476[1].datavalue.value.text
local iso_code = nil
local accessdate = nil
local publisher = nil
if v.qualifiers.P407 ~= nil then
local lang_qid = v.qualifiers.P407[1].datavalue.value.id
local lang_el = mw.wikibase.getEntity(lang_qid)
if lang_el.claims.P218 ~= nil then
iso_code = lang_el.claims.P218[1].mainsnak.datavalue.value
end
end
if v.qualifiers.P813 ~= nil then
accessdate = v.qualifiers.P813[1].datavalue.value.time
end
if v.qualifiers.P123 ~= nil then
publisher = mw.wikibase.label(v.qualifiers.P123[1].datavalue.value.id)
end
r = r .. '* {{cite web|title=' .. title .. '|url=' .. url
if iso_code ~= nil then r = r .. '|lang=' .. iso_code end
if accessdate ~= nil then r = r .. '|accessdate=' .. accessdate end
if publisher ~= nil then r = r .. '|publisher=' .. publisher end
r = r .. '}}\n'
end
end
return r
end
end
local function formatAwards( frame, entity )
local r = '\n\n' .. [[
== Награды и номинации ==
{| class="wikitable" style="font-size:90%"
|-
! scope="col" style="background:#B0C4DE" | Год
! scope="col" style="background:#B0C4DE" | Премия
! scope="col" style="background:#B0C4DE" | Работа
! scope="col" style="background:#B0C4DE" | Результат
! scope="col" style="background:#B0C4DE" | Примечание]]
local awards = entity.claims.P166
local nominations = entity.claims.P1411
local lst = {}
local nom = 'background:Gainsboro;" | Номинация'
local win = 'background:Gold;" | Победа'
local function fillAwards( from, to, isnom )
if from == nil then return end
for k, v in pairs( from ) do
local o = {}
o.name = mw.wikibase.renderSnak( v.mainsnak )
if v.qualifiers ~= nil and v.qualifiers.P585 ~= nil then
o.when = frame:preprocess(string.format('{{год в кино|%s}}', mw.wikibase.renderSnak( v.qualifiers.P585[1] )))
-- o.when = mw.wikibase.renderSnak( v.qualifiers.P585[1] )
end
if v.qualifiers ~= nil and v.qualifiers.P1686 ~= nil then
o.forwhat = mw.wikibase.renderSnaks( v.qualifiers.P1686 )
end
o.refs = v.references
o.isnom = isnom
table.insert(to, o)
end
end
local function formatRefs(references)
local out = ''
if references then
for _, reference in pairs(references) do
out = out .. renderReference(frame, entity, reference)
end
end
return out
end
fillAwards( awards, lst, false )
fillAwards( nominations, lst, true )
table.sort(lst, function (a, b)
return a.when < b.when
end)
for i = 1, #lst do
r = r .. string.format('\n' .. [[|-
| %s
| %s
| %s
| style="text-align:center; %s
| %s]], lst[i].when or "", lst[i].name, lst[i].forwhat or "", (lst[i].isnom and nom or win), formatRefs(lst[i].refs))
end
r = r .. '\n|}\n'
return r
end
local function top( frame, entity )
local r = frame:preprocess('{{ {{{|safesubst:}}}ifsubst||{{Предупреждение в типовой статье|Типовая статья о человеке|' .. entity.id .. '}}\n}}')
local surname = entity.claims.P734 ~= nil and mw.wikibase.sitelink( entity.claims.P734[1].mainsnak.datavalue.value.id )
local name = entity.claims.P735 ~= nil and mw.wikibase.sitelink( entity.claims.P735[1].mainsnak.datavalue.value.id )
if surname then
if name then
r = r .. frame:preprocess('{{имя+фамилия|'.. name .. '|' .. surname .. '}}\n')
else
r = r .. frame:preprocess('{{однофамильцы|' .. surname .. '}}\n')
end
end
r = r .. frame:preprocess('{{персона|from=' .. entity.id .. '}}\n')
local s = {}
local is_female = (entity.claims.P21 ~= nil) and (entity.claims.P21[1].mainsnak.datavalue.value['numeric-id'] == 6581072)
if is_female then
s.was_born = 'родилась'
s.His = 'Её'
s.Was_member_of = 'Была участницей'
s.Spouse = 'Муж'
s.Died = 'Умерла'
s.Buried = 'Похоронена'
s.Awarded = 'обладательница '
s.Finished = 'Закончила'
else
s.was_born = 'родился'
s.His = 'Его'
s.Was_member_of = 'Был участником'
s.Spouse = 'Жена'
s.Died = 'Умер'
s.Buried = 'Похоронен'
s.Awarded = 'обладатель '
s.Finished = 'Закончил'
end
local name = formatName( frame, mw.title.getCurrentTitle().text )
local birth_date = renderStatement(frame, {property='P569', ['value-module']='Wikidata/date', ['value-function']='formatBirthDate', from=entity.id})
local birth_place = renderStatement(frame, {property='P19', preset='name', ['claim-module']='Wikidata/Places', ['claim-function']='formatPlaceWithQualifiers', from=entity.id})
local basic_info = birth_date .. ', ' .. birth_place
if entity.claims.P570 ~= nil then
local death_date = renderStatement(frame, {property='P570', ['value-module']='Wikidata/date', ['value-function']='formatDeathDate', from=entity.id})
local death_place = renderStatement(frame, {property='P20', preset='name', ['claim-module']='Wikidata/Places', ['claim-function']='formatPlaceWithQualifiers', from=entity.id})
basic_info = basic_info .. ' — ' .. death_date .. ', ' .. death_place
end
if entity.claims.P1814 ~= nil then
r = r .. frame:preprocess('{{нихонго-но-намаэ|\'\'\'' .. name .. '\'\'\'|{{safesubst:#property:P1814}}||4=' .. basic_info .. '}}')
elseif entity.claims.P1559 ~= nil and entity.claims.P1559[1].mainsnak.datavalue.value.language ~= 'ru' then
local orig_name_val = entity.claims.P1559[1].mainsnak.datavalue.value
local orig_name = '{{lang-' .. orig_name_val.language .. '|' .. orig_name_val.text .. '}}'
r = r .. frame:preprocess('\'\'\'' .. name .. '\'\'\' (' .. orig_name .. '; ' .. basic_info .. ')')
else
r = r .. frame:preprocess('\'\'\'' .. name .. '\'\'\' (' .. basic_info .. ')')
end
if entity.claims.P27 ~= nil then
local occupation = renderStatement(frame, {property='P106', from=entity.id})
local citizenship = formatCitizenship(entity.claims.P27, is_female)
if citizenship ~= nil then
r = r .. frame:preprocess(' — ' .. citizenship .. ' ' .. occupation)
else
r = r .. frame:preprocess(' — ' .. occupation .. ' ({{safesubst:#property:P27}})')
end
end
if entity.claims.P166 ~= nil and hasPreferredAwards( entity ) then
r = r .. frame:preprocess(', ' .. s.Awarded) .. formatPreferredAwards( frame, entity )
end
r = r .. '.'
if entity.claims.P1875 ~= nil then
r = r .. frame:preprocess(' Работает под эгидой агентства {{safesubst:#property:P1875}}.')
end
r = r .. '\n\n== Биография ==\n'
r = r .. frame:preprocess(name .. ' ' .. s.was_born .. ' {{safesubst:#property:P569}} {{safesubst:wikidata/where|P19}}.')
if entity.claims.P69 ~= nil then -- учебное заведение
local schools = entity.claims.P69
r = r .. ' ' .. s.Finished .. ' ' .. formatSchool(mw.wikibase.label(schools[1].mainsnak.datavalue.value.id))
if schools[1].qualifiers ~= nil then
local at = schools[1].qualifiers.P582 -- дата окончания
if at ~= nil and at[1].datavalue.value.precision == 9 then
r = r .. ' в ' .. moduleDate.formatDate( {}, {}, at[1].datavalue.value ) .. ' году'
end
end
r = r .. '.'
end
if entity.claims.P793 ~= nil then
local stepping_out = nil
local events = entity.claims.P793
for k, v in pairs( events ) do
if v.mainsnak.datavalue.value['numeric-id'] == 22075993 and -- сценический дебют
v.qualifiers.P585[1].datavalue.value.precision == 9 then
stepping_out = 'в ' .. moduleDate.formatDate( {}, {}, v.qualifiers['P585'][1].datavalue.value ) .. ' году'
end
end
if stepping_out ~= nil then
r = r .. frame:preprocess(' ' .. s.His .. ' актёрский дебют состоялся ' .. stepping_out .. '.')
end
end
r = r .. '\n\n'
if entity.claims.P108 ~= nil then
local work_place = renderStatement(frame, {property='P108', preset='name', from=entity.id})
r = r .. frame:preprocess('Место работы — ' .. work_place .. '.\n\n') -- падеж, даты
end
if entity.claims.P463 ~= nil then
local member_of = renderStatement(frame, {property='P463', from=entity.id})
if #entity.claims.P463 == 1 then
r = r .. frame:preprocess(s.Was_member_of .. ' организации ' .. member_of .. '.\n\n')
else
r = r .. frame:preprocess(s.Was_member_of .. ' организаций: ' .. member_of .. '.\n\n')
end
end
if entity.claims.P26 ~= nil then
local spouse = renderStatement(frame, {property='P26', from=entity.id})
r = r .. frame:preprocess(s.Spouse .. ' — ' .. spouse .. '.\n\n')
end
if entity.claims.P570 ~= nil then -- умер
r = r .. frame:preprocess(s.Died .. ' {{safesubst:#property:P570}}')
if entity.claims.P20 ~= nil then -- где
r = r .. frame:preprocess(' {{safesubst:wikidata/where|P20}}')
end
if entity.claims.P1196 ~= nil then -- род смерти
local death_cause = renderStatement(frame, {property='P1196', from=entity.id})
r = r .. frame:preprocess(', род смерти — ' .. death_cause)
end
r = r .. '. '
end
if entity.claims.P119 ~= nil then -- похоронен
r = r .. frame:preprocess(s.Buried .. ' {{safesubst:wikidata/where|P119|P1791}}.\n')
end
if entity.claims.P166 ~= nil or entity.claims.P1411 ~= nil then
r = r .. formatAwards( frame, entity )
end
return r
end
local function bottom( frame, entity )
local r = ''
r = r .. '\n== Примечания ==\n'
r = r .. frame:preprocess('{{примечания|2}}\n')
r = r .. '\n== Ссылки ==\n'
if entity['claims']['P345'] ~= nil then
r = r .. frame:preprocess('* {{imdb name|{{safesubst:str sub|{{safesubst:#property:P345}}|2|100}}}}\n')
end
if entity['claims']['P2013'] ~= nil then
r = r .. frame:preprocess('* {{Facebook|{{safesubst:#property:P2013}}}}\n')
end
if entity['claims']['P973'] ~= nil then
r = r .. frame:preprocess(formatExtraSources(entity))
end
r = r .. frame:preprocess('\n{{Внешние ссылки}}')
return r
end
function p.render( frame )
local entity = mw.wikibase.getEntityObject(frame.args.from)
local r = top( frame, entity )
if frame.args[1] ~= nil and #frame.args[1] > 0 then
r = r .. '\n== ' .. frame.args[1] .. ' ==\n'
r = r .. frame.args[2]
end
r = r .. bottom( frame, entity )
return cleanup(r)
end
return p