1
0
mirror of https://github.com/moodle/moodle.git synced 2025-04-24 09:55:33 +02:00

MDL-11147:

Debug screen now supports LaTeX/Ghostscript renderer.

Merged from STABLE_18
This commit is contained in:
thepurpleblob 2007-09-07 14:24:18 +00:00
parent c2136cde22
commit d93a90dcfd

@ -6,6 +6,7 @@
$nomoodlecookie = true; // Because it interferes with caching
require_once("../../config.php");
require( 'latex.php' );
if (empty($CFG->textfilters)) {
error ('Filter not enabled!');
@ -18,52 +19,80 @@
$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);
// 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,'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";
}
// 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 = "DB cache_filters entry for $texexp not 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,'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";
} else {
$output = "Could not delete DB cache_filters entry for $texexp\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;
}
@ -181,6 +210,97 @@
}
}
// 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';
@ -211,16 +331,22 @@
<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">
@ -237,6 +363,9 @@ processed before. If not, it adds a DB entry for that expression. It then
replaces the TeX expression by an &lt;img src=&quot;.../filter/tex/pix.php...&quot;&gt;
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>
@ -244,8 +373,15 @@ you might try to fix them.</p>
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 &quot;Delete DB Entry&quot;</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