Модуль:Infocards
Поделись знанием:
Документация
Внимание! Это один из самых используемых модулей. Каждое его изменение создаёт дополнительную нагрузку на серверы проекта. Пожалуйста, убедитесь в адекватности и правильности ваших изменений, проверьте их на тестовых страницах. |
Прежде, чем вносить какие-либо изменения в данный модуль, просьба оттестировать их в /песочнице и проверить результат на странице с /контрольными примерами. Изменения могут быть внесены после этого в данный модуль всего одной правкой. |
Примеры вызова функции dateOfBirth
- {{#invoke:Infocards|dateOfBirth|-382|−336}} → 382 до н. э.
- {{#invoke:Infocards|dateOfBirth|11.1|}} → 11 января
- {{#invoke:Infocards|dateOfBirth|24.12.3|15.01.69}} → 24 декабря 3
- {{#invoke:Infocards|dateOfBirth|23.09.-63|19.08.14}} → 23 сентября 63 до н. э.
- {{#invoke:Infocards|dateOfBirth|42|9.6.42}} → 42
- {{#invoke:Infocards|dateOfBirth|870|13.8.900}} → 870
- {{#invoke:Infocards|dateOfBirth||22.01.984}} →
- {{#invoke:Infocards|dateOfBirth|16.06.1066|дата смерти неизвестна}} → 16 июня 1066
- {{#invoke:Infocards|dateOfBirth|8.2.1834 (27.1)|2.2.1907 (20.1)}} → 27 января (8 февраля) 1834
- {{#invoke:Infocards|dateOfBirth|29.06.1844 (17)|28.10.1883 (16)}} → 17 (29) июня 1844
- {{#invoke:Infocards|dateOfBirth|19.7.1893 (7)|}} → 7 (19) июля 1893
- {{#invoke:Infocards|dateOfBirth|3.10.1895 (21.9)|28.12.1925}} → 21 сентября (3 октября) 1895
- {{#invoke:Infocards|dateOfBirth|4.10.1916|8.11.2009}} → 4 октября 1916
- {{#invoke:Infocards|dateOfBirth|09.06.1942|}} → 9 июня 1942 (81 год)
- {{#invoke:Infocards|dateOfBirth|1955|}} → 1955
- {{#invoke:Infocards|dateOfBirth|29.02.1984|}} → 29 февраля 1984 (40 лет)
- {{#invoke:Infocards|dateOfBirth||}} →
- {{#invoke:Infocards|dateOfBirth|4.1.1885 (23.12.1884)|17.5.1951}} → 23 декабря 1884 (4 января 1885)
- {{#invoke:Infocards|dateOfBirth|{{ДатаРождения|24|12|3}}|{{ДатаСмерти|15|01|69}}}} → 24 декабря 3
- {{#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
Примеры вызова функции dateOfDeath
- {{#invoke:Infocards|dateOfDeath|-382|−336}} → 336 до н. э.
- {{#invoke:Infocards|dateOfDeath|24.12.3|15.01.69}} → 15 января 69 (65 лет)
- {{#invoke:Infocards|dateOfDeath|23.09.-63|19.08.14}} → 19 августа 14 (76 лет)
- {{#invoke:Infocards|dateOfDeath|42|9.6.42}} → 9 июня 42
- {{#invoke:Infocards|dateOfDeath|870|13.8.900}} → 13 августа 900
- {{#invoke:Infocards|dateOfDeath||22.01.984}} → 22 января 984
- {{#invoke:Infocards|dateOfDeath|16.06.1066|дата смерти неизвестна}} → дата смерти неизвестна
- {{#invoke:Infocards|dateOfDeath|8.2.1834 (27.1)|2.2.1907 (20.1)}} → 20 января (2 февраля) 1907 (72 года)
- {{#invoke:Infocards|dateOfDeath|29.06.1844 (17)|28.10.1883 (16)}} → 16 (28) октября 1883 (39 лет)
- {{#invoke:Infocards|dateOfDeath|19.7.1893 (7)|}} → 14 апреля 1930 (36 лет)
- {{#invoke:Infocards|dateOfDeath|3.10.1895 (21.9)|28.12.1925}} → 28 декабря 1925 (30 лет)
- {{#invoke:Infocards|dateOfDeath|4.10.1916|8.11.2009}} → 8 ноября 2009 (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
- {{#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 -- TODO: месяцы и дни для (нескольких) новорождённых (см. новейшие [[Категория:Родившиеся в ГГГГ году]]) local age = infocards.age ( parsedDate, os.date("*t") ) if ( age and age > 0 and age < 125) then result = result .. ' <span class="nowrap">(' .. age .. ' ' .. mw.language.new( 'ru' ):plural( age, 'год', 'года', 'лет') .. ')</span>' end if ( appendToCategory ) then if ( age and age > 115 ) then result = result .. '[[Категория:Википедия:Статьи о персоналиях с большим текущим возрастом]]' elseif ( age or ( parsedDate and parsedDate.year and os.date('*t').year - parsedDate.year <= 115 ) ) then -- утверждение во вложенных скобках вступает при неточной дате result = result .. '[[Категория:Википедия:Биографии современников]]' 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 "''неизвестно''[[Категория:Персоналии, чья дата смерти не установлена]]" 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 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 ( unixAvailable and os.time() - unixDateOfDeath < 31536000 and appendToCategory ) then result = result .. '[[Категория:Википедия:Персоналии, умершие менее года назад]]' 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 (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