MDL-30070 message: Optimised search for users over multiple courses
[moodle.git] / filter / tex / texdebug.php
CommitLineData
4317f92f 1<?php
f7f0909c
PS
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 */
9cc17305 28
9cc17305 29 require_once("../../config.php");
30
0662bd67 31 if (!filter_is_enabled('tex')) {
e25b7ded 32 print_error('filternotenabled');
33851b5c 33 }
34
220a90c5 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);
9cc17305 41
e42398e4 42 require_login();
6ca657a7 43 require_capability('moodle/site:config', context_system::instance(), $USER->id); /// Required cap to run this. MDL-18552
e42398e4 44
d93a90dc 45 $output = '';
9cc17305 46
d93a90dc 47 // look up in cache if required
220a90c5 48 if ($action=='ShowDB' or $action=='DeleteDB') {
49 $md5 = md5($texexp);
b402e134 50 $texcache = $DB->get_record("cache_filters", array("filter"=>"tex", "md5key"=>$md5));
d93a90dc 51 }
52
53 // Action: Show DB Entry
220a90c5 54 if ($action=='ShowDB') {
d93a90dc 55 if ($texcache) {
220a90c5 56 $output = "DB cache_filters entry for $texexp\n";
d93a90dc 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 {
220a90c5 64 $output = "DB cache_filters entry for $texexp not found\n";
623799eb 65 }
d93a90dc 66 }
67
68 // Action: Delete DB Entry
220a90c5 69 if ($action=='DeleteDB') {
d93a90dc 70 if ($texcache) {
220a90c5 71 $output = "Deleting DB cache_filters entry for $texexp\n";
8618fd2a 72 $result = $DB->delete_records("cache_filters", array("id"=>$texcache->id));
d93a90dc 73 if ($result) {
74 $result = 1;
623799eb 75 } else {
d93a90dc 76 $result = 0;
623799eb 77 }
d93a90dc 78 $output .= "Number of records deleted = $result\n";
79 } else {
220a90c5 80 $output = "Could not delete DB cache_filters entry for $texexp\nbecause it could not be found.\n";
9cc17305 81 }
d93a90dc 82 }
83
84 // Action: Show Image
220a90c5 85 if ($action=='ShowImageMimetex') {
86 tex2image($texexp);
d93a90dc 87 }
88
89 // Action: Check Slasharguments
220a90c5 90 if ($action=='SlashArguments') {
91 slasharguments($texexp);
d93a90dc 92 }
93
94 // Action: Show Tex command line output
220a90c5 95 if ($action=='ShowImageTex') {
96 TexOutput($texexp, true);
d93a90dc 97 exit;
98 }
99
100 // Action: Show Tex command line output
220a90c5 101 if ($action=='ShowOutputTex') {
54d08125 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 }
d93a90dc 107 exit;
108 }
109
220a90c5 110 if (!empty($action)) {
d93a90dc 111 outputText($output);
112 }
113
114 // nothing more to do if there was any action
220a90c5 115 if (!empty($action)) {
623799eb 116 exit;
9cc17305 117 }
118
119
623799eb 120 function outputText($texexp) {
8a7703ce 121 header("Content-type: text/html; charset=utf-8");
623799eb 122 echo "<html><body><pre>\n";
123 if ($texexp) {
f7f0909c 124 echo s($texexp)."\n\n";
623799eb 125 } else {
126 echo "No text output available\n\n";
127 }
128 echo "</pre></body></html>\n";
129 }
130
9dd9a426 131 function tex2image($texexp, $return=false) {
623799eb 132 global $CFG;
9cc17305 133
220a90c5 134 if (!$texexp) {
135 echo 'No tex expresion specified';
136 return;
623799eb 137 }
220a90c5 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;
35716b86
PS
150 $commandpath = filter_tex_get_executable(true);
151 $cmd = filter_tex_get_cmd($pathname, $texexp);
220a90c5 152 system($cmd, $status);
153
894ff63f 154 if ($return) {
155 return $image;
9dd9a426 156 }
220a90c5 157
158 if (file_exists($pathname)) {
159 send_file($pathname, $image);
160
54d08125 161 } else if (debugging()) {
623799eb 162 $ecmd = "$cmd 2>&1";
9a58f7cb 163 echo `$ecmd` . "<br />\n";
164 echo "The shell command<br />$cmd<br />returned status = $status<br />\n";
623799eb 165 if ($status == 4) {
9a58f7cb 166 echo "Status corresponds to illegal instruction<br />\n";
623799eb 167 } else if ($status == 11) {
9a58f7cb 168 echo "Status corresponds to bus error<br />\n";
623799eb 169 } else if ($status == 22) {
9a58f7cb 170 echo "Status corresponds to abnormal termination<br />\n";
623799eb 171 }
172 if (file_exists($commandpath)) {
9a58f7cb 173 echo "File size of mimetex executable $commandpath is " . filesize($commandpath) . "<br />";
174 echo "The file permissions are: " . decoct(fileperms($commandpath)) . "<br />";
623799eb 175 if (function_exists("md5_file")) {
9a58f7cb 176 echo "The md5 checksum of the file is " . md5_file($commandpath) . "<br />";
623799eb 177 } else {
178 $handle = fopen($commandpath,"rb");
179 $contents = fread($handle,16384);
180 fclose($handle);
9a58f7cb 181 echo "The md5 checksum of the first 16384 bytes is " . md5($contents) . "<br />";
623799eb 182 }
183 } else {
9a58f7cb 184 echo "mimetex executable $commandpath not found!<br />";
623799eb 185 }
186 echo "Image not found!";
54d08125 187 } else {
188 echo "Can not output detailed information due to security concerns, please turn on debug mode first.";
623799eb 189 }
190 }
ddea4cf0 191
d93a90dc 192
193 // test Tex/Ghostscript output - command execution only
220a90c5 194 function TexOutput($expression, $graphic=false) {
d93a90dc 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 $executables_exist = true;
203 if (is_file($CFG->filter_tex_pathlatex)) {
204 $output .= "latex executable ($CFG->filter_tex_pathlatex) is readable<br />\n";
205 }
206 else {
207 $executables_exist = false;
208 $output .= "<b>Error:</b> latex executable ($CFG->filter_tex_pathlatex) is not readable<br />\n";
209 }
210 if (is_file($CFG->filter_tex_pathdvips)) {
211 $output .= "dvips executable ($CFG->filter_tex_pathdvips) is readable<br />\n";
212 }
213 else {
214 $executables_exist = false;
215 $output .= "<b>Error:</b> dvips executable ($CFG->filter_tex_pathdvips) is not readable<br />\n";
216 }
217 if (is_file($CFG->filter_tex_pathconvert)) {
218 $output .= "convert executable ($CFG->filter_tex_pathconvert) is readable<br />\n";
219 }
220 else {
221 $executables_exist = false;
222 $output .= "<b>Error:</b> convert executable ($CFG->filter_tex_pathconvert) is not readable<br />\n";
223 }
224
220a90c5 225 // knowing that it might work..
226 $md5 = md5($expression);
d93a90dc 227 $output .= "<p>base filename for expression is '$md5'</p>\n";
220a90c5 228
d93a90dc 229 // temporary paths
230 $tex = "$latex->temp_dir/$md5.tex";
231 $dvi = "$latex->temp_dir/$md5.dvi";
232 $ps = "$latex->temp_dir/$md5.ps";
cf4e7548 233 $img = "$latex->temp_dir/$md5.{$CFG->filter_tex_convertformat}";
d93a90dc 234
235 // put the expression as a file into the temp area
220a90c5 236 $expression = html_entity_decode($expression);
07caf142 237 $output .= "<p>Processing TeX expression:</p><pre>$expression</pre>\n";
220a90c5 238 $doc = $latex->construct_latex_document($expression);
239 $fh = fopen($tex, 'w');
240 fputs($fh, $doc);
241 fclose($fh);
d93a90dc 242
243 // cd to temp dir
220a90c5 244 chdir($latex->temp_dir);
d93a90dc 245
246 // step 1: latex command
08d32575 247 $cmd = "$CFG->filter_tex_pathlatex --interaction=nonstopmode --halt-on-error $tex";
220a90c5 248 $output .= execute($cmd);
d93a90dc 249
250 // step 2: dvips command
251 $cmd = "$CFG->filter_tex_pathdvips -E $dvi -o $ps";
220a90c5 252 $output .= execute($cmd);
d93a90dc 253
254 // step 3: convert command
cf4e7548 255 $cmd = "$CFG->filter_tex_pathconvert -density 240 -trim $ps $img ";
220a90c5 256 $output .= execute($cmd);
d93a90dc 257
258 if (!$graphic) {
f7f0909c
PS
259 echo $output;
260 } else if (file_exists($img)){
cf4e7548 261 send_file($img, "$md5.{$CFG->filter_tex_convertformat}");
f7f0909c
PS
262 } else {
263 echo "Error creating image, see command execution output for more details.";
264 }
d93a90dc 265 }
266
220a90c5 267 function execute($cmd) {
268 exec($cmd, $result, $code);
d93a90dc 269 $output = "<pre>$ $cmd\n";
220a90c5 270 $lines = implode("\n", $result);
d93a90dc 271 $output .= "OUTPUT: $lines\n";
272 $output .= "RETURN CODE: $code\n</pre>\n";
273 return $output;
274 }
275
9dd9a426 276 function slasharguments($texexp) {
781cac72 277 global $CFG;
220a90c5 278 $admin = $CFG->wwwroot.'/'.$CFG->admin.'/settings.php?section=http';
9dd9a426 279 $image = tex2image($texexp,true);
781cac72 280 echo "<p>If the following image displays correctly, set your ";
220a90c5 281 echo "<a href=\"$admin\" target=\"_blank\">Administration->Server->HTTP</a> ";
6544f8d8 282 echo "setting for slasharguments to file.php/1/pic.jpg: ";
220a90c5 283 echo "<img src=\"$CFG->wwwroot/filter/tex/pix.php/$image\" align=\"absmiddle\"></p>\n";
6544f8d8 284 echo "<p>Otherwise set it to file.php?file=/1/pic.jpg ";
781cac72 285 echo "It should display correctly as ";
220a90c5 286 echo "<img src=\"$CFG->wwwroot/filter/tex/pix.php?file=$image\" align=\"absmiddle\"></p>\n";
781cac72 287 echo "<p>If neither equation image displays correctly, please seek ";
288 echo "further help at moodle.org at the ";
220a90c5 289 echo "<a href=\"http://moodle.org/mod/forum/view.php?id=752&loginguest=true\" target=\"_blank\">";
781cac72 290 echo "Mathematics Tools Forum</a></p>";
9dd9a426 291 }
292
9cc17305 293?>
294
295<html>
296<head><title>TeX Filter Debugger</title></head>
297<body>
9cc17305 298 <p>Please enter an algebraic expression <b>without</b> any surrounding $$ into
299 the text box below. (Click <a href="#help">here for help.</a>)
300 <form action="texdebug.php" method="get"
301 target="inlineframe">
302 <center>
9a58f7cb 303 <input type="text" name="tex" size="50"
cf4e7548 304 value="f(x)=\int_{-\infty}^x~e^{-t^2}dt" />
9cc17305 305 </center>
d93a90dc 306 <p>The following tests are available:</p>
9cc17305 307 <ol>
54d08125 308 <li><input type="radio" name="action" value="ShowDB" id="ShowDB" />
309 <label for="ShowDB">See the cache_filters database entry for this expression (if any).</label></li>
cf4e7548 310 <li><input type="radio" name="action" value="DeleteDB" id="DeleteDB" />
54d08125 311 <label for="DeleteDB">Delete the cache_filters database entry for this expression (if any).</label></li>
84585f1d 312 <li><input type="radio" name="action" value="ShowImageMimetex" id="ShowImageMimetex" checked="checked" />
54d08125 313 <label for="ShowImageMimetex">Show a graphic image of the algebraic expression rendered with mimetex.</label></li>
314 <li><input type="radio" name="action" value="ShowImageTex" id="ShowImageTex" />
315 <label for="ShowImageTex">Show a graphic image of the algebraic expression rendered with Tex/Ghostscript.</label></li>
316 <li><input type="radio" name="action" value="ShowOutputTex" id="ShowOutputTex" />
317 <label for="ShowOutputTex">Show command execution output from the algebraic expression rendered with Tex/Ghostscript.</label></li>
318 <li><input type="radio" name="action" value="SlashArguments" id="SlashArguments" />
319 <label for="SlashArguments">Check slasharguments setting.</label></li>
9cc17305 320 </ol>
d93a90dc 321 <input type="submit" value="Do it!" />
9a58f7cb 322 </form> <br /> <br />
9cc17305 323 <center>
324 <iframe name="inlineframe" align="middle" width="80%" height="200">
4317f92f 325 &lt;p&gt;Something is wrong...&lt;/p&gt;
9cc17305 326 </iframe>
9a58f7cb 327 </center> <br />
328<hr />
9cc17305 329<a name="help">
330<h2>Debugging Help</h2>
331</a>
332<p>First a brief overview of how the TeX filter works. The TeX filter first
333searches the database cache_filters table to see if this TeX expression had been
334processed before. If not, it adds a DB entry for that expression. It then
335replaces the TeX expression by an &lt;img src=&quot;.../filter/tex/pix.php...&quot;&gt;
336tag. The filter/tex/pix.php script then searches the database to find an
cf4e7548 337appropriate gif/png image file for that expression and to create one if it doesn't exist.
d93a90dc 338It will then use either the LaTex/Ghostscript renderer (using external executables
339on your system) or the bundled Mimetex executable. The full Latex/Ghostscript
4317f92f 340renderer produces better results and is tried first.
9cc17305 341Here are a few common things that can go wrong and some suggestions on how
342you might try to fix them.</p>
343<ol>
344<li>Something had gone wrong on a previous occasion when the filter tried to
345process this expression. Then the database entry for that expression contains
346a bad TeX expression in the rawtext field (usually blank). You can fix this
347by clicking on &quot;Delete DB Entry&quot;</li>
cf4e7548 348<li>The TeX to gif/png image conversion process does not work.
d93a90dc 349If paths are specified in the filter configuation screen for the three
350executables these will be tried first. Note that they still must be correctly
4317f92f 351installed and have the correct permissions. In particular make sure that you
d93a90dc 352have all the packages installed (e.g., on Debian/Ubuntu you need to install
353the 'tetex-extra' package). Running the 'show command execution' test should
354give a big clue.
4317f92f 355If this fails or is not available, the Mimetex executable is tried. If this
d93a90dc 356fails a likely cause is that the mimetex binary you are using is
9cc17305 357incompatible with your operating system. You can try compiling it from the
358C sources downloaded from <a href="http://www.forkosh.com/mimetex.zip">
359http://www.forkosh.com/mimetex.zip</a>, or looking for an appropriate
360binary at <a href="http://moodle.org/download/mimetex/">
361http://moodle.org/download/mimetex/</a>. You may then also need to
4317f92f 362edit your moodle/filter/tex/pix.php file to add
9cc17305 363<br /><?PHP echo "case &quot;" . PHP_OS . "&quot;:" ;?><br ?> to the list of operating systems
364in the switch (PHP_OS) statement. Windows users may have a problem properly
365unzipping mimetex.exe. Make sure that mimetex.exe is is <b>PRECISELY</b>
36130823 366433152 bytes in size. If not, download a fresh copy from
9cc17305 367<a href="http://moodle.org/download/mimetex/windows/mimetex.exe">
4317f92f 368http://moodle.org/download/mimetex/windows/mimetex.exe</a>.
9cc17305 369Another possible problem which may affect
370both Unix and Windows servers is that the web server doesn't have execute permission
371on the mimetex binary. In that case change permissions accordingly</li>
372</ol>
373</body>
374</html>