1<?php
2// must be run within Dokuwiki
3if(!defined('DOKU_INC')) die();
4
5if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
6require_once(DOKU_PLUGIN.'syntax.php');
7
8/**
9 * All DokuWiki plugins to extend the parser/rendering mechanism
10 * need to inherit from this class
11 */
12class syntax_plugin_tablecalc extends DokuWiki_Syntax_Plugin {
13	var $id_index=0;
14	/**
15	* left for compatibility
16	*/
17	function getInfo() {
18		return array(
19			'author' => 'Gryaznov Sergey',
20			'email'  => 'stalker@narezka.org',
21			'date'   => '09-02-17',
22			'name'   => 'Table Calculations Plugin',
23			'desc'   => 'Enables Excel style formulas in table syntax',
24			'url'    => 'https://narezka.org/tablecalc',
25		);
26	}
27
28	function getType() { return 'substition'; }
29	function getSort() { return 1213; }
30
31	/**
32	* Connect pattern to lexer
33	*/
34	function connectTo($mode) {
35		$this->Lexer->addSpecialPattern("~~=[_a-z\ A-Z0-9\%\:\.,\\\/\*\-\+\(\)\&\|#><!=;]*~~", $mode, 'plugin_tablecalc');
36	}
37
38	/**
39	* Handle the match
40	*/
41	function handle($match, $state, $pos, Doku_Handler $handler) {
42		global $ID, $ACT, $INFO;
43		$signs="-~=+*.,;\/!|&\(\)";
44		$pattern="/[$signs]*([a-zA-Z]+)\(/is";
45		$aAllowed=array("cell","row","col","sum","average","count","countif","nop","round","range","label","min","max","calc","check","compare");
46		if (preg_match_all($pattern,$match,$aMatches)) {
47			foreach ($aMatches[1] as $f) {
48				if (!in_array(strtolower($f),$aAllowed)) {
49					$match=preg_replace("/([$signs]*)$f\(/is","\\1nop(",$match);
50				}
51			}
52		}
53		$aNop=array('~~=','~~');
54		foreach ($aNop as $nop) {
55			$match = str_replace($nop,'',$match);
56		}
57		$match=preg_replace("/#([^\(\);,]+)/","'\\1'",$match);
58		$match=preg_replace("/\(([a-z0-9_]+)\)/","('\\1')",$match);
59		$this->id_index++;
60		return array('formula'=>$match, 'divid'=>'__tablecalc'.$this->id_index,'idx'=>$this->id_index);
61
62	}
63
64	function render($mode, Doku_Renderer $renderer, $data) {
65		global $INFO, $ID, $conf;
66		//var_dump($data);
67		if($mode == 'xhtml'){
68			$renderer->doc .= '<span id="'.$data['divid'].'"><script type="text/javascript" defer="defer">tablecalc("'.$data['divid'].'","'.$data['formula'].'")</script></span>';
69			return true;
70		}
71		return false;
72	}
73}
74?>
75