1<?php 2/** 3 * Math Plugin: incorporate mathematical formulae using MathPublisher into Dokuwiki 4 * 5 * Syntax: <m size>...mathematical formula..</m> 6 * size (optional) base glyph size in pixels, 7 * if not present will use the value of $mathplugin_size global, the value 8 * of which can be set below (default: 12) 9 * 10 * Formulae syntax: refer http://www.xm1math.net/phpmathpublisher/doc/help.html 11 * 12 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 13 * @author Christopher Smith <chris@jalakai.co.uk> 14 * @date 2005-12-17 15 * 16 * phpmathpublisher 17 * @link http://www.xm1math.net/phpmathpublisher/ 18 * @author Pascal Brachet 19 */ 20 21if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/'); 22if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 23require_once(DOKU_PLUGIN.'syntax.php'); 24require_once(DOKU_INC.'inc/io.php'); 25 26global $conf; 27 28// -----------------------[ math plugin globals ]--------------------------------------- 29global $mathplugin_size, $mathplugin_urlimg; 30 31 // default base size (pixels) of glyphs in the formulae 32 $mathplugin_size = 12; 33 34 // base url to access images, should correspond to $dirimg below. 35 // if left at default, it will be modified to add a subfolder to avoid filling 36 // the root media folder with clutter, refer _cacheExists() 37 $mathplugin_urlimg = DOKU_URL.'lib/exe/fetch.php?w=&h=&cache=cache&media='; 38 39// -----------------------[ mathpublisher settings ]------------------------------------ 40global $dirfonts,$dirimg; 41 42 // absolute path to the fonts directory (must not have '/' at end) 43 $dirfonts=dirname(__FILE__)."/phpmathpublisher/fonts"; 44 45 // absolute path to the img directory (must not have '/' at end) 46 // if left at default, it will be modified to add a subfolder to avoid filling 47 // the root media folder with clutter, refer _cacheExists() 48 $dirimg=$conf['mediadir']; 49 50// ------------------------------------------------------------------------------------ 51 52/** 53 * All DokuWiki plugins to extend the parser/rendering mechanism 54 * need to inherit from this class 55 */ 56class syntax_plugin_math extends DokuWiki_Syntax_Plugin { 57 58 // FIXME localise 59 var $str_nopng = "PHP's gd library is missing or unable to create PNG images"; 60 var $str_noft = "PHP installation missing access to freetype library"; 61 var $enable = false; 62 var $msg_disable = "math plugin disabled: "; 63 var $msg_sent = false; 64 65 function syntax_plugin_math() { 66 $this->enable = $this->_requirements_ok(); 67 } 68 69 /** 70 * return some info 71 */ 72 function getInfo(){ 73 74 return array( 75 'author' => 'Christopher Smith', 76 'email' => 'chris@jalakai.co.uk', 77 'date' => '2008-08-13', 78 'name' => 'Math Plugin'.(!$this->enable ? ' (disabled)' : ''), 79 'desc' => 'Add mathematical formulae to dokuwiki 80 Syntax: <m size>math formulae</m> 81 For formulae syntax visit http://www.xm1math.net/phpmathpublisher/doc/help.html'. 82 (!$this->enable ? "\n(".$this->msg_disable.")" : ''), 83 'url' => 'http://www.dokuwiki.org/plugin:math2', 84 ); 85 } 86 87 function getType(){ return 'protected'; } 88 function getPType(){ return 'normal'; } 89 function getSort(){ return 208; } 90 91 /** 92 * Connect pattern to lexer 93 */ 94 function connectTo($mode) { 95 $this->Lexer->addEntryPattern('<m(?=[^\r\n]*?>.*?</m>)',$mode,'plugin_math'); 96 } 97 98 function postConnect() { 99 $this->Lexer->addExitPattern('</m>','plugin_math'); 100 } 101 102 /** 103 * Handle the match 104 */ 105 function handle($match, $state, $pos, &$handler){ 106 global $mathplugin_size; 107 108 if ( $state == DOKU_LEXER_UNMATCHED ) { 109 list($size, $math) = preg_split('/>/u', $match, 2); // will split into size & math formulae 110 if (!is_numeric($size)) $size = $mathplugin_size; 111 112 if (strlen($math) > 1) { 113 $c_first = $math{0}; 114 $c_last = $math{strlen($math)-1}; 115 116 $align = ($c_first == ' ') ? ($c_last == ' ' ? 'center' : 'right') : ($c_last == ' ' ? 'left' : 'normal'); 117 } else { 118 $align = 'normal'; 119 } 120 121 return (array($size, trim($math), $align)); 122 } 123 return false; 124 } 125 126 /** 127 * Create output 128 */ 129 function render($mode, &$renderer, $data) { 130 global $mathplugin_urlimg; 131 132 if (!$data) return; // skip rendering for the enter and exit patterns 133 list($size, $math, $align) = $data; 134 135 if($mode == 'xhtml'){ 136 // phpmathpublisher generates many E_NOTICE errors, ensure error_reporting doesn't include E_NOTICE. 137 $error_level = error_reporting(); 138 error_reporting($error_level & ~E_NOTICE); 139 140 // check we have ability to create png images 141 if ($this->enable) { 142 // check we have somewhere to create our images & make them 143 if ($this->_cacheExists()) { 144 require_once(dirname(__FILE__).'/phpmathpublisher/mathpublisher.php'); 145 $math_html = mathimage($math, $size, $mathplugin_urlimg); 146 147 if ($align != 'normal') { 148 $math_html = preg_replace('/<img /i','\0 class="media'.$align.'" ',$math_html); 149 } 150 151 $renderer->doc .= $math_html; 152 } else { 153 $this->_msg("math plugin img folder is not writable", -1); 154 } 155 } else { 156 $this->_msg($this->msg_disable, -1); 157 } 158 159 // return to previous error reporting level 160 error_reporting($error_level); 161 return true; 162 } 163 return false; 164 } 165 166 function _cacheExists() { 167 global $dirimg, $mathplugin_urlimg, $conf; 168 169 // check for default setting 170 if (!isset($dirimg) || !$dirimg) { $dirimg = $conf['mediadir']; } 171 if ($dirimg == $conf['mediadir']) { 172 // we don't want to clutter the root media dir, so create our own subfolder 173 $dirimg .= "/cache_mathplugin"; 174 $mathplugin_urlimg .= "cache_mathplugin%3a"; 175 176 if (!@is_dir($dirimg)) { 177 $this->_mkdir($dirimg); 178 } 179 } 180 181 return @is_writable($dirimg); 182 } 183 184 // return true if php installation has required libraries/functions for mathpublisher 185 function _requirements_ok() { 186 if (!function_exists('imagepng')) { 187 $this->msg_disable .= $this->str_nopng; 188 return false; 189 } 190 191 if (!function_exists('imagettftext')) { 192 $this->msg_disable .= $this->str_noft; 193 return false; 194 } 195 196 return true; 197 } 198 199 // used to avoid multiple messages 200 function _msg($str, $lvl=0) { 201 if ($this->msg_sent) return; 202 203 msg($str, $lvl); 204 $this->msg_sent = true; 205 } 206 207 // would like to see this function in io.php :) 208 function _mkdir($d) { 209 global $conf; 210 211 umask($conf['dmask']); 212 $ok = io_mkdir_p($d); 213 umask($conf['umask']); 214 return $ok; 215 } 216 217} 218 219//Setup VIM: ex: et ts=4 enc=utf-8 : 220