Changeset 1066 for plugins/latexrender
- Timestamp:
- 04/22/09 22:45:18 (14 years ago)
- Location:
- plugins/latexrender
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
plugins/latexrender/_admin.php
r760 r1066 1 1 <?php 2 // ***** BEGIN LICENSE BLOCK ***** 3 // This file is (c) Jean-Christophe Dubacq. 4 // Licensed under CC-BY licence. 5 // 6 // ***** END LICENSE BLOCK ***** 2 # -- BEGIN LICENSE BLOCK ---------------------------------- 3 # This file is part of latexrender, a plugin for Dotclear. 4 # 5 # Copyright (c) 2009 Jean-Christophe Dubacq 6 # jcdubacq1@free.fr 7 # 8 # Licensed under the LGPL version 2.1 license. 9 # A copy of this license is available in LICENSE file or at 10 # http://www.gnu.org/licenses/lgpl-2.1.html 11 # -- END LICENSE BLOCK ------------------------------------ 7 12 8 $_menu['Plugins']->addItem('LaTeXrender','plugin.php?p=latexrender','index.php?pf=latexrender/icon.png', preg_match('/plugin.php\?p=latexrender/',$_SERVER['REQUEST_URI']), $core->auth->isSuperAdmin()); 13 $_menu['Plugins']->addItem('LaTeXrender','plugin.php?p=latexrender', 14 'index.php?pf=latexrender/icon.png', 15 preg_match('/plugin.php\?p=latexrender/', 16 $_SERVER['REQUEST_URI']), 17 $core->auth->isSuperAdmin()); 9 18 ?> -
plugins/latexrender/_define.php
r1043 r1066 1 1 <?php 2 # ***** BEGIN LICENSE BLOCK ***** 3 # This file is (c) Jean-Christophe Dubacq. 4 # Licensed under CC-BY licence. 5 # 6 # ***** END LICENSE BLOCK ***** 2 # -- BEGIN LICENSE BLOCK ---------------------------------- 3 # This file is part of latexrender, a plugin for Dotclear. 4 # 5 # Copyright (c) 2009 Jean-Christophe Dubacq 6 # jcdubacq1@free.fr 7 # 8 # Licensed under the LGPL version 2.1 license. 9 # A copy of this license is available in LICENSE file or at 10 # http://www.gnu.org/licenses/lgpl-2.1.html 11 # -- END LICENSE BLOCK ------------------------------------ 7 12 8 13 $this->registerModule( 9 /* Name */ "LatexRender",10 /* Description*/ "Allows rendering of some blocks by LaTeX",11 /* Author */ "Jean-Christophe Dubacq",12 /* Version */ '0.9',13 /* Permissions */ 'usage,contentadmin'14 );14 'LatexRender', /* Name */ 15 'Allows rendering of some blocks by LaTeX',/*Description*/ 16 'Jean-Christophe Dubacq', /* Author */ 17 '0.9.1', /* Version */ 18 'usage,contentadmin' /* Permissions */ 19 ); 15 20 ?> -
plugins/latexrender/_prepend.php
r760 r1066 1 1 <?php 2 // ***** BEGIN LICENSE BLOCK ***** 3 // This file is (c) Jean-Christophe Dubacq. 4 // Licensed under CC-BY licence. 5 // 6 // ***** END LICENSE BLOCK ***** 2 # -- BEGIN LICENSE BLOCK ---------------------------------- 3 # This file is part of latexrender, a plugin for Dotclear. 4 # 5 # Copyright (c) 2009 Jean-Christophe Dubacq 6 # jcdubacq1@free.fr 7 # 8 # Licensed under the LGPL version 2.1 license. 9 # A copy of this license is available in LICENSE file or at 10 # http://www.gnu.org/licenses/lgpl-2.1.html 11 # -- END LICENSE BLOCK ------------------------------------ 7 12 8 13 $core->addBehavior('initStacker', -
plugins/latexrender/_public.php
r760 r1066 1 1 <?php 2 // ***** BEGIN LICENSE BLOCK ***** 3 // This file is (c) Jean-Christophe Dubacq. 4 // Licensed under CC-BY licence. 5 // 6 // ***** END LICENSE BLOCK ***** 2 # -- BEGIN LICENSE BLOCK ---------------------------------- 3 # This file is part of latexrender, a plugin for Dotclear. 4 # 5 # Copyright (c) 2009 Jean-Christophe Dubacq 6 # jcdubacq1@free.fr 7 # 8 # Licensed under the LGPL version 2.1 license. 9 # A copy of this license is available in LICENSE file or at 10 # http://www.gnu.org/licenses/lgpl-2.1.html 11 # -- END LICENSE BLOCK ------------------------------------ 7 12 8 13 include_once(dirname(__FILE__).'/class.latexrender.php'); -
plugins/latexrender/class.latexrender.php
r1043 r1066 1 1 <?php 2 /** 3 * LaTeX Rendering Class 4 * Copyright (C) 2003 Benjamin Zeiss <zeiss@math.uni-goettingen.de> 5 * Modifications by Jean-Christophe Dubacq <jcdubacq1@free.fr> 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * -------------------------------------------------------------------- 21 * @author Benjamin Zeiss <zeiss@math.uni-goettingen.de> 22 * @version v0.8.9 23 * @package latexrender 24 * 25 * This version includes Mike Boyle's modifications to allow vertical 26 * offset of LaTeX formulae 27 * This version includes Jean-Christophe Dubacq's modifications to allow 28 * better offset of LaTeX formulae 29 * This version includes Jean-Christophe Dubacq's simplifications to better 30 * fit Dotclear 2 31 */ 2 # -- BEGIN LICENSE BLOCK ---------------------------------- 3 # This file is part of latexrender, a plugin for Dotclear. 4 # 5 # Copyright (c) 2003 Benjamin Zeiss <zeiss@math.uni-goettingen.de> 6 # Modifications 2006 Mike Boyle 7 # Modifications 2008 Jean-Christophe Dubacq <jcdubacq1@free.fr> 8 # 9 # Licensed under the LGPL version 2.1 license. 10 # A copy of this license is available in LICENSE file or at 11 # http://www.gnu.org/licenses/lgpl-2.1.html 12 # -- END LICENSE BLOCK ------------------------------------ 13 # This version includes Mike Boyle's modifications to allow vertical 14 # offset of LaTeX formulae 15 # This version includes Jean-Christophe Dubacq's modifications to allow 16 # better offset of LaTeX formulae 17 # This version includes Jean-Christophe Dubacq's simplifications to better 18 # fit Dotclear 2 32 19 33 20 class LatexRender { 34 var $_picture_path;35 var $_picture_path_httpd;36 var $_tmp_dir;37 var $_latex_path = '/usr/bin/latex';38 var $_dvips_path = '/usr/bin/dvips';39 var $_convert_path = '/usr/bin/convert';40 var $_identify_path='/usr/bin/identify';41 var $_formula_density = 120;42 var $_xsize_limit = 500;43 var $_ysize_limit = 500;44 var $_string_length_limit = 500;45 var $_font_size = 10;46 var $_latexclass = 'article';47 var $_tmp_filename;48 var $_latex_tags_blacklist =49 array(50 51 52 53 54 55 56 57 var $_errorcode;58 var $_errorextra;59 var $_wronginit=false;60 var $_initerrorcode;61 var $_initerrorextra;21 var $_picture_path; 22 var $_picture_path_httpd; 23 var $_tmp_dir; 24 var $_latex_path = '/usr/bin/latex'; 25 var $_dvips_path = '/usr/bin/dvips'; 26 var $_convert_path = '/usr/bin/convert'; 27 var $_identify_path='/usr/bin/identify'; 28 var $_formula_density = 120; 29 var $_xsize_limit = 500; 30 var $_ysize_limit = 500; 31 var $_string_length_limit = 500; 32 var $_font_size = 10; 33 var $_latexclass = 'article'; 34 var $_tmp_filename; 35 var $_latex_tags_blacklist = 36 array( 37 'include','def','command','loop','repeat','open','toks','output', 38 'input','catcode','name','^^', 39 '\every','\errhelp','\errorstopmode','\scrollmode','\nonstopmode', 40 '\batchmode','\read','\write','csname','\newhelp','\uppercase', 41 '\lowercase','\relax','\aftergroup', 42 '\afterassignment','\expandafter','\noexpand','\special' 43 ); 44 var $_errorcode; 45 var $_errorextra; 46 var $_wronginit=false; 47 var $_initerrorcode; 48 var $_initerrorextra; 62 49 63 /** 64 * Initializes the class 65 * 66 * @param object core object 67 */ 68 function LatexRender($core) { 69 $options=LatexRender::getConfig(); 70 $this->_formula_density = $options['formuladensity']; 71 $this->_method = $options['method']; 72 $this->_latexclass = $options['latexclass']; 73 $this->_font_size = $options['fontsize']; 74 $this->_string_length_limit = $options['stringlengthlimit']; 75 $this->_xsize_limit = $options['xsizelimit']; 76 $this->_ysize_limit = $options['ysizelimit']; 77 $this->_latex_path = $options['latexpath']; 78 $this->_dvips_path = $options['dvipspath']; 79 $this->_convert_path = $options['convertpath']; 80 $this->_identify_path = $options['identifypath']; 81 $latexrender_path_http = $core->blog->settings->public_url.'/latexrender/'; 82 if (strncmp($core->blog->settings->public_path,'/',1)==0) { 83 $latexrender_path = $core->blog->settings->public_path.'/latexrender/'; 84 } else { 85 $latexrender_path = dirname(__FILE__).'/../../'. 86 $core->blog->settings->public_path.'/latexrender/'; 87 } 88 $this->_picture_path = $latexrender_path.'pictures'; 89 if (defined('DC_CONTEXT_ADMIN')) { 90 $url=$core->blog->url; 91 if (substr($latexrender_path_http,0,1) == '/') { 92 $url=preg_replace('|(^[a-z]{3,}://.*?)(/.*$)|','$1',$core->blog->url); 93 } 94 $this->_picture_path_httpd = $url. 95 $latexrender_path_http.'pictures'; 96 } else { 97 $this->_picture_path_httpd = $latexrender_path_http.'pictures'; 98 } 99 $this->_tmp_dir = $latexrender_path.'tmp'; 100 files::makeDir($this->_picture_path,true); 101 files::makeDir($this->_tmp_dir,false); 102 $this->_tmp_filename = md5(rand()); 103 foreach (array($this->_latex_path,$this->_dvips_path, 104 $this->_convert_path,$this->_identify_path) as $j) { 105 if (!is_file($j)) { 106 $this->_initerrorcode = 'executable not found'; 107 $this->_initerrorextra = $j; 108 $this->_wronginit=true; 109 } 110 } 50 /** 51 * Initializes the class 52 * 53 * @param object core object 54 */ 55 function LatexRender($core) { 56 $options=LatexRender::getConfig(); 57 $this->_formula_density = $options['formuladensity']; 58 $this->_method = $options['method']; 59 $this->_latexclass = $options['latexclass']; 60 $this->_font_size = $options['fontsize']; 61 $this->_string_length_limit = $options['stringlengthlimit']; 62 $this->_xsize_limit = $options['xsizelimit']; 63 $this->_ysize_limit = $options['ysizelimit']; 64 $this->_latex_path = $options['latexpath']; 65 $this->_dvips_path = $options['dvipspath']; 66 $this->_convert_path = $options['convertpath']; 67 $this->_identify_path = $options['identifypath']; 68 $latexrender_path_http = $core->blog->settings->public_url.'/latexrender/'; 69 if (strncmp($core->blog->settings->public_path,'/',1)==0) { 70 $latexrender_path = $core->blog->settings->public_path.'/latexrender/'; 71 } else { 72 $latexrender_path = dirname(__FILE__).'/../../'. 73 $core->blog->settings->public_path.'/latexrender/'; 74 } 75 $this->_picture_path = $latexrender_path.'pictures'; 76 if (defined('DC_CONTEXT_ADMIN')) { 77 $url=$core->blog->url; 78 if (substr($latexrender_path_http,0,1) == '/') { 79 $url=preg_replace('|(^[a-z]{3,}://.*?)(/.*$)|','$1',$core->blog->url); 80 } 81 $this->_picture_path_httpd = $url. 82 $latexrender_path_http.'pictures'; 83 } else { 84 $this->_picture_path_httpd = $latexrender_path_http.'pictures'; 85 } 86 $this->_tmp_dir = $latexrender_path.'tmp'; 87 files::makeDir($this->_picture_path,true); 88 files::makeDir($this->_tmp_dir,false); 89 $this->_tmp_filename = md5(rand()); 90 foreach (array($this->_latex_path,$this->_dvips_path, 91 $this->_convert_path,$this->_identify_path) as $j) { 92 if (!is_file($j)) { 93 $this->_initerrorcode = 'executable not found'; 94 $this->_initerrorextra = $j; 95 $this->_wronginit=true; 96 } 97 } 98 } 99 100 // =================== 101 // public functions 102 // =================== 103 104 public static function defaultConfig() { 105 $base=array( 106 'xsizelimit' => '500', 107 'ysizelimit' => '500', 108 'stringlengthlimit' => '500', 109 'formuladensity' => '120', 110 'latexclass' => 'article', 111 'fontsize' => '10', 112 'method' => 'old' 113 ); 114 $commands=array('latex','dvips','convert','identify'); 115 foreach ($commands as $i) { 116 $base[$i.'path']='/usr/bin/'.$i; 117 } 118 119 return $base; 120 } 121 public static function getConfig() { 122 global $core; 123 $base = LatexRender::defaultConfig(); 124 if ($core->blog->settings->get('latexrender_options',true) === null) { 125 // First appearance of options combo on any blog 126 $core->blog->settings->setNameSpace('latexrender'); 127 $core->blog->settings->put('latexrender_options', 128 '','string', 129 'LatexRender options',true,true); 130 } 131 132 $user = $core->blog->settings->latexrender_options; 133 if ($user === null) { 134 $user = $base; 135 } else { 136 $user = @unserialize($user); 137 if (!is_array($user)) { 138 $user = array(); 139 } 140 $user = array_merge($base,$user); 141 } 142 return $user; 143 } 144 public static function storeConfig($config,$oldconfig=null) { 145 global $core; 146 $fixed_options=array(); 147 $base = LatexRender::defaultConfig(); 148 foreach ($config as $name => $value) { 149 if ((!isset($base[$name])) || 150 ($base[$name] != $value)) { 151 $fixed_options[$name]=$value; 152 } 153 } 154 if ($oldconfig) { 155 foreach ($config as $name => $value) { 156 if ((!isset($oldconfig[$name])) || 157 ($oldconfig[$name] != $value)) { 158 $fixed_options[$name]=$value; 159 } 160 } 161 162 } 163 if (count($fixed_options)) { 164 $core->blog->settings->setNameSpace('latexrender'); 165 $core->blog->settings->put('latexrender_options', 166 serialize($fixed_options)); 167 } 168 } 169 170 /** 171 * Returns the last error code 172 * 173 */ 174 public function getError() { 175 return(__($this->_errorcode).' {'.$this->_errorextra.'}'); 176 } 177 178 /** 179 * Tries to match the LaTeX Formula given as argument against the 180 * formula cache. If the picture has not been rendered before, it'll 181 * try to render the formula and drop it in the picture cache directory. 182 * 183 * @param string formula in LaTeX format 184 * @returns the webserver based URL to a picture which contains the 185 * requested LaTeX formula. If anything fails, the resultvalue is false. 186 */ 187 public function getFormulaHTML($latex_formula,$color='000000',$force=false) { 188 $aurl=$this->getFormulaURL($latex_formula,$color,$force); 189 $url = $aurl[0]; 190 $depth=$aurl[1]; 191 if ($depth) { 192 $style_css = ' style="vertical-align:-'.$depth.';"'; 193 } 194 $alt_latex_formula = htmlentities($latex_formula, ENT_QUOTES); 195 $alt_latex_formula = str_replace("\r",' ',$alt_latex_formula); 196 $alt_latex_formula = str_replace("\n",' ',$alt_latex_formula); 197 if ($url) { 198 $html='<img class="latex" src="'.$url.'" title="'.$alt_latex_formula.'" alt="'.$alt_latex_formula.'" '.$style_css.' />'; 199 } else { 200 $html='<strong>[Unparsable formula ('.$this->getError().'): '.$alt_latex_formula.']</strong>'; 201 } 202 return $html; 203 } 204 205 /** 206 * Tries to match the LaTeX Formula given as argument against the 207 * formula cache. If the picture has not been rendered before, it'll 208 * try to render the formula and drop it in the picture cache directory. 209 * 210 * @param string formula in LaTeX format 211 * @returns the webserver based URL to a picture which contains the 212 * requested LaTeX formula. If anything fails, the resultvalue is false. 213 */ 214 public function getFormulaURL($latex_formula,$color,$force) { 215 // circumvent certain security functions of web-software which 216 // is pretty pointless right here 217 if ($this->_wronginit) { 218 $this->_errorcode=$this->_initerrorcode; 219 $this->_errorextra=$this->_initerrorextra; 220 return array(false,0); 221 } else { 222 $this->_errorcode=''; 223 $this->_errorextra=''; 224 } 225 $latex_formula = preg_replace('/>/i', '>', $latex_formula); 226 $latex_formula = preg_replace('/</i', '<', $latex_formula); 227 $formula_hash = md5($latex_formula); 228 $filename = $formula_hash; 229 if ($color!='000000') { 230 $filename=$color.'X'.$filename.'.'; 231 } else { 232 $filename=$filename.'.'; 233 } 234 $full_path_filename = $this->_picture_path.'/'.$filename.'png'; 235 $full_path_filename_depth = $this->_picture_path.'/'.$filename.'depth'; 236 if ($force) { 237 if (is_file($full_path_filename)) { 238 unlink($full_path_filename); 239 } 240 if (is_file($full_path_filename_depth)) { 241 unlink($full_path_filename_depth); 242 } 243 } 244 if (!is_file($full_path_filename) || $force) { 245 // security filter: reject too long formulas 246 if (strlen($latex_formula) > $this->_string_length_limit) { 247 $this->_errorcode = 'formula too long'; 248 $this->_errorextra = strlen($latex_formula).'>'.$this->_string_length_limit; 249 return array(false,0); 250 } 251 252 // security filter: try to match against LaTeX-Tags Blacklist 253 for ($i=0;$i<sizeof($this->_latex_tags_blacklist);$i++) { 254 if (stristr($latex_formula,$this->_latex_tags_blacklist[$i])) { 255 $this->_errorcode = 'blacklisted TeX operator'; 256 $this->_errorextra = $this->_latex_tags_blacklist[$i]; 257 return array(false,0); 258 } 259 } 260 261 // security checks assume correct formula, let's render it 262 if (!($this->renderLatex($latex_formula,$color,$this->_picture_path.'/'.$filename))) { 263 // errorcode and errorextra should already be filled-in 264 return array(false,0); 265 } 266 if (!is_file($full_path_filename)) { 267 $this->_errorcode = 'file not moved correctly'; 268 $this->_errorextra = $full_path_filename; 269 return array(false,0); 270 } 271 } 272 if (is_file($full_path_filename_depth)) { 273 $depth=file_get_contents($full_path_filename_depth); 274 $depth=substr($depth,0,-1); 275 } else { 276 $depth='0pt'; 277 } 278 return array($this->_picture_path_httpd.'/'.$filename.'png', 279 $depth 280 ); 281 } 282 public function searchCache($clean=0) { 283 $count=0; 284 $dp=opendir($this->_picture_path); 285 while ($file=readdir($dp)) { 286 if ($file != '.' && $file != '..') { 287 $count++; 288 if ($clean) { unlink($this->_picture_path.'/'.$file); } 289 } 290 } 291 closedir($dp); 292 return $count; 293 } 294 295 // ==================== 296 // private functions 297 // ==================== 298 299 /** 300 * wraps a minimalistic LaTeX document around the formula and returns 301 * a string containing the whole document as string. Customize if you 302 * want other fonts for example. 303 * 304 * @param string formula in LaTeX format 305 * @returns minimalistic LaTeX document containing the given formula 306 */ 307 private function wrap_formula($latex_formula) { 308 $string = '\documentclass['.$this->_font_size.'pt]{'.$this->_latexclass."}\n"; 309 $string .= "\\usepackage[latin1]{inputenc}\n"; 310 $string .= "\\usepackage{amsmath}\n"; 311 $string .= "\\usepackage{amsfonts}\n"; 312 $string .= "\\usepackage{amssymb}\n"; 313 $string .= "\\pagestyle{empty}\n"; 314 $string .= "\\newsavebox{\\formulabox}\n"; 315 $string .= "\\newlength{\\formulawidth}\n"; 316 $string .= "\\newlength{\\formulaheight}\n"; 317 $string .= "\\newlength{\\formuladepth}\n"; 318 $string .= "\\setlength{\\topskip}{0pt}\n"; 319 $string .= "\\setlength{\\parindent}{0pt}\n"; 320 $string .= "\\setlength{\\abovedisplayskip}{0pt}\n"; 321 $string .= "\\setlength{\\belowdisplayskip}{0pt}\n"; 322 $string .= "\\begin{lrbox}{\\formulabox}\n"; 323 $string .= $latex_formula."\n"; 324 $string .= "\\end{lrbox}\n"; 325 $string .= "\\settowidth {\\formulawidth} {\\usebox{\\formulabox}}\n"; 326 $string .= "\\settoheight{\\formulaheight} {\\usebox{\\formulabox}}\n"; 327 $string .= "\\settodepth {\\formuladepth} {\\usebox{\\formulabox}}\n"; 328 $string .= "\\newwrite\\foo\n"; 329 $string .= "\\immediate\\openout\\foo=\\jobname.depth\n"; 330 $string .= " \\setlength{\\formuladepth}{1.25\\formuladepth}\n"; 331 $string .= " \\addtolength{\\formuladepth}{0.5pt}\n"; 332 $string .= " \\immediate\\write\\foo{\\the\\formuladepth}\n"; 333 $string .= "\\closeout\\foo\n"; 334 $string .= "\\begin{document}\n"; 335 $string .= "\\usebox{\\formulabox}\n"; 336 $string .= "\\end{document}\n"; 337 338 return $string; 339 } 340 341 /** 342 * returns the dimensions of a picture file using 'identify' of the 343 * imagemagick tools. The resulting array can be adressed with either 344 * $dim[0] / $dim[1] or $dim['x'] / $dim['y'] 345 * 346 * @param string path to a picture 347 * @returns array containing the picture dimensions 348 */ 349 private function getDimensions($filename) { 350 $output=exec($this->_identify_path.' '.$filename); 351 $result=explode(' ',$output); 352 $dim=explode('x',$result[2]); 353 $dim['x'] = $dim[0]; 354 $dim['y'] = $dim[1]; 355 356 return $dim; 357 } 358 359 /** 360 * Renders a LaTeX formula by the using the following method: 361 * - write the formula into a wrapped tex-file in a temporary directory 362 * and change to it 363 * - Create a DVI file using latex (tetex) 364 * - Convert DVI file to Postscript (PS) using dvips (tetex) 365 * - convert, trim and add transparancy by using 'convert' from the 366 * imagemagick package. 367 * - Save the resulting image to the picture cache directory using an 368 * md5 hash as filename. Already rendered formulas can be found 369 * directly this way. 370 * 371 * @param string LaTeX formula 372 * @returns true if the picture has been successfully saved to the picture 373 * cache directory 374 */ 375 function renderLatex($latex_formula,$color,$filenamenoext) { 376 $colorstring='#'.$color; 377 $latex_document = $this->wrap_formula($latex_formula); 378 $current_dir = getcwd(); 379 chdir($this->_tmp_dir); 380 // create temporary latex file 381 $fp = fopen($this->_tmp_dir.'/'.$this->_tmp_filename.'.tex','w'); 382 fputs($fp,$latex_document); 383 fclose($fp); 384 385 // create temporary dvi file 386 $command = $this->_latex_path.' --interaction=nonstopmode '.$this->_tmp_filename.'.tex'; 387 exec($command,$output,$status_code); 388 if ($status_code) { 389 $this->cleanTemporaryDirectory(); 390 chdir($current_dir); 391 $this->_errorcode = 'compilation failed'; 392 $this->_errorextra = implode(' ',$output); 393 return false; 394 } 395 unset($output); 396 397 // convert dvi file to postscript using dvips 398 $command = $this->_dvips_path.' -E '.$this->_tmp_filename.'.dvi -o '.$this->_tmp_filename.'.ps'; 399 exec($command,$output,$status_code); 400 if ($status_code) { 401 $this->cleanTemporaryDirectory(); 402 chdir($current_dir); 403 $this->_errorcode = 'compilation failed'; 404 $this->_errorextra = $command; 405 return false; 406 } 407 408 // imagemagick convert ps to image and trim picture 409 // test whether the old or new method should be used 410 unset($output); 411 if ($this->_method == 'new') { 412 $command = $this->_convert_path. 413 ' -channel RGBA'. 414 ' -density '.$this->_formula_density. 415 ' -trim '.$this->_tmp_filename.'.ps '. 416 "-fill '".$colorstring."' -colorize 100,100,100 ". 417 $this->_tmp_filename.'.png'; 418 } else { 419 $command = $this->_convert_path. 420 ' -density '.$this->_formula_density. 421 ' -trim -transparent \"#FFFFFF\" '.$this->_tmp_filename.'.ps '. 422 $this->_tmp_filename.'.png'; 423 } 424 $status_code = exec($command); 425 exec($command,$output,$status_code); 426 if ($status_code) { 427 $this->cleanTemporaryDirectory(); 428 chdir($current_dir); 429 $this->_errorcode = 'compilation failed'; 430 $this->_errorextra = $command.' -> '.implode(' ',$output); 431 return false; 432 } 433 434 // test picture for correct dimensions 435 $dim = $this->getDimensions($this->_tmp_filename.'.png'); 436 437 if ( ($dim['x'] > $this->_xsize_limit) or ($dim['y'] > $this->_ysize_limit)) { 438 $this->cleanTemporaryDirectory(); 439 chdir($current_dir); 440 $this->_errorcode = 'image too large'; 441 $this->_errorextra = $dim['x'].'x'.$dim['y'].'>>'. 442 $this->_xsize_limit.'x'.$this->_ysize_limit; 443 return false; 444 } 445 446 // copy temporary formula file to cached formula directory 447 $latex_hash = md5($latex_formula); 448 // offset: change file name to include depth information 449 $depthfile = $this->_tmp_filename.'.depth'; 450 if ($color != '000000') { 451 $latex_hash=$color.'X'.$latex_hash; 452 } 453 454 $status_code = (copy($this->_tmp_filename.'.png',$filenamenoext.'png')); 455 if (!$status_code) { 456 chdir($current_dir); 457 $this->cleanTemporaryDirectory(); 458 $this->_errorcode = 'Could not copy file'; 459 $this->_errorextra = $this->_tmp_filename.'.png'; 460 } 461 if(is_readable($depthfile)) { 462 $offset = file($depthfile); 463 $status_code = (copy($this->_tmp_filename.'.depth',$filenamenoext.'depth')); 464 if (!$status_code) { 465 $this->_errorcode = 'Could not copy file'; 466 $this->_errorextra = $this->_tmp_filename.'.depth'; 467 } 468 } else { 469 $offset='0pt'; 470 } 471 chdir($current_dir); 472 $this->cleanTemporaryDirectory(); 473 return true; 474 } 475 476 /** 477 * Cleans the temporary directory 478 */ 479 function cleanTemporaryDirectory() { 480 $term=array('tex','aux','log','depth','dvi','ps','png'); 481 foreach ($term as $i) { 482 $fn=$this->_tmp_dir.'/'.$this->_tmp_filename.$i; 483 if (is_file($fn)) { 484 unlink($fn); 485 } 486 } 487 } 488 111 489 } 112 113 // ===================114 // public functions115 // ===================116 117 public static function defaultConfig() {118 $base=array(119 'xsizelimit' => '500',120 'ysizelimit' => '500',121 'stringlengthlimit' => '500',122 'formuladensity' => '120',123 'latexclass' => 'article',124 'fontsize' => '10',125 'method' => 'old'126 );127 $commands=array('latex','dvips','convert','identify');128 foreach ($commands as $i) {129 $base[$i.'path']='/usr/bin/'.$i;130 }131 132 return $base;133 }134 public static function getConfig() {135 global $core;136 $base = LatexRender::defaultConfig();137 if ($core->blog->settings->get('latexrender_options',true) === null) {138 // First appearance of options combo on any blog139 $core->blog->settings->setNameSpace('latexrender');140 $core->blog->settings->put('latexrender_options',141 '','string',142 'LatexRender options',true,true);143 }144 145 $user = $core->blog->settings->latexrender_options;146 if ($user === null) {147 $user = $base;148 } else {149 $user = @unserialize($user);150 if (!is_array($user)) {151 $user = array();152 }153 $user = array_merge($base,$user);154 }155 return $user;156 }157 public static function storeConfig($config,$oldconfig=null) {158 global $core;159 $fixed_options=array();160 $base = LatexRender::defaultConfig();161 foreach ($config as $name => $value) {162 if ((!isset($base[$name])) ||163 ($base[$name] != $value)) {164 $fixed_options[$name]=$value;165 }166 }167 if ($oldconfig) {168 foreach ($config as $name => $value) {169 if ((!isset($oldconfig[$name])) ||170 ($oldconfig[$name] != $value)) {171 $fixed_options[$name]=$value;172 }173 }174 175 }176 if (count($fixed_options)) {177 $core->blog->settings->setNameSpace('latexrender');178 $core->blog->settings->put('latexrender_options',179 serialize($fixed_options));180 }181 }182 183 /**184 * Returns the last error code185 *186 */187 public function getError() {188 return(__($this->_errorcode).' {'.$this->_errorextra.'}');189 }190 191 /**192 * Tries to match the LaTeX Formula given as argument against the193 * formula cache. If the picture has not been rendered before, it'll194 * try to render the formula and drop it in the picture cache directory.195 *196 * @param string formula in LaTeX format197 * @returns the webserver based URL to a picture which contains the198 * requested LaTeX formula. If anything fails, the resultvalue is false.199 */200 public function getFormulaHTML($latex_formula,$color='000000',$force=false) {201 $aurl=$this->getFormulaURL($latex_formula,$color,$force);202 $url = $aurl[0];203 $depth=$aurl[1];204 if ($depth) {205 $style_css = ' style="vertical-align:-'.$depth.';"';206 }207 $alt_latex_formula = htmlentities($latex_formula, ENT_QUOTES);208 $alt_latex_formula = str_replace("\r",' ',$alt_latex_formula);209 $alt_latex_formula = str_replace("\n",' ',$alt_latex_formula);210 if ($url) {211 $html='<img class="latex" src="'.$url.'" title="'.$alt_latex_formula.'" alt="'.$alt_latex_formula.'" '.$style_css.' />';212 } else {213 $html='<strong>[Unparsable formula ('.$this->getError().'): '.$alt_latex_formula.']</strong>';214 }215 return $html;216 }217 218 /**219 * Tries to match the LaTeX Formula given as argument against the220 * formula cache. If the picture has not been rendered before, it'll221 * try to render the formula and drop it in the picture cache directory.222 *223 * @param string formula in LaTeX format224 * @returns the webserver based URL to a picture which contains the225 * requested LaTeX formula. If anything fails, the resultvalue is false.226 */227 public function getFormulaURL($latex_formula,$color,$force) {228 // circumvent certain security functions of web-software which229 // is pretty pointless right here230 if ($this->_wronginit) {231 $this->_errorcode=$this->_initerrorcode;232 $this->_errorextra=$this->_initerrorextra;233 return array(false,0);234 } else {235 $this->_errorcode='';236 $this->_errorextra='';237 }238 $latex_formula = preg_replace('/>/i', '>', $latex_formula);239 $latex_formula = preg_replace('/</i', '<', $latex_formula);240 $formula_hash = md5($latex_formula);241 $filename = $formula_hash;242 if ($color!='000000') {243 $filename=$color.'X'.$filename.'.';244 } else {245 $filename=$filename.'.';246 }247 $full_path_filename = $this->_picture_path.'/'.$filename.'png';248 $full_path_filename_depth = $this->_picture_path.'/'.$filename.'depth';249 if ($force) {250 if (is_file($full_path_filename)) {251 unlink($full_path_filename);252 }253 if (is_file($full_path_filename_depth)) {254 unlink($full_path_filename_depth);255 }256 }257 if (!is_file($full_path_filename) || $force) {258 // security filter: reject too long formulas259 if (strlen($latex_formula) > $this->_string_length_limit) {260 $this->_errorcode = 'formula too long';261 $this->_errorextra = strlen($latex_formula).'>'.$this->_string_length_limit;262 return array(false,0);263 }264 265 // security filter: try to match against LaTeX-Tags Blacklist266 for ($i=0;$i<sizeof($this->_latex_tags_blacklist);$i++) {267 if (stristr($latex_formula,$this->_latex_tags_blacklist[$i])) {268 $this->_errorcode = 'blacklisted TeX operator';269 $this->_errorextra = $this->_latex_tags_blacklist[$i];270 return array(false,0);271 }272 }273 274 // security checks assume correct formula, let's render it275 if (!($this->renderLatex($latex_formula,$color,$this->_picture_path.'/'.$filename))) {276 // errorcode and errorextra should already be filled-in277 return array(false,0);278 }279 if (!is_file($full_path_filename)) {280 $this->_errorcode = 'file not moved correctly';281 $this->_errorextra = $full_path_filename;282 return array(false,0);283 }284 }285 if (is_file($full_path_filename_depth)) {286 $depth=file_get_contents($full_path_filename_depth);287 $depth=substr($depth,0,-1);288 } else {289 $depth='0pt';290 }291 return array($this->_picture_path_httpd.'/'.$filename.'png',292 $depth293 );294 }295 public function searchCache($clean=0) {296 $count=0;297 $dp=opendir($this->_picture_path);298 while ($file=readdir($dp)) {299 if ($file != '.' && $file != '..') {300 $count++;301 if ($clean) { unlink($this->_picture_path.'/'.$file); }302 }303 }304 closedir($dp);305 return $count;306 }307 308 // ====================309 // private functions310 // ====================311 312 /**313 * wraps a minimalistic LaTeX document around the formula and returns314 * a string containing the whole document as string. Customize if you315 * want other fonts for example.316 *317 * @param string formula in LaTeX format318 * @returns minimalistic LaTeX document containing the given formula319 */320 private function wrap_formula($latex_formula) {321 $string = '\documentclass['.$this->_font_size.'pt]{'.$this->_latexclass."}\n";322 $string .= "\\usepackage[latin1]{inputenc}\n";323 $string .= "\\usepackage{amsmath}\n";324 $string .= "\\usepackage{amsfonts}\n";325 $string .= "\\usepackage{amssymb}\n";326 $string .= "\\pagestyle{empty}\n";327 $string .= "\\newsavebox{\\formulabox}\n";328 $string .= "\\newlength{\\formulawidth}\n";329 $string .= "\\newlength{\\formulaheight}\n";330 $string .= "\\newlength{\\formuladepth}\n";331 $string .= "\\setlength{\\topskip}{0pt}\n";332 $string .= "\\setlength{\\parindent}{0pt}\n";333 $string .= "\\setlength{\\abovedisplayskip}{0pt}\n";334 $string .= "\\setlength{\\belowdisplayskip}{0pt}\n";335 $string .= "\\begin{lrbox}{\\formulabox}\n";336 $string .= $latex_formula."\n";337 $string .= "\\end{lrbox}\n";338 $string .= "\\settowidth {\\formulawidth} {\\usebox{\\formulabox}}\n";339 $string .= "\\settoheight{\\formulaheight} {\\usebox{\\formulabox}}\n";340 $string .= "\\settodepth {\\formuladepth} {\\usebox{\\formulabox}}\n";341 $string .= "\\newwrite\\foo\n";342 $string .= "\\immediate\\openout\\foo=\\jobname.depth\n";343 $string .= " \\setlength{\\formuladepth}{1.25\\formuladepth}\n";344 $string .= " \\addtolength{\\formuladepth}{0.5pt}\n";345 $string .= " \\immediate\\write\\foo{\\the\\formuladepth}\n";346 $string .= "\\closeout\\foo\n";347 $string .= "\\begin{document}\n";348 $string .= "\\usebox{\\formulabox}\n";349 $string .= "\\end{document}\n";350 351 return $string;352 }353 354 /**355 * returns the dimensions of a picture file using 'identify' of the356 * imagemagick tools. The resulting array can be adressed with either357 * $dim[0] / $dim[1] or $dim['x'] / $dim['y']358 *359 * @param string path to a picture360 * @returns array containing the picture dimensions361 */362 private function getDimensions($filename) {363 $output=exec($this->_identify_path.' '.$filename);364 $result=explode(' ',$output);365 $dim=explode('x',$result[2]);366 $dim['x'] = $dim[0];367 $dim['y'] = $dim[1];368 369 return $dim;370 }371 372 /**373 * Renders a LaTeX formula by the using the following method:374 * - write the formula into a wrapped tex-file in a temporary directory375 * and change to it376 * - Create a DVI file using latex (tetex)377 * - Convert DVI file to Postscript (PS) using dvips (tetex)378 * - convert, trim and add transparancy by using 'convert' from the379 * imagemagick package.380 * - Save the resulting image to the picture cache directory using an381 * md5 hash as filename. Already rendered formulas can be found382 * directly this way.383 *384 * @param string LaTeX formula385 * @returns true if the picture has been successfully saved to the picture386 * cache directory387 */388 function renderLatex($latex_formula,$color,$filenamenoext) {389 $colorstring='#'.$color;390 $latex_document = $this->wrap_formula($latex_formula);391 $current_dir = getcwd();392 chdir($this->_tmp_dir);393 // create temporary latex file394 $fp = fopen($this->_tmp_dir.'/'.$this->_tmp_filename.'.tex','w');395 fputs($fp,$latex_document);396 fclose($fp);397 398 // create temporary dvi file399 $command = $this->_latex_path.' --interaction=nonstopmode '.$this->_tmp_filename.'.tex';400 exec($command,$output,$status_code);401 if ($status_code) {402 $this->cleanTemporaryDirectory();403 chdir($current_dir);404 $this->_errorcode = 'compilation failed';405 $this->_errorextra = implode(' ',$output);406 return false;407 }408 unset($output);409 410 // convert dvi file to postscript using dvips411 $command = $this->_dvips_path.' -E '.$this->_tmp_filename.'.dvi -o '.$this->_tmp_filename.'.ps';412 exec($command,$output,$status_code);413 if ($status_code) {414 $this->cleanTemporaryDirectory();415 chdir($current_dir);416 $this->_errorcode = 'compilation failed';417 $this->_errorextra = $command;418 return false;419 }420 421 // imagemagick convert ps to image and trim picture422 // test whether the old or new method should be used423 unset($output);424 if ($this->_method == 'new') {425 $command = $this->_convert_path.426 ' -channel RGBA'.427 ' -density '.$this->_formula_density.428 ' -trim '.$this->_tmp_filename.'.ps '.429 "-fill '".$colorstring."' -colorize 100,100,100 ".430 $this->_tmp_filename.'.png';431 } else {432 $command = $this->_convert_path.433 ' -density '.$this->_formula_density.434 ' -trim -transparent \"#FFFFFF\" '.$this->_tmp_filename.'.ps '.435 $this->_tmp_filename.'.png';436 }437 $status_code = exec($command);438 exec($command,$output,$status_code);439 if ($status_code) {440 $this->cleanTemporaryDirectory();441 chdir($current_dir);442 $this->_errorcode = 'compilation failed';443 $this->_errorextra = $command.' -> '.implode(' ',$output);444 return false;445 }446 447 // test picture for correct dimensions448 $dim = $this->getDimensions($this->_tmp_filename.'.png');449 450 if ( ($dim['x'] > $this->_xsize_limit) or ($dim['y'] > $this->_ysize_limit)) {451 $this->cleanTemporaryDirectory();452 chdir($current_dir);453 $this->_errorcode = 'image too large';454 $this->_errorextra = $dim['x'].'x'.$dim['y'].'>>'.455 $this->_xsize_limit.'x'.$this->_ysize_limit;456 return false;457 }458 459 // copy temporary formula file to cached formula directory460 $latex_hash = md5($latex_formula);461 // offset: change file name to include depth information462 $depthfile = $this->_tmp_filename.'.depth';463 if ($color != '000000') {464 $latex_hash=$color.'X'.$latex_hash;465 }466 467 $status_code = (copy($this->_tmp_filename.'.png',$filenamenoext.'png'));468 if (!$status_code) {469 chdir($current_dir);470 $this->cleanTemporaryDirectory();471 $this->_errorcode = 'Could not copy file';472 $this->_errorextra = $this->_tmp_filename.'.png';473 }474 if(is_readable($depthfile)) {475 $offset = file($depthfile);476 $status_code = (copy($this->_tmp_filename.'.depth',$filenamenoext.'depth'));477 if (!$status_code) {478 $this->_errorcode = 'Could not copy file';479 $this->_errorextra = $this->_tmp_filename.'.depth';480 }481 } else {482 $offset='0pt';483 }484 chdir($current_dir);485 $this->cleanTemporaryDirectory();486 return true;487 }488 489 /**490 * Cleans the temporary directory491 */492 function cleanTemporaryDirectory() {493 $term=array('tex','aux','log','depth','dvi','ps','png');494 foreach ($term as $i) {495 $fn=$this->_tmp_dir.'/'.$this->_tmp_filename.$i;496 if (is_file($fn)) {497 unlink($fn);498 }499 }500 }501 502 }503 504 490 ?> -
plugins/latexrender/doc/LISEZMOI.html
r1043 r1066 37 37 au contenu des billets (note: comme l'auteur en utilise plusieurs, il 38 38 considère ceci comme un bug).</p> 39 <p class="version">La version courante de cette extension est 0.9 (local svn 333).</p><p class="licence">Cette extension est sous la licence <a href="http://creativecommons.org/licenses/by/3.0/deed.fr" hreflang="fr">CC-BY</a>.</p>39 <p class="version">La version courante de cette extension est 0.9.1 (local svn 348).</p><p class="licence">Cette extension est sous la licence <a href="http://www.gnu.org/licenses/lgpl-2.1.html" hreflang="en">GPL version 2.0</a>.</p> 40 40 <h3>Utilisation</h3> 41 41 <h4>Utilisation basique</h4> … … 76 76 <p>FFFFFF est à remplacer par la <a href="http://www.commentcamarche.net/html/htmlcouleurs.php3" hreflang="fr">couleur voulue en hexadécimal</a> (ici, blanc; 77 77 jaune est FFFF00, rouge est FF0000...).</p> 78 <div class="bug"><h3>Pour signaler un bug ou aider cette extension</h3><p>Le mieux est de me contacter <a href="http://jean-christophe.dubacq.fr/pages/Contact">par courrier</a> (pour un bug) ou de laisser un commentaire (pour dire que vous avez testé cette extension). En cas de mise à jour, je modifierai ce billet.</p></div><div class="changelog"><h3>Liste des changements</h3><p>Note : ce journal est non-exhaustif, généré automatiquement, en anglais, et sans doute non-informatif avant 2009.</p><ul><li>Local SVN release 3 33 (jcdubacq,2009-04-18)<ul> <li>Allow for public path to be an absolute path, release</li> </ul></li> <li>Local SVN release 303 (jcdubacq,2009-01-27)<ul> <li>Fix locales</li> </ul></li> <li>Local SVN release 297 (jcdubacq,2009-01-26)<ul> <li>Adapt to version 0.3 of stacker (behavior initStacker)</li> </ul></li> <li>Local SVN release 292 (jcdubacq,2009-01-22)<ul> <li>Update documentation, release new version 0.6</li> </ul></li> <li>Local SVN release 259 (jcdubacq,2008-11-18)<ul> <li>Fix public url usage in admin area</li> </ul></li> <li>Local SVN release 205 (jcdubacq,2008-07-24)<ul> <li>Add documentation, new version</li> </ul></li> <li>Local SVN release 187 (jcdubacq,2008-07-09)<ul> <li>Add admin page, rewrite latexrender class to better fit the needs of DC2</li> </ul></li> <li>Local SVN release 168 (jcdubacq,2008-05-06)<ul> <li>Order plugins and themes</li> </ul></li> <li>Local SVN release 47 (jcdubacq,2008-02-15)<ul> <li>Add latexrender plugin</li> </ul></li></ul></div>78 <div class="bug"><h3>Pour signaler un bug ou aider cette extension</h3><p>Le mieux est de me contacter <a href="http://jean-christophe.dubacq.fr/pages/Contact">par courrier</a> (pour un bug) ou de laisser un commentaire (pour dire que vous avez testé cette extension). En cas de mise à jour, je modifierai ce billet.</p></div><div class="changelog"><h3>Liste des changements</h3><p>Note : ce journal est non-exhaustif, généré automatiquement, en anglais, et sans doute non-informatif avant 2009.</p><ul><li>Local SVN release 348 (jcdubacq,2009-04-22)<ul> <li>Fix documentation</li> </ul></li> <li>Local SVN release 346 (jcdubacq,2009-04-22)<ul> <li>Fix documentation</li> </ul></li> <li>Local SVN release 333 (jcdubacq,2009-04-18)<ul> <li>Allow for public path to be an absolute path, release</li> </ul></li> <li>Local SVN release 303 (jcdubacq,2009-01-27)<ul> <li>Fix locales</li> </ul></li> <li>Local SVN release 297 (jcdubacq,2009-01-26)<ul> <li>Adapt to version 0.3 of stacker (behavior initStacker)</li> </ul></li> <li>Local SVN release 292 (jcdubacq,2009-01-22)<ul> <li>Update documentation, release new version 0.6</li> </ul></li> <li>Local SVN release 259 (jcdubacq,2008-11-18)<ul> <li>Fix public url usage in admin area</li> </ul></li> <li>Local SVN release 205 (jcdubacq,2008-07-24)<ul> <li>Add documentation, new version</li> </ul></li> <li>Local SVN release 187 (jcdubacq,2008-07-09)<ul> <li>Add admin page, rewrite latexrender class to better fit the needs of DC2</li> </ul></li> <li>Local SVN release 168 (jcdubacq,2008-05-06)<ul> <li>Order plugins and themes</li> </ul></li> <li>Local SVN release 47 (jcdubacq,2008-02-15)<ul> <li>Add latexrender plugin</li> </ul></li></ul></div> 79 79 <h3>Travail restant à faire</h3> 80 80 <ul><li>Faire une version qui ne dépend pas de l'extension <code>stacker</code></li> -
plugins/latexrender/doc/LISEZMOI.txt
r1043 r1066 43 43 ceci comme un bug). 44 44 45 La version courante de cette extension est 0.9 (local svn 333).45 La version courante de cette extension est 0.9.1 (local svn 348). 46 46 47 Cette extension est sous la licence [5] CC-BY.47 Cette extension est sous la licence [5]GPL version 2.0. 48 48 49 49 === Utilisation === … … 101 101 Note : ce journal est non-exhaustif, généré automatiquement, en anglais, et sans 102 102 doute non-informatif avant 2009. 103 * Local SVN release 348 (jcdubacq,2009-04-22) 104 + Fix documentation 105 * Local SVN release 346 (jcdubacq,2009-04-22) 106 + Fix documentation 103 107 * Local SVN release 333 (jcdubacq,2009-04-18) 104 108 + Allow for public path to be an absolute path, release … … 136 140 3. http://www.imagemagick.org/script/index.php 137 141 4. http://jean-christophe.dubacq.fr/post/stacker 138 5. http:// creativecommons.org/licenses/by/3.0/deed.fr142 5. http://www.gnu.org/licenses/lgpl-2.1.html 139 143 6. http://www.commentcamarche.net/html/htmlcouleurs.php3 140 144 7. http://jean-christophe.dubacq.fr/pages/Contact -
plugins/latexrender/doc/README.html
r1043 r1066 48 48 contents (note: as the author uses several of them, this is therefore 49 49 considered as a bug).</p> 50 <p class="version">The current version of this plugin is 0.9 (local svn 333).</p><p class="licence">This plugin is licensed under <a href="http://creativecommons.org/licenses/by/3.0/deed.en" hreflang="en">CC-BY</a>.</p>50 <p class="version">The current version of this plugin is 0.9.1 (local svn 348).</p><p class="licence">This plugin is licensed under <a href="http://www.gnu.org/licenses/lgpl-2.1.html" hreflang="en">GPL version 2.0</a>.</p> 51 51 <h3>Usage</h3> 52 52 <h4>Basic usage</h4> … … 87 87 <pre class="code"><?php $core->theme_color='FFFFFF'; ?></pre> 88 88 <p>FFFFFF is to be replaced by the desired colour, coded in hexadecimal (here, white; yellow is FFFF00, red is FF0000).</p> 89 <div class="bug"><h3>To tell me about a bug or helping this plugin</h3><p>The best way is to contact me <a href="http://jean-christophe.dubacq.fr/pages/Contact">by mail</a> (for a bug) or leave a comment (telling me you tested this extension) at the maintenance page. In case of an update, I will modify the maintenance page accordingly.</p></div><div class="changelog"><p>Note: this changelog is not complete, automatically generated and probably not even informative before 2009.</p><ul><li>Local SVN release 3 33 (jcdubacq,2009-04-18)<ul> <li>Allow for public path to be an absolute path, release</li> </ul></li> <li>Local SVN release 303 (jcdubacq,2009-01-27)<ul> <li>Fix locales</li> </ul></li> <li>Local SVN release 297 (jcdubacq,2009-01-26)<ul> <li>Adapt to version 0.3 of stacker (behavior initStacker)</li> </ul></li> <li>Local SVN release 292 (jcdubacq,2009-01-22)<ul> <li>Update documentation, release new version 0.6</li> </ul></li> <li>Local SVN release 259 (jcdubacq,2008-11-18)<ul> <li>Fix public url usage in admin area</li> </ul></li> <li>Local SVN release 205 (jcdubacq,2008-07-24)<ul> <li>Add documentation, new version</li> </ul></li> <li>Local SVN release 187 (jcdubacq,2008-07-09)<ul> <li>Add admin page, rewrite latexrender class to better fit the needs of DC2</li> </ul></li> <li>Local SVN release 168 (jcdubacq,2008-05-06)<ul> <li>Order plugins and themes</li> </ul></li> <li>Local SVN release 47 (jcdubacq,2008-02-15)<ul> <li>Add latexrender plugin</li> </ul></li></ul></div>89 <div class="bug"><h3>To tell me about a bug or helping this plugin</h3><p>The best way is to contact me <a href="http://jean-christophe.dubacq.fr/pages/Contact">by mail</a> (for a bug) or leave a comment (telling me you tested this extension) at the maintenance page. In case of an update, I will modify the maintenance page accordingly.</p></div><div class="changelog"><p>Note: this changelog is not complete, automatically generated and probably not even informative before 2009.</p><ul><li>Local SVN release 348 (jcdubacq,2009-04-22)<ul> <li>Fix documentation</li> </ul></li> <li>Local SVN release 346 (jcdubacq,2009-04-22)<ul> <li>Fix documentation</li> </ul></li> <li>Local SVN release 333 (jcdubacq,2009-04-18)<ul> <li>Allow for public path to be an absolute path, release</li> </ul></li> <li>Local SVN release 303 (jcdubacq,2009-01-27)<ul> <li>Fix locales</li> </ul></li> <li>Local SVN release 297 (jcdubacq,2009-01-26)<ul> <li>Adapt to version 0.3 of stacker (behavior initStacker)</li> </ul></li> <li>Local SVN release 292 (jcdubacq,2009-01-22)<ul> <li>Update documentation, release new version 0.6</li> </ul></li> <li>Local SVN release 259 (jcdubacq,2008-11-18)<ul> <li>Fix public url usage in admin area</li> </ul></li> <li>Local SVN release 205 (jcdubacq,2008-07-24)<ul> <li>Add documentation, new version</li> </ul></li> <li>Local SVN release 187 (jcdubacq,2008-07-09)<ul> <li>Add admin page, rewrite latexrender class to better fit the needs of DC2</li> </ul></li> <li>Local SVN release 168 (jcdubacq,2008-05-06)<ul> <li>Order plugins and themes</li> </ul></li> <li>Local SVN release 47 (jcdubacq,2008-02-15)<ul> <li>Add latexrender plugin</li> </ul></li></ul></div> 90 90 <h3>To do</h3> 91 91 <ul> -
plugins/latexrender/doc/README.txt
r1043 r1066 40 40 considered as a bug). 41 41 42 The current version of this plugin is 0.9 (local svn 333).42 The current version of this plugin is 0.9.1 (local svn 348). 43 43 44 This plugin is licensed under [5] CC-BY.44 This plugin is licensed under [5]GPL version 2.0. 45 45 46 46 === Usage === … … 95 95 Note: this changelog is not complete, automatically generated and probably not 96 96 even informative before 2009. 97 * Local SVN release 348 (jcdubacq,2009-04-22) 98 + Fix documentation 99 * Local SVN release 346 (jcdubacq,2009-04-22) 100 + Fix documentation 97 101 * Local SVN release 333 (jcdubacq,2009-04-18) 98 102 + Allow for public path to be an absolute path, release … … 130 134 3. http://www.imagemagick.org/script/index.php 131 135 4. http://jean-christophe.dubacq.fr/post/stacker 132 5. http:// creativecommons.org/licenses/by/3.0/deed.en136 5. http://www.gnu.org/licenses/lgpl-2.1.html 133 137 6. http://jean-christophe.dubacq.fr/pages/Contact -
plugins/latexrender/index.php
r760 r1066 1 1 <?php 2 // ***** BEGIN LICENSE BLOCK ***** 3 // This file is (c) Jean-Christophe Dubacq. 4 // Licensed under CC-BY licence. 5 // 6 // ***** END LICENSE BLOCK ***** 2 # -- BEGIN LICENSE BLOCK ---------------------------------- 3 # This file is part of latexrender, a plugin for Dotclear. 4 # 5 # Copyright (c) 2009 Jean-Christophe Dubacq 6 # jcdubacq1@free.fr 7 # 8 # Licensed under the LGPL version 2.1 license. 9 # A copy of this license is available in LICENSE file or at 10 # http://www.gnu.org/licenses/lgpl-2.1.html 11 # -- END LICENSE BLOCK ------------------------------------ 7 12 8 13 if (!defined('DC_CONTEXT_ADMIN')) { return; } … … 12 17 $core->latex=new LatexRender($core); 13 18 $method_type = array( 14 15 16 19 __('Safe method') => 'old', 20 __('Colorization method') => 'new' 21 ); 17 22 18 23 try 19 24 { 20 // Create settings if they don't exist21 $options=LatexRender::getConfig();22 if ($_POST['reset']) {23 $options=LatexRender::defaultConfig();24 LatexRender::storeConfig($options);25 http::redirect($p_url);26 }25 // Create settings if they don't exist 26 $options=LatexRender::getConfig(); 27 if ($_POST['reset']) { 28 $options=LatexRender::defaultConfig(); 29 LatexRender::storeConfig($options); 30 http::redirect($p_url); 31 } 27 32 } catch (Exception $e) { 28 $core->error->add($e->getMessage());33 $core->error->add($e->getMessage()); 29 34 } 30 35 if (isset($_POST['latexrender_latexpath']) && !($_POST['reset']) 31 36 && !($_POST['clean'])) { 32 $boptions=LatexRender::defaultConfig(); 33 foreach ($boptions as $key => $value) { 34 if (isset($_POST['latexrender_'.$key])) { 35 $boptions[$key]=$_POST['latexrender_'.$key]; 36 } else { 37 $boptions[$key]=''; 37 $boptions=LatexRender::defaultConfig(); 38 foreach ($boptions as $key => $value) { 39 if (isset($_POST['latexrender_'.$key])) { 40 $boptions[$key]=$_POST['latexrender_'.$key]; 41 } else { 42 $boptions[$key]=''; 43 } 38 44 } 39 } 40 LatexRender::storeConfig($boptions,$options); 41 http::redirect($p_url.'&up=1'); 45 LatexRender::storeConfig($boptions,$options); 46 http::redirect($p_url.'&up=1'); 42 47 } 43 48 if (isset($_POST['clean'])) { 44 http::redirect($p_url.'&clean='.$core->latex->searchCache(1));49 http::redirect($p_url.'&clean='.$core->latex->searchCache(1)); 45 50 } 46 51 ?><html> … … 51 56 echo '<h2>LaTeXrender</h2>'; 52 57 if (!empty($_GET['up'])) { 53 echo '<p class="message">'.__('Settings have been successfully updated.').54 '</p>';58 echo '<p class="message">'.__('Settings have been successfully updated.'). 59 '</p>'; 55 60 } 56 61 if (!empty($_GET['clean'])) { 57 echo '<p class="message">'.__('Cache has been successfully cleaned.').58 '</p>';62 echo '<p class="message">'.__('Cache has been successfully cleaned.'). 63 '</p>'; 59 64 } 60 65 echo '<h3>'.__('Plugin auto-test').'</h3>'; … … 67 72 echo '<p>'.__('Files in cache:').$core->latex->searchCache(0).'</p>'; 68 73 if ($core->stacker) { 69 echo __('<p>The stacker extension is installed. Public display will take place.</p>');74 echo __('<p>The stacker extension is installed. Public display will take place.</p>'); 70 75 } else { 71 echo __('<p>Please install the stacker extension for public display to take place.</p>');76 echo __('<p>Please install the stacker extension for public display to take place.</p>'); 72 77 } 73 78 echo '</body>';
Note: See TracChangeset
for help on using the changeset viewer.