|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00002 // This file is part of Moodle - http://moodle.org/ 00003 // 00004 // Moodle is free software: you can redistribute it and/or modify 00005 // it under the terms of the GNU General Public License as published by 00006 // the Free Software Foundation, either version 3 of the License, or 00007 // (at your option) any later version. 00008 // 00009 // Moodle is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 // GNU General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 00016 00029 require_once("../../config.php"); 00030 00031 if (!filter_is_enabled('filter/tex')) { 00032 print_error('filternotenabled'); 00033 } 00034 00035 require_once($CFG->libdir.'/filelib.php'); 00036 require_once($CFG->dirroot.'/filter/tex/lib.php'); 00037 require_once($CFG->dirroot.'/filter/tex/latex.php'); 00038 00039 $action = optional_param('action', '', PARAM_ALPHA); 00040 $texexp = optional_param('tex', '', PARAM_RAW); 00041 00042 require_login(); 00043 require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM), $USER->id); 00044 00045 $output = ''; 00046 00047 // look up in cache if required 00048 if ($action=='ShowDB' or $action=='DeleteDB') { 00049 $md5 = md5($texexp); 00050 $texcache = $DB->get_record("cache_filters", array("filter"=>"tex", "md5key"=>$md5)); 00051 } 00052 00053 // Action: Show DB Entry 00054 if ($action=='ShowDB') { 00055 if ($texcache) { 00056 $output = "DB cache_filters entry for $texexp\n"; 00057 $output .= "id = $texcache->id\n"; 00058 $output .= "filter = $texcache->filter\n"; 00059 $output .= "version = $texcache->version\n"; 00060 $output .= "md5key = $texcache->md5key\n"; 00061 $output .= "rawtext = $texcache->rawtext\n"; 00062 $output .= "timemodified = $texcache->timemodified\n"; 00063 } else { 00064 $output = "DB cache_filters entry for $texexp not found\n"; 00065 } 00066 } 00067 00068 // Action: Delete DB Entry 00069 if ($action=='DeleteDB') { 00070 if ($texcache) { 00071 $output = "Deleting DB cache_filters entry for $texexp\n"; 00072 $result = $DB->delete_records("cache_filters", array("id"=>$texcache->id)); 00073 if ($result) { 00074 $result = 1; 00075 } else { 00076 $result = 0; 00077 } 00078 $output .= "Number of records deleted = $result\n"; 00079 } else { 00080 $output = "Could not delete DB cache_filters entry for $texexp\nbecause it could not be found.\n"; 00081 } 00082 } 00083 00084 // Action: Show Image 00085 if ($action=='ShowImageMimetex') { 00086 tex2image($texexp); 00087 } 00088 00089 // Action: Check Slasharguments 00090 if ($action=='SlashArguments') { 00091 slasharguments($texexp); 00092 } 00093 00094 // Action: Show Tex command line output 00095 if ($action=='ShowImageTex') { 00096 TexOutput($texexp, true); 00097 exit; 00098 } 00099 00100 // Action: Show Tex command line output 00101 if ($action=='ShowOutputTex') { 00102 if (debugging()) { 00103 TexOutput($texexp); 00104 } else { 00105 echo "Can not output detailed information due to security concerns, please turn on debug mode first."; 00106 } 00107 exit; 00108 } 00109 00110 if (!empty($action)) { 00111 outputText($output); 00112 } 00113 00114 // nothing more to do if there was any action 00115 if (!empty($action)) { 00116 exit; 00117 } 00118 00119 00120 function outputText($texexp) { 00121 header("Content-type: text/html; charset=utf-8"); 00122 echo "<html><body><pre>\n"; 00123 if ($texexp) { 00124 echo s($texexp)."\n\n"; 00125 } else { 00126 echo "No text output available\n\n"; 00127 } 00128 echo "</pre></body></html>\n"; 00129 } 00130 00131 function tex2image($texexp, $return=false) { 00132 global $CFG; 00133 00134 if (!$texexp) { 00135 echo 'No tex expresion specified'; 00136 return; 00137 } 00138 00139 $image = md5($texexp) . ".gif"; 00140 $filetype = 'image/gif'; 00141 if (!file_exists("$CFG->dataroot/filter/tex")) { 00142 make_upload_directory("filter/tex"); 00143 } 00144 $pathname = "$CFG->dataroot/filter/tex/$image"; 00145 if (file_exists($pathname)) { 00146 unlink($pathname); 00147 } 00148 00149 $texexp = '\Large '.$texexp; 00150 $commandpath = filter_tex_get_executable(true); 00151 $cmd = filter_tex_get_cmd($pathname, $texexp); 00152 system($cmd, $status); 00153 00154 if ($return) { 00155 return $image; 00156 } 00157 00158 if (file_exists($pathname)) { 00159 send_file($pathname, $image); 00160 00161 } else if (debugging()) { 00162 $ecmd = "$cmd 2>&1"; 00163 echo `$ecmd` . "<br />\n"; 00164 echo "The shell command<br />$cmd<br />returned status = $status<br />\n"; 00165 if ($status == 4) { 00166 echo "Status corresponds to illegal instruction<br />\n"; 00167 } else if ($status == 11) { 00168 echo "Status corresponds to bus error<br />\n"; 00169 } else if ($status == 22) { 00170 echo "Status corresponds to abnormal termination<br />\n"; 00171 } 00172 if (file_exists($commandpath)) { 00173 echo "File size of mimetex executable $commandpath is " . filesize($commandpath) . "<br />"; 00174 echo "The file permissions are: " . decoct(fileperms($commandpath)) . "<br />"; 00175 if (function_exists("md5_file")) { 00176 echo "The md5 checksum of the file is " . md5_file($commandpath) . "<br />"; 00177 } else { 00178 $handle = fopen($commandpath,"rb"); 00179 $contents = fread($handle,16384); 00180 fclose($handle); 00181 echo "The md5 checksum of the first 16384 bytes is " . md5($contents) . "<br />"; 00182 } 00183 } else { 00184 echo "mimetex executable $commandpath not found!<br />"; 00185 } 00186 echo "Image not found!"; 00187 } else { 00188 echo "Can not output detailed information due to security concerns, please turn on debug mode first."; 00189 } 00190 } 00191 00192 00193 // test Tex/Ghostscript output - command execution only 00194 function TexOutput($expression, $graphic=false) { 00195 global $CFG; 00196 $output = ''; 00197 00198 $latex = new latex(); 00199 00200 // first check if it is likely to work at all 00201 $output .= "<h3>Checking executables</h3>\n"; 00202 $executables_exist = true; 00203 if (is_file($CFG->filter_tex_pathlatex)) { 00204 $output .= "latex executable ($CFG->filter_tex_pathlatex) is readable<br />\n"; 00205 } 00206 else { 00207 $executables_exist = false; 00208 $output .= "<b>Error:</b> latex executable ($CFG->filter_tex_pathlatex) is not readable<br />\n"; 00209 } 00210 if (is_file($CFG->filter_tex_pathdvips)) { 00211 $output .= "dvips executable ($CFG->filter_tex_pathdvips) is readable<br />\n"; 00212 } 00213 else { 00214 $executables_exist = false; 00215 $output .= "<b>Error:</b> dvips executable ($CFG->filter_tex_pathdvips) is not readable<br />\n"; 00216 } 00217 if (is_file($CFG->filter_tex_pathconvert)) { 00218 $output .= "convert executable ($CFG->filter_tex_pathconvert) is readable<br />\n"; 00219 } 00220 else { 00221 $executables_exist = false; 00222 $output .= "<b>Error:</b> convert executable ($CFG->filter_tex_pathconvert) is not readable<br />\n"; 00223 } 00224 00225 // knowing that it might work.. 00226 $md5 = md5($expression); 00227 $output .= "<p>base filename for expression is '$md5'</p>\n"; 00228 00229 // temporary paths 00230 $tex = "$latex->temp_dir/$md5.tex"; 00231 $dvi = "$latex->temp_dir/$md5.dvi"; 00232 $ps = "$latex->temp_dir/$md5.ps"; 00233 $img = "$latex->temp_dir/$md5.{$CFG->filter_tex_convertformat}"; 00234 00235 // put the expression as a file into the temp area 00236 $expression = html_entity_decode($expression); 00237 $output .= "<p>Processing TeX expression:</p><pre>$expression</pre>\n"; 00238 $doc = $latex->construct_latex_document($expression); 00239 $fh = fopen($tex, 'w'); 00240 fputs($fh, $doc); 00241 fclose($fh); 00242 00243 // cd to temp dir 00244 chdir($latex->temp_dir); 00245 00246 // step 1: latex command 00247 $cmd = "$CFG->filter_tex_pathlatex --interaction=nonstopmode $tex"; 00248 $output .= execute($cmd); 00249 00250 // step 2: dvips command 00251 $cmd = "$CFG->filter_tex_pathdvips -E $dvi -o $ps"; 00252 $output .= execute($cmd); 00253 00254 // step 3: convert command 00255 $cmd = "$CFG->filter_tex_pathconvert -density 240 -trim $ps $img "; 00256 $output .= execute($cmd); 00257 00258 if (!$graphic) { 00259 echo $output; 00260 } else if (file_exists($img)){ 00261 send_file($img, "$md5.{$CFG->filter_tex_convertformat}"); 00262 } else { 00263 echo "Error creating image, see command execution output for more details."; 00264 } 00265 } 00266 00267 function execute($cmd) { 00268 exec($cmd, $result, $code); 00269 $output = "<pre>$ $cmd\n"; 00270 $lines = implode("\n", $result); 00271 $output .= "OUTPUT: $lines\n"; 00272 $output .= "RETURN CODE: $code\n</pre>\n"; 00273 return $output; 00274 } 00275 00276 function slasharguments($texexp) { 00277 global $CFG; 00278 $admin = $CFG->wwwroot.'/'.$CFG->admin.'/settings.php?section=http'; 00279 $image = tex2image($texexp,true); 00280 echo "<p>If the following image displays correctly, set your "; 00281 echo "<a href=\"$admin\" target=\"_blank\">Administration->Server->HTTP</a> "; 00282 echo "setting for slasharguments to file.php/1/pic.jpg: "; 00283 echo "<img src=\"$CFG->wwwroot/filter/tex/pix.php/$image\" align=\"absmiddle\"></p>\n"; 00284 echo "<p>Otherwise set it to file.php?file=/1/pic.jpg "; 00285 echo "It should display correctly as "; 00286 echo "<img src=\"$CFG->wwwroot/filter/tex/pix.php?file=$image\" align=\"absmiddle\"></p>\n"; 00287 echo "<p>If neither equation image displays correctly, please seek "; 00288 echo "further help at moodle.org at the "; 00289 echo "<a href=\"http://moodle.org/mod/forum/view.php?id=752&loginguest=true\" target=\"_blank\">"; 00290 echo "Mathematics Tools Forum</a></p>"; 00291 } 00292 00293 ?> 00294 00295 <html> 00296 <head><title>TeX Filter Debugger</title></head> 00297 <body> 00298 <p>Please enter an algebraic expression <b>without</b> any surrounding $$ into 00299 the text box below. (Click <a href="#help">here for help.</a>) 00300 <form action="texdebug.php" method="get" 00301 target="inlineframe"> 00302 <center> 00303 <input type="text" name="tex" size="50" 00304 value="f(x)=\int_{-\infty}^x~e^{-t^2}dt" /> 00305 </center> 00306 <p>The following tests are available:</p> 00307 <ol> 00308 <li><input type="radio" name="action" value="ShowDB" id="ShowDB" /> 00309 <label for="ShowDB">See the cache_filters database entry for this expression (if any).</label></li> 00310 <li><input type="radio" name="action" value="DeleteDB" id="DeleteDB" /> 00311 <label for="DeleteDB">Delete the cache_filters database entry for this expression (if any).</label></li> 00312 <li><input type="radio" name="action" value="ShowImageMimetex" id="ShowImageMimetex" checked="checked" /> 00313 <label for="ShowImageMimetex">Show a graphic image of the algebraic expression rendered with mimetex.</label></li> 00314 <li><input type="radio" name="action" value="ShowImageTex" id="ShowImageTex" /> 00315 <label for="ShowImageTex">Show a graphic image of the algebraic expression rendered with Tex/Ghostscript.</label></li> 00316 <li><input type="radio" name="action" value="ShowOutputTex" id="ShowOutputTex" /> 00317 <label for="ShowOutputTex">Show command execution output from the algebraic expression rendered with Tex/Ghostscript.</label></li> 00318 <li><input type="radio" name="action" value="SlashArguments" id="SlashArguments" /> 00319 <label for="SlashArguments">Check slasharguments setting.</label></li> 00320 </ol> 00321 <input type="submit" value="Do it!" /> 00322 </form> <br /> <br /> 00323 <center> 00324 <iframe name="inlineframe" align="middle" width="80%" height="200"> 00325 <p>Something is wrong...</p> 00326 </iframe> 00327 </center> <br /> 00328 <hr /> 00329 <a name="help"> 00330 <h2>Debugging Help</h2> 00331 </a> 00332 <p>First a brief overview of how the TeX filter works. The TeX filter first 00333 searches the database cache_filters table to see if this TeX expression had been 00334 processed before. If not, it adds a DB entry for that expression. It then 00335 replaces the TeX expression by an <img src=".../filter/tex/pix.php..."> 00336 tag. The filter/tex/pix.php script then searches the database to find an 00337 appropriate gif/png image file for that expression and to create one if it doesn't exist. 00338 It will then use either the LaTex/Ghostscript renderer (using external executables 00339 on your system) or the bundled Mimetex executable. The full Latex/Ghostscript 00340 renderer produces better results and is tried first. 00341 Here are a few common things that can go wrong and some suggestions on how 00342 you might try to fix them.</p> 00343 <ol> 00344 <li>Something had gone wrong on a previous occasion when the filter tried to 00345 process this expression. Then the database entry for that expression contains 00346 a bad TeX expression in the rawtext field (usually blank). You can fix this 00347 by clicking on "Delete DB Entry"</li> 00348 <li>The TeX to gif/png image conversion process does not work. 00349 If paths are specified in the filter configuation screen for the three 00350 executables these will be tried first. Note that they still must be correctly 00351 installed and have the correct permissions. In particular make sure that you 00352 have all the packages installed (e.g., on Debian/Ubuntu you need to install 00353 the 'tetex-extra' package). Running the 'show command execution' test should 00354 give a big clue. 00355 If this fails or is not available, the Mimetex executable is tried. If this 00356 fails a likely cause is that the mimetex binary you are using is 00357 incompatible with your operating system. You can try compiling it from the 00358 C sources downloaded from <a href="http://www.forkosh.com/mimetex.zip"> 00359 http://www.forkosh.com/mimetex.zip</a>, or looking for an appropriate 00360 binary at <a href="http://moodle.org/download/mimetex/"> 00361 http://moodle.org/download/mimetex/</a>. You may then also need to 00362 edit your moodle/filter/tex/pix.php file to add 00363 <br /><?PHP echo "case "" . PHP_OS . "":" ;?><br ?> to the list of operating systems 00364 in the switch (PHP_OS) statement. Windows users may have a problem properly 00365 unzipping mimetex.exe. Make sure that mimetex.exe is is <b>PRECISELY</b> 00366 433152 bytes in size. If not, download a fresh copy from 00367 <a href="http://moodle.org/download/mimetex/windows/mimetex.exe"> 00368 http://moodle.org/download/mimetex/windows/mimetex.exe</a>. 00369 Another possible problem which may affect 00370 both Unix and Windows servers is that the web server doesn't have execute permission 00371 on the mimetex binary. In that case change permissions accordingly</li> 00372 </ol> 00373 </body> 00374 </html>