MDL-30070 message: Optimised search for users over multiple courses
[moodle.git] / filter / tex / latex.php
CommitLineData
4317f92f 1<?php
18a2407e 2 // latex.php
3 // render TeX stuff using latex - this will not work on all platforms
4317f92f
PS
4 // or configurations. Only works on Linux and Mac with appropriate
5 // software installed.
18a2407e 6 // Much of this inspired/copied from Benjamin Zeiss' work
7
8 class latex {
9
10 var $temp_dir;
18a2407e 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 function latex() {
4317f92f
PS
19 global $CFG;
20
18a2407e 21 // construct directory structure
7aa06e6d 22 $this->temp_dir = $CFG->tempdir . "/latex";
af9b1444 23 make_temp_directory('latex');
64ffa2a2 24 }
18a2407e 25
64ffa2a2 26 /**
4317f92f 27 * Accessor function for support_platform field.
64ffa2a2 28 * @return boolean value of supported_platform
29 */
30 function supported() {
31 return $this->supported_platform;
18a2407e 32 }
33
34 /**
35 * Turn the bit of TeX into a valid latex document
36 * @param string $forumula the TeX formula
37 * @param int $fontsize the font size
38 * @return string the latex document
39 */
40 function construct_latex_document( $formula, $fontsize=12 ) {
5b540fa9 41 global $CFG;
c94985ef 42
35716b86 43 $formula = filter_tex_sanitize_formula($formula);
c94985ef 44
45 // $fontsize don't affects to formula's size. $density can change size
4317f92f 46 $doc = "\\documentclass[{$fontsize}pt]{article}\n";
5b540fa9 47 $doc .= $CFG->filter_tex_latexpreamble;
18a2407e 48 $doc .= "\\pagestyle{empty}\n";
49 $doc .= "\\begin{document}\n";
82a76d38 50//dlnsk $doc .= "$ {$formula} $\n";
51 if (preg_match("/^[[:space:]]*\\\\begin\\{(gather|align|alignat|multline).?\\}/i",$formula)) {
52 $doc .= "$formula\n";
53 } else {
54 $doc .= "$ {$formula} $\n";
55 }
18a2407e 56 $doc .= "\\end{document}\n";
57 return $doc;
58 }
59
4317f92f 60 /**
18a2407e 61 * execute an external command, with optional logging
62 * @param string $command command to execute
63 * @param file $log valid open file handle - log info will be written to this file
64 * @return return code from execution of command
65 */
66 function execute( $command, $log=null ) {
67 $output = array();
68 exec( $command, $output, $return_code );
69 if ($log) {
70 fwrite( $log, "COMMAND: $command \n" );
71 $outputs = implode( "\n", $output );
72 fwrite( $log, "OUTPUT: $outputs \n" );
73 fwrite( $log, "RETURN_CODE: $return_code\n " );
74 }
75 return $return_code;
76 }
77
78 /**
cf4e7548 79 * Render TeX string into gif/png
18a2407e 80 * @param string $formula TeX formula
81 * @param string $filename base of filename for output (no extension)
82 * @param int $fontsize font size
cf4e7548 83 * @param int $density density value for .ps to .gif/.png conversion
18a2407e 84 * @param string $background background color (e.g, #FFFFFF).
85 * @param file $log valid open file handle for optional logging (debugging only)
86 * @return bool true if successful
87 */
88 function render( $formula, $filename, $fontsize=12, $density=240, $background='', $log=null ) {
4317f92f 89
dd153b32 90 global $CFG;
4317f92f 91
64ffa2a2 92 // quick check - will this work?
dd153b32 93 if (empty($CFG->filter_tex_pathlatex)) {
64ffa2a2 94 return false;
95 }
96
18a2407e 97 $doc = $this->construct_latex_document( $formula, $fontsize );
98
99 // construct some file paths
100 $tex = "{$this->temp_dir}/$filename.tex";
101 $dvi = "{$this->temp_dir}/$filename.dvi";
6ef8d79a 102 $ps = "{$this->temp_dir}/$filename.ps";
cf4e7548 103 $img = "{$this->temp_dir}/$filename.{$CFG->filter_tex_convertformat}";
18a2407e 104
105 // turn the latex doc into a .tex file in the temp area
106 $fh = fopen( $tex, 'w' );
107 fputs( $fh, $doc );
108 fclose( $fh );
109
110 // run latex on document
08d32575 111 $command = "{$CFG->filter_tex_pathlatex} --interaction=nonstopmode --halt-on-error $tex";
18a2407e 112 chdir( $this->temp_dir );
6ef8d79a 113 if ($this->execute($command, $log)) { // It allways False on Windows
114// return false;
4317f92f 115 }
18a2407e 116
117 // run dvips (.dvi to .ps)
dd153b32 118 $command = "{$CFG->filter_tex_pathdvips} -E $dvi -o $ps";
18a2407e 119 if ($this->execute($command, $log )) {
120 return false;
121 }
122
cf4e7548 123 // run convert on document (.ps to .gif/.png)
18a2407e 124 if ($background) {
6ef8d79a 125 $bg_opt = "-transparent \"$background\""; // Makes transparent background
18a2407e 126 } else {
127 $bg_opt = "";
128 }
cf4e7548 129 $command = "{$CFG->filter_tex_pathconvert} -density $density -trim $bg_opt $ps $img";
18a2407e 130 if ($this->execute($command, $log )) {
131 return false;
132 }
133
cf4e7548 134 return $img;
18a2407e 135 }
136
137 /**
138 * Delete files created in temporary area
cf4e7548 139 * Don't forget to copy the final gif/png before calling this
18a2407e 140 * @param string $filename file base (no extension)
141 */
142 function clean_up( $filename ) {
cf4e7548
I
143 global $CFG;
144
18a2407e 145 unlink( "{$this->temp_dir}/$filename.tex" );
146 unlink( "{$this->temp_dir}/$filename.dvi" );
147 unlink( "{$this->temp_dir}/$filename.ps" );
cf4e7548 148 unlink( "{$this->temp_dir}/$filename.{$CFG->filter_tex_convertformat}" );
18a2407e 149 unlink( "{$this->temp_dir}/$filename.aux" );
150 unlink( "{$this->temp_dir}/$filename.log" );
450a0a7d 151 return;
18a2407e 152 }
153
154 }
155
156
4317f92f 157