$nomoodlecookie = true; // Because it interferes with caching
require_once("../../config.php");
+ require( 'latex.php' );
if (empty($CFG->textfilters)) {
error ('Filter not enabled!');
$CFG->texfilterdir = "filter/tex";
$CFG->teximagedir = "filter/tex";
+
+ $param = null;
+ $param->action = optional_param( 'action','',PARAM_ALPHA );
+ $param->tex = optional_param( 'tex','' );
$query = urldecode($_SERVER['QUERY_STRING']);
error_reporting(E_ALL);
+ $output = '';
- if ($query) {
- $output = $query;
- $splitpos = strpos($query,'&')-4;
- $texexp = substr($query,4,$splitpos);
- $md5 = md5($texexp);
- if (strpos($query,'ShowDB') || strpos($query,'DeleteDB')) {
- $texcache = get_record("cache_filters","filter","tex", "md5key", $md5);
- }
- if (strpos($query,'ShowDB')) {
- if ($texcache) {
- $output = "DB cache_filters entry for $texexp\n";
- $output .= "id = $texcache->id\n";
- $output .= "filter = $texcache->filter\n";
- $output .= "version = $texcache->version\n";
- $output .= "md5key = $texcache->md5key\n";
- $output .= "rawtext = $texcache->rawtext\n";
- $output .= "timemodified = $texcache->timemodified\n";
- } else {
- $output = "DB cache_filters entry for $texexp not found\n";
- }
+ // look up in cache if required
+ if ($param->action=='ShowDB' or $param->action=='DeleteDB') {
+ $md5 = md5($param->tex);
+ $texcache = get_record("cache_filters","filter","tex", "md5key", $md5);
+ }
+
+ // Action: Show DB Entry
+ if ($param->action=='ShowDB') {
+ if ($texcache) {
+ $output = "DB cache_filters entry for $param->tex\n";
+ $output .= "id = $texcache->id\n";
+ $output .= "filter = $texcache->filter\n";
+ $output .= "version = $texcache->version\n";
+ $output .= "md5key = $texcache->md5key\n";
+ $output .= "rawtext = $texcache->rawtext\n";
+ $output .= "timemodified = $texcache->timemodified\n";
+ } else {
+ $output = "DB cache_filters entry for $param->tex not found\n";
}
- if (strpos($query,'DeleteDB')) {
- if ($texcache) {
- $output = "Deleting DB cache_filters entry for $texexp\n";
- $result = delete_records("cache_filters","id",$texcache->id);
- if ($result) {
- $result = 1;
- } else {
- $result = 0;
- }
- $output .= "Number of records deleted = $result\n";
+ }
+
+ // Action: Delete DB Entry
+ if ($param->action=='DeleteDB') {
+ if ($texcache) {
+ $output = "Deleting DB cache_filters entry for $param->tex\n";
+ $result = delete_records("cache_filters","id",$texcache->id);
+ if ($result) {
+ $result = 1;
} else {
- $output = "Could not delete DB cache_filters entry for $texexp\nbecause it could not be found.\n";
+ $result = 0;
}
+ $output .= "Number of records deleted = $result\n";
+ } else {
+ $output = "Could not delete DB cache_filters entry for $param->tex\nbecause it could not be found.\n";
}
- if (strpos($query,'ShowImage')) {
- tex2image($texexp);
- } else if (strpos($query,'SlashArguments')) {
- slasharguments($texexp);
- } else {
- outputText($output);
- }
+ }
+
+ // Action: Show Image
+ if ($param->action=='ShowImageMimetex') {
+ tex2image($param->tex);
+ }
+
+ // Action: Check Slasharguments
+ if ($param->action=='SlashArguments') {
+ slasharguments($param->tex);
+ }
+
+ // Action: Show Tex command line output
+ if ($param->action=='ShowImageTex') {
+ TexOutput($param->tex, true);
+ exit;
+ }
+
+ // Action: Show Tex command line output
+ if ($param->action=='ShowOutputTex') {
+ TexOutput($param->tex);
+ exit;
+ }
+
+ if (!empty($param->action)) {
+ outputText($output);
+ }
+
+ // nothing more to do if there was any action
+ if (!empty($param->action)) {
exit;
}
}
}
+
+ // test Tex/Ghostscript output - command execution only
+ function TexOutput( $expression, $graphic=false ) {
+ global $CFG;
+ $output = '';
+
+ $latex = new latex();
+
+ // first check if it is likely to work at all
+ $output .= "<h3>Checking executables</h3>\n";
+ $executables_exist = true;
+ if (is_file($CFG->filter_tex_pathlatex)) {
+ $output .= "latex executable ($CFG->filter_tex_pathlatex) is readable<br />\n";
+ }
+ else {
+ $executables_exist = false;
+ $output .= "<b>Error:</b> latex executable ($CFG->filter_tex_pathlatex) is not readable<br />\n";
+ }
+ if (is_file($CFG->filter_tex_pathdvips)) {
+ $output .= "dvips executable ($CFG->filter_tex_pathdvips) is readable<br />\n";
+ }
+ else {
+ $executables_exist = false;
+ $output .= "<b>Error:</b> dvips executable ($CFG->filter_tex_pathdvips) is not readable<br />\n";
+ }
+ if (is_file($CFG->filter_tex_pathconvert)) {
+ $output .= "convert executable ($CFG->filter_tex_pathconvert) is readable<br />\n";
+ }
+ else {
+ $executables_exist = false;
+ $output .= "<b>Error:</b> convert executable ($CFG->filter_tex_pathconvert) is not readable<br />\n";
+ }
+
+ // knowing that it might work..
+ $md5 = md5( $expression );
+ $output .= "<p>base filename for expression is '$md5'</p>\n";
+
+ // temporary paths
+ $tex = "$latex->temp_dir/$md5.tex";
+ $dvi = "$latex->temp_dir/$md5.dvi";
+ $ps = "$latex->temp_dir/$md5.ps";
+ $gif = "$latex->temp_dir/$md5.gif";
+
+ // put the expression as a file into the temp area
+ $doc = $latex->construct_latex_document( $expression );
+ $fh = fopen( $tex, 'w' );
+ fputs( $fh, $doc );
+ fclose( $fh );
+
+ // cd to temp dir
+ chdir( $latex->temp_dir );
+
+ // step 1: latex command
+ $cmd = "$CFG->filter_tex_pathlatex --interaction=nonstopmode $tex";
+ $output .= execute( $cmd );
+
+ // step 2: dvips command
+ $cmd = "$CFG->filter_tex_pathdvips -E $dvi -o $ps";
+ $output .= execute( $cmd );
+
+ // step 3: convert command
+ $cmd = "$CFG->filter_tex_pathconvert -density 240 -trim $ps $gif ";
+ $output .= execute( $cmd );
+
+ if (!$graphic) {
+ echo( $output );
+ } else {
+ $lastmodified = filemtime($gif);
+ $lifetime = 86400;
+ $filetype = 'image/gif';
+ $image = "$md5.gif";
+ header("Last-Modified: " . gmdate("D, d M Y H:i:s", $lastmodified) . " GMT");
+ header("Expires: " . gmdate("D, d M Y H:i:s", time() + $lifetime) . " GMT");
+ header("Cache-control: max_age = $lifetime"); // a day
+ header("Pragma: ");
+ header("Content-disposition: inline; filename=$image");
+ header("Content-length: ".filesize($gif));
+ header("Content-type: $filetype");
+ readfile("$gif");
+ }
+ }
+
+ function execute( $cmd ) {
+ exec( $cmd, $result, $code );
+ $output = "<pre>$ $cmd\n";
+ $lines = implode( "\n", $result );
+ $output .= "OUTPUT: $lines\n";
+ $output .= "RETURN CODE: $code\n</pre>\n";
+ return $output;
+ }
+
function slasharguments($texexp) {
global $CFG;
$admin = $CFG->wwwroot . '/' . $CFG->admin . '/config.php';
<input type="text" name="tex" size="50"
value="f(x)=\Bigint_{-\infty}^x~e^{-t^2}dt" />
</center>
+ <p>The following tests are available:</p>
<ol>
- <li>First click on this button <input type="submit" name="ShowDB" value="Show DB Entry" />
- to see the cache_filters database entry for this expression.</li>
- <li>If the database entry looks corrupt, click on this button to delete it:
- <input type="submit" name="DeleteDB" value="Delete DB Entry" /></li>
- <li>Then click on this button <input type="submit" name="ShowImage" value="Show Image" />
- to show a graphic image of the algebraic expression.</li>
- <li>Finally check your slash arguments setting
- <input type="submit" name="SlashArguments" value="Check Slash Arguments" /></li>
+ <li><input type="radio" name="action" value="ShowDB" />
+ See the cache_filters database entry for this expression (if any).</li>
+ <li><input type="radio" name="DeleteDB" value="DeleteDB" />
+ Delete the cache_filters database entry for this expression (if any).</li>
+ <li><input type="radio" name="action" value="ShowImageMimetex" />
+ Show a graphic image of the algebraic expression rendered with mimetex.</li>
+ <li><input type="radio" name="action" value="ShowImageTex" />
+ Show a graphic image of the algebraic expression rendered with Tex/Ghostscript.</li>
+ <li><input type="radio" name="action" value="ShowOutputTex" />
+ Show command execution output from the algebraic expression rendered with Tex/Ghostscript.</li>
+ <li><input type="radio" name="action" value="SlashArguments" />
+ Check slasharguments setting.</li>
</ol>
+ <input type="submit" value="Do it!" />
</form> <br /> <br />
<center>
<iframe name="inlineframe" align="middle" width="80%" height="200">
replaces the TeX expression by an <img src=".../filter/tex/pix.php...">
tag. The filter/tex/pix.php script then searches the database to find an
appropriate gif image file for that expression and to create one if it doesn't exist.
+It will then use either the LaTex/Ghostscript renderer (using external executables
+on your system) or the bundled Mimetex executable. The full Latex/Ghostscript
+renderer produces better results and is tried first.
Here are a few common things that can go wrong and some suggestions on how
you might try to fix them.</p>
<ol>
process this expression. Then the database entry for that expression contains
a bad TeX expression in the rawtext field (usually blank). You can fix this
by clicking on "Delete DB Entry"</li>
-<li>The TeX to gif image conversion process does not work. If your server is
-running Unix, a likely cause is that the mimetex binary you are using is
+<li>The TeX to gif image conversion process does not work.
+If paths are specified in the filter configuation screen for the three
+executables these will be tried first. Note that they still must be correctly
+installed and have the correct permissions. In particular make sure that you
+have all the packages installed (e.g., on Debian/Ubuntu you need to install
+the 'tetex-extra' package). Running the 'show command execution' test should
+give a big clue.
+If this fails or is not available, the Mimetex executable is tried. If this
+fails a likely cause is that the mimetex binary you are using is
incompatible with your operating system. You can try compiling it from the
C sources downloaded from <a href="http://www.forkosh.com/mimetex.zip">
http://www.forkosh.com/mimetex.zip</a>, or looking for an appropriate