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

Материал из Буквицы
Перейти к навигации Перейти к поиску
Нет описания правки
м (обновление данных с вики)
Строка 1: Строка 1:
local infocards = {}
local infocards = {};
local calculateAge = true;
 
--[[
--[[
Helper function that populates the argument list given that user may need to use a mix of
Helper function that populates the argument list given that user may need to use a mix of
Строка 23: Строка 24:
     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'} );
Строка 33: Строка 34:
     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
Строка 41: Строка 42:
     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', 'nocat'} );
Строка 52: Строка 53:
     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.dateOfBirthImpl( dateOfBirth, dateOfDeath, nocat );
     return infocards.dateOfBirthImpl( dateOfBirth, dateOfDeath, nocat );
end
end
 
function infocards.dateOfBirthImpl( dateOfBirth, dateOfDeath, nocat )
function infocards.dateOfBirthImpl( dateOfBirth, dateOfDeath, 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 '[[Категория:Википедия:Персоны без указанной даты рождения]]'
         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
Строка 76: Строка 77:
         end
         end
     end
     end
 
     local appendAge = infocards.isBlank( dateOfDeath );
     local appendAge = calculateAge and infocards.isBlank( dateOfDeath );
 
     local parsedDate = infocards.convertToDate ( dateOfBirth )
     local parsedDate = infocards.convertToDate ( dateOfBirth )
     if ( parsedDate == nil ) then
     if ( parsedDate == nil ) then
         if ( appendToCategory ) then
         if ( appendToCategory ) then
             return dateOfBirth .. '[[Категория:Буквица:Статьи с ручной викификацией дат в карточке]]'
             return dateOfBirth .. '[[Категория:Википедия:Статьи с ручной викификацией дат в карточке]]'
         else
         else
             return dateOfBirth
             return dateOfBirth
         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
         local age = infocards.age ( parsedDate,  os.date("*t") )
         local age = infocards.age ( parsedDate,  os.date("*t") )
Строка 96: Строка 97:
         end
         end
         if ( age > 150 and appendToCategory ) then
         if ( age > 150 and appendToCategory ) then
             result = result .. '[[Категория:Буквица:Статьи о персоналиях с большим текущим возрастом]]'
             result = result .. '[[Категория:Википедия:Статьи о персоналиях с большим текущим возрастом]]'
         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'} );
Строка 108: Строка 109:
     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
Строка 127: Строка 128:
         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
         if ( appendToCategory ) then
         if ( appendToCategory ) then
             return dateOfDeath .. '[[Категория:Буквица:Статьи с ручной викификацией дат в карточке]]'
             return dateOfDeath .. '[[Категория:Википедия:Статьи с ручной викификацией дат в карточке]]'
         else
         else
             return dateOfDeath
             return dateOfDeath
         end
         end
     end
     end
 
     local result = infocards.formatDateImpl ( parsedDateOfDeath, 'dday', appendToCategory and 'Умершие' or nil )
     local result = infocards.formatDateImpl ( parsedDateOfDeath, 'dday', appendToCategory and 'Умершие' or nil )
 
    local age = infocards.age ( parsedDateOfBirth, parsedDateOfDeath )
if ( calculateAge ) then
    if ( age > 0 ) then
local age = infocards.age ( parsedDateOfBirth, parsedDateOfDeath )
        result = result .. ' <span style="white-space:nowrap;">(' .. age .. ' ' .. mw.language.new( 'ru' ):plural( age, 'год', 'года', 'лет') .. ')</span>'
if ( age > 0 ) then
    end
result = result .. ' <span style="white-space:nowrap;">(' .. age .. ' ' .. mw.language.new( 'ru' ):plural( age, 'год', 'года', 'лет') .. ')</span>'
    if ( age > 150 and appendToCategory ) then
end
        result = result .. '[[Категория:Буквица:Статьи о персоналиях с большим возрастом во время смерти]]'
if ( age > 150 and appendToCategory ) then
    end
result = result .. '[[Категория:Википедия:Статьи о персоналиях с большим возрастом во время смерти]]'
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 0
         return 0
     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
Строка 175: Строка 178:
     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"];
Строка 186: Строка 189:
     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 style="white-space:nowrap;">'
     local datePart = '<span style="white-space:nowrap;">'
     if (template == "12") then
     if (template == "12") then
Строка 218: Строка 221:
     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 (template == "12") then
     if (infocardTemplate == "123") then
         datePart = '<span style="display:none">(<span class="' .. infocardClass .. '">{{padleft:' .. ny .. '|4|0}}-{{padleft:' .. nm .. '|2|0}}-{{padleft:' .. nd .. '|2|0}}</span>)</span>'
         datePart = datePart .. '<span style="display:none">(<span class="' .. infocardClass .. '">{{padleft:' .. ny .. '|4|0}}-{{padleft:' .. nm .. '|2|0}}-{{padleft:' .. nd .. '|2|0}}</span>)</span>'
     elseif (template == "3") then
     elseif (infocardTemplate == "23") then
        datePart = datePart .. '<span style="display:none">(<span class="' .. infocardClass .. '">{{padleft:' .. ny .. '|4|0}}-{{padleft:' .. nm .. '|2|0}}</span>)</span>'
    elseif (infocardTemplate == "3") then
         datePart = datePart .. '<span style="display:none;">(<span class="' .. infocardClass .. '">{{padleft:' .. ny .. '|4|0}}</span>)</span>'
         datePart = datePart .. '<span style="display:none;">(<span class="' .. infocardClass .. '">{{padleft:' .. ny .. '|4|0}}</span>)</span>'
     end
     end
 
     if ( categoryNamePrefix ~= nil ) then
     if ( categoryNamePrefix ~= nil ) then
         if ( nd ~= nil and nm ~= nil) then
         if ( nd ~= nil and nm ~= nil) then
Строка 236: Строка 241:
         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
Строка 247: Строка 252:
     end
     end
end
end
 
function infocards.inYear( year )
function infocards.inYear( year )
     if ( year >= 0 ) then
     if ( year >= 0 ) then
Строка 255: Строка 260:
     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
Строка 278: Строка 283:
         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
 
 
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)
Строка 310: Строка 315:
         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
        return {day = tonumber(nd), month = tonumber(nm), year = tonumber(ny)}
    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
     end
 
     return nil
     return nil
end
end
 
return infocards
return infocards

Версия от 10:03, 18 марта 2015

Примеры вызова функции dateOfBirth

  • {{#invoke:Infocards|dateOfBirth|-382|−336}} → 382 до н. э.({{padleft:-382|4|0}})
  • {{#invoke:Infocards|dateOfBirth|24.12.3|15.01.69}} → 24 декабря 3({{padleft:3|4|0}}-{{padleft:12|2|0}}-{{padleft:24|2|0}})
  • {{#invoke:Infocards|dateOfBirth|23.09.-63|19.08.14}} → 23 сентября 63 до н. э.({{padleft:-63|4|0}}-{{padleft:9|2|0}}-{{padleft:23|2|0}})
  • {{#invoke:Infocards|dateOfBirth|42|9.6.42}} → 42({{padleft:42|4|0}})
  • {{#invoke:Infocards|dateOfBirth|870|13.8.900}} → 870({{padleft:870|4|0}})
  • {{#invoke:Infocards|dateOfBirth||22.01.984}} →
  • {{#invoke:Infocards|dateOfBirth|16.06.1066|дата смерти неизвестна}} → 16 июня 1066({{padleft:1066|4|0}}-{{padleft:6|2|0}}-{{padleft:16|2|0}})
  • {{#invoke:Infocards|dateOfBirth|8.2.1834 (27.1)|2.2.1907 (20.1)}} → 27 января (8 февраля) 1834({{padleft:1834|4|0}}-{{padleft:2|2|0}}-{{padleft:8|2|0}})
  • {{#invoke:Infocards|dateOfBirth|29.06.1844 (17)|28.10.1883 (16)}} → 17 (29) июня 1844({{padleft:1844|4|0}}-{{padleft:6|2|0}}-{{padleft:29|2|0}})
  • {{#invoke:Infocards|dateOfBirth|19.7.1893 (7)|}} → 7 (19) июля 1893({{padleft:1893|4|0}}-{{padleft:7|2|0}}-{{padleft:19|2|0}})
  • {{#invoke:Infocards|dateOfBirth|3.10.1895 (21.9)|28.12.1925}} → 21 сентября (3 октября) 1895({{padleft:1895|4|0}}-{{padleft:10|2|0}}-{{padleft:3|2|0}})
  • {{#invoke:Infocards|dateOfBirth|4.10.1916|8.11.2009}} → 4 октября 1916({{padleft:1916|4|0}}-{{padleft:10|2|0}}-{{padleft:4|2|0}})
  • {{#invoke:Infocards|dateOfBirth|09.06.1942|}} → 9 июня 1942({{padleft:1942|4|0}}-{{padleft:6|2|0}}-{{padleft:9|2|0}}) (82 года)
  • {{#invoke:Infocards|dateOfBirth|1955|}} → 1955({{padleft:1955|4|0}})
  • {{#invoke:Infocards|dateOfBirth|29.02.1984|}} → 29 февраля 1984({{padleft:1984|4|0}}-{{padleft:2|2|0}}-{{padleft:29|2|0}}) (40 лет)
  • {{#invoke:Infocards|dateOfBirth||}} →
  • {{#invoke:Infocards|dateOfBirth|4.1.1885 (23.12.1884)|17.5.1951}} → 23 декабря 1884 (4 января 1885)({{padleft:1885|4|0}}-{{padleft:1|2|0}}-{{padleft:4|2|0}})
  • {{#invoke:Infocards|dateOfBirth|{{ДатаРождения|24|12|3}}|{{ДатаСмерти|15|01|69}}}} → 24 декабря 3(00031224)
  • {{#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 года)}} → 27 января (8 февраля) 1834(18340208)

Примеры вызова функции dateOfDeath

  • {{#invoke:Infocards|dateOfDeath|-382|−336}} → 336 до н. э.({{padleft:-336|4|0}})
  • {{#invoke:Infocards|dateOfDeath|24.12.3|15.01.69}} → 15 января 69({{padleft:69|4|0}}-{{padleft:1|2|0}}-{{padleft:15|2|0}}) (65 лет)
  • {{#invoke:Infocards|dateOfDeath|23.09.-63|19.08.14}} → 19 августа 14({{padleft:14|4|0}}-{{padleft:8|2|0}}-{{padleft:19|2|0}}) (76 лет)
  • {{#invoke:Infocards|dateOfDeath|42|9.6.42}} → 9 июня 42({{padleft:42|4|0}}-{{padleft:6|2|0}}-{{padleft:9|2|0}})
  • {{#invoke:Infocards|dateOfDeath|870|13.8.900}} → 13 августа 900({{padleft:900|4|0}}-{{padleft:8|2|0}}-{{padleft:13|2|0}})
  • {{#invoke:Infocards|dateOfDeath||22.01.984}} → 22 января 984({{padleft:984|4|0}}-{{padleft:1|2|0}}-{{padleft:22|2|0}})
  • {{#invoke:Infocards|dateOfDeath|16.06.1066|дата смерти неизвестна}} → дата смерти неизвестна
  • {{#invoke:Infocards|dateOfDeath|8.2.1834 (27.1)|2.2.1907 (20.1)}} → 20 января (2 февраля) 1907({{padleft:1907|4|0}}-{{padleft:2|2|0}}-{{padleft:2|2|0}}) (72 года)
  • {{#invoke:Infocards|dateOfDeath|29.06.1844 (17)|28.10.1883 (16)}} → 16 (28) октября 1883({{padleft:1883|4|0}}-{{padleft:10|2|0}}-{{padleft:28|2|0}}) (39 лет)
  • {{#invoke:Infocards|dateOfDeath|19.7.1893 (7)|}} → 14 апреля 1930({{padleft:1930|4|0}}-{{padleft:4|2|0}}-{{padleft:14|2|0}}) (36 лет)
  • {{#invoke:Infocards|dateOfDeath|3.10.1895 (21.9)|28.12.1925}} → 28 декабря 1925({{padleft:1925|4|0}}-{{padleft:12|2|0}}-{{padleft:28|2|0}}) (30 лет)
  • {{#invoke:Infocards|dateOfDeath|4.10.1916|8.11.2009}} → 8 ноября 2009({{padleft:2009|4|0}}-{{padleft:11|2|0}}-{{padleft:8|2|0}}) (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}}}} → 15 января 69
  • {{#invoke:Infocards|dateOfDeath|ок. [[5]] года|24.01.41}} → 24 января 41({{padleft:41|4|0}}-{{padleft:1|2|0}}-{{padleft:24|2|0}})
  • {{#invoke:Infocards|dateOfDeath|ок. [[5]] года|{{ДатаСмерти|24|01|41}}}} → 24 января 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 года)}} → 20 января (2 февраля) 1907 (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;

--[[
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', '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.dateOfBirthImpl( dateOfBirth, dateOfDeath, nocat );
end

function infocards.dateOfBirthImpl( dateOfBirth, dateOfDeath, nocat )

    local appendToCategory = infocards.isBlank( nocat );

    if ( infocards.isBlank( dateOfBirth ) ) then
        if ( appendToCategory ) then
            return '[[Категория:Википедия:Персоны без указанной даты рождения]]'
        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 "''неизвестно''[[Категория:Персоналии, чья дата рождения не установлена]]"
        else
            return "''неизвестно''"
        end
    end

    local appendAge = calculateAge and infocards.isBlank( dateOfDeath );

    local parsedDate = infocards.convertToDate ( dateOfBirth )
    if ( parsedDate == nil ) then
        if ( appendToCategory ) then
            return dateOfBirth .. '[[Категория:Википедия:Статьи с ручной викификацией дат в карточке]]'
        else
            return dateOfBirth
        end
    end

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

    if ( appendAge ) then
        local age = infocards.age ( parsedDate,  os.date("*t") )
        if ( age > 0 ) then
            result = result .. ' <span style="white-space:nowrap;">(' .. age .. ' ' .. mw.language.new( 'ru' ):plural( age, 'год', 'года', 'лет') .. ')</span>'
        end
        if ( age > 150 and appendToCategory ) then
            result = result .. '[[Категория:Википедия:Статьи о персоналиях с большим текущим возрастом]]'
        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 "''неизвестно''[[Категория:Персоналии, чья дата смерти не установлена]]"
        else
            return "''неизвестно''"
        end
    end

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

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

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

	if ( calculateAge ) then
		local age = infocards.age ( parsedDateOfBirth, parsedDateOfDeath )
		if ( age > 0 ) then
			result = result .. ' <span style="white-space:nowrap;">(' .. age .. ' ' .. mw.language.new( 'ru' ):plural( age, 'год', 'года', 'лет') .. ')</span>'
		end
		if ( age > 150 and appendToCategory ) then
			result = result .. '[[Категория:Википедия:Статьи о персоналиях с большим возрастом во время смерти]]'
		end
	end

    return result
end

function infocards.age( parsedBirthDate, parsedFinishDate ) 
    if ( parsedBirthDate == nil or parsedFinishDate == nil ) then
        return 0
    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 0
    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 style="white-space:nowrap;">'
    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 style="white-space: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 .. '<span style="display:none">(<span class="' .. infocardClass .. '">{{padleft:' .. ny .. '|4|0}}-{{padleft:' .. nm .. '|2|0}}-{{padleft:' .. nd .. '|2|0}}</span>)</span>'
    elseif (infocardTemplate == "23") then
        datePart = datePart .. '<span style="display:none">(<span class="' .. infocardClass .. '">{{padleft:' .. ny .. '|4|0}}-{{padleft:' .. nm .. '|2|0}}</span>)</span>'
    elseif (infocardTemplate == "3") then
        datePart = datePart .. '<span style="display:none;">(<span class="' .. infocardClass .. '">{{padleft:' .. ny .. '|4|0}}</span>)</span>'
    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