#### Wiki source for CalcInfo

Show raw source

===This action allows you to put calculations (with variables or not) and write out the result.===

==Basic usage==
By typing:
%%
1 day ={{calc 24*60*60}} seconds
%%
you will obtain:
1 day =86400 seconds

==With variables usage==
By typing:
%%
{{calc total=0}}
- red: {{calc q=2;total+=q;q}}
- blue: {{calc q=3;total+=q;q}}
- yellow: {{calc q=6;total+=q;q}}
- **total**: **{{calc total}}**
- **total+taxes**: **{{calc total+total*18.6/100.0}}**
%%
You will obtain:
- red: 2
- blue: 3
- yellow: 6
- **total**: **11**
- **total+taxes**: **13.046**
Because:
- Several expressions separated by a semicolon can appear in a **calc** action,
- only those that aren't assignations (not containing the equal sign) are displayed.

==Features==
- Secure
- The variables are keys in an associative array named calcvar (//i.e. calcvar['total']//)
- The function calls are forgotten.
- Powerful
- It makes your wiki page a spreadsheet.
- It allows displaying not hard-coded numerical values (such the number of seconds in a day), preventing errors...
- It allows modification of values in a page without recalculation by-hand of a global result (if you add an item //green: 12// in the list)

==Restrictions==
- Variables names are necessary alphabetics (see line 14).
- You can't (because of security) call functions (see line 28).
- A few operators are allowed (see line 16).

==Improvements==
- You can easily add an operator (currently -*/+) by adding a char in the regexp line 16.
- You could authorize the call of specific functions (such ln, exp,...) by matching them (a little bit more difficult)
- You could define options in order to set the precision of the result by example.

==Code==
Save this as actions/calc.php
%%(php;1)
<?php

/*
*Author:Jean-françois Delesse (jfdelesse@free.fr)
*
*/
if (!function_exists('strtonum'))
{
\$calcvar=array();
function strtonum(\$str)
{
static \$calcvar;
\$pattern = '/([^;])+/';
\$varpat='([a-zA-Z]+\s*\(*)';
\$varpattern="/\$varpat/";
\$otherpat='([0-9\.*\(\)\-+\/=]+)';
\$allpattern="/\$varpat|\$otherpat/";
preg_match_all(\$pattern,\$str,\$blocks);
foreach (\$blocks as \$k=>\$block)
{
\$affichage=true;
\$blockstr="";
preg_match_all(\$allpattern,\$block,\$out,PREG_SET_ORDER);
foreach (\$out as \$k2=>\$token)
{
if (\$token!="")
{
\$token=preg_replace('/\s*\(*/','',\$token);
\$tokstr='\$calcvar[\''.\$token.'\']';
}
if (\$token!="")
{
\$tokstr=\$token;

if (!(strpos(\$tokstr,"=")===false))
{
\$affichage=false;
}
}
\$blockstr.=\$tokstr;
}
if(!empty(\$blockstr))
{
\$blockstr="\$blockstr;";
\$blockstr=eval("return ".\$blockstr);
if (\$affichage)
\$outstr.=(\$outstr!=""?";":"").\$blockstr ;
}
}
return \$outstr;
}
}

if (is_array(\$vars))
{
print strtonum(\$vars['wikka_vars']);
}
?>
%%