source: moodle/trunk/fuentes/filter/tex/texdebug.php @ 136

Last change on this file since 136 was 136, checked in by mabarracus, 3 years ago

Ported code to xenial

File size: 15.9 KB
Line 
1<?php
2// This file is part of Moodle - http://moodle.org/
3//
4// Moodle is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// Moodle is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
17/**
18 * This function fetches math. images from the data directory
19 * If not, it obtains the corresponding TeX expression from the cache_tex db table
20 * and uses mimeTeX to create the image file
21 *
22 * @package    filter
23 * @subpackage tex
24 * @copyright  2004 Zbigniew Fiedorowicz fiedorow@math.ohio-state.edu
25 *             Originally based on code provided by Bruno Vernier bruno@vsbeducation.ca
26 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
27 */
28
29    require_once("../../config.php");
30
31    if (!filter_is_enabled('tex')) {
32        print_error('filternotenabled');
33    }
34
35    require_once($CFG->libdir.'/filelib.php');
36    require_once($CFG->dirroot.'/filter/tex/lib.php');
37    require_once($CFG->dirroot.'/filter/tex/latex.php');
38
39    $action = optional_param('action', '', PARAM_ALPHA);
40    $texexp = optional_param('tex', '', PARAM_RAW);
41
42    require_login();
43    require_capability('moodle/site:config', context_system::instance(), $USER->id); /// Required cap to run this. MDL-18552
44
45    $output = '';
46
47    // look up in cache if required
48    if ($action=='ShowDB' or $action=='DeleteDB') {
49        $md5 = md5($texexp);
50        $texcache = $DB->get_record("cache_filters", array("filter"=>"tex", "md5key"=>$md5));
51    }
52
53    // Action: Show DB Entry
54    if ($action=='ShowDB') {
55        if ($texcache) {
56            $output = "DB cache_filters entry for $texexp\n";
57            $output .= "id = $texcache->id\n";
58            $output .= "filter = $texcache->filter\n";
59            $output .= "version = $texcache->version\n";
60            $output .= "md5key = $texcache->md5key\n";
61            $output .= "rawtext = $texcache->rawtext\n";
62            $output .= "timemodified = $texcache->timemodified\n";
63        } else {
64            $output = "DB cache_filters entry for $texexp not found\n";
65        }
66    }
67
68    // Action: Delete DB Entry
69    if ($action=='DeleteDB') {
70        if ($texcache) {
71            $output = "Deleting DB cache_filters entry for $texexp\n";
72            $result =  $DB->delete_records("cache_filters", array("id"=>$texcache->id));
73            if ($result) {
74                $result = 1;
75            } else {
76                $result = 0;
77            }
78            $output .= "Number of records deleted = $result\n";
79        } else {
80            $output = "Could not delete DB cache_filters entry for $texexp\nbecause it could not be found.\n";
81        }
82    }
83
84    // Action: Show Image
85    if ($action=='ShowImageMimetex') {
86        tex2image($texexp);
87    }
88
89    // Action: Check Slasharguments
90    if ($action=='SlashArguments') {
91        slasharguments($texexp);
92    }
93
94    // Action: Show Tex command line output
95    if ($action=='ShowImageTex') {
96        TexOutput($texexp, true);
97        exit;
98    }
99
100    // Action: Show Tex command line output
101    if ($action=='ShowOutputTex') {
102        if (debugging()) {
103            TexOutput($texexp);
104        } else {
105            echo "Can not output detailed information due to security concerns, please turn on debug mode first.";
106        }
107        exit;
108    }
109
110    if (!empty($action)) {
111        outputText($output);
112    }
113
114    // nothing more to do if there was any action
115    if (!empty($action)) {
116        exit;
117    }
118
119
120    function outputText($texexp) {
121        header("Content-type: text/html; charset=utf-8");
122        echo "<html><body><pre>\n";
123        if ($texexp) {
124            echo s($texexp)."\n\n";
125        } else {
126            echo "No text output available\n\n";
127        }
128        echo "</pre></body></html>\n";
129    }
130
131    function tex2image($texexp, $return=false) {
132        global $CFG;
133
134        if (!$texexp) {
135            echo 'No tex expresion specified';
136            return;
137        }
138
139        $image  = md5($texexp) . ".gif";
140        $filetype = 'image/gif';
141        if (!file_exists("$CFG->dataroot/filter/tex")) {
142            make_upload_directory("filter/tex");
143        }
144        $pathname = "$CFG->dataroot/filter/tex/$image";
145        if (file_exists($pathname)) {
146            unlink($pathname);
147        }
148
149        $texexp = '\Large '.$texexp;
150        $commandpath = filter_tex_get_executable(true);
151        $cmd = filter_tex_get_cmd($pathname, $texexp);
152        system($cmd, $status);
153
154        if ($return) {
155          return $image;
156        }
157
158        if (file_exists($pathname)) {
159            send_file($pathname, $image);
160
161        } else if (debugging()) {
162            $ecmd = "$cmd 2>&1";
163            echo `$ecmd` . "<br />\n";
164            echo "The shell command<br />$cmd<br />returned status = $status<br />\n";
165            if ($status == 4) {
166                echo "Status corresponds to illegal instruction<br />\n";
167            } else if ($status == 11) {
168                echo "Status corresponds to bus error<br />\n";
169            } else if ($status == 22) {
170                echo "Status corresponds to abnormal termination<br />\n";
171            }
172            if (file_exists($commandpath)) {
173                echo "File size of mimetex executable  $commandpath is " . filesize($commandpath) . "<br />";
174                echo "The file permissions are: " . decoct(fileperms($commandpath)) . "<br />";
175                if (function_exists("md5_file")) {
176                    echo "The md5 checksum of the file is " . md5_file($commandpath) . "<br />";
177                } else {
178                    $handle = fopen($commandpath,"rb");
179                    $contents = fread($handle,16384);
180                    fclose($handle);
181                    echo "The md5 checksum of the first 16384 bytes is " . md5($contents) . "<br />";
182                }
183            } else {
184                echo "mimetex executable $commandpath not found!<br />";
185            }
186            echo "Image not found!";
187        } else {
188            echo "Can not output detailed information due to security concerns, please turn on debug mode first.";
189        }
190    }
191
192
193    // test Tex/Ghostscript output - command execution only
194    function TexOutput($expression, $graphic=false) {
195        global $CFG;
196        $output = '';
197
198        $latex = new latex();
199
200        // first check if it is likely to work at all
201        $output .= "<h3>Checking executables</h3>\n";
202        $executablesexist = true;
203        $pathlatex = trim(get_config('filter_tex', 'pathlatex'), " '\"");
204        if (is_file($pathlatex)) {
205            $output .= "latex executable ($pathlatex) is readable<br />\n";
206        } else {
207            $executablesexist = false;
208            $output .= "<b>Error:</b> latex executable ($pathlatex) is not readable<br />\n";
209        }
210        $pathdvips = trim(get_config('filter_tex', 'pathdvips'), " '\"");
211        if (is_file($pathdvips)) {
212            $output .= "dvips executable ($pathdvips) is readable<br />\n";
213        } else {
214            $executablesexist = false;
215            $output .= "<b>Error:</b> dvips executable ($pathdvips) is not readable<br />\n";
216        }
217        $pathconvert = trim(get_config('filter_tex', 'pathconvert'), " '\"");
218        if (is_file($pathconvert)) {
219            $output .= "convert executable ($pathconvert) is readable<br />\n";
220        } else {
221            $executablesexist = false;
222            $output .= "<b>Error:</b> convert executable ($pathconvert) is not readable<br />\n";
223        }
224        $pathdvisvgm = trim(get_config('filter_tex', 'pathdvisvgm'), " '\"");
225        if (is_file($pathdvisvgm)) {
226            $output .= "dvisvgm executable ($pathdvisvgm) is readable<br />\n";
227        } else {
228            $executablesexist = false;
229            $output .= "<b>Error:</b> dvisvgm executable ($pathdvisvgm) is not readable<br />\n";
230        }
231
232        // knowing that it might work..
233        $md5 = md5($expression);
234        $output .= "<p>base filename for expression is '$md5'</p>\n";
235
236        // temporary paths
237        $tex = "$latex->temp_dir/$md5.tex";
238        $dvi = "$latex->temp_dir/$md5.dvi";
239        $ps = "$latex->temp_dir/$md5.ps";
240        $convertformat = get_config('filter_tex', 'convertformat');
241        $img = "$latex->temp_dir/$md5.{$convertformat}";
242
243        // put the expression as a file into the temp area
244        $expression = html_entity_decode($expression);
245        $output .= "<p>Processing TeX expression:</p><pre>$expression</pre>\n";
246        $doc = $latex->construct_latex_document($expression);
247        $fh = fopen($tex, 'w');
248        fputs($fh, $doc);
249        fclose($fh);
250
251        // cd to temp dir
252        chdir($latex->temp_dir);
253
254        // step 1: latex command
255        $pathlatex = escapeshellarg($pathlatex);
256        $cmd = "$pathlatex --interaction=nonstopmode --halt-on-error $tex";
257        $output .= execute($cmd);
258
259        // step 2: dvips command
260        $pathdvips = escapeshellarg($pathdvips);
261        $cmd = "$pathdvips -E $dvi -o $ps";
262        $output .= execute($cmd);
263
264        // Step 3: Set convert or dvisvgm command.
265        if ($convertformat == 'svg') {
266            $pathdvisvgm = escapeshellarg($pathdvisvgm);
267            $cmd = "$pathdvisvgm -E $ps -o $img";
268        } else {
269            $pathconvert = escapeshellarg($pathconvert);
270            $cmd = "$pathconvert -density 240 -trim $ps $img ";
271        }
272        $output .= execute($cmd);
273
274        if (!$graphic) {
275            echo $output;
276        } else if (file_exists($img)) {
277            send_file($img, "$md5.{$convertformat}");
278        } else {
279            echo "Error creating image, see command execution output for more details.";
280        }
281    }
282
283    function execute($cmd) {
284        exec($cmd, $result, $code);
285        $output = "<pre>$ $cmd\n";
286        $lines = implode("\n", $result);
287        $output .= "OUTPUT: $lines\n";
288        $output .= "RETURN CODE: $code\n</pre>\n";
289        return $output;
290    }
291
292    function slasharguments($texexp) {
293        global $CFG;
294        $admin = $CFG->wwwroot.'/'.$CFG->admin.'/settings.php?section=http';
295        $image = tex2image($texexp,true);
296        echo "<p>If the following image displays correctly, set your ";
297        echo "<a href=\"$admin\" target=\"_blank\">Administration->Server->HTTP</a> ";
298        echo "setting for slasharguments to file.php/1/pic.jpg: ";
299        echo "<img src=\"$CFG->wwwroot/filter/tex/pix.php/$image\" align=\"absmiddle\"></p>\n";
300        echo "<p>Otherwise set it to file.php?file=/1/pic.jpg ";
301        echo "It should display correctly as ";
302        echo "<img src=\"$CFG->wwwroot/filter/tex/pix.php?file=$image\" align=\"absmiddle\"></p>\n";
303        echo "<p>If neither equation image displays correctly, please seek ";
304        echo "further help at moodle.org at the ";
305        echo "<a href=\"http://moodle.org/mod/forum/view.php?id=752&loginguest=true\" target=\"_blank\">";
306        echo "Mathematics Tools Forum</a></p>";
307    }
308
309?>
310
311<html>
312<head><title>TeX Filter Debugger</title></head>
313<body>
314  <p>Please enter an algebraic expression <b>without</b> any surrounding $$ into
315       the text box below. (Click <a href="#help">here for help.</a>)
316          <form action="texdebug.php" method="get"
317           target="inlineframe">
318            <center>
319             <input type="text" name="tex" size="50"
320                    value="f(x)=\int_{-\infty}^x~e^{-t^2}dt" />
321            </center>
322           <p>The following tests are available:</p>
323           <ol>
324           <li><input type="radio" name="action" value="ShowDB" id="ShowDB" />
325               <label for="ShowDB">See the cache_filters database entry for this expression (if any).</label></li>
326           <li><input type="radio" name="action" value="DeleteDB" id="DeleteDB" />
327               <label for="DeleteDB">Delete the cache_filters database entry for this expression (if any).</label></li>
328           <li><input type="radio" name="action" value="ShowImageMimetex" id="ShowImageMimetex"  checked="checked" />
329               <label for="ShowImageMimetex">Show a graphic image of the algebraic expression rendered with mimetex.</label></li>
330           <li><input type="radio" name="action" value="ShowImageTex" id="ShowImageTex" />
331               <label for="ShowImageTex">Show a graphic image of the algebraic expression rendered with Tex/Ghostscript.</label></li>
332           <li><input type="radio" name="action" value="ShowOutputTex" id="ShowOutputTex" />
333               <label for="ShowOutputTex">Show command execution output from the algebraic expression rendered with Tex/Ghostscript.</label></li>
334           <li><input type="radio" name="action" value="SlashArguments" id="SlashArguments" />
335               <label for="SlashArguments">Check slasharguments setting.</label></li>
336           </ol>
337           <input type="submit" value="Do it!" />
338          </form> <br /> <br />
339       <center>
340          <iframe name="inlineframe" align="middle" width="80%" height="200">
341          &lt;p&gt;Something is wrong...&lt;/p&gt;
342          </iframe>
343       </center> <br />
344<hr />
345<a name="help">
346<h2>Debugging Help</h2>
347</a>
348<p>First a brief overview of how the TeX filter works. The TeX filter first
349searches the database cache_filters table to see if this TeX expression had been
350processed before. If not, it adds a DB entry for that expression.  It then
351replaces the TeX expression by an &lt;img src=&quot;.../filter/tex/pix.php...&quot;&gt;
352tag.  The filter/tex/pix.php script then searches the database to find an
353appropriate gif/png/svg image file for that expression and to create one if it doesn't exist.
354It will then use either the LaTex/Ghostscript renderer (using external executables
355on your system) or the bundled Mimetex executable. The full Latex/Ghostscript
356renderer produces better results and is tried first.
357Here are a few common things that can go wrong and some suggestions on how
358you might try to fix them.</p>
359<ol>
360<li>Something had gone wrong on a previous occasion when the filter tried to
361process this expression. Then the database entry for that expression contains
362a bad TeX expression in the rawtext field (usually blank). You can fix this
363by clicking on &quot;Delete DB Entry&quot;</li>
364<li>The TeX to gif/png/svg image conversion process does not work.
365If paths are specified in the filter configuation screen for the three
366executables these will be tried first. Note that they still must be correctly
367installed and have the correct permissions. In particular make sure that you
368have all the packages installed (e.g., on Debian/Ubuntu you need to install
369the 'tetex-extra' package). Running the 'show command execution' test should
370give a big clue.
371If this fails or is not available, the Mimetex executable is tried. If this
372fails a likely cause is that the mimetex binary you are using is
373incompatible with your operating system. You can try compiling it from the
374C sources downloaded from <a href="http://www.forkosh.com/mimetex.zip">
375http://www.forkosh.com/mimetex.zip</a>, or looking for an appropriate
376binary at <a href="http://moodle.org/download/mimetex/">
377http://moodle.org/download/mimetex/</a>. You may then also need to
378edit your moodle/filter/tex/pix.php file to add
379<br /><?php echo "case &quot;" . PHP_OS . "&quot;:" ;?><br ?> to the list of operating systems
380in the switch (PHP_OS) statement. Windows users may have a problem properly
381unzipping mimetex.exe. Make sure that mimetex.exe is is <b>PRECISELY</b>
382433152 bytes in size. If not, download a fresh copy from
383<a href="http://moodle.org/download/mimetex/windows/mimetex.exe">
384http://moodle.org/download/mimetex/windows/mimetex.exe</a>.
385Another possible problem which may affect
386both Unix and Windows servers is that the web server doesn't have execute permission
387on the mimetex binary. In that case change permissions accordingly</li>
388</ol>
389</body>
390</html>
Note: See TracBrowser for help on using the repository browser.