diff --git a/filter/tex/filter.php b/filter/tex/filter.php index 7e076aac97f..78f74192a14 100644 --- a/filter/tex/filter.php +++ b/filter/tex/filter.php @@ -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 .= "\"\"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;$itemp_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" ); + } + + } + + +?> diff --git a/filter/tex/pix.php b/filter/tex/pix.php index a5f84d3b1bd..e85a07e1d3a 100644 --- a/filter/tex/pix.php +++ b/filter/tex/pix.php @@ -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('<','<',$texexp); - $texexp = str_replace('>','>',$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('<','<',$texexp); + $texexp = str_replace('>','>',$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); } }