Summary: custom markup expression samples
Version: 2007-12-08
Prerequisites: PmWiki 2.2.0 beta
Status:
Maintainer:
Custom Markup Expressions
{{(calc )}
Example: {(calc 'sqrt(7^2 + 9^2)')}
Extended calculator markup expression. Uses basic and extended math functions. Use + - * / ^ as operators, other PHP math functions with brackets and comma separated arguments: pow(), sqrt(), sin(), cos(), tan(), asin(), acos(), atan(), log(), max(), min(), abs(), ceil(), floor(), round(), rand(), fmod(), deg2rad(), rad2deg(); constant: pi.
$MarkupExpr['calc'] = 'MxCalc($args)';
function MxCalc($args) {
global $MxCalcChars, $MxCalcFunc1, $MxCalcFunc2;
//allowed characters (operators, digits, brackets etc) apart from function names below
SDV($MxCalcChars, "/^[-+*,\\/% ><=()0-9.^]+$/");
//math functions with single argument
SDV($MxCalcFunc1, array(
'sqrt','sin','cos','tan','asin','acos','atan','log',
'abs','ceil','floor','round','deg2rad','rad2deg',
));
//math functions with 2 or more arguments, constants, and others
SDV($MxCalcFunc2, array(
'pow','max','min','rand','fmod','pi',
));
$mathfn = array_merge($MxCalcFunc1, $MxCalcFunc2);
$arg = implode(" ", $args);
//nothing to do
if ($arg == '') return "empty input!";
//check if math expression has only allowed characters and function names
$str = $arg;
foreach($mathfn as $fn) {
$str = str_replace($fn, '', $str);
}
if ($str!='' && !preg_match($MxCalcChars, $str, $m)) return "Input error!";
//translate easy input
$arg = str_replace('pi', M_PI, $arg);
$arg = preg_replace("/(\\-?[\\d.]+)\\^(\\-?[\\d.]+)/", "pow($1, $2)", $arg);
foreach($MxCalcFunc1 as $fn)
$arg = preg_replace("/{$fn}\\s?(\\-?[\\d.]+)/", "{$fn}($1)", $arg);
//do the work
eval("\$res = $arg;");
//provide for 0 as result from comparison operations
if ($res=='')
if (preg_match("/[><=]/", $arg)) $res = '0';
return $res;
}
{(utime)} and {(udays)}
Input formatted date, like for instance 2008-02-26.
utime returns unix timestamp of the date input.
{(utime DATE)} is equivalent to {(ftime %s DATE)}
udays returns the unix timestamp converted to whole days.
# unix time, seconds since 1970-01-01
$MarkupExpr['utime'] = 'MxUTime($args[0])';
function MxUTime($arg) {
$udate = date('U', strtotime($arg));
if ($arg=='now' || $arg=='') $udate = time();
return $udate;
}
# unix time as days since 1970-01-01 to midnight of DATE entered
$MarkupExpr['udays'] = 'MxUDays($args[0])';
function MxUDays($arg) {
$udate = date('U', strtotime($arg));
if ($arg=='now' || $arg=='') $udate = time();
return floor($udate/86400);
}
{(catlist)}
{(catlist PAGENAME SEPARATOR)} extracts a list of full pagenames of all category links on a page.
- use with no arguments:
{(catlist)} returns comma separated list of full pagenames of all category links.
- first argument PAGENAME: category list retuned is from page PAGENAME.
- second argument: a different separator can be given (default is ,)
$MarkupExpr['catlist'] = 'CategoryList($pagename, $args[0], $args[1])';
function CategoryList($pn, $arg='', $sep=',') {
global $CategoryGroup;
if(!$arg=='') $pn = MakePageName($pn, $arg);
if($sep==NULL) $sep = ",";
$page = RetrieveAuthPage($pn, 'read', true);
$pat = '/\\[\\[\\!(.*?)\\]\\]/';
$text = preg_replace('/\\(:(.*?):\\)/' ,"", $page['text']);
if(preg_match_all($pat, $text, $matches)) {
foreach($matches[1] as $i=>$m)
$catlist[] = MakePageName($pn, $CategoryGroup.".".$m);
return implode($sep, $catlist);
}
}
Notes
Release Notes
If the recipe has multiple releases, then release notes can be placed here. Note that it's often easier for people to work with "release dates" instead of "version numbers".
See Also
Contributors
Comments
I put the Extended calculator markup expression in my wikis config.php and it gives this message:
Parse error: syntax error, unexpected ')' in /mywikiaddress/local/config.php(276) : eval()'d code on line 1
What's wrong?
I updated the code slightly. Please give more information of what you exactly did. It may be important to enclose the math argument string in single quotes inside the markup, as shown in the example. HansB March 07, 2008, at 04:51 AM
This calculator one is nice recipe but I got a problem with it. It gives results like 2,45 where is comma for decimals. But it don't accept comma for decimals as input. For input it requires dot for decimals. So it can't use the variables calculated by itself. Is there something to do to solve this problem?