▶️
Planeshift.
The documentation for this module can be found at Template:Calculate.
You may be forwarded to another wiki language, in case a translation is not available.
Tests
All tests passed.
Name | Expected | Actual | |
---|---|---|---|
test_non_substituted_expression | |||
test_non_substituted_expression_with_percentage | |||
test_non_substituted_expression_with_round | |||
test_non_substituted_expression_with_round_at_end | |||
test_percentage_in_main_expression | |||
test_percentage_in_v_value | |||
test_percentage_output_percentage_in_both | |||
test_percentage_output_percentage_in_expression | |||
test_percentage_output_percentage_in_v | |||
test_substituted_expression_1v | |||
test_substituted_expression_2v | |||
test_substituted_expression_3v | |||
test_substitution_1v | |||
test_substitution_2v | |||
test_substitution_3v |
Dependencies
local p = {}
local expr = mw.ext.ParserFunctions.expr
local getArgs = require( 'Module:Arguments' ).getArgs
local split = require( 'Module:Split' )
local yesno = require( 'Module:Yesno' )
local i18n = {
value_separator = '/',
error_no_expression = 'Enter an expression',
}
function p.main( frame )
local args = getArgs( frame, {
wrappers = {
'Template:Calculate'
}
} )
return p._main( args )
end
function p._main( args )
local calculate = function( calc )
-- Replaces percentage signs with /100 since #expr can't handle them.
calc = string.gsub( calc, '%%', '/100' )
local success, result = pcall( expr, calc )
if success then
return result
else
-- Remove the leading "Expression error: " and the trailing ".".
local error_message = result:sub( 19, -2 )
-- Add the faulty expression to make debugging easier.
local error_message = string.format( '%s in expression "%s"', error_message, calc )
error( error_message )
end
end
assert( args and args[1], i18n.error_no_expression )
if args['v1'] then
-- Create a table that holds a table for each v argument.
local v_values = {}
local n = 1
while args['v'..n] do
-- Escape percentage signs to prevent them from escaping the / during the split.
v = string.gsub( args['v'..n], '%%', '%%%%' )
-- Split the v into the individual values and add them to the v_values table.
table.insert( v_values, split( v, i18n.value_separator ) )
n = n + 1
end
local output = {}
-- Run once for each value in the v1 argument.
for level=1,#v_values[1] do
local calc = args[1]
-- Do a replacement for each v arg.
for i,v in ipairs( v_values ) do
calc = calc:gsub( 'v'..i, v[level] )
end
-- Solve the calculation we just constructed and insert it into the output.
-- args[2] is used to trigger special percentage handling.
if yesno( args.percent ) or args[2] then
table.insert( output, calculate( '( '..calc..' )*100' ) .. '%' )
else
table.insert( output, calculate( calc ) )
end
end
-- Return the values in the output table separated by a /.
return table.concat( output, i18n.value_separator )
else
-- Just do a normal #expr if no v values are given.
-- Still has percentage handling which normal #expr doesn't.
-- TODO: Remove the args[2] once all pages are transitioned.
if yesno( args.percent ) or args[2] then
return calculate( '( '..args[1]..' )*100' ) .. '%'
else
return calculate( args[1] )
end
end
end
return p