*/ // based on http://wiki.splitbrain.org/plugin:tutorial // must be run within Dokuwiki if (!defined('DOKU_INC')) die(); if (!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN', DOKU_INC . 'lib/plugins/'); require_once(DOKU_PLUGIN . 'syntax.php'); /** * All DokuWiki plugins to extend the parser/rendering mechanism * need to inherit from this class */ class syntax_plugin_calc extends DokuWiki_Syntax_Plugin { function getInfo() { return array( 'author' => 'Etienne Mauvais', 'email' => 'emauvaisfr@yahoo.fr', 'date' => @file_get_contents(DOKU_PLUGIN.'calc/VERSION'), 'name' => 'Calc Plugin', 'desc' => $this->getLang('calc_description'), 'url' => 'http://www.dokuwiki.org/plugin:calc' ); } function connectTo($mode) { $this->Lexer->addSpecialPattern('calc:.*?=', $mode, 'plugin_calc'); } //function getType() { return 'substition'; } function getType() { return 'disabled'; } function getSort() { return 667; } function handle($match, $state, $pos, &$handler) { return array($match, $state, $pos); } function render($mode, &$renderer, $data) { if ($mode == 'xhtml') { //On recupere l'expression $calc=split("calc:",$data[0]); if (isset($calc) && isset($calc[1])) $calc=$calc[1]; //On enleve le "=" final if ($calc[strlen($calc)-1]=='=') $calc[strlen($calc)-1]=" "; $calc=rtrim($calc); //Si on a un ">" final on l'enleve et on affichera l'expression avant le resultat if ($calc[strlen($calc)-1]=='>') { $calc[strlen($calc)-1]=" "; $affiche=true; } $calc=rtrim($calc); //On retire les fonctions interdites $encore=1; while($encore) { $encore=0; $calc=preg_replace_callback("/([a-z].+?\(.*?\))/", create_function('$f', 'GLOBAL $encore; $autorisees=Array("abs", "acos", "acosh", "asin", "asinh", "atan", "atan2", "atanh", "base_convert", "bindec", "ceil", "cos", "cosh", "decbin", "dechex", "decoct", "deg2rad", "exp", "expm1", "floor", "fmod", "getrandmax", "hexdec", "hypot", "is_finite", "is_infinite", "is_nan", "lcg_value", "log", "log10", "log1p", "max", "min", "mt_getrandmax", "mt_rand", "mt_srand", "octdec", "pi", "pow", "rad2deg", "rand", "round", "sin", "sinh", "sqrt", "srand", "tan", "tanh"); //print " Trouve : ".$f[1]; $nomF=explode("(",$f[1]); $nomF=$nomF[0]; if(in_array($nomF, $autorisees)) { //print " -> autorisee\n"; return $f[1]; } else { //print " -> interdite !!!\n"; $encore=1; return ""; }' ), $calc); } //On retire les ";" et les "$" $calc=str_replace(";","",$calc); $calc=str_replace("\$","",$calc); //On affiche un commentaire dans le source de la page $renderer->doc .= "\n\n"; $calc_propre=$calc; $calc="\$n=$calc;"; //On passe en mode track_errors (apres avoir recupere l'ancien mode) $track=ini_get('track_errors'); ini_set('track_errors', 'true'); $php_errormsg=""; try { eval($calc); } catch (Exception $e) { $renderer->doc .= "\"".$this->getLang('calc_erreur')." ".$e->getMessage()."\""; return true; } //On repasse dans l'ancien mode track_error ini_set('track_error', $track); //S'il y a eu une erreur (non catchee par try) if ($php_errormsg) { $renderer->doc .= "\"".$this->getLang('calc_erreur')." ".$php_errormsg."\""; return true; } //Si la valeur retournee n'est pas un nombre (ex : sqrt(-1) if (is_nan($n)) { $renderer->doc .= "\"".$this->getLang('calc_valeurincorrecte')."\""; return true; } //Mise en forme du resultat //Si on a obtenu un nombre (et pas une chaine, suite a base_convert, par exemple) if ($n*1===$n) { $tmp=explode('.',$n); $out=number_format($tmp[0], 0, $this->getLang('calc_sepdec'), $this->getLang('calc_sepmil')); if (isset($tmp[1])) $out.= $this->getLang('calc_sepdec').$tmp[1]; } else $out=$n; $out=preg_replace("/ /"," ", $out); //Si on est en mode affichage, on affiche d'abord l'expression avant le resultat if ($affiche) $renderer->doc .= $calc_propre." = "; $renderer->doc .= $out; return true; } return false; } } ?>