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