1<?php
2/**
3 * mimeTeX Rendering Class
4 * Copyright (C) 2011 Michael Gritsaenko <michael.gritsaenko@gmail.com>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 * --------------------------------------------------------------------
20 * @author 2011 Michael Gritsaenko <michael.gritsaenko@gmail.com>
21 * @version v0.1
22 * @package mimetexrender
23 *
24 */
25
26/**
27 * ChangeLog:
28 *
29 * [04/30/2015]: by LarsDW223
30 *               Added support for Linux systems:
31 *               The location of 'mimetex' under Linux is queried by executing 'which mimetex'.
32 *               The Linux version of 'mimetex' is not included in this plugin, if it is not installed
33 *               it needs to be installed manually first e.g. using 'sudo apt-get install mimetex'.
34 */
35
36if(!defined('MIMETEXEXE')) define('MIMETEXEXE','"'.realpath(dirname(__FILE__).'/mimetex.exe').'"');
37
38class mimetexRender {
39
40    // ====================================================================================
41    // Variable Definitions
42    // ====================================================================================
43
44    // i was too lazy to write mutator functions for every single program used
45    // just access it outside the class or change it here if nescessary
46//    var $_mimetex_path = ;
47    var $_string_length_limit = 5000;
48    var $_latexclass = "article"; //install extarticle class if you wish to have smaller font sizes
49    // this most certainly needs to be extended. in the long term it is planned to use
50    // a positive list for more security. this is hopefully enough for now. i'd be glad
51    // to receive more bad tags !
52    var $_latex_tags_blacklist = array(
53        "include","def","command","loop","repeat","open","toks","output","input",
54        "catcode","name","^^",
55        "\\every","\\errhelp","\\errorstopmode","\\scrollmode","\\nonstopmode","\\batchmode",
56        "\\read","\\write","csname","\\newhelp","\\uppercase", "\\lowercase","\\relax","\\aftergroup",
57        "\\afterassignment","\\expandafter","\\noexpand","\\special"
58        );
59    var $_error = "";
60
61    /**
62     * Renders a LaTeX formula by the using the following method:
63     *  - write the formula into a wrapped tex-file in a temporary directory
64     *    and change to it
65     *  - Create a GIF file using mimeTeX
66     *  - Save the resulting image to the picture cache directory
67     *
68     * @param string image filename in cache
69     * @param string LaTeX formula
70     * @returns true if the picture has been successfully saved to the picture
71     *          cache directory
72     */
73    function render($cachefilename, $formula) {
74        // Guess operating system
75        $usr_bin_dir = opendir('/usr/bin');
76        if ( $usr_bin_dir === false ) {
77            // Directory '/usr/bin' does not exist (or is not accessible).
78            // Assume Windows installation.
79            $_tmp_dir = "c:/temp";
80            $executeable = MIMETEXEXE;
81        } else {
82            // Directory '/usr/bin' exists. Assume Linux installation.
83            closedir ($usr_bin_dir);
84            $_tmp_dir = DOKU_PLUGIN.'temp';
85            $executeable = exec('which mimetex');
86        }
87
88        if ( empty ($executeable) === true ) {
89            $this->_error = "could not locate 'mimetex' command";
90            return false;
91        }
92
93        $formula = preg_replace("/&gt;/i", ">", $formula);
94        $formula = preg_replace("/&lt;/i", "<", $formula);
95
96        // security filter: reject too long formulas
97        if (strlen($formula) > $this->_string_length_limit) {
98            return false;
99        }
100
101        // security filter: try to match against LaTeX-Tags Blacklist
102/*        for ($i=0;$i<sizeof($this->_latex_tags_blacklist);$i++) {
103            if (stristr($formula, $this->_latex_tags_blacklist[$i])) {
104                $this->_error = "LaTeX tag [".$this->_latex_tags_blacklist[$i]."] in Blacklist";
105                return false;
106            }
107        }
108*/
109        $current_dir = getcwd();
110        chdir($this->_tmp_dir);
111
112        $tmp = md5(rand());
113        $tex = $tmp.".tex";
114
115        // create temporary latex file
116        $fp = fopen($tex,"a+");
117        fputs($fp, $formula);
118        fclose($fp);
119
120        // convert tex file to gif using mimetex.exe
121        $img = $tmp.".gif";
122
123        $command = $executeable." -f ".$tex." -e ".$img;
124
125        $status_code = exec($command);
126
127        unlink($tex);
128
129        if ($status_code) {
130            chdir($current_dir);
131            $this->_error = "can't execute [$command] ";
132            return false;
133        }
134        $status_code = rename($img, $cachefilename);
135        if (!$status_code) {
136            chdir($current_dir);
137            $this->_error = "can't rename [$img] to [$cachefilename]";
138            return false;
139        }
140
141        return true;
142    }
143
144}
145
146?>
147