Module:Age: Difference between revisions

Created page with "-- Implement various "age of" and other date-related templates. local mtext = { -- Message and other text that should be localized. -- Also need to localize text in table names in function dateDifference. ['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-s..."
 
No edit summary
 
Line 4: Line 4:
-- Message and other text that should be localized.
-- Message and other text that should be localized.
-- Also need to localize text in table names in function dateDifference.
-- Also need to localize text in table names in function dateDifference.
['mt-bad-param1'] =            'Invalid parameter $1',
['mt-bad-param2'] =            'Parameter $1=$2 is invalid',
['mt-bad-param2'] =            'Parameter $1=$2 is invalid',
['mt-bad-show'] =              'Parameter show=$1 is not supported here',
['mt-bad-show'] =              'Parameter show=$1 is not supported here',
Line 26: Line 25:
['mt-template-bad-name'] =      'The specified template name is not valid',
['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',
['mt-template-x'] =            'The template invoking this must have "|template=x" where x is the wanted operation',
['mt-warn-param1'] =            'Invalid parameter $1',
['mt-warn-param2'] =            'Parameter $1=$2 is invalid',
['txt-affirmative'] =          { y = true, yes = true, Y = true, Yes = true, YES = true },  -- valid values for df + mf parameters
['txt-yes'] =                  { y = true, yes = true, on = true },  -- valid values for parameters introduced with this module
['txt-and'] =                  ' and ',
['txt-and'] =                  ' and ',
['txt-or'] =                    ' or ',
['txt-or'] =                    ' or ',
Line 44: Line 47:


local isWarning = {
local isWarning = {
['mt-bad-param1'] = true,
['mt-warn-param1'] = true,
['mt-warn-param2'] = true,
}
}
-- yes[parameter] is true if parameter should be interpreted as "yes".
-- Do not want to accept mixed upper/lowercase unless done by previously used templates.
-- Need to accept "on" because "round=on" is wanted.
local yes = mtext['txt-yes']


local translate, from_en, to_en, isZero
local translate, from_en, to_en, isZero
Line 116: Line 125:
end
end
return text
return text
end
local function dateFormat(args)
-- Return string for wanted date format.
local default = mtext['txt-format-default']
local other = default == 'df' and 'mf' or 'df'
local wanted = stripToNil(args[other]) and other or default
return wanted == 'df' and mtext['txt-dmy'] or mtext['txt-mdy']
end
end


Line 129: Line 130:
-- Return text after substituting any given parameters for $1, $2, etc.
-- Return text after substituting any given parameters for $1, $2, etc.
return mw.message.newRawMessage(text, ...):plain()
return mw.message.newRawMessage(text, ...):plain()
end
local function yes(parameter)
-- Return true if parameter should be interpreted as "yes".
-- Do not want to accept mixed upper/lowercase unless done by current templates.
-- Need to accept "on" because "round=on" is wanted.
return ({ y = true, yes = true, on = true })[parameter]
end
end


Line 167: Line 161:
b ..
b ..
(category or '')
(category or '')
end
local function dateFormat(args)
-- Return
--    nil, f if parameter is valid
--      m, f    otherwise
-- where
--      m = string for warning message with category
--      f = string for wanted date format
local problem
local wanted = mtext['txt-format-default']
local other = wanted == 'df' and 'mf' or 'df'
local parm = args[other] or ''
if mtext['txt-affirmative'][parm] then
wanted = other
elseif parm ~= '' then
problem = message('mt-warn-param2', other, parm)
end
return problem, wanted == 'df' and mtext['txt-dmy'] or mtext['txt-mdy']
end
end


Line 331: Line 344:
parms[i] = v
parms[i] = v
end
end
if yes(args.fix) then
if yes[args.fix] then
table.insert(parms, 'fix')
table.insert(parms, 'fix')
end
end
if yes(args.partial) then
if yes[args.partial] then
table.insert(parms, 'partial')
table.insert(parms, 'partial')
end
end
Line 729: Line 742:
flag = 'usesCurrent',
flag = 'usesCurrent',
omitZero = true,
omitZero = true,
range = 'no',
range = 'dash',
},
},
age_full_years_nts = {      -- {{age nts}}
age_full_years_nts = {      -- {{age nts}}
Line 753: Line 766:
age_infant = {              -- {{age for infant}}
age_infant = {              -- {{age for infant}}
-- Do not set show because special processing is done later.
-- Do not set show because special processing is done later.
abbr = yes(args.abbr) and 'abbr_infant' or 'abbr_off',
abbr = yes[args.abbr] and 'abbr_infant' or 'abbr_off',
disp = 'disp_age',
disp = 'disp_age',
sep = 'sep_space',
sep = 'sep_space',
Line 816: Line 829:
--    ("on" is equivalent to "yes", and "off" is equivalent to "no").
--    ("on" is equivalent to "yes", and "off" is equivalent to "no").
-- "|range=OTHER" sets range = nil and rejects partial dates.
-- "|range=OTHER" sets range = nil and rejects partial dates.
range = ({ dash = 'dash', off = 'no', no = 'no', [true] = true })[range] or yes(range)
range = ({ dash = 'dash', off = 'no', no = 'no', [true] = true })[range] or yes[range]
if range then
if range then
partial = true  -- accept partial dates with a possible age range for the result
partial = true  -- accept partial dates with a possible age range for the result
Line 826: Line 839:
end
end
local getopt = {
local getopt = {
fix = yes(args.fix),
fix = yes[args.fix],
flag = stripToNil(args.flag) or spec.flag,
flag = stripToNil(args.flag) or spec.flag,
omitZero = spec.omitZero,
omitZero = spec.omitZero,
Line 845: Line 858:
local parms = {
local parms = {
diff = date2:subtract(date1, { fill = autofill }),
diff = date2:subtract(date1, { fill = autofill }),
wantDuration = spec.duration or yes(args.duration),
wantDuration = spec.duration or yes[args.duration],
range = range,
range = range,
wantSc = yes(args.sc),
wantSc = yes[args.sc],
show = args.show == 'hide' and 'hide' or spec.show,
show = args.show == 'hide' and 'hide' or spec.show,
abbr = spec.abbr,
abbr = spec.abbr,
Line 853: Line 866:
extra = makeExtra(args, getopt.usesCurrent and format ~= 'format_raw'),
extra = makeExtra(args, getopt.usesCurrent and format ~= 'format_raw'),
format = format or spec.format,
format = format or spec.format,
round = yes(args.round),
round = yes[args.round],
sep = spec.sep,
sep = spec.sep,
sortable = translateParameters.sortable[args.sortable or spec.sortable],
sortable = translateParameters.sortable[args.sortable or spec.sortable],
Line 862: Line 875:
end
end
return from_en(dateDifference(parms))
return from_en(dateDifference(parms))
end
local function isFake(args)
-- Some templates have TemplateData with an auto value like "{{Birth date and age|YYYY|MM|DD}}".
-- Return true if that appears to be the case so the caller can output nothing rather than an error.
return args[1] == 'YYYY'
end
end


Line 867: Line 886:
-- Implement [[Template:Birth date and age]].
-- Implement [[Template:Birth date and age]].
local args = frame:getParent().args
local args = frame:getParent().args
if isFake(args) then
return ''
end
local options = {
local options = {
missing1 = 'mt-need-valid-bd',
missing1 = 'mt-need-valid-bd',
Line 891: Line 913:
end
end
end
end
local problem, format = dateFormat(args)
local result = substituteParameters(
local result = substituteParameters(
mtext['txt-bda'],
mtext['txt-bda'],
date:text('%-Y-%m-%d'),
date:text('%-Y-%m-%d'),
from_en(date:text(dateFormat(args))),
from_en(date:text(format)),
from_en(dateDifference({
from_en(dateDifference({
diff = diff,
diff = diff,
Line 902: Line 925:
sep = 'sep_space',
sep = 'sep_space',
}))
}))
)
) .. (problem or '')
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 954:
end
end
if invalid then
if invalid then
result = result .. message('mt-bad-param1', invalid)
result = result .. message('mt-warn-param1', invalid)
end
end
end
end
Line 940: Line 963:
-- Implement [[Template:Death date and age]].
-- Implement [[Template:Death date and age]].
local args = frame:getParent().args
local args = frame:getParent().args
if isFake(args) then
return ''
end
local options = {
local options = {
missing1 = 'mt-need-valid-dd',
missing1 = 'mt-need-valid-dd',
Line 969: Line 995:
return message('mt-invalid-dates-age')
return message('mt-invalid-dates-age')
end
end
local fmt_date, fmt_ymd
local fmt_date, fmt_ymd, problem
if date1.day then  -- y, m, d known
if date1.day then  -- y, m, d known
fmt_date = dateFormat(args)
problem, fmt_date = dateFormat(args)
fmt_ymd = '%-Y-%m-%d'
fmt_ymd = '%-Y-%m-%d'
elseif date1.month then  -- y, m known; d unknown
elseif date1.month then  -- y, m known; d unknown
Line 998: Line 1,024:
sep = 'sep_space',
sep = 'sep_space',
}))
}))
)
) .. (problem or '')
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,021: Line 1,047:
end
end
if invalid then
if invalid then
result = result .. message('mt-bad-param1', invalid)
result = result .. message('mt-warn-param1', invalid)
end
end
end
end
Line 1,074: Line 1,100:
local parms = {
local parms = {
extra = makeExtra(args),
extra = makeExtra(args),
wantDuration = yes(args.duration),
wantDuration = yes[args.duration],
range = yes(args.range) or (args.range == 'dash' and 'dash' or nil),
range = yes[args.range] or (args.range == 'dash' and 'dash' or nil),
wantSc = yes(args.sc),
wantSc = yes[args.sc],
}
}
local fix = yes(args.fix) and 'fix' or ''
local fix = yes[args.fix] and 'fix' or ''
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
Line 1,113: Line 1,139:
end
end
return from_en(dateDifference(parms))
return from_en(dateDifference(parms))
end
local function templateGeneric(frame)
local name = frame.args.template
if not name then
return message('mt-template-x')
end
return ageGeneric(frame:newChild{title = mw.title.new(name, 10), args = frame.args})
end
end


Line 1,124: Line 1,158:
JULIANDAY = dateToJd,              -- Template:JULIANDAY
JULIANDAY = dateToJd,              -- Template:JULIANDAY
time_interval = timeInterval,      -- Template:Time_interval
time_interval = timeInterval,      -- Template:Time_interval
[''] = templateGeneric,            -- same as age_generic, but can be invoked directly
}
}