local p = {}
local getArgs = require('Module:Arguments').getArgs
local mm = require('Module:Math')
local yesno = require('Module:Yesno')
local lang = mw.getContentLanguage()
local currentyear = tonumber(os.date('%Y'))
local function formatnum(num)
return lang:parseFormattedNumber(num) and lang:formatNum(lang:parseFormattedNumber(num)) or num
end
local function moduleExists(t)
return package.loaded[t] or package.loaders[1](t) or package.loaders[2](t) or false
end
local function checkYearRangeForError(index, argstartyear, argendyear, datastartyear, dataendyear)
local errorParams = {}
local msg
if argstartyear < datastartyear then
msg = "{{para|start_year|'''" .. argstartyear
.. "'''}} (parameter 3) is lower than the earliest available year ('''" .. datastartyear .. "''')"
.. " in index \"'''" .. index .. "'''\""
table.insert(errorParams, msg)
end
if argstartyear > argendyear then
if argstartyear ~= currentyear then
msg = "{{para|start_year|'''" .. argstartyear .. "'''}} (parameter 3) is greater than "
-- ToDo Fix
.. "{{para|end_year|'''" .. argendyear .. "'''}} (parameter 4) "
.. "the latest available year ('''" .. dataendyear .. "''') in index \"'''" .. index .. "'''\""
table.insert(errorParams, msg)
end
end
-- 4c: [parameter 4/end_year] greater than [parameter 1/index] highest year
if argendyear > dataendyear then
msg = "{{para|end_year|'''" .. argendyear
.. "'''}} (parameter 4) is greater than the latest available year ('''" .. dataendyear .. "''') "
.. "in index \"'''" .. index .. "'''\""
table.insert(errorParams, msg)
end
if next(errorParams) ~= nil then
return mw.text.listToText(errorParams, ', & #32;', '  and  ') .. '.'
end
return nil
end
function p._parse(index, value, startyear, endyear, round)
local dataset = mw.loadData('Module:Inflation/' .. index)
-- Dataset is not properly configured
if dataset.data == nil or dataset['start_year'] == nil or dataset.default == nil then
return {inflatedValue = nil, endyear = nil, error = 'error'}
end
startyear = tonumber(startyear)
if endyear ~= nil then
endyear = tonumber(endyear)
else
endyear = tonumber(dataset.default)
end
-- Check if a parameter is out of calculable bounds
local er = checkYearRangeForError(index, startyear, endyear, dataset['start_year'], dataset.default)
if er ~= nil then
return {inflatedValue = nil, endyear = nil, error = er}
end
-- ToDo Throw error
-- dataset.data[dataset.default]
local m
if currentyear == startyear then
m = 1
else
m = mm._divide(dataset.data[endyear], dataset.data[startyear])
end
inflatedValue = lang:parseFormattedNumber(value) * m
inflatedValue = mm._round(inflatedValue, round)
return {inflatedValue = inflatedValue, endyear = endyear, error = nil}
end
local function checkForError(index, value, startyear, endyear, round)
-- Check if required parameters are set
local errorParams = {}
if not index then
table.insert(errorParams, '{{para|index}} (parameter 1)')
end
if not value then
table.insert(errorParams, '{{para|value}} (parameter 2)')
end
if not startyear then
table.insert(errorParams, '{{para|start_year}} (parameter 3)')
end
if next(errorParams) ~= nil then
return mw.text.listToText(errorParams, ', & #32;', '  and  ') .. 'must be specified.'
end
-- Check if dataset exists
if not moduleExists('Module:Inflation/' .. index) then
return "{{para|index|'''" .. index .. "'''}} (parameter 1) not a recognized index."
end
-- Check if numeric parameters have non-numeric data
errorParams = {}
if lang:parseFormattedNumber(value) == nil then
table.insert(errorParams, "{{para|value|'''" .. value .. "'''}} (parameter 2)")
end
if lang:parseFormattedNumber(startyear) == nil then
table.insert(errorParams, "{{para|start_year|'''" .. startyear .. "'''}} (parameter 3)")
end
if lang:parseFormattedNumber(endyear) == nil then
table.insert(errorParams, "{{para|end_year|'''" .. endyear .. "'''}} (parameter 4)")
end
if lang:parseFormattedNumber(round) == nil then
table.insert(errorParams, "{{para|r|'''" .. round .. "'''}}")
end
if next(errorParams) ~= nil then
return '[[NaN]], check parameters for non-numeric data:'
.. mw.text.listToText(errorParams, ', & #32;', '  and  ')
.. '.'
end
return nil
end
local function formatResult(originalValue, endyear, inflatedValue, fmt, cursign, orig)
local result = inflatedValue
if fmt == 'eq' then
result = 'equivalent to ' .. cursign .. formatnum(inflatedValue) .. ' in '
if currentyear == startyear then
result = result .. currentyear
else
result = result .. endyear
end
if orig then
result = cursign .. originalValue .. ' (' .. result .. ')'
end
end
if fmt == 'c' then
result = formatnum(inflatedValue)
end
return result
end
local function formatError(er, nocat)
er = "<span class=\"error\">Error when using {{tl|'''Inflation'''}}: " .. er .. "</span>"
if not nocat then
er = er .. '{{main other|[[Category:Pages with errors in inflation template]]}}'
end
return er
end
function p.main(frame)
local args = getArgs(frame)
if not frame then frame = mw.getCurrentFrame() end
local index = args[1] or args.index --or frame:getParent().args[1] or frame:getParent().args.index
local value = args[2] or args.value --or frame:getParent().args[2] or frame:getParent().args.value
local startyear = args[3] or args['start_year'] --or frame:getParent().args[3] or frame:getParent().args['start_year']
local endyear = args[4] or args['end_year'] --or frame:getParent().args[4] or frame:getParent().args['end_year']
local round = args.r or 0
local fmt = args.fmt or 'raw'
local orig = yesno(args.orig) or false
local cursign = args.cursign or '$'
local nocat = yesno(args.nocat) or false
local error = checkForError(index, value, startyear, endyear, round)
if error ~= nil then
return frame:preprocess(formatError(error, nocat))
end
local parsed = p._parse(index, value, startyear, endyear, round)
if parsed.error ~= nil then
return frame:preprocess(formatError(parsed.error, nocat))
end
return formatResult(value, parsed.endyear, parsed.inflatedValue, fmt, cursign, orig)
end
return p