Module:Currency
Appearance
![]() | This Lua module is used on approximately 4,700 pages and changes may be widely noticed. Test changes in the module's /sandbox or /testcases subpages, or in your own module sandbox. Consider discussing changes on the talk page before implementing them. |
Related pages |
---|
This code is invoked from {{Currency}}
. All of the template parameters are passed in the module's frame.
{{#invoke:Currency|currency|<amount>|<code>|<first>|<linked>|<passthrough>}}
See the template code for a description of the parameters.
Other modules may use this code. The entry point for other modules is _render_currency (amount, code, long_form, linked)
. See the function render_currency()
for detail.
The data file Module:Currency/Presentation holds required currency presentation characteristics.
require('Module:No globals')
local getArgs = require('Module:Arguments').getArgs
local p = {}
local presentation ={}; -- table of tales that contain currencty presentation data
--[[--------------------------< I S _ S E T >------------------------------------------------------------------
Whether variable is set or not. A variable is set when it is not nil and not empty.
]]
local function is_set( var )
return not (var == nil or var == '');
end
--[[--------------------------< G R O U P I N G >--------------------------------------------------------------
Takes a number string in the form nnnn.nn and adds grouping to it, return n,nnn.nn
Grouping is added by reversing the digits portion of the value:
123456789.nn
becomes
987654321
Then, string.gsub replaces each group of three digits with the same three digits (the capture) followed by a comma:
987,654,321,
The string is reversed again:
,123,456,789
and the leading comma (if present) is removed:
123,456,789
At the end, the digits and decimal portions are reunited with a decimal point which is returned to calling function.
Unrecognized 'numbers' return '0.00'
]]
local function grouping (val)
local digits; -- left side of the decimal point
local decimals; -- right side of the decimal point
if val:match ('^%d+%.%d+$') then -- has digits and decimals
digits, decimals = val:match ('(%d+)%.(%d+)');
elseif val:match ('^%d+%.$') then -- has digits and decimal point but no decimals
digits = val:match ('(%d+)%.')
elseif val:match ('^%.%d+$') then -- has no digits but has decimal point and decimals
decimals = val:match ('%.(%d+)')
elseif val:match ('^%d+$') then -- just has digits
digits = val;
else
return '0.00'; -- something that isn't a number; return default TODO: error message here
end
if is_set (digits) then
digits = digits:reverse():gsub ('%d%d%d', '%1,'):reverse():gsub('^,', ''); -- apply grouping
else
digits = '0'; -- otherwise set default value
end
if not is_set (decimals) then
decimals = '00'; -- set to default
end
return digits .. '.' .. decimals; -- return formatted value
end
--[[--------------------------< F O R M A T _ C U R R E N C Y >------------------------------------------------
]]
local function format_currency (val, code)
local symbol = string.format ('[[%s|%s]]', presentation.currency_properties[code].page, presentation.currency_properties[code].symbol); -- make wikilink of page and symbol
local position = presentation.currency_properties[code].position;
if 'b' == position then -- choose appropriate format: unspaced before the amount
return string.format ('%s%s', symbol, val);
elseif 'bs' == position then -- spaced before the amount
return string.format ('%s %s', symbol, val);
elseif 'a' == position then -- unspaced after the amount
return string.format ('%s%s', val, symbol);
elseif 'as' == position then -- spaced after the amount
return string.format ('%s %s', val, symbol);
else
return val; -- position not defined TODO: error message here
end
end
--[[--------------------------< P . C U R R E N C Y >----------------------------------------------------------
]]
function p.currency (frame)
local args = getArgs(frame);
local amount, code;
if not tonumber (args[1]) then -- if args[1] can't be converted to a number then error
return '{{currency}} – invalid amount';
end
if nil == args[2] then -- if not provided
args[2] = USD; -- default to USD
else
code = args[2]:upper();
end
presentation = mw.loadData ('Module:Currency/Presentation');
if nil == presentation.currency_properties[code] then
return '{{currency}} – invalid code';
end
amount = grouping (args[1]); -- format the amount
amount = format_currency (amount, code); -- wrap the amount with appropriate symbol
return amount;
end
return p;