Difference between revisions of "Module:Currency"

From blackwiki
Jump to navigation Jump to search
blackwiki>Trappist the monk
blackwiki>Trappist the monk
Line 24: Line 24:
 
]]
 
]]
  
local function make_short_form_name (amount, code)
+
local function make_short_form_name (amount, code, linked)
 
local symbol;
 
local symbol;
local position;
+
local position = properties[code].position;
-- local properties;
 
-- if presentation.currency_properties[code] then
 
-- properties = presentation.currency_properties;
 
-- elseif presentation.non_standard_properties[code] then
 
-- properties = presentation.non_standard_properties;
 
-- else
 
-- return '<span style="font-size:inherit" class="error">{{currency}} – cannot find code: ' .. code .. '</span>'; -- should not be here
 
-- end
 
  
local symbol = string.format ('[[%s|%s]]', properties[code].page, properties[code].symbol); -- make wikilink of page and symbol
+
if linked then
local position = properties[code].position;
+
symbol = string.format ('[[%s|%s]]', properties[code].page, properties[code].symbol); -- make wikilink of page and symbol
 +
else
 +
symbol = properties[code].symbol;
 +
end
  
 
 
amount = lang:formatNum (tonumber(amount));
 
amount = lang:formatNum (tonumber(amount));
  
Line 63: Line 57:
 
end
 
end
 
return amount .. ' <span style="font-size:inherit" class="error">{{currency}} – definition missing position</span>'; -- position not defined
 
return amount .. ' <span style="font-size:inherit" class="error">{{currency}} – definition missing position</span>'; -- position not defined
 +
end
 +
 +
 +
--[[--------------------------< M A K E _ N A M E >----------------------------------------------------------
 +
 +
Make a wikilink from the currency's article title and its plural (if provided).  If linked is false, returns only
 +
the article title (unlinked)
 +
 +
]]
 +
 +
local function make_name (linked, page, plural)
 +
if not linked then
 +
if not is_set (plural) then
 +
return page; -- just the page
 +
elseif 's' == plural then -- if the simple plural form
 +
return string.format ('%ss', page); -- append an 's'
 +
else
 +
return plural; -- must be the complex plural form (pounds sterling v. dollars)
 +
end
 +
else
 +
if not is_set (plural) then
 +
return string.format ('[[%s]]', page);
 +
elseif 's' == plural then -- if the simple plural form
 +
return string.format ('[[%s]]s', page);
 +
else
 +
return string.format ('[[%s|%s]]', page, plural); -- must be the complex plural form (pounds sterling v. dollars)
 +
end
 +
end
 
end
 
end
  
Line 72: Line 94:
 
]]
 
]]
  
local function make_long_form_name (amount, code)
+
local function make_long_form_name (amount, code, linked)
-- local properties;
 
 
local name;
 
local name;
 
-- if presentation.currency_properties[code] then
 
-- properties = presentation.currency_properties;
 
-- elseif presentation.non_standard_properties[code] then
 
-- properties = presentation.non_standard_properties;
 
-- else
 
-- return '<span style="font-size:inherit" class="error">{{currency}} – cannot find code: ' .. code .. '</span>'; -- should not be here
 
-- end
 
 
 
 
if not is_set (properties[code].page) then
 
if not is_set (properties[code].page) then
Line 91: Line 104:
 
 
 
if 1 == amount then
 
if 1 == amount then
name = string.format ('[[%s]]', properties[code].page); -- the singular form
+
name = make_name (linked, properties[code].page); -- the singular form
elseif 's' == properties[code].plural then
+
elseif is_set (properties[code].plural) then -- plural and there is a plural form
name = string.format ('[[%s]]s', properties[code].page); -- a plural form
+
name = make_name (linked, properties[code].page, properties[code].plural);
elseif is_set (properties[code].plural) then -- plural is not an 's' form
 
name = string.format ('[[%s|%s]]', properties[code].page, properties[code].plural); -- another plural form (pounds sterling v. dollars)
 
 
else
 
else
name = string.format ('[[%s]]', properties[code].page); -- no plural form so use the singular form
+
name = make_name (linked, properties[code].page); -- plural but no separate plural form so use the singular form
 
end
 
end
  
Line 113: Line 124:
 
]]
 
]]
  
local function render_currency (amount, code, long_form)
+
local function render_currency (amount, code, long_form, linked)
 
local name;
 
local name;
 
local ouput;
 
local ouput;
  
 
presentation = mw.loadData ('Module:Currency/Presentation'); -- get presentation data
 
presentation = mw.loadData ('Module:Currency/Presentation'); -- get presentation data
 
-- if nil == presentation.currency_properties[code] then -- if not an iso 4217 code
 
-- if presentation.code_translation[code] then -- but can be translated
 
-- code = presentation.code_translation[code]; -- then translate
 
-- elseif nil == presentation.non_standard_properties[code] then -- last chance, is it a non-standard code?
 
-- return '<span style="font-size:inherit" class="error">{{currency}} – invalid code</span>';
 
-- end
 
-- end
 
  
if presentation.currency_properties[code] then -- if not an iso 4217 code
+
if presentation.currency_properties[code] then -- if code is an iso 4217 code
 
properties = presentation.currency_properties;
 
properties = presentation.currency_properties;
elseif presentation.code_translation[code] then -- but can be translated
+
elseif presentation.code_translation[code] then -- not iso 4217 but can be translated
 
code = presentation.code_translation[code]; -- then translate
 
code = presentation.code_translation[code]; -- then translate
 
properties = presentation.currency_properties;
 
properties = presentation.currency_properties;
Line 137: Line 140:
 
return '<span style="font-size:inherit" class="error">{{currency}} – invalid code</span>';
 
return '<span style="font-size:inherit" class="error">{{currency}} – invalid code</span>';
 
end
 
end
 
 
  
 
if long_form then
 
if long_form then
return make_long_form_name (amount, code); --  
+
return make_long_form_name (amount, code, linked); --  
 
else
 
else
return make_short_form_name (amount, code);
+
return make_short_form_name (amount, code, linked);
 
end
 
end
  
Line 164: Line 165:
 
local amount, code;
 
local amount, code;
 
local long_form = false;
 
local long_form = false;
 +
local linked = true;
  
 
amount = lang:parseFormattedNumber(args[1]); -- if args[1] can't be converted to a number then error (this just strips grouping characters)
 
amount = lang:parseFormattedNumber(args[1]); -- if args[1] can't be converted to a number then error (this just strips grouping characters)
Line 180: Line 182:
 
end
 
end
 
 
return render_currency (amount, code, long_form)
+
if 'no' == args[4] then -- this is the |linked= parameter; defaults to 'yes'; any value but 'no' means yes
 +
linked = false;
 +
end
 +
 +
return render_currency (amount, code, long_form, linked)
 
end
 
end
  

Revision as of 20:19, 10 April 2016

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 p = {}
local lang = mw.language.getContentLanguage();									-- language object for this wiki
local presentation ={};															-- table of tables that contain currency presentation data
local properties;


--[[--------------------------< 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


--[[--------------------------< M A K E _ S H O R T _ F O R M  _ N A M E >-------------------------------------

Assembles value and symbol according to the order specified in the properties table for this currency code

]]

local function make_short_form_name (amount, code, linked)
	local symbol;
	local position = properties[code].position;

	if linked then
		symbol = string.format ('[[%s|%s]]', properties[code].page, properties[code].symbol);	-- make wikilink of page and symbol
	else
		symbol = properties[code].symbol;
	end

	amount = lang:formatNum (tonumber(amount));

	if 'b' == position then														-- choose appropriate format: unspaced before the amount
		return string.format ('%s%s', symbol, amount);
	elseif 'bs' == position then												-- spaced before the amount
		return string.format ('%s&nbsp;%s', symbol, amount);
	elseif 'a' == position then													-- unspaced after the amount
		return string.format ('%s%s', amount, symbol);
	elseif 'as' == position then												-- spaced after the amount
		return string.format ('%s&nbsp;%s', amount, symbol);
	elseif 'd' == position then													-- special case that replaces the decimal separator with symbol (Cifrão for CVE is the only extant case)
		local digits, decimals;													-- this code may not work for other currencies or on other language wikis
		if amount:match ('[%d,]+%.%d+') then									-- with decimal separator and decimals
			digits, decimals = amount:match ('([%d,]+)%.(%d+)')
			amount = string.format ('%s%s%s', digits, symbol, decimals);		-- insert symbol
		elseif amount:match ('[%d,]+%.?$') then									-- with or without decimal separator
			digits = amount:match ('([%d,]+)%.?$')
			amount = string.format ('%s%s00', digits, symbol);					-- add symbol and 00 ($00)
		end
		amount = amount:gsub (',', '%.');										-- replace grouping character with period
		return amount;
	end
	return amount .. ' <span style="font-size:inherit" class="error">{{currency}} – definition missing position</span>';	-- position not defined
end


--[[--------------------------< M A K E _ N A M E >----------------------------------------------------------

Make a wikilink from the currency's article title and its plural (if provided).  If linked is false, returns only
the article title (unlinked)

]]

local function make_name (linked, page, plural)
	if not linked then
		if not is_set (plural) then
			return page;														-- just the page
		elseif 's' == plural then												-- if the simple plural form
			return string.format ('%ss', page);									-- append an 's'
		else
			return plural;														-- must be the complex plural form (pounds sterling v. dollars)
		end
	else
		if not is_set (plural) then
			return string.format ('[[%s]]', page);
		elseif 's' == plural then												-- if the simple plural form
			return string.format ('[[%s]]s', page);
		else
			return string.format ('[[%s|%s]]', page, plural);					-- must be the complex plural form (pounds sterling v. dollars)
		end
	end
end


--[[--------------------------< M A K E _ L O N G _ F O R M  _ N A M E >---------------------------------------

assembles a long-form currency name from amount and name from the properties tables; plural for all values not equal to 1

]]

local function make_long_form_name (amount, code, linked)
	local name;
	
	if not is_set (properties[code].page) then
		return '<span style="font-size:inherit" class="error">{{currency}} – definition missing page</span>';
	end

	amount = tonumber (amount);													-- make sure it's a number
	
	if 1 == amount then
		name = make_name (linked, properties[code].page);						-- the singular form
	elseif is_set (properties[code].plural) then								-- plural and there is a plural form
		name = make_name (linked, properties[code].page, properties[code].plural);
	else
		name = make_name (linked, properties[code].page);						-- plural but no separate plural form so use the singular form
	end

	return string.format ('%s %s', lang:formatNum (amount), name);				-- put it all together
end


--[[--------------------------< R E N D E R _ C U R R E N C Y >------------------------------------------------

Renders currency amount with symbol or long-form name.

Also, entry point for other modules.  Assumes that parameters have been vetted; amount is a number, code is upper
case string, long_form is boolean; all are required.

]]

local function render_currency (amount, code, long_form, linked)
	local name;
	local ouput;

	presentation = mw.loadData ('Module:Currency/Presentation');				-- get presentation data

	if presentation.currency_properties[code] then								-- if code is an iso 4217 code
		properties = presentation.currency_properties;
	elseif presentation.code_translation[code] then								-- not iso 4217 but can be translated
		code = presentation.code_translation[code];								-- then translate
		properties = presentation.currency_properties;
	elseif presentation.non_standard_properties[code] then						-- last chance, is it a non-standard code?
		properties = presentation.non_standard_properties;
	else
		return '<span style="font-size:inherit" class="error">{{currency}} – invalid code</span>';
	end

	if long_form then
		return make_long_form_name (amount, code, linked);								-- 
	else
		return make_short_form_name (amount, code, linked);
	end

	return amount;
end


--[[--------------------------< C U R R E N C Y >--------------------------------------------------------------

Template:Currency entry point.  The template takes three parameters:
	positional (1st), |amount=, |Amount=	: digits and decimal points only
	positional (2nd), |type=, |Type=		: code that identifies the currency
	|first=									: uses currency name instead of symbol

]]

local function currency (frame)
	local args = require('Module:Arguments').getArgs (frame);

	local amount, code;
	local long_form = false;
	local linked = true;

	amount = lang:parseFormattedNumber(args[1]);								-- if args[1] can't be converted to a number then error (this just strips grouping characters)
	if args[1]:find ('[^%d%.]') or not amount then								-- non-digit characters or more than one decimal point (because lag:parse... is broken)
		return '<span style="font-size:inherit" class="error">{{currency}} – invalid amount</span>';
	end
	
	if nil == args[2] then														-- if not provided
		code = USD;																-- default to USD
	else
		code = args[2]:upper();													-- always upper case; used as index into data tables which all use upper case
	end
	
	if args[3] then																-- this is the |first= parameter  TODO: make this value meaningful? y, yes, true?
		long_form = true;
	end
	
	if 'no' == args[4] then														-- this is the |linked= parameter; defaults to 'yes'; any value but 'no' means yes
		linked = false;
	end
	
	return render_currency (amount, code, long_form, linked)
end

return {
	currency = currency,														-- template entry point
	_render_currency = render_currency,											-- other modules entry point
	}