LaTeX Plugin for DokuWiki
Inline Offset
The problem is that the basic plugin returns an image and just puts that right in line with the rest of the text. Of course, if—for instance—we have a subscript, the browser believes that the bottom of that subscript is the baseline. The effect is an expression which sticks up out of the line of text. For example, the equation
sticks up out of the line. We would hope that the bottoms of the letters would be at the baseline, rather than the bottoms of the parentheses.
Suppose we magically obtain the baseline offset; suppose that it is 4pt. If, in the image inclusion tag (in the HTML) we put the following:
style="vertical-align: -4pt;"
the image would look as though it were properly aligned. Thus, instead of this:
, we would have something more like
that.
We can actually get the offset using a trick I stumbled across on this page. We need to rewrite the class.latexrender.php a little, but nothing too insanely complicated. I’ve modified the tex document found at that link slightly, and incorporated it with my own version of class.latexrender.php, arriving at the following code:
Code for class.latexrender_offset.php:
<?php /** * Modified version of Benjamin Zeiss's LaTeX Rendering class * This version accounts for the vertical offset of LaTeX formulas, * and allows for inline formulas to be displayed aligned with the * surrounding text. * Modifications by Mike Boyle. */ /** * LaTeX Rendering Class * Copyright (C) 2003 Benjamin Zeiss <zeiss@math.uni-goettingen.de> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * -------------------------------------------------------------------- * @author Benjamin Zeiss <zeiss@math.uni-goettingen.de> * @version v0.8 * @package latexrender * */ class LatexRender_Offset { // ==================================================================================== // Variable Definitions // ==================================================================================== var $_picture_path = ""; var $_picture_path_httpd = ""; var $_tmp_dir = ""; // i was too lazy to write mutator functions for every single program used // just access it outside the class or change it here if nescessary var $_latex_path = "/usr/bin/latex"; var $_pdfcrop_path = "/usr/local/bin/pdfcrop"; var $_dvips_path = "/usr/bin/dvips"; var $_convert_path = "/usr/bin/convert"; var $_identify_path="/usr/bin/identify"; var $_formula_density = 120; var $_xsize_limit = 2000; var $_ysize_limit = 4000; var $_string_length_limit = 5000; var $_font_size = 12; var $_latexclass = "article"; //use extarticle class if you wish to have smaller fonts var $_tmp_filename; var $_image_format = "png"; //change to jpg if you prefer // this most certainly needs to be extended. in the long term it is planned to use // a positive list for more security. this is hopefully enough for now. i'd be glad // to receive more bad tags ! var $_latex_tags_blacklist = array( "include","def","command","loop","repeat","open","toks","output","input", "catcode","name","^^", "\\every","\\errhelp","\\errorstopmode","\\scrollmode","\\nonstopmode","\\batchmode", "\\read","\\write","csname","\\newhelp","\\uppercase", "\\lowercase","\\relax", "\\aftergroup","\\afterassignment","\\expandafter","\\noexpand","\\special" ); var $_errorcode = 0; var $_errorextra = ""; // ==================================================================================== // constructor // ==================================================================================== /** * Initializes the class * * @param string path where the rendered pictures should be stored * @param string same path, but from the httpd chroot */ function LatexRender_Offset($picture_path,$picture_path_httpd,$tmp_dir) { $this->_picture_path = $picture_path; $this->_picture_path_httpd = $picture_path_httpd; $this->_tmp_dir = $tmp_dir; $this->_tmp_filename = md5(rand()); } // ==================================================================================== // public functions // ==================================================================================== /** * Picture path Mutator function * * @param string sets the current picture path to a new location */ function setPicturePath($name) { $this->_picture_path = $name; } /** * Picture path Mutator function * * @returns the current picture path */ function getPicturePath() { return $this->_picture_path; } /** * Picture path HTTPD Mutator function * * @param string sets the current httpd picture path to a new location */ function setPicturePathHTTPD($name) { $this->_picture_path_httpd = $name; } /** * Picture path HTTPD Mutator function * * @returns the current picture path */ function getPicturePathHTTPD() { return $this->_picture_path_httpd; } /** * Tries to match the LaTeX Formula given as argument against the * formula cache. If the picture has not been rendered before, it'll * try to render the formula and drop it in the picture cache directory. * * @param string formula in LaTeX format * @returns the webserver based URL to a picture which contains the * requested LaTeX formula. If anything fails, the resultvalue is false. */ function getFormulaURL($latex_formula) { // circumvent certain security functions of web-software which // is pretty pointless right here $latex_formula = preg_replace("/>/i", ">", $latex_formula); $latex_formula = preg_replace("/</i", "<", $latex_formula); $formula_hash = md5($latex_formula); $filename = $formula_hash.".".$this->_image_format; $full_path_filename = $this->getPicturePath()."/".$filename; if (is_file($full_path_filename)) { return $this->getPicturePathHTTPD()."/".$filename; } else { // security filter: reject too long formulas if (strlen($latex_formula) > $this->_string_length_limit) { $this->_errorcode = 1; return false; } // security filter: try to match against LaTeX-Tags Blacklist for ($i=0;$i<sizeof($this->_latex_tags_blacklist);$i++) { if (stristr($latex_formula,$this->_latex_tags_blacklist[$i])) { $this->_errorcode = 2; return false; } } // security checks assume correct formula, let's render it if ($this->renderLatex($latex_formula)) { return $this->getPicturePathHTTPD()."/".$filename; } else { // uncomment if required // $this->_errorcode = 3; return false; } } } // ==================================================================================== // private functions // ==================================================================================== /** * wraps a minimalistic LaTeX document around the formula and returns a string * containing the whole document as string. Customize if you want other fonts for * example. * * @param string formula in LaTeX format * @returns minimalistic LaTeX document containing the given formula */ function wrap_formula($latex_formula) { $string = "\documentclass[".$this->_font_size."pt]{".$this->_latexclass."}\n"; $string .= "\usepackage[latin1]{inputenc}\n"; $string .= "\usepackage{amsmath}\n"; $string .= "\usepackage{amsfonts}\n"; $string .= "\usepackage{amssymb}\n"; $string .= "\usepackage{bm}\n"; $string .= "\usepackage{mathrsfs}\n"; $string .= "\usepackage{color}\n"; $string .= "\pagestyle{empty}\n"; $string .= "\\newsavebox{\formulabox}\n"; $string .= "\\newlength{\formulawidth}\n"; $string .= "\\newlength{\formulaheight}\n"; $string .= "\\newlength{\formuladepth}\n"; $string .= "\setlength{\\topskip}{0pt}\n"; $string .= "\setlength{\parindent}{0pt}\n"; $string .= "\setlength{\abovedisplayskip}{0pt}\n"; $string .= "\setlength{\belowdisplayskip}{0pt}\n"; $string .= "\definecolor{MyRed}{rgb}{0.408,0.094,0.059}\n"; // For colored output $string .= "\begin{lrbox}{\formulabox}\n"; $string .= "{\\color{MyRed}\n"; // For colored output $string .= $latex_formula."\n"; $string .= "}\n"; // For colored output $string .= "\end{lrbox}\n"; $string .= "\settowidth {\formulawidth} {\usebox{\formulabox}}\n"; $string .= "\settoheight{\formulaheight} {\usebox{\formulabox}}\n"; $string .= "\settodepth {\formuladepth} {\usebox{\formulabox}}\n"; $string .= "\\newwrite\foo\n"; $string .= "\immediate\openout\foo=\jobname.depth\n"; $string .= " \addtolength{\formuladepth} {1pt}\n"; $string .= " \immediate\write\foo{\\the\formuladepth}\n"; $string .= "\closeout\foo\n"; $string .= "\begin{document}\n"; $string .= "\usebox{\formulabox}\n"; $string .= "\end{document}\n"; return $string; } /** * returns the dimensions of a picture file using 'identify' of the * imagemagick tools. The resulting array can be adressed with either * $dim[0] / $dim[1] or $dim["x"] / $dim["y"] * * @param string path to a picture * @returns array containing the picture dimensions */ function getDimensions($filename) { $output=exec($this->_identify_path." ".$filename); $result=explode(" ",$output); $dim=explode("x",$result[2]); $dim["x"] = $dim[0]; $dim["y"] = $dim[1]; return $dim; } /** * Renders a LaTeX formula by the using the following method: * - write the formula into a wrapped tex-file in a temporary directory * and change to it * - Create a DVI file using latex (tetex) * - Convert DVI file to Postscript (PS) using dvips (tetex) * - convert, trim and add transparancy by using 'convert' from the * imagemagick package. * - Save the resulting image to the picture cache directory using an * md5 hash as filename. Already rendered formulas can be found directly * this way. * * @param string LaTeX formula * @returns true if the picture has been successfully saved to the picture * cache directory */ function renderLatex($latex_formula) { $latex_document = $this->wrap_formula($latex_formula); $current_dir = getcwd(); chdir($this->_tmp_dir); // create temporary latex file $fp = fopen($this->_tmp_dir."/".$this->_tmp_filename.".tex","a+"); fputs($fp,$latex_document); fclose($fp); // create temporary dvi file $command = $this->_latex_path." --interaction=nonstopmode ".$this->_tmp_filename.".tex"; $status_code = exec($command); if (!$status_code) { $this->cleanTemporaryDirectory(); chdir($current_dir); $this->_errorcode = 4; return false; } // convert dvi file to postscript using dvips $command = $this->_dvips_path." -E ".$this->_tmp_filename.".dvi"." -o " .$this->_tmp_filename.".ps"; $status_code = exec($command); // imagemagick convert ps to image and trim picture $command = $this->_convert_path." -density ".$this->_formula_density. " -trim -transparent \"#FFFFFF\" ".$this->_tmp_filename.".ps ". $this->_tmp_filename.".".$this->_image_format; $status_code = exec($command); // test picture for correct dimensions $dim = $this->getDimensions($this->_tmp_filename.".".$this->_image_format); if ( ($dim["x"] > $this->_xsize_limit) or ($dim["y"] > $this->_ysize_limit)) { $this->cleanTemporaryDirectory(); chdir($current_dir); $this->_errorcode = 5; $this->_errorextra = ": " . $dim["x"] . "x" . number_format($dim["y"],0,"",""); return false; } // copy temporary formula file to cahed formula directory $latex_hash = md5($latex_formula); $filename = $this->getPicturePath()."/".$latex_hash.".".$this->_image_format; $status_code = copy($this->_tmp_filename.".".$this->_image_format,$filename); $status_code = copy($this->_tmp_filename.".depth",$this->getPicturePath()."/" .$latex_hash.".depth"); $this->cleanTemporaryDirectory(); if (!$status_code) { chdir($current_dir); $this->_errorcode = 6; return false; } chdir($current_dir); return true; } /** * Cleans the temporary directory */ function cleanTemporaryDirectory() { $current_dir = getcwd(); chdir($this->_tmp_dir); unlink($this->_tmp_dir."/".$this->_tmp_filename.".tex"); unlink($this->_tmp_dir."/".$this->_tmp_filename.".aux"); unlink($this->_tmp_dir."/".$this->_tmp_filename.".log"); unlink($this->_tmp_dir."/".$this->_tmp_filename.".dvi"); unlink($this->_tmp_dir."/".$this->_tmp_filename.".ps"); unlink($this->_tmp_dir."/".$this->_tmp_filename.".depth"); unlink($this->_tmp_dir."/".$this->_tmp_filename.".".$this->_image_format); chdir($current_dir); } } ?>
Note that I want a text color which isn’t black. If you want black, just comment out those lines.
Now, there is no need to do the extra work for formulas which are displayed on their own. I have a separate syntax which calls it for inline formulas, then calls the original classlatexrender for formulas on their own lines. Here is my version of Alexander Krause’s latexrender plugin for the inline case:
Code for syntax/dollar.php
<?php if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/'); 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_latex_dollar extends DokuWiki_Syntax_Plugin { /** settings * */ var $_tmp_dir = '/tmp'; // This is reset to a DokuWiki-local directory below var $_image_format='png'; var $_style_css=''; /** * return some info */ function getInfo(){ return array( 'author' => 'Alexander Krause (changes by Michael Boyle)', 'email' => 'alexander.krause@erazor-zone.de', 'date' => '2006-05-05', 'name' => 'Latex Plugin; dollar extension', 'desc' => 'Enables inline LaTeX syntax in wikitext', 'url' => '' ); } function getType(){ return 'protected'; } function getSort(){ return 405; } function connectTo($mode) { $this->Lexer->addEntryPattern('\$(?=.*\$)',$mode,'plugin_latex_dollar'); } function postConnect() { $this->Lexer->addExitPattern('\$','plugin_latex_dollar'); } /** * Handle the match */ function handle($match, $state, $pos, &$handler){ $match = str_replace("$","",$match); return array($match, NULL); } /** * Create output */ function render($mode, &$renderer, $data) { global $conf; $this->_tmp_dir = $conf['mediadir'] . '/latex/tmp'; if($mode == 'xhtml' && strlen($data[0]) > 0) { $data[0] = "$" . $data[0] . "$"; if ( !is_dir($conf['mediadir'] . '/latex') ) { mkdir($conf['mediadir'] . '/latex', 0777-$conf['dmask']); } $hash = md5(serialize($data)); $filename = $conf['mediadir'] . '/latex/'.$hash.'.'.$this->_image_format; $url = DOKU_BASE.'lib/exe/fetch.php?cache='.$cache.'&media=' .urlencode('latex:'.$hash.'.'.$this->_image_format); $style_css = ''; if ( is_readable($filename) ) { $depthfile = preg_replace('|png$|','depth',$filename); if(is_readable($depthfile)) { $offset = file($depthfile); $style_css = 'style="vertical-align:-'.rtrim($offset[0]).';"'; } else { $style_css = 'style="vertical-align:-2pt;"'; } $renderer->doc .= ' <img '. $style_css .' src="'.$url.'" alt="'.$data[0].'" />'; return true; } if (!$this->createImage($filename, $data[0])) { $depthfile = preg_replace('|png$|','depth',$filename); if(is_readable($depthfile)) { $offset = file($depthfile); $style_css = 'style="vertical-align:-'.rtrim($offset[0]).';"'; } else { $style_css = 'style="vertical-align:-2pt;"'; } $renderer->doc .= ' <img '. $style_css .' src="'.$url.'" alt="'.$data[0].'" />'; } else { $renderer->doc .= '**ERROR RENDERING LATEX**'; } return true; } return false; } function createImage($filename, &$data) { global $conf; require_once(DOKU_PLUGIN.'latex/class.latexrender_offset.php'); // require_once(DOKU_PLUGIN.'latex/class.latexrender.php'); $latex = new LatexRender_Offset($this->_tmp_dir,$this->_tmp_dir,$this->_tmp_dir); $latex->_image_format=$this->_image_format; if ($url = $latex->getFormulaURL($data)) { rename($url,$filename); $url = preg_replace('|png$|','depth',$url); $filename = preg_replace('|png$|','depth',$filename); if(is_readable($filename)) { rename($url,$filename); } rename($url,$filename); } return 0; } }
New Syntax
I use a lot of latex, as does the group I work in. I found that people (including, but not limited to me) didn’t want to use the latex plugin because they would have to enter something like <latex>\alpha</latex>, and would invariably forget the direction of that second slash.
To cure this problem, I extended the syntax used in the original plugin, so that people could enter math just like they do in a regular latex document. That is, by entering something like $E=mc^2$, the inline formula
would appear. Similarly, we can now enter things like
\begin{eqnarray*}
\Psi_0 &=& -C_{abcd} Y_0^a m^b Y_1^c m^d e^{-2i\gamma} \\
\Psi_4 &=& -C_{abcd} Y_1^a \bar{m}^b Y_1^c \bar{m}^d e^{2i\gamma}
\end{eqnarray*}
The result is the following formula: 
just as it would appear in a latex document. The other environments—displaymath, equation, equation*, and eqnarray*—are also present.
Not only does this require less memory power because the syntax is the same, it also allows us to simply cut and paste from our notes when it comes time to move them over to actual latex documents.
To implement this, I’ve taken the original plugin—found in ‘lib/plugins/latex/’—and made a subdirectory syntax. I then moved the file syntax.php to syntax/latex.php, and added a bunch of new files of my own. Those files are the following:
dollar.php
<?php if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/'); 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_latex_dollar extends DokuWiki_Syntax_Plugin { /** settings * */ var $_tmp_dir = '/tmp'; // This is reset to a DokuWiki-local directory below var $_image_format='png'; var $_style_css=''; /** * return some info */ function getInfo(){ return array( 'author' => 'Alexander Krause (changes by Michael Boyle)', 'email' => 'alexander.krause@erazor-zone.de', 'date' => '2006-05-05', 'name' => 'Latex Plugin; dollar extension', 'desc' => 'Enables inline LaTeX syntax in wikitext', 'url' => '' ); } function getType(){ return 'protected'; } function getSort(){ return 405; } function connectTo($mode) { $this->Lexer->addEntryPattern('\$(?=.*\$)',$mode,'plugin_latex_dollar'); } function postConnect() { $this->Lexer->addExitPattern('\$','plugin_latex_dollar'); } /** * Handle the match */ function handle($match, $state, $pos, &$handler){ $match = str_replace("$","",$match); return array($match, NULL); } /** * Create output */ function render($mode, &$renderer, $data) { global $conf; $this->_tmp_dir = $conf['mediadir'] . '/latex/tmp'; if($mode == 'xhtml' && strlen($data[0]) > 0) { $data[0] = "$" . $data[0] . "$"; if ( !is_dir($conf['mediadir'] . '/latex') ) { mkdir($conf['mediadir'] . '/latex', 0777-$conf['dmask']); } $hash = md5(serialize($data)); $filename = $conf['mediadir'] . '/latex/'.$hash.'.'.$this->_image_format; $url = DOKU_BASE.'lib/exe/fetch.php?cache='.$cache.'&media=' .urlencode('latex:'.$hash.'.'.$this->_image_format); $style_css = ''; if ( is_readable($filename) ) { $depthfile = preg_replace('|png$|','depth',$filename); if(is_readable($depthfile)) { $offset = file($depthfile); $style_css = 'style="vertical-align:-'.rtrim($offset[0]).';"'; } else { $style_css = 'style="vertical-align:-2pt;"'; } $renderer->doc .= ' <img '. $style_css .' src="'.$url.'" alt="'.$data[0].'" />'; return true; } if (!$this->createImage($filename, $data[0])) { $depthfile = preg_replace('|png$|','depth',$filename); if(is_readable($depthfile)) { $offset = file($depthfile); $style_css = 'style="vertical-align:-'.rtrim($offset[0]).';"'; } else { $style_css = 'style="vertical-align:-2pt;"'; } $renderer->doc .= ' <img '. $style_css .' src="'.$url.'" alt="'.$data[0].'" />'; } else { $renderer->doc .= '**ERROR RENDERING LATEX**'; } return true; } return false; } function createImage($filename, &$data) { global $conf; require_once(DOKU_PLUGIN.'latex/class.latexrender_offset.php'); $latex = new LatexRender_Offset($this->_tmp_dir,$this->_tmp_dir,$this->_tmp_dir); // require_once(DOKU_PLUGIN.'latex/class.latexrender.php'); // $latex = new LatexRender($this->_tmp_dir,$this->_tmp_dir,$this->_tmp_dir); $latex->_image_format=$this->_image_format; if ($url = $latex->getFormulaURL($data)) { rename($url,$filename); $url = preg_replace('|png$|','depth',$url); $filename = preg_replace('|png$|','depth',$filename); if(is_readable($filename)) { rename($url,$filename); } rename($url,$filename); } return 0; } }
<?php if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/'); 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_latex_displaymath extends DokuWiki_Syntax_Plugin { /** settings * */ var $_tmp_dir='/tmp'; // This is reset to a DokuWiki-local directory below var $_image_format='png'; /** * return some info */ function getInfo(){ return array( 'author' => 'Alexander Krause (changes by Michael Boyle)', 'email' => 'alexander.krause@erazor-zone.de', 'date' => '2006-05-05', 'name' => 'Latex Plugin; displaymath extension', 'desc' => 'Enables displaymath LaTeX syntax in wikitext', 'url' => '' ); } function getType(){ return 'protected'; } //'formatting'; } // function getAllowedTypes() { // return array('substition','protected','disabled','formatting'); // } function getSort(){ return 405; } function connectTo($mode) { $this->Lexer->addEntryPattern('\x5Cbegin\{displaymath\}(?=.*\x5Cend\{displaymath\})', $mode,'plugin_latex_displaymath'); } function postConnect() { $this->Lexer->addExitPattern('\x5Cend\{displaymath\}','plugin_latex_displaymath'); } /** * Handle the match */ function handle($match, $state, $pos, &$handler){ $match = str_replace("\begin{displaymath}","",$match); $match = str_replace("\end{displaymath}","",$match); return array($match, NULL); } /** * Create output */ function render($mode, &$renderer, $data) { global $conf; $this->_tmp_dir = $conf['mediadir'] . '/latex/tmp'; if($mode == 'xhtml' && strlen($data[0]) > 0) { $data[0] = "\begin{displaymath}" . $data[0] . "\end{displaymath}"; if ( !is_dir($conf['mediadir'] . '/latex') ) { mkdir($conf['mediadir'] . '/latex', 0777-$conf['dmask']); } $hash = md5(serialize($data)); $filename = $conf['mediadir'] . '/latex/'.$hash.'.'.$this->_image_format; $url = DOKU_BASE.'lib/exe/fetch.php?cache='.$cache.'&media=' .urlencode('latex:'.$hash.'.'.$this->_image_format); if ( is_readable($filename) ) { $renderer->doc .= ' <br><img src="'.$url.'" style="padding:5px;" alt="'.$data[0].'" /><br>'; return true; } if (!$this->createImage($filename, $data[0])) { $renderer->doc .= ' <br><img src="'.$url.'" style="padding:5px;" alt="'.$data[0].'" /><br>'; } else { $renderer->doc .= '**ERROR RENDERING LATEX**'; } return true; } return false; } function createImage($filename, &$data) { global $conf; require_once(DOKU_PLUGIN.'latex/class.latexrender.php'); $latex = new LatexRender($this->_tmp_dir,$this->_tmp_dir,$this->_tmp_dir); $latex->_image_format=$this->_image_format; if ($url = $latex->getFormulaURL($data)) { rename($url,$filename); } return 0; } }
<?php if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/'); 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_latex_equation extends DokuWiki_Syntax_Plugin { /** settings * */ var $_tmp_dir='/tmp'; // This is reset to a DokuWiki-local directory below var $_image_format='png'; /** * return some info */ function getInfo(){ return array( 'author' => 'Alexander Krause (changes by Michael Boyle)', 'email' => 'alexander.krause@erazor-zone.de', 'date' => '2006-05-05', 'name' => 'Latex Plugin; equation extension', 'desc' => 'Enables equation LaTeX syntax in wikitext', 'url' => '' ); } function getType(){ return 'protected'; } //'formatting'; } // function getAllowedTypes() { // return array('substition','protected','disabled','formatting'); // } function getSort(){ return 405; } function connectTo($mode) { $this->Lexer->addEntryPattern('\x5Cbegin\{equation\}(?=.*\x5Cend\{equation\})', $mode,'plugin_latex_equation'); } function postConnect() { $this->Lexer->addExitPattern('\x5Cend\{equation\}','plugin_latex_equation'); } /** * Handle the match */ function handle($match, $state, $pos, &$handler){ $match = str_replace("\begin{equation}","",$match); $match = str_replace("\end{equation}","",$match); return array($match, NULL); } /** * Create output */ function render($mode, &$renderer, $data) { global $conf; $this->_tmp_dir = $conf['mediadir'] . '/latex/tmp'; if($mode == 'xhtml' && strlen($data[0]) > 0) { $data[0] = "\begin{equation}" . $data[0] . "\end{equation}"; if ( !is_dir($conf['mediadir'] . '/latex') ) { mkdir($conf['mediadir'] . '/latex', 0777-$conf['dmask']); } $hash = md5(serialize($data)); $filename = $conf['mediadir'] . '/latex/'.$hash.'.'.$this->_image_format; $url = DOKU_BASE.'lib/exe/fetch.php?cache='.$cache.'&media='.urlencode('latex:'.$hash.'.'.$this->_image_format); if ( is_readable($filename) ) { $renderer->doc .= ' <br><img src="'.$url.'" style="padding:5px;" alt="'.$data[0].'" /><br>'; return true; } if (!$this->createImage($filename, $data[0])) { $renderer->doc .= ' <br><img src="'.$url.'" style="padding:5px;" alt="'.$data[0].'" /><br>'; } else { $renderer->doc .= '**ERROR RENDERING LATEX**'; } return true; } return false; } function createImage($filename, &$data) { global $conf; require_once(DOKU_PLUGIN.'latex/class.latexrender.php'); $latex = new LatexRender($this->_tmp_dir,$this->_tmp_dir,$this->_tmp_dir); $latex->_image_format=$this->_image_format; if ($url = $latex->getFormulaURL($data)) { rename($url,$filename); } return 0; } }
<?php if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/'); 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_latex_equationstar extends DokuWiki_Syntax_Plugin { /** settings * */ var $_tmp_dir='/tmp'; // This is reset to a DokuWiki-local directory below var $_image_format='png'; /** * return some info */ function getInfo(){ return array( 'author' => 'Alexander Krause (changes by Michael Boyle)', 'email' => 'alexander.krause@erazor-zone.de', 'date' => '2006-05-05', 'name' => 'Latex Plugin; equationstar extension', 'desc' => 'Enables equation* LaTeX syntax in wikitext', 'url' => '' ); } function getType(){ return 'protected'; } //'formatting'; } // function getAllowedTypes() { // return array('substition','protected','disabled','formatting'); // } function getSort(){ return 405; } function connectTo($mode) { $this->Lexer->addEntryPattern('\x5Cbegin\{equation\*\}(?=.*\x5Cend\{equation\*\})', $mode,'plugin_latex_equationstar'); } function postConnect() { $this->Lexer->addExitPattern('\x5Cend\{equation\*\}','plugin_latex_equationstar'); } /** * Handle the match */ function handle($match, $state, $pos, &$handler){ $match = str_replace("\begin{equation*}","",$match); $match = str_replace("\end{equation*}","",$match); return array($match, NULL); } /** * Create output */ function render($mode, &$renderer, $data) { global $conf; $this->_tmp_dir = $conf['mediadir'] . '/latex/tmp'; if($mode == 'xhtml' && strlen($data[0]) > 0) { $data[0] = "\begin{equation*}" . $data[0] . "\end{equation*}"; if ( !is_dir($conf['mediadir'] . '/latex') ) { mkdir($conf['mediadir'] . '/latex', 0777-$conf['dmask']); } $hash = md5(serialize($data)); $filename = $conf['mediadir'] . '/latex/'.$hash.'.'.$this->_image_format; $url = DOKU_BASE.'lib/exe/fetch.php?cache='.$cache.'&media='.urlencode('latex:'.$hash.'.'.$this->_image_format); if ( is_readable($filename) ) { $renderer->doc .= ' <br><img src="'.$url.'" style="padding:5px;" alt="'.$data[0].'" /><br>'; return true; } if (!$this->createImage($filename, $data[0])) { $renderer->doc .= ' <br><img src="'.$url.'" style="padding:5px;" alt="'.$data[0].'" /><br>'; } else { $renderer->doc .= '**ERROR RENDERING LATEX**'; } return true; } return false; } function createImage($filename, &$data) { global $conf; require_once(DOKU_PLUGIN.'latex/class.latexrender.php'); $latex = new LatexRender($this->_tmp_dir,$this->_tmp_dir,$this->_tmp_dir); $latex->_image_format=$this->_image_format; if ($url = $latex->getFormulaURL($data)) { rename($url,$filename); } return 0; } }
<?php if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/'); 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_latex_eqnarray extends DokuWiki_Syntax_Plugin { /** settings * */ var $_tmp_dir='/tmp'; // This is reset to a DokuWiki-local directory below var $_image_format='png'; /** * return some info */ function getInfo(){ return array( 'author' => 'Alexander Krause (changes by Michael Boyle)'
