Модуль:Infocards: различия между версиями

Материал из Тептар — свободной энциклопедии
Перейти к навигации Перейти к поиску
(Новая страница: «local infocards = {}; local calculateAge = true; --[[ Helper function that populates the argument list given that user may need to use a mix of named and unnamed...»)
 
Нет описания правки
 
Строка 1: Строка 1:
local infocards = {};
local infocards = {}
local calculateAge = true;
local calculateAge = true
local dateCat = require("Module:Infocards/dateCat")


--[[
--[[
Строка 9: Строка 10:
]]
]]
function infocards._getParameters( frame_args, arg_list )
function infocards._getParameters( frame_args, arg_list )
    local new_args = {};
local new_args = {}
    local index = 1;
local index = 1
    local value;
local value
   
   
    for i,arg in ipairs( arg_list ) do
for i,arg in ipairs( arg_list ) do
        value = frame_args[arg]
value = frame_args[arg]
        if value == nil then
if value == nil then
            value = frame_args[index];
value = frame_args[index]
            index = index + 1;
index = index + 1
        end
end
        new_args[arg] = value;
new_args[arg] = value
    end
end
   
   
    return new_args;
return new_args
end         
end         


function infocards.isBlank( someString )
function infocards.isBlank( someString )
    return someString == nil or mw.ustring.match(someString, '^%s*$') ~= nil;
return someString == nil or mw.ustring.match(someString, '^%s*$') ~= nil
end
end


function infocards.isDate ( frame )
function infocards.isDate ( frame )
    local new_args = infocards._getParameters( frame.args, {'s', 't', 'f'} );
local new_args = infocards._getParameters( frame.args, {'s', 't', 'f'} )
    local s = new_args['s'] or '';
local s = new_args['s'] or ''
    local t = new_args['t'] or '';
local t = new_args['t'] or ''
    local f = new_args['f'] or '';
local f = new_args['f'] or ''


    local result = infocards.isDateImpl ( s )
local result = infocards.isDateImpl ( s )
    if (result) then
if (result) then
        return t
return t
    else
else
        return f
return f
    end
end
end
end


function infocards.isDateImpl ( s )
function infocards.isDateImpl ( s )
    local converted = infocards.convertToDate ( s );
local converted = infocards.convertToDate ( s )
    return converted ~= nil
return converted ~= nil
end
end


function infocards.dateOfBirth( frame )
function infocards.dateOfBirth( frame )
    local new_args = infocards._getParameters( frame.args, {'dateOfBirth', 'dateOfDeath', 'nocat'} );
local new_args = infocards._getParameters( frame.args, {'dateOfBirth', 'dateOfDeath', 'suppressAge', 'nocat'} )
    local dateOfBirth = new_args['dateOfBirth'] or '';
local dateOfBirth = new_args['dateOfBirth'] or ''
    local dateOfDeath = new_args['dateOfDeath'] or '';
local dateOfDeath = new_args['dateOfDeath'] or ''
    local nocat = new_args['nocat'] or mw.title.getCurrentTitle().nsText;
local suppressAge = new_args['suppressAge'] or ''
local nocat = new_args['nocat'] or mw.title.getCurrentTitle().nsText


    return infocards.dateOfBirthImpl( dateOfBirth, dateOfDeath, nocat );
return infocards.dateOfBirthImpl( dateOfBirth, dateOfDeath, suppressAge, nocat )
end
end


function infocards.dateOfBirthImpl( dateOfBirth, dateOfDeath, nocat )
function infocards.dateOfBirthImpl( dateOfBirth, dateOfDeath, suppressAge, nocat )


    local appendToCategory = infocards.isBlank( nocat );
local appendToCategory = infocards.isBlank( nocat )


    if ( infocards.isBlank( dateOfBirth ) ) then
if ( infocards.isBlank( dateOfBirth ) ) then
        if ( appendToCategory ) then
if ( appendToCategory ) then
            return '[[Категория:Тептар:Персоны без указанной даты рождения]]'
return dateCat.categoryNoBirthDate
        else
else
            return ''
return ''
        end
end
    end
end


    if ( mw.ustring.match( dateOfBirth, '^%s*неизвестн.%s*$' ) ~= nil
if ( mw.ustring.match( dateOfBirth, '^%s*неизвестн.%s*$' ) ~= nil
            or mw.ustring.match( dateOfBirth, '^%s*%?%s*$' ) ~= nil ) then
or mw.ustring.match( dateOfBirth, '^%s*%?%s*$' ) ~= nil ) then
        if ( appendToCategory ) then
if ( appendToCategory ) then
            return "''неизвестно''[[Категория:Персоналии, чья дата рождения не установлена]]"
return "''неизвестно''" .. dateCat.categoryUnknownBirthDate
        else
else
            return "''неизвестно''"
return "''неизвестно''"
        end
end
    end
end


    local appendAge = calculateAge and infocards.isBlank( dateOfDeath );
local appendAge = not (suppressAge ~= '' or not calculateAge) and infocards.isBlank( dateOfDeath )


    local parsedDate = infocards.convertToDate ( dateOfBirth )
local parsedDate = infocards.convertToDate ( dateOfBirth )
    if ( parsedDate == nil ) then
if ( parsedDate == nil ) then
--[[ Temporary hack in order to enable export dates to wikidata ]]
--[[ Temporary hack in order to enable export dates to wikidata ]]
local bDateStart = '<span class="no-wikidata" data-wikidata-property-id="P569">'
local bDateStart = '<span class="no-wikidata" data-wikidata-property-id="P569">'
local bDateEnd = '</span>'
local bDateEnd = '</span>'


        if ( appendToCategory ) then
if ( appendToCategory ) then
            return bDateStart .. dateOfBirth .. bDateEnd .. '[[Категория:Тептар:Статьи с ручной тептарфикацией дат в карточке]]'
return bDateStart .. dateOfBirth .. bDateEnd .. dateCat.categoryManualWikification
        else
else
            return bDateStart .. dateOfBirth .. bDateEnd
return bDateStart .. dateOfBirth .. bDateEnd
        end
end
    end
end


    local result = infocards.formatDateImpl ( parsedDate, 'bday', appendToCategory and 'Родившиеся' or nil )
local result = infocards.formatDateImpl ( parsedDate, 'bday', appendToCategory and 'Родившиеся' or nil )


    if ( appendAge ) then
if ( appendAge ) then
        -- TODO: месяцы и дни для (нескольких) новорождённых (см. новейшие [[Категория:Родившиеся в ГГГГ году]])
-- TODO: месяцы и дни для (нескольких) новорождённых (см. новейшие [[Категория:Родившиеся в ГГГГ году]])
        local age = infocards.age ( parsedDate,  os.date("*t") )
local age = infocards.age ( parsedDate,  os.date("*t") )
        if ( age and age > 0 and age < 125) then
if ( age and age < 125) then
            result = result .. ' <span class="nowrap">(' .. age .. ' ' .. mw.language.new( 'ru' ):plural( age, 'год', 'года', 'лет') .. ')</span>'
result = result .. ' <span class="nowrap">(' .. age .. ' ' .. mw.language.new( 'ru' ):plural( age, 'год', 'года', 'лет') .. ')</span>'
        end
end
       
if ( appendToCategory ) then
if ( appendToCategory ) then
if ( age and age > 115 ) then
if (not age and parsedDate and parsedDate.year ) then
result = result .. '[[Категория:Тептар:Статьи о персоналиях с большим текущим возрастом]]'
age = os.date('*t').year - parsedDate.year -- при неточной дате
elseif ( age or ( parsedDate and parsedDate.year and os.date('*t').year - parsedDate.year <= 115 ) ) then  -- утверждение во вложенных скобках вступает при неточной дате
end
result = result .. '[[Категория:Тептар:Биографии современников]]'
if ( age ) then
if ( age > 115 ) then
result = result .. dateCat.categoryBigCurrentAge
elseif ( age >= 0 ) then
result = result .. dateCat.categoryBiographiesOfLivingPersons
else
result = result .. dateCat.categoryNegativeAge
end
end
end
end
end
    end
end


    return result
return result
end
end


function infocards.dateOfDeath( frame )
function infocards.dateOfDeath( frame )
    local new_args = infocards._getParameters( frame.args, {'dateOfBirth', 'dateOfDeath', 'nocat'} );
local new_args = infocards._getParameters( frame.args, {'dateOfBirth', 'dateOfDeath', 'nocat'} )
    local dateOfBirth = new_args['dateOfBirth'] or '';
local dateOfBirth = new_args['dateOfBirth'] or ''
    local dateOfDeath = new_args['dateOfDeath'] or '';
local dateOfDeath = new_args['dateOfDeath'] or ''
    local nocat = new_args['nocat'] or mw.title.getCurrentTitle().nsText;
local nocat = new_args['nocat'] or mw.title.getCurrentTitle().nsText


    return infocards.dateOfDeathImpl( dateOfBirth, dateOfDeath, nocat );
return infocards.dateOfDeathImpl( dateOfBirth, dateOfDeath, nocat )
end
end


function infocards.dateOfDeathImpl( dateOfBirth, dateOfDeath, nocat )
function infocards.dateOfDeathImpl( dateOfBirth, dateOfDeath, nocat )
    if ( infocards.isBlank( dateOfDeath ) ) then
if ( infocards.isBlank( dateOfDeath ) ) then
        return ''
return ''
    end
end


    local appendToCategory = infocards.isBlank( nocat );
local appendToCategory = infocards.isBlank( nocat )


    if ( mw.ustring.match( dateOfDeath, '^%s*неизвестн.%s*$' ) ~= nil
if ( mw.ustring.match( dateOfDeath, '^%s*неизвестн.%s*$' ) ~= nil
            or mw.ustring.match( dateOfDeath, '^%s*%?%s*$' ) ~= nil ) then
or mw.ustring.match( dateOfDeath, '^%s*%?%s*$' ) ~= nil ) then
        if ( appendToCategory ) then
if ( appendToCategory ) then
            return "''неизвестно''[[Категория:Персоналии, чья дата смерти не установлена]]"
return "''неизвестно''" .. dateCat.categoryUnknownDeathDate
        else
else
            return "''неизвестно''"
return "''неизвестно''"
        end
end
    end
end


    local parsedDateOfBirth = infocards.convertToDate ( dateOfBirth )
local parsedDateOfBirth = infocards.convertToDate ( dateOfBirth )
    local parsedDateOfDeath = infocards.convertToDate ( dateOfDeath )
local parsedDateOfDeath = infocards.convertToDate ( dateOfDeath )


    if ( parsedDateOfDeath == nil ) then
if ( parsedDateOfDeath == nil ) then
--[[ Temporary hack in order to enable export dates to wikidata ]]
--[[ Temporary hack in order to enable export dates to wikidata ]]
local dDateStart = '<span class="no-wikidata" data-wikidata-property-id="P570">'
local dDateStart = '<span class="no-wikidata" data-wikidata-property-id="P570">'
local dDateEnd = '</span>'
local dDateEnd = '</span>'


        if ( appendToCategory ) then
if ( appendToCategory ) then
            return dDateStart .. dateOfDeath .. dDateEnd .. '[[Категория:Тептар:Статьи с ручной тептарфикацией дат в карточке]]'
return dDateStart .. dateOfDeath .. dDateEnd .. dateCat.categoryManualWikification
        else
else
            return dDateStart .. dateOfDeath .. dDateEnd
return dDateStart .. dateOfDeath .. dDateEnd
        end
end
    end
end


    local result = infocards.formatDateImpl ( parsedDateOfDeath, 'dday', appendToCategory and 'Умершие' or nil )
local result = infocards.formatDateImpl ( parsedDateOfDeath, 'dday', appendToCategory and 'Умершие' or nil )


if ( calculateAge ) then
if ( calculateAge ) then
Строка 170: Строка 179:
error()
error()
end)
end)
if ( unixAvailable and os.time() - unixDateOfDeath < 31536000 and appendToCategory ) then
if (appendToCategory) then
result = result .. '[[Категория:Тептар:Персоналии, умершие менее года назад]]'
if ( unixAvailable and os.time() - unixDateOfDeath < 31536000 ) then
result = result .. dateCat.categoryRecentlyDeceased
elseif (age and age < 0) then
result = result .. dateCat.categoryNegativeAge
end
end
end
end
end


    return result
return result
end
end


function infocards.age( parsedBirthDate, parsedFinishDate )  
function infocards.age( parsedBirthDate, parsedFinishDate )  
    if ( parsedBirthDate == nil or parsedFinishDate == nil ) then
if ( parsedBirthDate == nil or parsedFinishDate == nil ) then
        return nil
return nil
    end
end


    local bd = parsedBirthDate["day"]
local bd = parsedBirthDate["day"]
    local bm = parsedBirthDate["month"]
local bm = parsedBirthDate["month"]
    local by = parsedBirthDate["year"]
local by = parsedBirthDate["year"]


    local dd = parsedFinishDate["day"];
local dd = parsedFinishDate["day"]
    local dm = parsedFinishDate["month"];
local dm = parsedFinishDate["month"]
    local dy = parsedFinishDate["year"];
local dy = parsedFinishDate["year"]


    if ( bd and bm and by and dd and dm and dy ) then
if ( bd and bm and by and dd and dm and dy ) then
        if ( dm > bm or ( dm == bm and dd >= bd ) ) then
if ( dm > bm or ( dm == bm and dd >= bd ) ) then
            return dy - by
return dy - by
        else
else
            return dy - by - 1
return dy - by - 1
        end
end
    else
else
        return nil
return nil
    end
end
end
end


local genitivusMonthes = {'января', 'февраля', 'марта', 'апреля', 'мая', 'июня',
local genitivusMonthes = {'января', 'февраля', 'марта', 'апреля', 'мая', 'июня',
    'июля', 'августа', 'сентября', 'октября', 'ноября', 'декабря'}
'июля', 'августа', 'сентября', 'октября', 'ноября', 'декабря'}


function infocards.formatDateImpl( parsedDate, infocardClass, categoryNamePrefix )
function infocards.formatDateImpl( parsedDate, infocardClass, categoryNamePrefix )
    local nd = parsedDate["day"];
local nd = parsedDate["day"]
    local nm = parsedDate["month"];
local nm = parsedDate["month"]
    local ny = parsedDate["year"];
local ny = parsedDate["year"]
    local od = parsedDate["osday"];
local od = parsedDate["osday"]
    local om = parsedDate["osmonth"];
local om = parsedDate["osmonth"]
    local oy = parsedDate["osyear"];
local oy = parsedDate["osyear"]
   
    local template =
local template =
        (nd ~= nil and "1" or "") .. (nm ~= nil and "2" or "") .. (ny ~= nil and "3" or "") ..
(nd ~= nil and "1" or "") .. (nm ~= nil and "2" or "") .. (ny ~= nil and "3" or "") ..
        (od ~= nil and "4" or "") .. (om ~= nil and "5" or "") .. (oy ~= nil and "6" or "")
(od ~= nil and "4" or "") .. (om ~= nil and "5" or "") .. (oy ~= nil and "6" or "")


    local datePart = '<span class="nowrap">'
local datePart = '<span class="nowrap">'
    if (infocardClass == "bday") then --[[ Temporary hack in order to enable export dates to wikidata ]]
if (infocardClass == "bday") then --[[ Temporary hack in order to enable export dates to wikidata ]]
    datePart = '<span class="no-wikidata" data-wikidata-property-id="P569">'
datePart = '<span class="no-wikidata" data-wikidata-property-id="P569">'
    elseif (infocardClass == "dday") then
elseif (infocardClass == "dday") then
    datePart = '<span class="no-wikidata" data-wikidata-property-id="P570">'
datePart = '<span class="no-wikidata" data-wikidata-property-id="P570">'
    end
end
    if (template == "12") then
if (template == "12") then
        datePart = datePart .. string.format( "[[%d %s]]", nd, genitivusMonthes[nm] )
datePart = datePart .. string.format( "[[%d %s]]", nd, genitivusMonthes[nm] )
    elseif (template == "3") then
elseif (template == "3") then
        datePart = datePart .. infocards.nominativeYear( ny )
datePart = datePart .. infocards.nominativeYear( ny )
    elseif (template == "123") then
elseif (template == "123") then
        datePart = datePart .. string.format( "[[%d %s]] %s",
datePart = datePart .. string.format( "[[%d %s]] %s",
                                        nd, genitivusMonthes[nm], infocards.nominativeYear( ny ) )
nd, genitivusMonthes[nm], infocards.nominativeYear( ny ) )
    elseif (template == "124") then
elseif (template == "124") then
        datePart = datePart .. string.format( "[[%d %s|%d (%d) %s]]",
datePart = datePart .. string.format( "[[%d %s|%d (%d) %s]]",
                                        nd, genitivusMonthes[nm], od, nd, genitivusMonthes[nm] )
nd, genitivusMonthes[nm], od, nd, genitivusMonthes[nm] )
    elseif (template == "1234") then
elseif (template == "1234") then
        datePart = datePart .. string.format( "[[%d %s|%d (%d) %s]] %s",
datePart = datePart .. string.format( "[[%d %s|%d (%d) %s]] %s",
                                        nd, genitivusMonthes[nm], od, nd, genitivusMonthes[nm], infocards.nominativeYear( ny ) )
nd, genitivusMonthes[nm], od, nd, genitivusMonthes[nm], infocards.nominativeYear( ny ) )
    elseif (template == "1245") then
elseif (template == "1245") then
        datePart = datePart .. string.format( "%d %s ([[%d %s]])",
datePart = datePart .. string.format( "%d %s ([[%d %s]])",
                                        od, genitivusMonthes[om], nd, genitivusMonthes[nm] )
od, genitivusMonthes[om], nd, genitivusMonthes[nm] )
    elseif (template == "12345") then
elseif (template == "12345") then
        datePart = datePart .. string.format( "%d %s ([[%d %s]]) %s",
datePart = datePart .. string.format( "%d %s ([[%d %s]]) %s",
                                        od, genitivusMonthes[om], nd, genitivusMonthes[nm], infocards.nominativeYear( ny ) )
od, genitivusMonthes[om], nd, genitivusMonthes[nm], infocards.nominativeYear( ny ) )
    elseif (template == "123456") then
elseif (template == "123456") then
        datePart = datePart .. string.format( '%d %s %d</span> <span class="nowrap">([[%d %s]] %s)',
datePart = datePart .. string.format( '%d %s %d</span> <span class="nowrap">([[%d %s]] %s)',
                                        od, genitivusMonthes[om], oy, nd, genitivusMonthes[nm], infocards.nominativeYear( ny ) )
od, genitivusMonthes[om], oy, nd, genitivusMonthes[nm], infocards.nominativeYear( ny ) )
    else
else
        datePart = datePart .. 'формат неверен'
datePart = datePart .. 'формат неверен'
    end
end
    datePart = datePart .. '</span>'
datePart = datePart .. '</span>'


    local infocardTemplate =
local infocardTemplate =
        (nd ~= nil and "1" or "") .. (nm ~= nil and "2" or "") .. (ny ~= nil and "3" or "")
(nd ~= nil and "1" or "") .. (nm ~= nil and "2" or "") .. (ny ~= nil and "3" or "")


if (infocardTemplate == "123") then
if (infocardTemplate == "123") then
Строка 261: Строка 274:
end
end


    if ( categoryNamePrefix ~= nil ) then
if ( categoryNamePrefix ~= nil ) then
        if ( nd ~= nil and nm ~= nil) then
if ( nd ~= nil and nm ~= nil) then
            datePart = datePart .. '[[Категория:' .. categoryNamePrefix .. ' ' .. nd .. ' ' .. genitivusMonthes[nm] .. ']]'
datePart = datePart .. '[[Категория:' .. categoryNamePrefix .. ' ' .. nd .. ' ' .. genitivusMonthes[nm] .. ']]'
        end
end
        if ( ny ~= nil) then
if ( ny ~= nil) then
            datePart = datePart .. '[[Категория:' .. categoryNamePrefix .. ' в ' .. infocards.inYear( ny ) .. ']]'
datePart = datePart .. '[[Категория:' .. categoryNamePrefix .. ' в ' .. infocards.inYear( ny ) .. ']]'
        end
end
    end
end


    return datePart
return datePart
end
end


function infocards.nominativeYear( year )
function infocards.nominativeYear( year )
    if ( year >= 0 ) then
if ( year >= 0 ) then
        return '[[' .. year .. ' год|' .. year .. ']]'
return '[[' .. year .. ' год|' .. year .. ']]'
    else
else
        return '[[' .. ( 0 - year ) .. ' год до н. э.|' .. ( 0 - year ) .. ' до н. э.]]'
return '[[' .. ( 0 - year ) .. ' год до н. э.|' .. ( 0 - year ) .. ' до н. э.]]'
    end
end
end
end


function infocards.inYear( year )
function infocards.inYear( year )
    if ( year >= 0 ) then
if ( year >= 0 ) then
        return '' .. year .. ' году'
return '' .. year .. ' году'
    else
else
        return '' .. ( 0 - year) .. ' году до н. э.'
return '' .. ( 0 - year) .. ' году до н. э.'
    end
end
end
end


function infocards.convertToDate( possibleDateString )
function infocards.convertToDate( possibleDateString )


    possibleDateString = mw.ustring.gsub( possibleDateString, '−', '-')
possibleDateString = mw.ustring.gsub( possibleDateString, '−', '-')


    local simpleDate = mw.ustring.match(possibleDateString, '^%s*([%-%d%.]+)%s*$', 0)
local simpleDate = mw.ustring.match(possibleDateString, '^%s*([%-%d%.]+)%s*$', 0)
    if ( simpleDate ) then
if ( simpleDate ) then
        return infocards.convertToDateNewStylePart( simpleDate );
return infocards.convertToDateNewStylePart( simpleDate )
    end
end


    local complexDate1, complexDate2 = mw.ustring.match(possibleDateString, '^%s*([%-%d%.]+)%s*%(([%-%d%.]+)%)%s*$', 0)
local complexDate1, complexDate2 = mw.ustring.match(possibleDateString, '^%s*([%-%d%.]+)%s*%(([%-%d%.]+)%)%s*$', 0)
    if ( complexDate1 and complexDate2) then
if ( complexDate1 and complexDate2) then
        local table1 = infocards.convertToDateNewStylePart( complexDate1 );
local table1 = infocards.convertToDateNewStylePart( complexDate1 )
        local table2 = infocards.convertToDateOldStylePart( complexDate2 );
local table2 = infocards.convertToDateOldStylePart( complexDate2 )
        if ( table1 and table2 ) then
if ( table1 and table2 ) then
            return {
return {
                    year = table1["year"], month = table1["month"], day = table1["day"],  
year = table1["year"], month = table1["month"], day = table1["day"],  
                    osyear = table2["year"], osmonth = table2["month"], osday = table2["day"]
osyear = table2["year"], osmonth = table2["month"], osday = table2["day"]
                }
}
        else
else
            return nil
return nil
        end
end
    end
end


    return nil
return nil
end
end


function infocards.convertToDateNewStylePart( possibleDateString )
function infocards.convertToDateNewStylePart( possibleDateString )


    local ny = mw.ustring.match(possibleDateString, '^(%-?%d+)$', 0)
local ny = mw.ustring.match(possibleDateString, '^(%-?%d+)$', 0)
    if (ny ~= nil) then
if (ny ~= nil) then
        return {year = tonumber(ny)}
return {year = tonumber(ny)}
    end
end


    return infocards.convertToDateCommonPart( possibleDateString )
return infocards.convertToDateCommonPart( possibleDateString )
end
end


function infocards.convertToDateOldStylePart( possibleDateString )
function infocards.convertToDateOldStylePart( possibleDateString )


    local nd = mw.ustring.match(possibleDateString, '^(%-?%d+)$', 0)
local nd = mw.ustring.match(possibleDateString, '^(%-?%d+)$', 0)
    if (nd ~= nil) then
if (nd ~= nil) then
        return {day = tonumber(nd)}
return {day = tonumber(nd)}
    end
end


    return infocards.convertToDateCommonPart( possibleDateString )
return infocards.convertToDateCommonPart( possibleDateString )
end
end


Строка 338: Строка 351:
function infocards.convertToDateCommonPart( possibleDateString )
function infocards.convertToDateCommonPart( possibleDateString )


    local nd, nm
local nd, nm
        = mw.ustring.match(possibleDateString, '^(%d?%d)%.(%d?%d)$', 0)
= mw.ustring.match(possibleDateString, '^(%d?%d)%.(%d?%d)$', 0)
    if (nd ~= nil and nm ~= nil) then
if (nd ~= nil and nm ~= nil) then
        return {day = tonumber(nd), month = tonumber(nm)}
return {day = tonumber(nd), month = tonumber(nm)}
    end
end


    local nd, nm, ny
local nd, nm, ny
        = mw.ustring.match(possibleDateString, '^(%d?%d)%.(%d?%d)%.(%-?%d+)$', 0)
= mw.ustring.match(possibleDateString, '^(%d?%d)%.(%d?%d)%.(%-?%d+)$', 0)
    if (nd ~= nil and nm ~= nil and ny ~= nil) then
if (nd ~= nil and nm ~= nil and ny ~= nil) then
    local ndn = tonumber(nd)
local ndn = tonumber(nd)
    local nmn = tonumber(nm)
local nmn = tonumber(nm)
    local nyn = tonumber(ny)
local nyn = tonumber(ny)
    if (ndn > 0 and ndn < 33 and nmn > 0 and nmn < 13) then
if (ndn > 0 and ndn < 33 and nmn > 0 and nmn < 13) then
        return {day = ndn, month = nmn, year = nyn}
return {day = ndn, month = nmn, year = nyn}
        end
end
    end
end


    return nil
return nil
end
end


return infocards
return infocards

Текущая версия от 19:38, 12 февраля 2022

Примеры вызова функции dateOfBirth[править код]

  • {{#invoke:Infocards|dateOfBirth|-382|−336}} → 382 до н. э.(-382)
  • {{#invoke:Infocards|dateOfBirth|11.1|}} → 11 января
  • {{#invoke:Infocards|dateOfBirth|24.12.3|15.01.69}} → 24 декабря 3(0003-12-24)
  • {{#invoke:Infocards|dateOfBirth|23.09.-63|19.08.14}} → 23 сентября 63 до н. э.(-063-09-23)
  • {{#invoke:Infocards|dateOfBirth|42|9.6.42}} → 42(0042)
  • {{#invoke:Infocards|dateOfBirth|870|13.8.900}} → 870(0870)
  • {{#invoke:Infocards|dateOfBirth||22.01.984}} →
  • {{#invoke:Infocards|dateOfBirth|16.06.1066|дата смерти неизвестна}} → 16 июня 1066(1066-06-16)
  • {{#invoke:Infocards|dateOfBirth|8.2.1834 (27.1)|2.2.1907 (20.1)}} → 27 января (8 февраля) 1834(1834-02-08)
  • {{#invoke:Infocards|dateOfBirth|29.06.1844 (17)|28.10.1883 (16)}} → 17 (29) июня 1844(1844-06-29)
  • {{#invoke:Infocards|dateOfBirth|19.7.1893 (7)|}} → 7 (19) июля 1893(1893-07-19)
  • {{#invoke:Infocards|dateOfBirth|3.10.1895 (21.9)|28.12.1925}} → 21 сентября (3 октября) 1895(1895-10-03)
  • {{#invoke:Infocards|dateOfBirth|4.10.1916|8.11.2009}} → 4 октября 1916(1916-10-04)
  • {{#invoke:Infocards|dateOfBirth|09.06.1942|}} → 9 июня 1942(1942-06-09) (82 года)
  • {{#invoke:Infocards|dateOfBirth|1955|}} → 1955(1955)
  • {{#invoke:Infocards|dateOfBirth|29.02.1984|}} → 29 февраля 1984(1984-02-29) (40 лет)
  • {{#invoke:Infocards|dateOfBirth||}} →
  • {{#invoke:Infocards|dateOfBirth|4.1.1885 (23.12.1884)|17.5.1951}} → 23 декабря 1884 (4 января 1885)(1885-01-04)
  • {{#invoke:Infocards|dateOfBirth|{{ДатаРождения|24|12|3}}|{{ДатаСмерти|15|01|69}}}} → Шаблон:ДатаРождения
  • {{#invoke:Infocards|dateOfBirth|ок. [[5]] года|24.01.41}} → ок. 5 года
  • {{#invoke:Infocards|dateOfBirth|ок. [[5]] года|{{ДатаСмерти|24|01|41}}}} → ок. 5 года
  • {{#invoke:Infocards|dateOfBirth|[[868]]/[[872]]|[[15 сентября]]/[[15 ноября]] [[890]]}} → 868/872
  • {{#invoke:Infocards|dateOfBirth|{{ДатаРождения|8|2|1834|27|1}}|{{ДатаСмерти|2|2|1907|20|1}} (72 года)}} → Шаблон:ДатаРождения

Примеры вызова функции dateOfDeath[править код]

  • {{#invoke:Infocards|dateOfDeath|-382|−336}} → 336 до н. э.(-336)
  • {{#invoke:Infocards|dateOfDeath|24.12.3|15.01.69}} → 15 января 69(0069-01-15) (65 лет)
  • {{#invoke:Infocards|dateOfDeath|23.09.-63|19.08.14}} → 19 августа 14(0014-08-19) (76 лет)
  • {{#invoke:Infocards|dateOfDeath|42|9.6.42}} → 9 июня 42(0042-06-09)
  • {{#invoke:Infocards|dateOfDeath|870|13.8.900}} → 13 августа 900(0900-08-13)
  • {{#invoke:Infocards|dateOfDeath||22.01.984}} → 22 января 984(0984-01-22)
  • {{#invoke:Infocards|dateOfDeath|16.06.1066|дата смерти неизвестна}} → дата смерти неизвестна
  • {{#invoke:Infocards|dateOfDeath|8.2.1834 (27.1)|2.2.1907 (20.1)}} → 20 января (2 февраля) 1907(1907-02-02) (72 года)
  • {{#invoke:Infocards|dateOfDeath|29.06.1844 (17)|28.10.1883 (16)}} → 16 (28) октября 1883(1883-10-28) (39 лет)
  • {{#invoke:Infocards|dateOfDeath|19.7.1893 (7)|}} → 14 апреля 1930(1930-04-14) (36 лет)
  • {{#invoke:Infocards|dateOfDeath|3.10.1895 (21.9)|28.12.1925}} → 28 декабря 1925(1925-12-28) (30 лет)
  • {{#invoke:Infocards|dateOfDeath|4.10.1916|8.11.2009}} → 8 ноября 2009(2009-11-08) (93 года)
  • {{#invoke:Infocards|dateOfDeath|09.06.1942|}} →
  • {{#invoke:Infocards|dateOfDeath|1955|}} →
  • {{#invoke:Infocards|dateOfDeath|29.02.1984|}} →
  • {{#invoke:Infocards|dateOfDeath||}} →
  • {{#invoke:Infocards|dateOfDeath|{{ДатаРождения|24|12|3}}|{{ДатаСмерти|15|01|69}}}} → Шаблон:ДатаСмерти
  • {{#invoke:Infocards|dateOfDeath|ок. [[5]] года|24.01.41}} → 24 января 41(0041-01-24)
  • {{#invoke:Infocards|dateOfDeath|ок. [[5]] года|{{ДатаСмерти|24|01|41}}}} → Шаблон:ДатаСмерти
  • {{#invoke:Infocards|dateOfDeath|[[868]]/[[872]]|[[15 сентября]]/[[15 ноября]] [[890]]}} → 15 сентября/15 ноября 890
  • {{#invoke:Infocards|dateOfDeath|{{ДатаРождения|8|2|1834|27|1}}|{{ДатаСмерти|2|2|1907|20|1}} (72 года)}} → Шаблон:ДатаСмерти (72 года)

Примеры вызова функции isDate[править код]

  • {{#invoke:Infocards|isDate||TRUE|FALSE}} → FALSE
  • {{#invoke:Infocards|isDate|-382|TRUE|FALSE}} → TRUE
  • {{#invoke:Infocards|isDate|−336|TRUE|FALSE}} → TRUE
  • {{#invoke:Infocards|isDate|24.12.3|TRUE|FALSE}} → TRUE
  • {{#invoke:Infocards|isDate|19.7.1893 (7)|TRUE|FALSE}} → TRUE
  • {{#invoke:Infocards|isDate|19.7.67.18/93 (7)|TRUE|FALSE}} → FALSE
  • {{#invoke:Infocards|isDate|13 декабря 2005|TRUE|FALSE}} → FALSE
  • {{#invoke:Infocards|isDate|дата смерти неизвестна|TRUE|FALSE}} → FALSE
  • {{#invoke:Infocards|isDate|{{ДатаРождения|24|12|3}}|TRUE|FALSE}} → FALSE

local infocards = {}
local calculateAge = true
local dateCat = require("Module:Infocards/dateCat")

--[[
Helper function that populates the argument list given that user may need to use a mix of
named and unnamed parameters.  This is relevant because named parameters are not
identical to unnamed parameters due to string trimming, and when dealing with strings
we sometimes want to either preserve or remove that whitespace depending on the application.
]]
function infocards._getParameters( frame_args, arg_list )
	local new_args = {}
	local index = 1
	local value
 
	for i,arg in ipairs( arg_list ) do
		value = frame_args[arg]
		if value == nil then
			value = frame_args[index]
			index = index + 1
		end
		new_args[arg] = value
	end
 
	return new_args
end        

function infocards.isBlank( someString )
	return someString == nil or mw.ustring.match(someString, '^%s*$') ~= nil
end

function infocards.isDate ( frame )
	local new_args = infocards._getParameters( frame.args, {'s', 't', 'f'} )
	local s = new_args['s'] or ''
	local t = new_args['t'] or ''
	local f = new_args['f'] or ''

	local result = infocards.isDateImpl ( s )
	if (result) then
		return t
	else
		return f
	end
end

function infocards.isDateImpl ( s )
	local converted = infocards.convertToDate ( s )
	return converted ~= nil
end

function infocards.dateOfBirth( frame )
	local new_args = infocards._getParameters( frame.args, {'dateOfBirth', 'dateOfDeath', 'suppressAge', 'nocat'} )
	local dateOfBirth = new_args['dateOfBirth'] or ''
	local dateOfDeath = new_args['dateOfDeath'] or ''
	local suppressAge = new_args['suppressAge'] or ''
	local nocat = new_args['nocat'] or mw.title.getCurrentTitle().nsText

	return infocards.dateOfBirthImpl( dateOfBirth, dateOfDeath, suppressAge, nocat )
end

function infocards.dateOfBirthImpl( dateOfBirth, dateOfDeath, suppressAge, nocat )

	local appendToCategory = infocards.isBlank( nocat )

	if ( infocards.isBlank( dateOfBirth ) ) then
		if ( appendToCategory ) then
			return dateCat.categoryNoBirthDate
		else
			return ''
		end
	end

	if ( mw.ustring.match( dateOfBirth, '^%s*неизвестн.%s*$' ) ~= nil
			or mw.ustring.match( dateOfBirth, '^%s*%?%s*$' ) ~= nil ) then
		if ( appendToCategory ) then
			return "''неизвестно''" .. dateCat.categoryUnknownBirthDate
		else
			return "''неизвестно''"
		end
	end

	local appendAge = not (suppressAge ~= '' or not calculateAge) and infocards.isBlank( dateOfDeath )

	local parsedDate = infocards.convertToDate ( dateOfBirth )
	if ( parsedDate == nil ) then
		--[[ Temporary hack in order to enable export dates to wikidata ]]
		local bDateStart = '<span class="no-wikidata" data-wikidata-property-id="P569">'
		local bDateEnd = '</span>'

		if ( appendToCategory ) then
			return bDateStart .. dateOfBirth .. bDateEnd .. dateCat.categoryManualWikification
		else
			return bDateStart .. dateOfBirth .. bDateEnd
		end
	end

	local result = infocards.formatDateImpl ( parsedDate, 'bday', appendToCategory and 'Родившиеся' or nil )

	if ( appendAge ) then
		-- TODO: месяцы и дни для (нескольких) новорождённых (см. новейшие [[Категория:Родившиеся в ГГГГ году]])
		local age = infocards.age ( parsedDate,  os.date("*t") )
		if ( age and age < 125) then
			result = result .. ' <span class="nowrap">(' .. age .. ' ' .. mw.language.new( 'ru' ):plural( age, 'год', 'года', 'лет') .. ')</span>'
		end
		
		if ( appendToCategory ) then
			if (not age and parsedDate and parsedDate.year ) then
				age = os.date('*t').year - parsedDate.year -- при неточной дате
 			end
			if ( age ) then 
				if ( age > 115 ) then
					result = result .. dateCat.categoryBigCurrentAge
				elseif ( age >= 0 ) then
 					result = result .. dateCat.categoryBiographiesOfLivingPersons
				else
					result = result .. dateCat.categoryNegativeAge
				end
			end
		end
	end

	return result
end

function infocards.dateOfDeath( frame )
	local new_args = infocards._getParameters( frame.args, {'dateOfBirth', 'dateOfDeath', 'nocat'} )
	local dateOfBirth = new_args['dateOfBirth'] or ''
	local dateOfDeath = new_args['dateOfDeath'] or ''
	local nocat = new_args['nocat'] or mw.title.getCurrentTitle().nsText

	return infocards.dateOfDeathImpl( dateOfBirth, dateOfDeath, nocat )
end

function infocards.dateOfDeathImpl( dateOfBirth, dateOfDeath, nocat )
	if ( infocards.isBlank( dateOfDeath ) ) then
		return ''
	end

	local appendToCategory = infocards.isBlank( nocat )

	if ( mw.ustring.match( dateOfDeath, '^%s*неизвестн.%s*$' ) ~= nil
			or mw.ustring.match( dateOfDeath, '^%s*%?%s*$' ) ~= nil ) then
		if ( appendToCategory ) then
			return "''неизвестно''" .. dateCat.categoryUnknownDeathDate
		else
			return "''неизвестно''"
		end
	end

	local parsedDateOfBirth = infocards.convertToDate ( dateOfBirth )
	local parsedDateOfDeath = infocards.convertToDate ( dateOfDeath )

	if ( parsedDateOfDeath == nil ) then
		--[[ Temporary hack in order to enable export dates to wikidata ]]
		local dDateStart = '<span class="no-wikidata" data-wikidata-property-id="P570">'
		local dDateEnd = '</span>'

		if ( appendToCategory ) then
			return dDateStart .. dateOfDeath .. dDateEnd .. dateCat.categoryManualWikification
		else
			return dDateStart .. dateOfDeath .. dDateEnd
		end
	end

	local result = infocards.formatDateImpl ( parsedDateOfDeath, 'dday', appendToCategory and 'Умершие' or nil )

	if ( calculateAge ) then
		local age = infocards.age ( parsedDateOfBirth, parsedDateOfDeath )
		if ( age and age > 0 ) then
			result = result .. ' <span class="nowrap">(' .. age .. ' ' .. mw.language.new( 'ru' ):plural( age, 'год', 'года', 'лет') .. ')</span>'
		end
		
		-- returns category to recently deceased persons
		local unixAvailable, unixDateOfDeath = pcall(function()
			local r = os.time(parsedDateOfDeath)
			if ( r ~= os.time() ) then
				return r
			end
			error()
		end)
		if (appendToCategory) then
			if ( unixAvailable and os.time() - unixDateOfDeath < 31536000 ) then
				result = result .. dateCat.categoryRecentlyDeceased
			elseif (age and age < 0) then
				result = result .. dateCat.categoryNegativeAge
			end
		end
	end

	return result
end

function infocards.age( parsedBirthDate, parsedFinishDate ) 
	if ( parsedBirthDate == nil or parsedFinishDate == nil ) then
		return nil
	end

	local bd = parsedBirthDate["day"]
	local bm = parsedBirthDate["month"]
	local by = parsedBirthDate["year"]

	local dd = parsedFinishDate["day"]
	local dm = parsedFinishDate["month"]
	local dy = parsedFinishDate["year"]

	if ( bd and bm and by and dd and dm and dy ) then
		if ( dm > bm or ( dm == bm and dd >= bd ) ) then
			return dy - by
		else
			return dy - by - 1
		end
	else
		return nil
	end
end

local genitivusMonthes = {'января', 'февраля', 'марта', 'апреля', 'мая', 'июня',
	'июля', 'августа', 'сентября', 'октября', 'ноября', 'декабря'}

function infocards.formatDateImpl( parsedDate, infocardClass, categoryNamePrefix )
	local nd = parsedDate["day"]
	local nm = parsedDate["month"]
	local ny = parsedDate["year"]
	local od = parsedDate["osday"]
	local om = parsedDate["osmonth"]
	local oy = parsedDate["osyear"]
	
	local template =
		(nd ~= nil and "1" or "") .. (nm ~= nil and "2" or "") .. (ny ~= nil and "3" or "") ..
		(od ~= nil and "4" or "") .. (om ~= nil and "5" or "") .. (oy ~= nil and "6" or "")

	local datePart = '<span class="nowrap">'
	if (infocardClass == "bday") then --[[ Temporary hack in order to enable export dates to wikidata ]]
		datePart = '<span class="no-wikidata" data-wikidata-property-id="P569">'
	elseif (infocardClass == "dday") then
		datePart = '<span class="no-wikidata" data-wikidata-property-id="P570">'
	end	
	if (template == "12") then
		datePart = datePart .. string.format( "[[%d %s]]", nd, genitivusMonthes[nm] )
	elseif (template == "3") then
		datePart = datePart .. infocards.nominativeYear( ny )
	elseif (template == "123") then
		datePart = datePart .. string.format( "[[%d %s]] %s",
										nd, genitivusMonthes[nm], infocards.nominativeYear( ny ) )
	elseif (template == "124") then
		datePart = datePart .. string.format( "[[%d %s|%d (%d) %s]]",
										nd, genitivusMonthes[nm], od, nd, genitivusMonthes[nm] )
	elseif (template == "1234") then
		datePart = datePart .. string.format( "[[%d %s|%d (%d) %s]] %s",
										nd, genitivusMonthes[nm], od, nd, genitivusMonthes[nm], infocards.nominativeYear( ny ) )
	elseif (template == "1245") then
		datePart = datePart .. string.format( "%d %s ([[%d %s]])",
										od, genitivusMonthes[om], nd, genitivusMonthes[nm] )
	elseif (template == "12345") then
		datePart = datePart .. string.format( "%d %s ([[%d %s]]) %s",
										od, genitivusMonthes[om], nd, genitivusMonthes[nm], infocards.nominativeYear( ny ) )
	elseif (template == "123456") then
		datePart = datePart .. string.format( '%d %s %d</span> <span class="nowrap">([[%d %s]] %s)',
										od, genitivusMonthes[om], oy, nd, genitivusMonthes[nm], infocards.nominativeYear( ny ) )
	else
		datePart = datePart .. 'формат неверен'
	end
	datePart = datePart .. '</span>'

	local infocardTemplate =
		(nd ~= nil and "1" or "") .. (nm ~= nil and "2" or "") .. (ny ~= nil and "3" or "")

	if (infocardTemplate == "123") then
		datePart = datePart .. string.format('<span style="display:none">(<span class="%s">%04d-%02d-%02d</span>)</span>', infocardClass , ny , nm , nd )
	elseif (infocardTemplate == "23") then
		datePart = datePart .. string.format('<span style="display:none">(<span class="%s">%04d-%02d</span>)</span>', infocardClass , ny , nm )
	elseif (infocardTemplate == "3") then
		datePart = datePart .. string.format('<span style="display:none;">(<span class="%s">%04d</span>)</span>', infocardClass , ny )
	end

	if ( categoryNamePrefix ~= nil ) then
		if ( nd ~= nil and nm ~= nil) then
			datePart = datePart .. '[[Категория:' .. categoryNamePrefix .. ' ' .. nd .. ' ' .. genitivusMonthes[nm] .. ']]'
		end
		if ( ny ~= nil) then
			datePart = datePart .. '[[Категория:' .. categoryNamePrefix .. ' в ' .. infocards.inYear( ny ) .. ']]'
		end
	end

	return datePart
end

function infocards.nominativeYear( year )
	if ( year >= 0 ) then
		return '[[' .. year .. ' год|' .. year .. ']]'
	else
		return '[[' .. ( 0 - year ) .. ' год до н. э.|' .. ( 0 - year ) .. ' до н. э.]]'
	end
end

function infocards.inYear( year )
	if ( year >= 0 ) then
		return '' .. year .. ' году'
	else
		return '' .. ( 0 - year) .. ' году до н. э.'
	end
end

function infocards.convertToDate( possibleDateString )

	possibleDateString = mw.ustring.gsub( possibleDateString, '−', '-')

	local simpleDate = mw.ustring.match(possibleDateString, '^%s*([%-%d%.]+)%s*$', 0)
	if ( simpleDate ) then
		return infocards.convertToDateNewStylePart( simpleDate )
	end

	local complexDate1, complexDate2 = mw.ustring.match(possibleDateString, '^%s*([%-%d%.]+)%s*%(([%-%d%.]+)%)%s*$', 0)
	if ( complexDate1 and complexDate2) then
		local table1 = infocards.convertToDateNewStylePart( complexDate1 )
		local table2 = infocards.convertToDateOldStylePart( complexDate2 )
		if ( table1 and table2 ) then
			return {
					year = table1["year"], month = table1["month"], day = table1["day"], 
					osyear = table2["year"], osmonth = table2["month"], osday = table2["day"]
				}
		else
			return nil
		end
	end

	return nil
end

function infocards.convertToDateNewStylePart( possibleDateString )

	local ny = mw.ustring.match(possibleDateString, '^(%-?%d+)$', 0)
	if (ny ~= nil) then
		return {year = tonumber(ny)}
	end

	return infocards.convertToDateCommonPart( possibleDateString )
end

function infocards.convertToDateOldStylePart( possibleDateString )

	local nd = mw.ustring.match(possibleDateString, '^(%-?%d+)$', 0)
	if (nd ~= nil) then
		return {day = tonumber(nd)}
	end

	return infocards.convertToDateCommonPart( possibleDateString )
end


function infocards.convertToDateCommonPart( possibleDateString )

	local nd, nm
		= mw.ustring.match(possibleDateString, '^(%d?%d)%.(%d?%d)$', 0)
	if (nd ~= nil and nm ~= nil) then
		return {day = tonumber(nd), month = tonumber(nm)}
	end

	local nd, nm, ny
		= mw.ustring.match(possibleDateString, '^(%d?%d)%.(%d?%d)%.(%-?%d+)$', 0)
	if (nd ~= nil and nm ~= nil and ny ~= nil) then
		local ndn = tonumber(nd)
		local nmn = tonumber(nm)
		local nyn = tonumber(ny)
		if (ndn > 0 and ndn < 33 and nmn > 0 and nmn < 13) then
			return {day = ndn, month = nmn, year = nyn}
		end
	end

	return nil
end

return infocards