MDL-25973 add missing charset
[moodle.git] / filter / algebra / algebradebug.php
CommitLineData
e25b7ded 1<?php
9b361d24 2 // This function fetches math. images from the data directory
3 // If not, it obtains the corresponding TeX expression from the cache_tex db table
4 // and uses mimeTeX to create the image file
5
6800d78e 6 define('NO_MOODLE_COOKIES', true); // Because it interferes with caching
9b361d24 7
8 require_once("../../config.php");
9
6b037e04 10 if (!filter_is_enabled('filter/algebra')) {
e25b7ded 11 print_error('filternotenabled');
33851b5c 12 }
9b361d24 13
220a90c5 14 require_once($CFG->libdir.'/filelib.php');
15 require_once($CFG->dirroot.'/filter/tex/lib.php');
9b361d24 16
5e6d46cb 17 require_login();
18 require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
19
9b361d24 20 $query = urldecode($_SERVER['QUERY_STRING']);
21
22 if ($query) {
23 $output = $query;
24 $splitpos = strpos($query,'&')-8;
25 $algebra = substr($query,8,$splitpos);
26 $md5 = md5($algebra);
27 if (strpos($query,'ShowDB') || strpos($query,'DeleteDB')) {
219f652b 28 $texcache = $DB->get_record("cache_filters", array("filter"=>"algebra", "md5key"=>$md5));
9b361d24 29 }
30 if (strpos($query,'ShowDB')) {
31 if ($texcache) {
894ff63f 32 $output = "DB cache_filters entry for $algebra\n";
9b361d24 33 $output .= "id = $texcache->id\n";
34 $output .= "filter = $texcache->filter\n";
35 $output .= "version = $texcache->version\n";
36 $output .= "md5key = $texcache->md5key\n";
37 $output .= "rawtext = $texcache->rawtext\n";
38 $output .= "timemodified = $texcache->timemodified\n";
39 } else {
40 $output = "DB cache_filters entry for $algebra not found\n";
41 }
42 }
43 if (strpos($query,'DeleteDB')) {
44 if ($texcache) {
45 $output = "Deleting DB cache_filters entry for $algebra\n";
8618fd2a 46 $result = $DB->delete_records("cache_filters", array("id"=>$texcache->id));
9b361d24 47 if ($result) {
894ff63f 48 $result = 1;
9b361d24 49 } else {
50 $result = 0;
51 }
52 $output .= "Number of records deleted = $result\n";
53 } else {
54 $output = "Could not delete DB cache_filters entry for $algebra\nbecause it could not be found.\n";
55 }
56 }
57 if (strpos($query,'TeXStage1')) {
894ff63f 58 $output = algebra2tex($algebra);
9b361d24 59 }
60 if (strpos($query,'TeXStage2')) {
894ff63f 61 $output = algebra2tex($algebra);
9b361d24 62 $output = refineTeX($output);
63 }
380e47f5 64 if (strpos($query,'ShowImage')||strpos($query,'SlashArguments')) {
894ff63f 65 $output = algebra2tex($algebra);
9b361d24 66 $output = refineTeX($output);
380e47f5 67 if (strpos($query,'ShowImage')) {
894ff63f 68 tex2image($output, $md5);
380e47f5 69 } else {
70 slasharguments($output, $md5);
71 }
220a90c5 72 } else {
9b361d24 73 outputText($output);
74 }
75 exit;
76 }
77
78function algebra2tex($algebra) {
10ccb7a7 79 global $CFG;
9b361d24 80 $algebra = str_replace('&lt;','<',$algebra);
81 $algebra = str_replace('&gt;','>',$algebra);
82 $algebra = str_replace('<>','#',$algebra);
83 $algebra = str_replace('<=','%',$algebra);
84 $algebra = str_replace('>=','!',$algebra);
1b71c53e 85 $algebra = preg_replace('/([=><%!#] *)-/',"\$1 zeroplace -",$algebra);
e86a754b 86 $algebra = str_replace('delta','zdelta',$algebra);
87 $algebra = str_replace('beta','bita',$algebra);
88 $algebra = str_replace('theta','thita',$algebra);
89 $algebra = str_replace('zeta','zita',$algebra);
90 $algebra = str_replace('eta','xeta',$algebra);
91 $algebra = str_replace('epsilon','zepslon',$algebra);
92 $algebra = str_replace('upsilon','zupslon',$algebra);
9b361d24 93 $algebra = preg_replace('!\r\n?!',' ',$algebra);
10ccb7a7 94 $algebra = escapeshellarg($algebra);
e86a754b 95
9b361d24 96 if ( (PHP_OS == "WINNT") || (PHP_OS == "WIN32") || (PHP_OS == "Windows") ) {
220a90c5 97 $cmd = "cd $CFG->dirroot\\filter\\algebra & algebra2tex.pl x/2";
d7e3f044 98 $test = `$cmd`;
99 if ($test != '\frac{x}{2}') {
71502268 100 echo "There is a problem with either Perl or the script algebra2tex.pl<br/>";
d7e3f044 101 $ecmd = $cmd . " 2>&1";
71502268 102 echo `$ecmd` . "<br/>\n";
103 echo "The shell command<br/>$cmd<br/>returned status = $status<br/>\n";
220a90c5 104 $commandpath = "$CFG->dirroot\\filter\\algebra\\algebra2tex.pl";
d7e3f044 105 if (file_exists($commandpath)) {
71502268 106 echo "The file permissions of algebra2tex.pl are: " . decoct(fileperms($commandpath)) . "<br/>";
d7e3f044 107 }
108 die;
109 }
220a90c5 110 $cmd = "cd $CFG->dirroot\\filter\\algebra & algebra2tex.pl $algebra";
111 } else {
112 $cmd = "cd $CFG->dirroot/filter/algebra; ./algebra2tex.pl x/2";
d7e3f044 113 $test = `$cmd`;
114 if ($test != '\frac{x}{2}') {
71502268 115 echo "There is a problem with either Perl or the script algebra2tex.pl<br/>";
d7e3f044 116 $ecmd = $cmd . " 2>&1";
71502268 117 echo `$ecmd` . "<br/>\n";
118 echo "The shell command<br/>$cmd<br/>returned status = $status<br/>\n";
220a90c5 119 $commandpath = "$CFG->dirroot/filter/algebra/algebra2tex.pl";
d7e3f044 120 if (file_exists($commandpath)) {
71502268 121 echo "The file permissions of algebra2tex.pl are: " . decoct(fileperms($commandpath)) . "<br/>";
d7e3f044 122 }
123 die;
124 }
220a90c5 125 $cmd = "cd $CFG->dirroot/filter/algebra; ./algebra2tex.pl $algebra";
9b361d24 126 }
127 $texexp = `$cmd`;
128 return $texexp;
129}
130
131function refineTeX($texexp) {
1b71c53e 132 $texexp = str_replace('zeroplace','',$texexp);
9b361d24 133 $texexp = str_replace('#','\not= ',$texexp);
134 $texexp = str_replace('%','\leq ',$texexp);
135 $texexp = str_replace('!','\geq ',$texexp);
136 $texexp = str_replace('\left{','{',$texexp);
137 $texexp = str_replace('\right}','}',$texexp);
138 $texexp = str_replace('\fun',' ',$texexp);
139 $texexp = str_replace('infty','\infty',$texexp);
e86a754b 140 $texexp = str_replace('alpha','\alpha',$texexp);
141 $texexp = str_replace('gamma','\gamma',$texexp);
142 $texexp = str_replace('iota','\iota',$texexp);
143 $texexp = str_replace('kappa','\kappa',$texexp);
144 $texexp = str_replace('lambda','\lambda',$texexp);
145 $texexp = str_replace('mu','\mu',$texexp);
146 $texexp = str_replace('nu','\nu',$texexp);
147 $texexp = str_replace('xi','\xi',$texexp);
148 $texexp = str_replace('rho','\rho',$texexp);
149 $texexp = str_replace('sigma','\sigma',$texexp);
150 $texexp = str_replace('tau','\tau',$texexp);
151 $texexp = str_replace('phi','\phi',$texexp);
152 $texexp = str_replace('chi','\chi',$texexp);
153 $texexp = str_replace('psi','\psi',$texexp);
154 $texexp = str_replace('omega','\omega',$texexp);
155 $texexp = str_replace('zdelta','\delta',$texexp);
156 $texexp = str_replace('bita','\beta',$texexp);
157 $texexp = str_replace('thita','\theta',$texexp);
158 $texexp = str_replace('zita','\zeta',$texexp);
159 $texexp = str_replace('xeta','\eta',$texexp);
160 $texexp = str_replace('zepslon','\epsilon',$texexp);
161 $texexp = str_replace('zupslon','\upsilon',$texexp);
9b361d24 162 $texexp = str_replace('\mbox{logten}','\mbox{log}_{10}',$texexp);
163 $texexp = str_replace('\mbox{acos}','\mbox{cos}^{-1}',$texexp);
164 $texexp = str_replace('\mbox{asin}','\mbox{sin}^{-1}',$texexp);
165 $texexp = str_replace('\mbox{atan}','\mbox{tan}^{-1}',$texexp);
166 $texexp = str_replace('\mbox{asec}','\mbox{sec}^{-1}',$texexp);
167 $texexp = str_replace('\mbox{acsc}','\mbox{csc}^{-1}',$texexp);
168 $texexp = str_replace('\mbox{acot}','\mbox{cot}^{-1}',$texexp);
169 $texexp = str_replace('\mbox{acosh}','\mbox{cosh}^{-1}',$texexp);
170 $texexp = str_replace('\mbox{asinh}','\mbox{sinh}^{-1}',$texexp);
171 $texexp = str_replace('\mbox{atanh}','\mbox{tanh}^{-1}',$texexp);
172 $texexp = str_replace('\mbox{asech}','\mbox{sech}^{-1}',$texexp);
173 $texexp = str_replace('\mbox{acsch}','\mbox{csch}^{-1}',$texexp);
174 $texexp = str_replace('\mbox{acoth}','\mbox{coth}^{-1}',$texexp);
175 $texexp = preg_replace('/\\\sqrt{(.+?),(.+?)}/s','\sqrt['. "\$2]{\$1}",$texexp);
176 $texexp = preg_replace('/\\\mbox{abs}\\\left\((.+?)\\\right\)/s',"|\$1|",$texexp);
177 $texexp = preg_replace('/\\\log\\\left\((.+?),(.+?)\\\right\)/s','\log_{'. "\$2}\\left(\$1\\right)",$texexp);
178 $texexp = preg_replace('/(\\\cos|\\\sin|\\\tan|\\\sec|\\\csc|\\\cot)([h]*)\\\left\((.+?),(.+?)\\\right\)/s',"\$1\$2^{". "\$4}\\left(\$3\\right)",$texexp);
179 $texexp = preg_replace('/\\\int\\\left\((.+?),(.+?),(.+?)\\\right\)/s','\int_'. "{\$2}^{\$3}\$1 ",$texexp);
180 $texexp = preg_replace('/\\\int\\\left\((.+?d[a-z])\\\right\)/s','\int '. "\$1 ",$texexp);
181 $texexp = preg_replace('/\\\lim\\\left\((.+?),(.+?),(.+?)\\\right\)/s','\lim_'. "{\$2\\to \$3}\$1 ",$texexp);
182 return $texexp;
183}
184
185function outputText($texexp) {
8a7703ce 186 header("Content-type: text/html; charset=utf-8");
9b361d24 187 echo "<html><body><pre>\n";
188 if ($texexp) {
189 $texexp = str_replace('<','&lt;',$texexp);
190 $texexp = str_replace('>','&gt;',$texexp);
191 $texexp = str_replace('"','&quot;',$texexp);
192 echo "$texexp\n\n";
193 } else {
194 echo "No text output available\n\n";
195 }
196 echo "</pre></body></html>\n";
197}
198
380e47f5 199function tex2image($texexp, $md5, $return=false) {
10ccb7a7 200 global $CFG;
ddea4cf0 201
220a90c5 202 if (!$texexp) {
203 echo 'No tex expresion specified';
204 return;
205 }
206
207 $texexp = '\Large ' . $texexp;
208 $image = $md5 . ".gif";
209 $filetype = 'image/gif';
210 if (!file_exists("$CFG->dataroot/filter/algebra")) {
211 make_upload_directory("filter/algebra");
212 }
213 $pathname = "$CFG->dataroot/filter/algebra/$image";
214 if (file_exists($pathname)) {
215 unlink($pathname);
10ccb7a7 216 }
35716b86
PS
217 $commandpath = filter_tex_get_executable(true);
218 $cmd = filter_tex_get_cmd($pathname, $texexp);
220a90c5 219 system($cmd, $status);
220
10ccb7a7 221 if ($return) {
222 return $image;
223 }
220a90c5 224 if (file_exists($pathname)) {
225 send_file($pathname, $image);
226
10ccb7a7 227 } else {
220a90c5 228 $ecmd = "$cmd 2>&1";
229 echo `$ecmd` . "<br />\n";
230 echo "The shell command<br />$cmd<br />returned status = $status<br />\n";
231 if ($status == 4) {
232 echo "Status corresponds to illegal instruction<br />\n";
233 } else if ($status == 11) {
234 echo "Status corresponds to bus error<br />\n";
235 } else if ($status == 22) {
236 echo "Status corresponds to abnormal termination<br />\n";
237 }
238 if (file_exists($commandpath)) {
239 echo "File size of mimetex executable $commandpath is " . filesize($commandpath) . "<br />";
240 echo "The file permissions are: " . decoct(fileperms($commandpath)) . "<br />";
241 if (function_exists("md5_file")) {
9a58f7cb 242 echo "The md5 checksum of the file is " . md5_file($commandpath) . "<br />";
220a90c5 243 } else {
e072c85e 244 $handle = fopen($commandpath,"rb");
245 $contents = fread($handle,16384);
246 fclose($handle);
9a58f7cb 247 echo "The md5 checksum of the first 16384 bytes is " . md5($contents) . "<br />";
220a90c5 248 }
249 } else {
250 echo "mimetex executable $commandpath not found!<br />";
251 }
252 echo "Image not found!";
10ccb7a7 253 }
9b361d24 254}
380e47f5 255
256function slasharguments($texexp, $md5) {
257 global $CFG;
220a90c5 258 $admin = $CFG->wwwroot.'/'.$CFG->admin.'/settings.php?section=http';
380e47f5 259 $image = tex2image($texexp,$md5,true);
260 echo "<p>If the following image displays correctly, set your ";
220a90c5 261 echo "<a href=\"$admin\" target=\"_blank\">Administration->Server->HTTP</a> ";
6544f8d8 262 echo "setting for slasharguments to file.php/1/pic.jpg: ";
380e47f5 263 echo "<img src=\"pix.php/$image\" align=\"absmiddle\"></p>\n";
6544f8d8 264 echo "<p>Otherwise set it to file.php?file=/1/pic.jpg ";
380e47f5 265 echo "It should display correctly as ";
266 echo "<img src=\"pix.php?file=$image\" align=\"absmiddle\"></p>\n";
267 echo "<p>If neither equation image displays correctly, please seek ";
268 echo "further help at moodle.org at the ";
220a90c5 269 echo "<a href=\"http://moodle.org/mod/forum/view.php?id=752&loginguest=true\" target=\"_blank\">";
380e47f5 270 echo "Mathematics Tools Forum</a></p>";
271}
272
9b361d24 273?>
274
275<html>
276<head><title>Algebra Filter Debugger</title></head>
277<body>
9b361d24 278 <p>Please enter an algebraic expression <b>without</b> any surrounding @@ into
279 the text box below. (Click <a href="#help">here for help.</a>)
280 <form action="algebradebug.php" method="get"
281 target="inlineframe">
282 <center>
9a58f7cb 283 <input type="text" name="algebra" size="50"
60af2703 284 value="sin(z)/(x^2+y^2)" />
9b361d24 285 </center>
286 <ol>
60af2703 287 <li>First click on this button <input type="submit" name="ShowDB" value="Show DB Entry" />
9b361d24 288 to see the cache_filters database entry for this expression.</li>
894ff63f 289 <li>If the database entry looks corrupt, click on this button to delete it:
60af2703 290 <input type="submit" name="DeleteDB" value="Delete DB Entry" /></li>
291 <li>Now click on this button <input type="submit" name="TeXStage1" value="First Stage Tex Translation" />.
9b361d24 292 A preliminary translation into TeX will appear in the box below.</li>
60af2703 293 <li>Next click on this button <input type="submit" name="TeXStage2" value="Second Stage Tex Translation" />.
9b361d24 294 A more refined translation into TeX will appear in the box below.</li>
60af2703 295 <li>Then click on this button <input type="submit" name="ShowImage" value="Show Image" />
9b361d24 296 to show a graphic image of the algebraic expression.</li>
380e47f5 297 <li>Finally check your slash arguments setting
60af2703 298 <input type="submit" name="SlashArguments" value="Check Slash Arguments" /></li>
9b361d24 299 </ol>
9a58f7cb 300 </form> <br /> <br />
9b361d24 301 <center>
302 <iframe name="inlineframe" align="middle" width="80%" height="200">
4317f92f 303 &lt;p&gt;Something is wrong...&lt;/p&gt;
9b361d24 304 </iframe>
9a58f7cb 305 </center> <br />
306<hr />
9b361d24 307<a name="help">
308<h2>Debugging Help</h2>
309</a>
310<p>First here is a brief overview on how the algebra filter works. It
311takes an algebra expression and first translates it into TeX. It first
312looks for the TeX translation in the Moodle database in the table cache_filters
313in the field rawtext. If not found, it passes the algebraic expression to the
314Perl script algebra2tex.pl, which also uses the Perl library AlgParser.pm.
315It then saves the TeX translation in the database for subsequent uses and
316passes the TeX to the mimetex executable to be converted to a gif image.
317Here are a few common things that can go wrong and some suggestions on how
318you might try to fix them.</p>
319<ol>
320<li>Something had gone wrong on a previous occasion when the filter tried to
321translate this expression. Then the database entry for that expression contains
322a bad TeX translation in the rawtext field (usually blank). You can fix this
323by clicking on &quot;Delete DB Entry&quot;</li>
324<li>The First Stage TeX Translation gives a &quot;No text output available&quot;
325message. If your server is running Windows, this may be due to the fact that
326you haven't installed Perl or didn't install it correctly. If your server is
327running some version of Unix (e.g. Linux), then this may be due to your Perl
328binary being installed in a nonstandard location. To fix this edit the first
329line of the algebra2tex.pl script. Another possible problem which may affect
330both Unix and Windows servers is that the web server doesn't have execute permission
331on the algebra2tex.pl script. In that case change permissions accordingly</li>
332<li>The Second Stage TeX Translation produces malformed TeX. This indicates
333a bug in the algebra filter. Post the original algebraic expression and the
334bad TeX translation in the <a href="http://moodle.org/mod/forum/view.php?id=752">
335Mathematics Tools</a> forum in the Using Moodle course on moodle.org.</li>
336<li>The TeX to gif image conversion process does not work. If your server is
337running Unix, a likely cause is that the mimetex binary you are using is
338incompatible with your operating system. You can try compiling it from the
339C sources downloaded from <a href="http://www.forkosh.com/mimetex.zip">
340http://www.forkosh.com/mimetex.zip</a>, or looking for an appropriate
341binary at <a href="http://moodle.org/download/mimetex/">
342http://moodle.org/download/mimetex/</a>. You may then also need to
4317f92f 343edit your moodle/filter/algebra/pix.php file to add
9b361d24 344<br /><?PHP echo "case &quot;" . PHP_OS . "&quot;:" ;?><br ?> to the list of operating systems
345in the switch (PHP_OS) statement. Windows users may have a problem properly
346unzipping mimetex.exe. Make sure that mimetex.exe is is <b>PRECISELY</b>
36130823 347433152 bytes in size. If not, download fresh copy from
9b361d24 348<a href="http://moodle.org/download/mimetex/windows/mimetex.exe">
349http://moodle.org/download/mimetex/windows/mimetex.exe</a>. Lastly check
350the execute permissions on your mimetex binary, as outlined in item 2 above.</li>
351</ol>
352</body>
353</html>