Module:Age: Difference between revisions
fix message per Template talk:Death date and age#confusing error message and update from i18n for bn:Module:বয়স
(update from sandbox: implement Template:Death date and age) |
(fix message per Template talk:Death date and age#confusing error message and update from i18n for bn:Module:বয়স) |
||
Line 1: | Line 1: | ||
-- Implement various "age of" and other date-related templates. | -- Implement various "age of" and other date-related templates. | ||
local mtext = { | |||
-- Message and other text that should be localized. | |||
['mt-bad-param1'] = 'Invalid parameter $1', | |||
['mt-bad-param2'] = 'Parameter $1=$2 is invalid', | |||
['mt-bad-show'] = 'Parameter show=$1 is not supported here', | |||
['mt-cannot-add'] = 'Cannot add "$1"', | |||
['mt-conflicting-show'] = 'Parameter show=$1 conflicts with round=$2', | |||
['mt-date-wrong-order'] = 'The second date must be later in time than the first date', | |||
['mt-dd-wrong-order'] = 'Death date (first date) must be later in time than the birth date (second date)', | |||
['mt-invalid-bd-age'] = 'Invalid birth date for calculating age', | |||
['mt-invalid-dates-age'] = 'Invalid dates for calculating age', | |||
['mt-invalid-end'] = 'Invalid end date in second parameter', | |||
['mt-invalid-start'] = 'Invalid start date in first parameter', | |||
['mt-need-jdn'] = 'Need valid Julian date number', | |||
['mt-need-valid-bd'] = 'Need valid birth date: year, month, day', | |||
['mt-need-valid-bd2'] = 'Need valid birth date (second date): year, month, day', | |||
['mt-need-valid-date'] = 'Need valid date', | |||
['mt-need-valid-dd'] = 'Need valid death date (first date): year, month, day', | |||
['mt-need-valid-ymd'] = 'Need valid year, month, day', | |||
['mt-need-valid-ymd-current'] = 'Need valid year|month|day or "currentdate"', | |||
['mt-need-valid-ymd2'] = 'Second date should be year, month, day', | |||
['mt-template-bad-name'] = 'The specified template name is not valid', | |||
['mt-template-x'] = 'The template invoking this must have "|template=x" where x is the wanted operation', | |||
['txt-age'] = '(age ', | |||
['txt-aged'] = ' (aged ', | |||
['txt-and'] = ' and ', | |||
['txt-comma-and'] = ', and ', | |||
['txt-error'] = 'Error: ', | |||
['txt-or'] = ' or ', | |||
} | |||
local translate, from_en, to_en, isZero | |||
if translate then | |||
-- Functions to translate from en to local language and reverse go here. | |||
-- See example at [[:bn:Module:বয়স]]. | |||
else | |||
from_en = function (text) | |||
return text | |||
end | |||
isZero = function (text) | |||
return tonumber(text) == 0 | |||
end | |||
end | |||
local _Date, _currentDate | local _Date, _currentDate | ||
Line 7: | Line 51: | ||
local sandbox = frame:getTitle():find('sandbox', 1, true) and '/sandbox' or '' | local sandbox = frame:getTitle():find('sandbox', 1, true) and '/sandbox' or '' | ||
local datemod = require('Module:Date' .. sandbox) | local datemod = require('Module:Date' .. sandbox) | ||
local realDate = datemod._Date | |||
_currentDate = datemod._current | _currentDate = datemod._current | ||
if to_en then | |||
_Date = function (...) | |||
local args = {} | |||
for i, v in ipairs({...}) do | |||
args[i] = to_en(v) | |||
end | |||
return realDate(unpack(args)) | |||
end | |||
else | |||
_Date = realDate | |||
end | |||
end | end | ||
return _Date, _currentDate | return _Date, _currentDate | ||
Line 57: | Line 112: | ||
local function message(msg, id) | local function message(msg, id) | ||
-- Return formatted message text for an error or warning. | -- Return formatted message text for an error or warning. | ||
local function getText(msg) | |||
return mtext[msg] or error('Bug: message "' .. tostring(msg) .. '" not defined') | |||
end | |||
local text | |||
if type(msg) == 'table' then | |||
text = getText(msg[1]) | |||
local rep = {} | |||
for i, v in ipairs(msg) do | |||
if i > 1 then | |||
rep['$' .. (i - 1)] = v | |||
end | |||
end | |||
text = text:gsub('$%d+', rep) | |||
else | |||
text = getText(msg) | |||
end | |||
local categories = { | local categories = { | ||
error = '[[Category:Age error]]', | error = '[[Category:Age error]]', | ||
Line 66: | Line 137: | ||
b = '</i>]</sup>' | b = '</i>]</sup>' | ||
else | else | ||
a = '<strong class="error"> | a = '<strong class="error">' .. getText('txt-error') | ||
b = '</strong>' | b = '</strong>' | ||
end | end | ||
Line 75: | Line 146: | ||
return | return | ||
a .. | a .. | ||
mw.text.nowiki( | mw.text.nowiki(text) .. | ||
b .. | b .. | ||
(category or '') | (category or '') | ||
Line 252: | Line 323: | ||
return 'error' | return 'error' | ||
end | end | ||
return message(' | return message('mt-need-valid-date') | ||
end | end | ||
local add = stripToNil(args.add) | local add = stripToNil(args.add) | ||
Line 259: | Line 330: | ||
date = date + item | date = date + item | ||
if not date then | if not date then | ||
return message(' | return message({ 'mt-cannot-add', item }) | ||
end | end | ||
end | end | ||
Line 272: | Line 343: | ||
result = date[show] | result = date[show] | ||
if result == nil then | if result == nil then | ||
result = date:text(show) | result = from_en(date:text(show)) | ||
elseif type(result) == 'boolean' then | elseif type(result) == 'boolean' then | ||
result = result and '1' or '0' | result = result and '1' or '0' | ||
else | else | ||
result = tostring(result) | result = from_en(tostring(result)) | ||
end | end | ||
end | end | ||
Line 284: | Line 355: | ||
local function rangeJoin(range) | local function rangeJoin(range) | ||
-- Return text to be used between a range of ages. | -- Return text to be used between a range of ages. | ||
return range == 'dash' and '–' or ' | return range == 'dash' and '–' or mtext['txt-or'] | ||
end | end | ||
Line 335: | Line 406: | ||
elseif options.join == 'sep_serialcomma' and text.n > 2 then | elseif options.join == 'sep_serialcomma' and text.n > 2 then | ||
first = ', ' | first = ', ' | ||
last = ' | last = mtext['txt-comma-and'] | ||
else | else | ||
first = ', ' | first = ', ' | ||
last = ' and ' | last = mtext['txt-and'] | ||
end | end | ||
for i, v in ipairs(text) do | for i, v in ipairs(text) do | ||
Line 478: | Line 549: | ||
(textOptions.suffix or '') | (textOptions.suffix or '') | ||
end | end | ||
return message(' | return message({ 'mt-bad-show', show.id }) | ||
end | end | ||
Line 533: | Line 604: | ||
end | end | ||
if getopt.omitZero and i % 3 ~= 1 then -- omit zero months and days as unknown values but keep year 0 which is 1 BCE | if getopt.omitZero and i % 3 ~= 1 then -- omit zero months and days as unknown values but keep year 0 which is 1 BCE | ||
if | if isZero(fields[i]) then | ||
fields[i] = nil | fields[i] = nil | ||
getopt.partial = true | getopt.partial = true | ||
Line 578: | Line 649: | ||
end | end | ||
if not dates[1] then | if not dates[1] then | ||
return message(getopt.missing1 or ' | return message(getopt.missing1 or 'mt-need-valid-ymd') | ||
end | end | ||
if getopt.single then | if getopt.single then | ||
Line 584: | Line 655: | ||
end | end | ||
if not dates[2] then | if not dates[2] then | ||
return message(getopt.missing2 or ' | return message(getopt.missing2 or 'mt-need-valid-ymd2') | ||
end | end | ||
return dates[1], dates[2] | return dates[1], dates[2] | ||
Line 595: | Line 666: | ||
local name = frame.args.template | local name = frame.args.template | ||
if not name then | if not name then | ||
return message(' | return message('mt-template-x') | ||
end | end | ||
local args = frame:getParent().args | local args = frame:getParent().args | ||
Line 692: | Line 763: | ||
local spec = specs[name] | local spec = specs[name] | ||
if not spec then | if not spec then | ||
return message(' | return message('mt-template-bad-name') | ||
end | end | ||
if name == 'age_days' then | if name == 'age_days' then | ||
Line 756: | Line 827: | ||
} | } | ||
if (spec.negative or frame.args.negative) == 'error' and parms.diff.isnegative then | if (spec.negative or frame.args.negative) == 'error' and parms.diff.isnegative then | ||
return message(' | return message('mt-date-wrong-order') | ||
end | end | ||
return dateDifference(parms) | return from_en(dateDifference(parms)) | ||
end | end | ||
Line 765: | Line 836: | ||
local args = frame:getParent().args | local args = frame:getParent().args | ||
local options = { | local options = { | ||
missing1 = ' | missing1 = 'mt-need-valid-bd', | ||
noMissing = true, | noMissing = true, | ||
single = true, | single = true, | ||
Line 776: | Line 847: | ||
local diff = Date('currentdate') - date | local diff = Date('currentdate') - date | ||
if diff.isnegative or diff.years > 150 then | if diff.isnegative or diff.years > 150 then | ||
return message(' | return message('mt-invalid-bd-age') | ||
end | end | ||
local disp, show = 'disp_raw', 'y' | local disp, show = 'disp_raw', 'y' | ||
Line 788: | Line 859: | ||
end | end | ||
local df = stripToNil(args.df) -- day first (dmy); default is month first (mdy) | local df = stripToNil(args.df) -- day first (dmy); default is month first (mdy) | ||
local | local result = '(<span class="bday">%-Y-%m-%d</span>) </span>' .. | ||
(df and '%-d %B %-Y' or '%B %-d, %-Y') | |||
result = from_en('<span style="display:none"> ' .. | |||
result = '<span style="display:none"> ' .. | |||
date:text(result) .. | date:text(result) .. | ||
'<span class="noprint ForceAgeToShow"> ' .. | '<span class="noprint ForceAgeToShow"> ' .. | ||
' | mtext['txt-age'] .. | ||
dateDifference({ | dateDifference({ | ||
diff = diff, | diff = diff, | ||
Line 803: | Line 872: | ||
sep = 'sep_space', | sep = 'sep_space', | ||
}) .. | }) .. | ||
')</span>' | ')</span>') | ||
local warnings = tonumber(frame.args.warnings) | local warnings = tonumber(frame.args.warnings) | ||
if warnings and warnings > 0 then | if warnings and warnings > 0 then | ||
Line 832: | Line 901: | ||
end | end | ||
if invalid then | if invalid then | ||
result = result .. message(' | result = result .. message({ 'mt-bad-param1', invalid }, 'warning') | ||
end | end | ||
end | end | ||
Line 842: | Line 911: | ||
local args = frame:getParent().args | local args = frame:getParent().args | ||
local options = { | local options = { | ||
missing1 = ' | missing1 = 'mt-need-valid-dd', | ||
missing2 = ' | missing2 = 'mt-need-valid-bd2', | ||
noMissing = true, | noMissing = true, | ||
partial = true, | partial = true, | ||
Line 853: | Line 922: | ||
local diff = date1 - date2 | local diff = date1 - date2 | ||
if diff.isnegative then | if diff.isnegative then | ||
return message(' | return message('mt-dd-wrong-order') | ||
end | end | ||
local years | local years | ||
Line 863: | Line 932: | ||
end | end | ||
if years > 150 then | if years > 150 then | ||
return message(' | return message('mt-invalid-dates-age') | ||
end | end | ||
local df = stripToNil(args.df) -- day first (dmy); default is month first (mdy) | local df = stripToNil(args.df) -- day first (dmy); default is month first (mdy) | ||
Line 881: | Line 950: | ||
'<span style="display:none">(%-Y-00-00)</span>' | '<span style="display:none">(%-Y-00-00)</span>' | ||
end | end | ||
result = date1:text(result) .. | result = from_en(date1:text(result) .. | ||
' | mtext['txt-aged'] .. | ||
dateDifference({ | dateDifference({ | ||
diff = diff, | diff = diff, | ||
Line 891: | Line 960: | ||
sep = 'sep_space', | sep = 'sep_space', | ||
}) .. | }) .. | ||
')' | ')') | ||
local warnings = tonumber(frame.args.warnings) | local warnings = tonumber(frame.args.warnings) | ||
if warnings and warnings > 0 then | if warnings and warnings > 0 then | ||
Line 914: | Line 983: | ||
end | end | ||
if invalid then | if invalid then | ||
result = result .. message(' | result = result .. message({ 'mt-bad-param1', invalid }, 'warning') | ||
end | end | ||
end | end | ||
Line 940: | Line 1,009: | ||
local date = Date('juliandate', args[1], args[2]) | local date = Date('juliandate', args[1], args[2]) | ||
if date then | if date then | ||
return date:text() | return from_en(date:text()) | ||
end | end | ||
return message(' | return message('mt-need-jdn') | ||
end | end | ||
Line 955: | Line 1,024: | ||
return tostring(date.jd) | return tostring(date.jd) | ||
end | end | ||
return message(' | return message('mt-need-valid-ymd-current') | ||
end | end | ||
Line 974: | Line 1,043: | ||
local date1 = Date(fix, 'partial', stripToNil(args[1]) or 'currentdatetime') | local date1 = Date(fix, 'partial', stripToNil(args[1]) or 'currentdatetime') | ||
if not date1 then | if not date1 then | ||
return message(' | return message('mt-invalid-start') | ||
end | end | ||
local date2 = Date(fix, 'partial', stripToNil(args[2]) or 'currentdatetime') | local date2 = Date(fix, 'partial', stripToNil(args[2]) or 'currentdatetime') | ||
if not date2 then | if not date2 then | ||
return message(' | return message('mt-invalid-end') | ||
end | end | ||
parms.diff = date2 - date1 | parms.diff = date2 - date1 | ||
Line 986: | Line 1,055: | ||
parm = translate[parm] | parm = translate[parm] | ||
if parm == nil then -- test for nil because false is a valid setting | if parm == nil then -- test for nil because false is a valid setting | ||
return message(' | return message({ 'mt-bad-param2', argname, args[argname] }) | ||
end | end | ||
parms[argname] = parm | parms[argname] = parm | ||
Line 997: | Line 1,066: | ||
if show then | if show then | ||
if show.id ~= round then | if show.id ~= round then | ||
return message(' | return message({ 'mt-conflicting-show', args.show, args.round }) | ||
end | end | ||
else | else | ||
Line 1,005: | Line 1,074: | ||
parms.round = true | parms.round = true | ||
end | end | ||
return dateDifference(parms) | return from_en(dateDifference(parms)) | ||
end | end | ||