Модуль:Wikidata/P512
Содержит функции для форматирования учёных степеней, получаемых из свойства викиданных d:Property:P512. По сравнению с formatPropertyDefault()
из Модуль:Wikidata включает в себя следующую логику:
- В викиданных отмечаются факты получения всех степеней, но в карточке нет смысла показывать кандидатскую при наличии соответствующей докторской. Например Путилов, Борис Николаевич (показывается только д. ф. н.), Зайцев, Александр Иосифович (показывается и к. ф. н. и д. и. н.)
- После самой учёной степени в скобках показывается год её присвоения (из квалификатора d:P585). Иногда для указания этой же информации используют d:P580, но первый вариант гораздо распространённее (ср. [1] и [2])
- В статью добавляется соответствующая степени категория (например Категория:Кандидаты искусствоведения)
Для правильной реализации пунктов 1 и 3 нужно загружать элемент, соответствующий каждой ученой степени персоны и обращаться к свойствам d:P156 и d:P910 соответственно. Однако, для первой версии, решено захардкодить связи между степенями первой и второй ступени, а также соответствующими категориями по соображениям производительности и для минимизации зависимостей данного модуля от других.
Названия функций данного модуля, а также их сигнатуры могут меняться без предупреждения, поэтому не рекомендуется использовать их напрямую. Штатно модуль используется из шаблона {{wikidata/p512}}, в котором осуществляется вызов {{#invoke:Wikidata|formatStatements
с параметрами property-module=Wikidata/P512
и property-function=formatAcademicDegree
Тесты
эдер
6 tests failed.
test_formatAcademicDegree:
Text
Expected
Actual
demo
<span class="wikidata-claim" data-wikidata-property-id="P512" data-wikidata-claim-id="Q4115189$2fb0ce43-4ffe-9e6e-6dab-0d101b0ceac0">филология эртемнериниң доктору</span>[[Аңгылал:Филология эртемнериниң докторлары]]
<span class="wikidata-claim" data-wikidata-property-id="P512" data-wikidata-claim-id="Q4115189$2fb0ce43-4ffe-9e6e-6dab-0d101b0ceac0">филология эртемнериниң доктору</span>[[Аңгылал:Докторлар филологических наук]]
test_formatCorrespondingCategory:
test_formatQualifier:
Text
Expected
Actual
{}
""
""
{1987}
" (1987)"
" (1987)"
{2017, 2024}
" (2017)"
" (2017)"
test_getPreviousDegrees:
Text
Expected
Actual
{}
{}
{}
{1}
{}
{}
{1, 16698078, 19610224}
{[19610224]=true}
{[19610224]=true}
{17281125, 17281125}
{[18071588]=true}
{[18071588]=true}
local p = {}
--[[
Функция формирует строку с викиразметкой для переданного свойства
Принимает: объект контекста для вызова форматтеров и таблицу настройек
Возвращает: вики-форматированную строку
]]
function p.formatAcademicDegree( 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 ''
end
local blackList = p.getPreviousDegrees( claims )
local formattedClaims = {}
for i, claim in ipairs(claims) do
if (claim.mainsnak.datavalue and not blackList[claim.mainsnak.datavalue.value['numeric-id']]) then
local formattedStatement = context.formatStatement( options, claim )
if (formattedStatement) then
formattedStatement = '<span class="wikidata-claim"' ..
' data-wikidata-property-id="' ..
string.upper( options.property ) ..
'" data-wikidata-claim-id="' ..
claim.id .. '">' ..
formattedStatement .. '</span>'
if (claim.qualifiers) then
formattedStatement = formattedStatement ..
p.formatQualifier( context, options, claim.qualifiers.P585 )
end
formattedStatement = formattedStatement ..
p.formatCorrespondingCategory( claim )
table.insert( formattedClaims, formattedStatement )
end
end
end
-- создание текстовой строки со списком оформленых заявлений из таблицы
return mw.text.listToText( formattedClaims, options.separator, options.conjunction );
end
--[[
Функция помещает в скобки текст первого квалификатора из переданной таблицы
Принимает: объект контекста для вызова форматтеров, таблицу настроеки
и таблицу квалификаторов
Возвращает: отформатированная строка с квалификатором
]]
function p.formatQualifier( context, options, qualifiers )
if (qualifiers~=nil and qualifiers[1] ~= nil) then
return ' (' .. context.formatSnak( options, qualifiers[1] ) .. ')'
end
return ''
end
--[[
Функция формирует список соответствующих ученых степеней нижней ступени (P155)
Например, для "доктор искусствоведения" это будет "кандидат искусствоведения"
Принимает: объект таблицу сущностей - академических степеней персоны (P512)
Возвращает: объект таблицу идентификаторов степеней нижней ступени
]]
function p.getPreviousDegrees( claims )
-- Пока нет нормальной возможности загружать элементы c кэшем
-- снаружи Module:Wikidata, мы эти соответствия захардкодим (без Q)
local correspondingCandidates = {
[16698078] = 19610224, -- архитектор
[17281188] = 19610186, -- биолог
[17281187] = 19610187, -- ветеринар
[17281186] = 19610193, -- военный
[16698080] = 19610195, -- географ
[16698082] = 19610197, -- гео-мин
[17281180] = 18523814, -- искусствовед
[12101789] = 18523811, -- историк
[16698084] = 19610200, -- культуролог
[17281165] = 19610203, -- медик
[17281161] = 19610206, -- педагог
[12101787] = 4212319, -- политолог
[17281156] = 19610208, -- психолог
[17281153] = 19610210, -- сель-хоз
[17281152] = 19610212, -- социолог
[17281125] = 18071588, -- техник
[17281115] = 19610228, -- фармацевт
[17281097] = 18002832, -- физ-мат
[17281087] = 19603970, -- филолог
[17281084] = 19603972, -- философ
[17281079] = 19610312, -- химик
[17281072] = 17744738, -- экономист
[18745564] = 19610320 -- юрист
}
local previousElements = {}
for i, claim in ipairs(claims) do
if(claim.mainsnak.datavalue) then
local entityId = claim.mainsnak.datavalue.value['numeric-id']
if (entityId) then
if correspondingCandidates[entityId] then
previousElements[correspondingCandidates[entityId]] = true
end
end
end
end
return previousElements
end
--[[
Функция формирует вики-разметку категории, соответствующей ученой степени
Принимает: объект таблицу утверждения
Возвращает: строку оформленного текста либо пустую строку
]]
function p.formatCorrespondingCategory (claim)
if ( not claim ) then return '' end;
if ( not claim.references ) then return '' end;
if ( not claim.mainsnak ) then return '' end;
local label = mw.wikibase.label("Q" .. claim.mainsnak.datavalue.value['numeric-id'])
local result, changes = string.gsub(label, "доктор ", "Аңгылал:Докторлар ")
if (changes == 1) then
return '[[' .. result .. ']]'
end
result, changes = string.gsub(label, "кандидат ", "Аңгылал:Кандидаттар ")
if (changes == 1) then
return '[[' .. result .. ']]'
end
return ''
end
return p