Differences Between: [Versions 311 and 400] [Versions 311 and 401] [Versions 311 and 402] [Versions 311 and 403]
1 <?php 2 // latex.php 3 // render TeX stuff using latex - this will not work on all platforms 4 // or configurations. Only works on Linux and Mac with appropriate 5 // software installed. 6 // Much of this inspired/copied from Benjamin Zeiss' work 7 8 class latex { 9 10 var $temp_dir; 11 var $error; 12 13 /** 14 * Constructor - create temporary directories and build paths to 15 * external 'helper' binaries. 16 * Other platforms could/should be added 17 */ 18 public function __construct() { 19 global $CFG; 20 21 // construct directory structure 22 $this->temp_dir = $CFG->tempdir . "/latex"; 23 make_temp_directory('latex'); 24 } 25 26 /** 27 * Old syntax of class constructor. Deprecated in PHP7. 28 * 29 * @deprecated since Moodle 3.1 30 */ 31 public function latex() { 32 debugging('Use of class name as constructor is deprecated', DEBUG_DEVELOPER); 33 self::__construct(); 34 } 35 36 /** 37 * Accessor function for support_platform field. 38 * @return boolean value of supported_platform 39 */ 40 function supported() { 41 return $this->supported_platform; 42 } 43 44 /** 45 * Turn the bit of TeX into a valid latex document 46 * @param string $forumula the TeX formula 47 * @param int $fontsize the font size 48 * @return string the latex document 49 */ 50 function construct_latex_document($formula, $fontsize = 12) { 51 // $fontsize don't affects to formula's size. $density can change size 52 $doc = "\\documentclass[{$fontsize}pt]{article}\n"; 53 $doc .= get_config('filter_tex', 'latexpreamble'); 54 $doc .= "\\pagestyle{empty}\n"; 55 $doc .= "\\begin{document}\n"; 56 if (preg_match("/^[[:space:]]*\\\\begin\\{(gather|align|alignat|multline).?\\}/i", $formula)) { 57 $doc .= "$formula\n"; 58 } else { 59 $doc .= "$ {$formula} $\n"; 60 } 61 $doc .= "\\end{document}\n"; 62 63 // Sanitize the whole document (rather than just the formula) to make sure no one can bypass sanitization 64 // by using \newcommand in preamble to give an alias to a blocked command. 65 $doc = filter_tex_sanitize_formula($doc); 66 67 return $doc; 68 } 69 70 /** 71 * execute an external command, with optional logging 72 * @param string $command command to execute 73 * @param file $log valid open file handle - log info will be written to this file 74 * @return return code from execution of command 75 */ 76 function execute( $command, $log=null ) { 77 $output = array(); 78 exec( $command, $output, $return_code ); 79 if ($log) { 80 fwrite( $log, "COMMAND: $command \n" ); 81 $outputs = implode( "\n", $output ); 82 fwrite( $log, "OUTPUT: $outputs \n" ); 83 fwrite( $log, "RETURN_CODE: $return_code\n " ); 84 } 85 return $return_code; 86 } 87 88 /** 89 * Render TeX string into gif/png 90 * @param string $formula TeX formula 91 * @param string $filename filename for output (including extension) 92 * @param int $fontsize font size 93 * @param int $density density value for .ps to .gif/.png conversion 94 * @param string $background background color (e.g, #FFFFFF). 95 * @param file $log valid open file handle for optional logging (debugging only) 96 * @return bool true if successful 97 */ 98 function render( $formula, $filename, $fontsize=12, $density=240, $background='', $log=null ) { 99 100 global $CFG; 101 102 // quick check - will this work? 103 $pathlatex = get_config('filter_tex', 'pathlatex'); 104 if (empty($pathlatex)) { 105 return false; 106 } 107 $pathlatex = escapeshellarg(trim($pathlatex, " '\"")); 108 109 $doc = $this->construct_latex_document( $formula, $fontsize ); 110 111 // construct some file paths 112 $convertformat = get_config('filter_tex', 'convertformat'); 113 if (!strpos($filename, ".{$convertformat}")) { 114 $convertformat = 'png'; 115 } 116 $filename = str_replace(".{$convertformat}", '', $filename); 117 $tex = "$filename.tex"; // Absolute paths won't work with openin_any = p setting. 118 $dvi = "{$this->temp_dir}/$filename.dvi"; 119 $ps = "{$this->temp_dir}/$filename.ps"; 120 $img = "{$this->temp_dir}/$filename.{$convertformat}"; 121 122 // Change directory to temp dir so that we can work with relative paths. 123 chdir($this->temp_dir); 124 125 // turn the latex doc into a .tex file in the temp area 126 $fh = fopen( $tex, 'w' ); 127 fputs( $fh, $doc ); 128 fclose( $fh ); 129 130 // run latex on document 131 $command = "$pathlatex --interaction=nonstopmode --halt-on-error $tex"; 132 133 if ($this->execute($command, $log)) { // It allways False on Windows 134 // return false; 135 } 136 137 // run dvips (.dvi to .ps) 138 $pathdvips = escapeshellarg(trim(get_config('filter_tex', 'pathdvips'), " '\"")); 139 $command = "$pathdvips -q -E $dvi -o $ps"; 140 if ($this->execute($command, $log )) { 141 return false; 142 } 143 144 // Run convert on document (.ps to .gif/.png) or run dvisvgm (.ps to .svg). 145 if ($background) { 146 $bg_opt = "-transparent \"$background\""; // Makes transparent background 147 } else { 148 $bg_opt = ""; 149 } 150 if ($convertformat == 'svg') { 151 $pathdvisvgm = escapeshellarg(trim(get_config('filter_tex', 'pathdvisvgm'), " '\"")); 152 $command = "$pathdvisvgm -E $ps -o $img"; 153 } else { 154 $pathconvert = escapeshellarg(trim(get_config('filter_tex', 'pathconvert'), " '\"")); 155 $command = "$pathconvert -density $density -trim $bg_opt $ps $img"; 156 } 157 if ($this->execute($command, $log )) { 158 return false; 159 } 160 161 return $img; 162 } 163 164 /** 165 * Delete files created in temporary area 166 * Don't forget to copy the final gif/png before calling this 167 * @param string $filename file base (no extension) 168 */ 169 function clean_up( $filename ) { 170 global $CFG; 171 172 unlink( "{$this->temp_dir}/$filename.tex" ); 173 unlink( "{$this->temp_dir}/$filename.dvi" ); 174 unlink( "{$this->temp_dir}/$filename.ps" ); 175 $convertformat = get_config('filter_tex', 'convertformat'); 176 unlink( "{$this->temp_dir}/$filename.{$convertformat}" ); 177 unlink( "{$this->temp_dir}/$filename.aux" ); 178 unlink( "{$this->temp_dir}/$filename.log" ); 179 return; 180 } 181 182 } 183 184 185
title
Description
Body
title
Description
Body
title
Description
Body
title
Body