Added class to render images using Latex rather than mimetex. It will only

be used if it works on the server, otherwise mimetex is used as before.
Produces rather nicer images, and the full range of formatting can be used,
rather than mimetex's limited set.
This commit is contained in:
thepurpleblob
2005-06-28 13:23:57 +00:00
parent f8e0e46a4d
commit 18a2407ef4
3 changed files with 208 additions and 37 deletions
+1 -2
View File
@@ -69,7 +69,7 @@ function string_file_picture_tex($imagefile, $tex= "", $height="", $width="", $a
$output .= urlencode($tex) . "', 'popup', 'menubar=0,location=0,scrollbars,";
$output .= "resizable,width=300,height=240', 0);\">";
}
$output .= "<img border=\"0\" $title $height $width alt=\"\" src=\"";
$output .= "<img class=\"texrender\" border=\"0\" $title $height $width alt=\"\" src=\"";
if ($CFG->slasharguments) { // Use this method if possible for better caching
$output .= "$CFG->wwwroot/$CFG->texfilterdir/pix.php/$imagefile";
} else {
@@ -108,7 +108,6 @@ function tex_filter ($courseid, $text) {
# if ($discussion->forum != 130) {
# return $text;
# }
$text .= ' ';
preg_match_all('/\$(\$\$+?)([^\$])/s',$text,$matches);
for ($i=0;$i<count($matches[0]);$i++) {
+161
View File
@@ -0,0 +1,161 @@
<?php
// latex.php
// render TeX stuff using latex - this will not work on all platforms
// or configurations. Only works on Linux and Mac with appropriate
// software installed.
// Much of this inspired/copied from Benjamin Zeiss' work
class latex {
var $temp_dir;
var $path_latex;
var $path_dvips;
var $path_convert;
var $path_identify;
var $supported_platform;
var $error;
/**
* Constructor - create temporary directories and build paths to
* external 'helper' binaries.
* Other platforms could/should be added
*/
function latex() {
global $CFG;
// construct directory structure
$this->temp_dir = $CFG->dataroot . "/temp/latex";
if (!file_exists("$CFG->dataroot/temp")) {
mkdir( "$CFG->dataroot/temp", $CFG->directorypermissions );
}
if (!file_exists( $this->temp_dir )) {
mkdir( $this->temp_dir, $CFG->directorypermissions );
}
// load the paths for the appropriate OS
// it would be nice to expand this
if (PHP_OS=='Linux') {
$binpath = '/usr/bin/';
$this->supported_platform = true;
}
elseif (PHP_OS=='Darwin') {
$binpath = '/sw/bin/'; // most likely needs a fink install (fink.sf.net)
$this->supported_platform = true;
}
else {
$this->supported_platform = false;
return false;
}
$this->path_latex = "{$binpath}latex";
$this->path_dvips = "{$binpath}dvips";
$this->path_convert = "{$binpath}convert";
$this->path_identify = "{$binpath}identify";
return true;
}
/**
* Turn the bit of TeX into a valid latex document
* @param string $forumula the TeX formula
* @param int $fontsize the font size
* @return string the latex document
*/
function construct_latex_document( $formula, $fontsize=12 ) {
$doc = "\\documentclass[{$fontsize}pt]{article}\n";
$doc .= "\\usepackage[latin1]{inputenc}\n";
$doc .= "\\usepackage{amsmath}\n";
$doc .= "\\usepackage{amsfonts}\n";
$doc .= "\\pagestyle{empty}\n";
$doc .= "\\begin{document}\n";
$doc .= "$ {$formula} $\n";
$doc .= "\\end{document}\n";
return $doc;
}
/**
* execute an external command, with optional logging
* @param string $command command to execute
* @param file $log valid open file handle - log info will be written to this file
* @return return code from execution of command
*/
function execute( $command, $log=null ) {
$output = array();
exec( $command, $output, $return_code );
if ($log) {
fwrite( $log, "COMMAND: $command \n" );
$outputs = implode( "\n", $output );
fwrite( $log, "OUTPUT: $outputs \n" );
fwrite( $log, "RETURN_CODE: $return_code\n " );
}
return $return_code;
}
/**
* Render TeX string into gif
* @param string $formula TeX formula
* @param string $filename base of filename for output (no extension)
* @param int $fontsize font size
* @param int $density density value for .ps to .gif conversion
* @param string $background background color (e.g, #FFFFFF).
* @param file $log valid open file handle for optional logging (debugging only)
* @return bool true if successful
*/
function render( $formula, $filename, $fontsize=12, $density=240, $background='', $log=null ) {
$doc = $this->construct_latex_document( $formula, $fontsize );
// construct some file paths
$tex = "{$this->temp_dir}/$filename.tex";
$dvi = "{$this->temp_dir}/$filename.dvi";
$ps = "{$this->temp_dir}/$filename.ps";
$gif = "{$this->temp_dir}/$filename.gif";
// turn the latex doc into a .tex file in the temp area
$fh = fopen( $tex, 'w' );
fputs( $fh, $doc );
fclose( $fh );
// run latex on document
$command = "{$this->path_latex} --interaction=nonstopmode $tex";
chdir( $this->temp_dir );
if ($this->execute($command, $log)) {
return false;
}
// run dvips (.dvi to .ps)
$command = "{$this->path_dvips} -E $dvi -o $ps";
if ($this->execute($command, $log )) {
return false;
}
// run convert on document (.ps to .gif)
if ($background) {
$bg_opt = "-background \"$background\"";
} else {
$bg_opt = "";
}
$command = "{$this->path_convert} -density $density -trim $bg_opt $ps $gif";
if ($this->execute($command, $log )) {
return false;
}
return $gif;
}
/**
* Delete files created in temporary area
* Don't forget to copy the final gif before calling this
* @param string $filename file base (no extension)
*/
function clean_up( $filename ) {
unlink( "{$this->temp_dir}/$filename.tex" );
unlink( "{$this->temp_dir}/$filename.dvi" );
unlink( "{$this->temp_dir}/$filename.ps" );
unlink( "{$this->temp_dir}/$filename.gif" );
unlink( "{$this->temp_dir}/$filename.aux" );
unlink( "{$this->temp_dir}/$filename.log" );
}
}
?>
+46 -35
View File
@@ -7,6 +7,7 @@
require_once('../../config.php');
require_once($CFG->libdir.'/filelib.php');
require_once('latex.php');
$CFG->texfilterdir = 'filter/tex';
$CFG->teximagedir = 'filter/tex';
@@ -15,7 +16,7 @@
$cmd = ''; // Initialise these variables
$status = '';
//error_reporting(E_ALL);
error_reporting(E_ALL);
$relativepath = get_file_argument('pix.php');
@@ -35,48 +36,58 @@
make_upload_directory($CFG->teximagedir);
}
$texexp = $texcache->rawtext;
$texexp = str_replace('&lt;','<',$texexp);
$texexp = str_replace('&gt;','>',$texexp);
$texexp = preg_replace('!\r\n?!',' ',$texexp);
$texexp = '\Large ' . $texexp;
// try and render with latex first
$latex = new latex();
$latex_path = $latex->render( $texcache->rawtext, $md5, 12, 200, '#FFFFFF' );
if ($latex_path) {
copy( $latex_path, $pathname );
$latex->clean_up( $md5 );
}
else {
// failing that, use mimetex
$texexp = $texcache->rawtext;
$texexp = str_replace('&lt;','<',$texexp);
$texexp = str_replace('&gt;','>',$texexp);
$texexp = preg_replace('!\r\n?!',' ',$texexp);
$texexp = '\Large ' . $texexp;
if ((PHP_OS == "WINNT") || (PHP_OS == "WIN32") || (PHP_OS == "Windows")) {
$texexp = str_replace('"','\"',$texexp);
$cmd = "$CFG->dirroot/$CFG->texfilterdir/mimetex.exe";
$cmd = str_replace(' ','^ ',$cmd);
$cmd .= " ++ -e \"$pathname\" -- \"$texexp\"";
} else if (is_executable("$CFG->dirroot/$CFG->texfilterdir/mimetex")) { /// Use the custom binary
if ((PHP_OS == "WINNT") || (PHP_OS == "WIN32") || (PHP_OS == "Windows")) {
$texexp = str_replace('"','\"',$texexp);
$cmd = "$CFG->dirroot/$CFG->texfilterdir/mimetex.exe";
$cmd = str_replace(' ','^ ',$cmd);
$cmd .= " ++ -e \"$pathname\" -- \"$texexp\"";
} else if (is_executable("$CFG->dirroot/$CFG->texfilterdir/mimetex")) { /// Use the custom binary
$cmd = "$CFG->dirroot/$CFG->texfilterdir/mimetex -e $pathname -- ". escapeshellarg($texexp);
$cmd = "$CFG->dirroot/$CFG->texfilterdir/mimetex -e $pathname -- ". escapeshellarg($texexp);
} else { /// Auto-detect the right TeX binary
switch (PHP_OS) {
} else { /// Auto-detect the right TeX binary
switch (PHP_OS) {
case "Linux":
$cmd = "\"$CFG->dirroot/$CFG->texfilterdir/mimetex.linux\" -e \"$pathname\" -- ". escapeshellarg($texexp);
break;
case "Linux":
$cmd = "\"$CFG->dirroot/$CFG->texfilterdir/mimetex.linux\" -e \"$pathname\" -- ". escapeshellarg($texexp);
break;
case "Darwin":
$cmd = "\"$CFG->dirroot/$CFG->texfilterdir/mimetex.darwin\" -e \"$pathname\" -- ". escapeshellarg($texexp);
break;
case "Darwin":
$cmd = "\"$CFG->dirroot/$CFG->texfilterdir/mimetex.darwin\" -e \"$pathname\" -- ". escapeshellarg($texexp);
break;
default: /// Nothing was found, so tell them how to fix it.
if ($CFG->debug > 7) {
echo "Make sure you have an appropriate MimeTeX binary here:\n\n";
echo " $CFG->dirroot/$CFG->texfilterdir/mimetex\n\n";
echo "and that it has the right permissions set on it as executable program.\n\n";
echo "You can get the latest binaries for your ".PHP_OS." platform from: \n\n";
echo " http://moodle.org/download/mimetex/";
} else {
echo "Mimetex executable was not found,\n";
echo "Please turn on debug mode in site configuration to see more info here.";
}
die;
break;
default: /// Nothing was found, so tell them how to fix it.
if ($CFG->debug > 7) {
echo "Make sure you have an appropriate MimeTeX binary here:\n\n";
echo " $CFG->dirroot/$CFG->texfilterdir/mimetex\n\n";
echo "and that it has the right permissions set on it as executable program.\n\n";
echo "You can get the latest binaries for your ".PHP_OS." platform from: \n\n";
echo " http://moodle.org/download/mimetex/";
} else {
echo "Mimetex executable was not found,\n";
echo "Please turn on debug mode in site configuration to see more info here.";
}
die;
break;
}
}
system($cmd, $status);
}
system($cmd, $status);
}
}