Editing Module:Age
The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then publish the changes below to finish undoing the edit.
Latest revision | Your text | ||
Line 1: | Line 1: | ||
-- Implement various "age of" and other date-related templates. | -- Implement various "age of" and other date-related templates. | ||
local _Date, _currentDate | local _Date, _currentDate | ||
Line 64: | Line 5: | ||
-- Return objects exported from the date module or its sandbox. | -- Return objects exported from the date module or its sandbox. | ||
if not _Date then | if not _Date then | ||
local sandbox = frame:getTitle():find( | local sandbox = frame:getTitle():find('sandbox', 1, true) and '/sandbox' or '' | ||
local datemod = require( | local datemod = require('Module:Date' .. sandbox) | ||
_Date = datemod._Date | |||
_currentDate = datemod._current | _currentDate = datemod._current | ||
end | end | ||
return _Date, _currentDate | return _Date, _currentDate | ||
Line 116: | Line 46: | ||
end | end | ||
return text | return text | ||
end | end | ||
Line 138: | Line 55: | ||
end | end | ||
local function message(msg, | local function message(msg, id) | ||
-- Return formatted message text for an error or warning. | -- Return formatted message text for an error or warning. | ||
local categories = { | local categories = { | ||
error = | error = '[[Category:Age error]]', | ||
warning = | warning = '[[Category:Age error]]', -- same as error until determine whether 'Age warning' would be worthwhile | ||
} | } | ||
local a, b | local a, b, category | ||
if id == 'warning' then | |||
a = '<sup>[<i>' | a = '<sup>[<i>' | ||
b = '</i>]</sup>' | b = '</i>]</sup>' | ||
else | else | ||
a = '<strong class="error">' | a = '<strong class="error">Error: ' | ||
b = '</strong>' | b = '</strong>' | ||
end | end | ||
if mw.title.getCurrentTitle():inNamespaces(0) then | if mw.title.getCurrentTitle():inNamespaces(0) then | ||
-- Category only in namespaces: 0=article. | -- Category only in namespaces: 0=article. | ||
category = | category = categories[id or 'error'] | ||
end | end | ||
return | return | ||
a .. | a .. | ||
mw.text.nowiki( | mw.text.nowiki(msg) .. | ||
b .. | b .. | ||
(category or '') | (category or '') | ||
Line 195: | Line 106: | ||
-- i == 1 for the first number which can optionally start with an uppercase letter. | -- i == 1 for the first number which can optionally start with an uppercase letter. | ||
number = tostring(number) | number = tostring(number) | ||
return require( | return require('Module:ConvertNumeric').spell_number( | ||
number, | number, | ||
nil, -- fraction numerator | nil, -- fraction numerator | ||
Line 212: | Line 123: | ||
if mw.ustring.len(extra) > 1 then | if mw.ustring.len(extra) > 1 then | ||
-- Parameter "~" gives "~3" whereas "over" gives "over 3". | -- Parameter "~" gives "~3" whereas "over" gives "over 3". | ||
extra = extra .. ' ' | |||
end | end | ||
if flagCurrent then | if flagCurrent then | ||
Line 239: | Line 148: | ||
sortKey = string.format('%d', sortKey) .. string.format('%015.0f', math.floor(value * 10^(14-mag))) | sortKey = string.format('%d', sortKey) .. string.format('%015.0f', math.floor(value * 10^(14-mag))) | ||
end | end | ||
local | local lhs, rhs | ||
if sortable == 'sortable_table' then | if sortable == 'sortable_table' then | ||
lhs = 'data-sort-value="' | |||
rhs = '"|' | |||
else | else | ||
lhs = sortable == 'sortable_debug' and | |||
'<span style="border:1px solid;display:inline;" class="sortkey">' or | |||
'<span style="display:none" class="sortkey">' | |||
rhs = '♠</span>' | |||
end | end | ||
return | return lhs .. sortKey .. rhs | ||
end | end | ||
end | end | ||
Line 293: | Line 204: | ||
hm = { 'H', 'M', id = 'hm' }, | hm = { 'H', 'M', id = 'hm' }, | ||
hms = { 'H', 'M', 'S', id = 'hms' }, | hms = { 'H', 'M', 'S', id = 'hms' }, | ||
d = { 'd', id = 'd' }, | d = { 'd', id = 'd' }, | ||
dh = { 'd', 'H', id = 'dh' }, | dh = { 'd', 'H', id = 'dh' }, | ||
Line 343: | Line 252: | ||
return 'error' | return 'error' | ||
end | end | ||
return message(' | return message('Need valid date') | ||
end | end | ||
local add = stripToNil(args.add) | local add = stripToNil(args.add) | ||
Line 350: | Line 259: | ||
date = date + item | date = date + item | ||
if not date then | if not date then | ||
return message(' | return message('Cannot add "' .. item .. '"') | ||
end | end | ||
end | end | ||
Line 363: | Line 272: | ||
result = date[show] | result = date[show] | ||
if result == nil then | if result == nil then | ||
result = | result = 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 = | result = tostring(result) | ||
end | end | ||
end | end | ||
return (sortKey or '' | return (sortKey or '') .. (result or '') | ||
end | end | ||
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 ' or ' | ||
end | end | ||
Line 407: | Line 316: | ||
local name = names[components[i]] | local name = names[components[i]] | ||
if name then | if name then | ||
local plural = names.plural | |||
if not plural or (islist and v[2] or v) == 1 then | |||
plural = '' | |||
end | end | ||
text:add(vstr .. sep .. name) | text:add(vstr .. sep .. name .. plural) | ||
else | else | ||
text:add(vstr) | text:add(vstr) | ||
Line 425: | Line 335: | ||
elseif options.join == 'sep_serialcomma' and text.n > 2 then | elseif options.join == 'sep_serialcomma' and text.n > 2 then | ||
first = ', ' | first = ', ' | ||
last = | last = ', and ' | ||
else | else | ||
first = ', ' | first = ', ' | ||
last = | last = ' and ' | ||
end | end | ||
for i, v in ipairs(text) do | for i, v in ipairs(text) do | ||
Line 458: | Line 368: | ||
-- which have been validated. | -- which have been validated. | ||
local names = { | local names = { | ||
abbr_off = { | abbr_off = { | ||
plural = 's', | |||
sep = ' ', | sep = ' ', | ||
y = | y = 'year', | ||
m = | m = 'month', | ||
w = | w = 'week', | ||
d = | d = 'day', | ||
H = | H = 'hour', | ||
M = | M = 'minute', | ||
S = | S = 'second', | ||
}, | }, | ||
abbr_on = { | abbr_on = { | ||
Line 482: | Line 389: | ||
}, | }, | ||
abbr_infant = { -- for {{age for infant}} | abbr_infant = { -- for {{age for infant}} | ||
plural = 's', | |||
sep = ' ', | sep = ' ', | ||
y = | y = 'yr', | ||
m = | m = 'mo', | ||
w = | w = 'wk', | ||
d = | d = 'day', | ||
H = | H = 'hr', | ||
M = | M = 'min', | ||
S = | S = 'sec', | ||
}, | }, | ||
abbr_raw = {}, | abbr_raw = {}, | ||
Line 570: | Line 478: | ||
(textOptions.suffix or '') | (textOptions.suffix or '') | ||
end | end | ||
return message(' | return message('Parameter show=' .. show.id .. ' is not supported here') | ||
end | end | ||
Line 625: | Line 533: | ||
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 tonumber(fields[i]) == 0 then | ||
fields[i] = nil | fields[i] = nil | ||
getopt.partial = true | getopt.partial = true | ||
Line 644: | Line 552: | ||
for i = 1, nrDates do | for i = 1, nrDates do | ||
local index = i == 1 and 1 or 4 | local index = i == 1 and 1 or 4 | ||
dates[i] = Date(fields[index], fields[index+1], fields[index+2]) | |||
end | end | ||
else | else | ||
Line 681: | Line 578: | ||
end | end | ||
if not dates[1] then | if not dates[1] then | ||
return message(getopt.missing1 or ' | return message(getopt.missing1 or 'Need valid year, month, day') | ||
end | end | ||
if getopt.single then | if getopt.single then | ||
Line 687: | Line 584: | ||
end | end | ||
if not dates[2] then | if not dates[2] then | ||
return message(getopt.missing2 or ' | return message(getopt.missing2 or 'Second date should be year, month, day') | ||
end | end | ||
return dates[1], dates[2] | return dates[1], dates[2] | ||
Line 698: | Line 595: | ||
local name = frame.args.template | local name = frame.args.template | ||
if not name then | if not name then | ||
return message(' | return message('The template invoking this must have "|template=x" where x is the wanted operation') | ||
end | end | ||
local args = frame:getParent().args | local args = frame:getParent().args | ||
Line 795: | Line 692: | ||
local spec = specs[name] | local spec = specs[name] | ||
if not spec then | if not spec then | ||
return message(' | return message('The specified template name is not valid') | ||
end | end | ||
if name == 'age_days' then | if name == 'age_days' then | ||
Line 859: | Line 756: | ||
} | } | ||
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('The second date should not be before the first date') | ||
end | end | ||
return | return dateDifference(parms) | ||
end | end | ||
Line 868: | Line 765: | ||
local args = frame:getParent().args | local args = frame:getParent().args | ||
local options = { | local options = { | ||
missing1 = ' | missing1 = 'Need valid birth date: year, month, day', | ||
noMissing = true, | noMissing = true, | ||
single = true, | single = true, | ||
Line 879: | Line 776: | ||
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('Invalid birth date for calculating age') | ||
end | end | ||
local disp = | local disp, show = 'disp_raw', 'y' | ||
if diff.years < 2 then | if diff.years < 2 then | ||
disp = 'disp_age' | disp = 'disp_age' | ||
Line 891: | Line 787: | ||
end | end | ||
end | end | ||
local result = | local df = stripToNil(args.df) -- day first (dmy); default is month first (mdy) | ||
local result = df and | |||
'%-d %B %-Y' or | |||
'%B %-d, %-Y' | |||
result = '(<span class="bday">%-Y-%m-%d</span>) </span>' .. result | |||
result = '<span style="display:none"> ' .. | |||
date:text(result) .. | |||
'<span class="noprint ForceAgeToShow"> ' .. | |||
'(age ' .. | |||
dateDifference({ | |||
diff = diff, | diff = diff, | ||
show = show, | show = show, | ||
Line 901: | Line 802: | ||
disp = disp, | disp = disp, | ||
sep = 'sep_space', | sep = 'sep_space', | ||
}) | }) .. | ||
')</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 931: | Line 832: | ||
end | end | ||
if invalid then | if invalid then | ||
result = result .. message(' | result = result .. message('invalid parameter ' .. invalid, 'warning') | ||
end | end | ||
end | end | ||
Line 941: | Line 842: | ||
local args = frame:getParent().args | local args = frame:getParent().args | ||
local options = { | local options = { | ||
missing1 = ' | missing1 = 'Need valid death date (first date): year, month, day', | ||
missing2 = ' | missing2 = 'Need valid birth date (second date): year, month, day', | ||
noMissing = true, | noMissing = true, | ||
partial = true, | partial = true, | ||
Line 952: | Line 853: | ||
local diff = date1 - date2 | local diff = date1 - date2 | ||
if diff.isnegative then | if diff.isnegative then | ||
return message(' | return message('Death date (first date) must occur after birth date (second date)') | ||
end | end | ||
local years | local years | ||
Line 967: | Line 863: | ||
end | end | ||
if years > 150 then | if years > 150 then | ||
return message(' | return message('Invalid dates for calculating age') | ||
end | end | ||
local | local df = stripToNil(args.df) -- day first (dmy); default is month first (mdy) | ||
local result | |||
if date1.day then -- y, m, d known | if date1.day then -- y, m, d known | ||
result = (df and | |||
'%-d %B %-Y' or | |||
'%B %-d, %-Y') .. | |||
'<span style="display:none">(%-Y-%m-%d)</span>' | |||
elseif date1.month then -- y, m known; d unknown | elseif date1.month then -- y, m known; d unknown | ||
result = | |||
'%B %-Y' .. | |||
'<span style="display:none">(%-Y-%m-00)</span>' | |||
else -- y known; m, d unknown | else -- y known; m, d unknown | ||
result = | |||
'%-Y' .. | |||
'<span style="display:none">(%-Y-00-00)</span>' | |||
end | end | ||
result = date1:text(result) .. | |||
' (aged ' .. | |||
dateDifference({ | |||
diff = diff, | diff = diff, | ||
show = 'y', | show = 'y', | ||
abbr = 'abbr_off', | abbr = 'abbr_off', | ||
disp = | disp = 'disp_raw', | ||
range = 'dash', | range = 'dash', | ||
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 1,015: | Line 914: | ||
end | end | ||
if invalid then | if invalid then | ||
result = result .. message(' | result = result .. message('invalid parameter ' .. invalid, 'warning') | ||
end | end | ||
end | end | ||
Line 1,041: | Line 940: | ||
local date = Date('juliandate', args[1], args[2]) | local date = Date('juliandate', args[1], args[2]) | ||
if date then | if date then | ||
return | return date:text() | ||
end | end | ||
return message(' | return message('Need valid Julian date number') | ||
end | end | ||
Line 1,056: | Line 955: | ||
return tostring(date.jd) | return tostring(date.jd) | ||
end | end | ||
return message(' | return message('Need valid year/month/day or "currentdate"') | ||
end | end | ||
Line 1,075: | Line 974: | ||
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('Invalid start date in first parameter') | ||
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('Invalid end date in second parameter') | ||
end | end | ||
parms.diff = date2 - date1 | parms.diff = date2 - date1 | ||
Line 1,087: | Line 986: | ||
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('Parameter ' .. argname .. '=' .. args[argname] .. ' is invalid') | ||
end | end | ||
parms[argname] = parm | parms[argname] = parm | ||
Line 1,098: | Line 997: | ||
if show then | if show then | ||
if show.id ~= round then | if show.id ~= round then | ||
return message(' | return message('Parameter show=' .. args.show .. ' conflicts with round=' .. args.round) | ||
end | end | ||
else | else | ||
Line 1,106: | Line 1,005: | ||
parms.round = true | parms.round = true | ||
end | end | ||
return | return dateDifference(parms) | ||
end | end | ||