source: moodle/trunk/fuentes/filter/tex/latex.php @ 1331

Last change on this file since 1331 was 1331, checked in by jrpelegrina, 3 years ago

Updated to moodle 3.0.3

File size: 6.5 KB
Line 
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        public function latex() {
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            global $CFG;
49
50            $formula = filter_tex_sanitize_formula($formula);
51
52            // $fontsize don't affects to formula's size. $density can change size
53            $doc =  "\\documentclass[{$fontsize}pt]{article}\n";
54            $doc .= get_config('filter_tex', 'latexpreamble');
55            $doc .= "\\pagestyle{empty}\n";
56            $doc .= "\\begin{document}\n";
57//dlnsk            $doc .= "$ {$formula} $\n";
58            if (preg_match("/^[[:space:]]*\\\\begin\\{(gather|align|alignat|multline).?\\}/i",$formula)) {
59               $doc .= "$formula\n";
60            } else {
61               $doc .= "$ {$formula} $\n";
62            }
63            $doc .= "\\end{document}\n";
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 = "{$this->temp_dir}/$filename.tex";
115            $dvi = "{$this->temp_dir}/$filename.dvi";
116            $ps  = "{$this->temp_dir}/$filename.ps";
117            $img = "{$this->temp_dir}/$filename.{$convertformat}";
118
119            // turn the latex doc into a .tex file in the temp area
120            $fh = fopen( $tex, 'w' );
121            fputs( $fh, $doc );
122            fclose( $fh );
123
124            // run latex on document
125            $command = "$pathlatex --interaction=nonstopmode --halt-on-error $tex";
126            chdir( $this->temp_dir );
127            if ($this->execute($command, $log)) { // It allways False on Windows
128//                return false;
129            }
130
131            // run dvips (.dvi to .ps)
132            $pathdvips = escapeshellarg(trim(get_config('filter_tex', 'pathdvips'), " '\""));
133            $command = "$pathdvips -q -E $dvi -o $ps";
134            if ($this->execute($command, $log )) {
135                return false;
136            }
137
138            // Run convert on document (.ps to .gif/.png) or run dvisvgm (.ps to .svg).
139            if ($background) {
140                $bg_opt = "-transparent \"$background\""; // Makes transparent background
141            } else {
142                $bg_opt = "";
143            }
144            if ($convertformat == 'svg') {
145                $pathdvisvgm = escapeshellarg(trim(get_config('filter_tex', 'pathdvisvgm'), " '\""));
146                $command = "$pathdvisvgm -E $ps -o $img";
147            } else {
148                $pathconvert = escapeshellarg(trim(get_config('filter_tex', 'pathconvert'), " '\""));
149                $command = "$pathconvert -density $density -trim $bg_opt $ps $img";
150            }
151            if ($this->execute($command, $log )) {
152                return false;
153            }
154
155            return $img;
156        }
157
158        /**
159         * Delete files created in temporary area
160         * Don't forget to copy the final gif/png before calling this
161         * @param string $filename file base (no extension)
162         */
163        function clean_up( $filename ) {
164            global $CFG;
165
166            unlink( "{$this->temp_dir}/$filename.tex" );
167            unlink( "{$this->temp_dir}/$filename.dvi" );
168            unlink( "{$this->temp_dir}/$filename.ps" );
169            $convertformat = get_config('filter_tex', 'convertformat');
170            unlink( "{$this->temp_dir}/$filename.{$convertformat}" );
171            unlink( "{$this->temp_dir}/$filename.aux" );
172            unlink( "{$this->temp_dir}/$filename.log" );
173            return;
174        }
175
176    }
177
178
179
Note: See TracBrowser for help on using the repository browser.