Dota 2 Wiki
Advertisement

Documentation for Module:Calculate Jump to code ↴ [ edit | purge ]

Reality Rift icon
▶️ 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

YesY All tests passed.

Name Expected Actual
YesY test_non_substituted_expression
YesY test_non_substituted_expression_with_percentage
YesY test_non_substituted_expression_with_round
YesY test_non_substituted_expression_with_round_at_end
YesY test_percentage_in_main_expression
YesY test_percentage_in_v_value
YesY test_percentage_output_percentage_in_both
YesY test_percentage_output_percentage_in_expression
YesY test_percentage_output_percentage_in_v
YesY test_substituted_expression_1v
YesY test_substituted_expression_2v
YesY test_substituted_expression_3v
YesY test_substitution_1v
YesY test_substitution_2v
YesY 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
Advertisement