textfilters)) { error ('Filter not enabled!'); } else { $filters = explode(',', $CFG->textfilters); if (array_search('filter/tex', $filters) === FALSE) { 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 = ''; // 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"; } } // 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 { $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"; } } // 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; } function outputText($texexp) { header("Content-type: text/html"); echo "
\n";
if ($texexp) {
$texexp = str_replace('<','<',$texexp);
$texexp = str_replace('>','>',$texexp);
$texexp = str_replace('"','"',$texexp);
echo "$texexp\n\n";
} else {
echo "No text output available\n\n";
}
echo "\n";
}
function tex2image($texexp, $return=false) {
global $CFG;
$error_message1 = "Your system is not configured to run mimeTeX. ";
$error_message1 .= "You need to download the appropriate case "' . PHP_OS . "\":\n";
$error_message1 .= " \$cmd = \"\\\\\"\$CFG->dirroot/\$CFG->texfilterdir/";
$error_message1 .= 'mimetex.' . strtolower(PHP_OS) . "\\\\\" -e \\\\\"\$pathname\\\\\" \". escapeshellarg(\$texexp);";
$error_message1 .= "You also need to add this to your texdebug.php file.";
if ($texexp) {
$texexp = '\Large ' . $texexp;
$lifetime = 86400;
$image = md5($texexp) . ".gif";
$filetype = 'image/gif';
if (!file_exists("$CFG->dataroot/$CFG->teximagedir")) {
make_upload_directory($CFG->teximagedir);
}
$pathname = "$CFG->dataroot/$CFG->teximagedir/$image";
if (file_exists($pathname)) {
unlink($pathname);
}
$commandpath = "";
$cmd = "";
$texexp = escapeshellarg($texexp);
switch (PHP_OS) {
case "Linux":
$commandpath="$CFG->dirroot/$CFG->texfilterdir/mimetex.linux";
$cmd = "\"$CFG->dirroot/$CFG->texfilterdir/mimetex.linux\" -e \"$pathname\" $texexp";
break;
case "WINNT":
case "WIN32":
case "Windows":
$commandpath="$CFG->dirroot/$CFG->texfilterdir/mimetex.exe";
$cmd = str_replace(' ','^ ',$commandpath);
$cmd .= " ++ -e \"$pathname\" $texexp";
break;
case "Darwin":
$commandpath="$CFG->dirroot/$CFG->texfilterdir/mimetex.darwin";
$cmd = "\"$CFG->dirroot/$CFG->texfilterdir/mimetex.darwin\" -e \"$pathname\" $texexp";
break;
}
if (!$cmd) {
if (is_executable("$CFG->dirroot/$CFG->texfilterdir/mimetex")) { /// Use the custom binary
$commandpath="$CFG->dirroot/$CFG->texfilterdir/mimetex";
$cmd = "$CFG->dirroot/$CFG->texfilterdir/mimetex -e $pathname $texexp";
} else {
error($error_message1);
}
}
system($cmd, $status);
}
if ($return) {
return $image;
}
if ($texexp && file_exists($pathname)) {
$lastmodified = filemtime($pathname);
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($pathname));
header("Content-type: $filetype");
readfile("$pathname");
} else {
$ecmd = "$cmd 2>&1";
echo `$ecmd` . "base filename for expression is '$md5'
\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 $expression = stripslashes( $expression ); $expression = html_entity_decode( $expression ); $output .= "Processing TeX expression:
$expression\n"; $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 = "
$ $cmd\n";
$lines = implode( "\n", $result );
$output .= "OUTPUT: $lines\n";
$output .= "RETURN CODE: $code\n\n";
return $output;
}
function slasharguments($texexp) {
global $CFG;
$admin = $CFG->wwwroot . '/' . $CFG->admin . '/config.php';
$image = tex2image($texexp,true);
echo "If the following image displays correctly, set your ";
echo "Administration->Configuration->Variables ";
echo "setting for slasharguments to file.php/1/pic.jpg: ";
echo "
Otherwise set it to file.php?file=/1/pic.jpg ";
echo "It should display correctly as ";
echo "
If neither equation image displays correctly, please seek "; echo "further help at moodle.org at the "; echo ""; echo "Mathematics Tools Forum
"; } ?>Please enter an algebraic expression without any surrounding $$ into the text box below. (Click here for help.)
First a brief overview of how the TeX filter works. The TeX filter first searches the database cache_filters table to see if this TeX expression had been processed before. If not, it adds a DB entry for that expression. It then 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.