forked from moodle/moodle
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathlatex.php
182 lines (156 loc) · 6.66 KB
/
latex.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
<?php
// latex.php
// render TeX stuff using latex - this will not work on all platforms
// or configurations. Only works on Linux and Mac with appropriate
// software installed.
// Much of this inspired/copied from Benjamin Zeiss' work
class latex {
var $temp_dir;
var $error;
/**
* Constructor - create temporary directories and build paths to
* external 'helper' binaries.
* Other platforms could/should be added
*/
public function __construct() {
global $CFG;
// construct directory structure
$this->temp_dir = $CFG->tempdir . "/latex";
make_temp_directory('latex');
}
/**
* Old syntax of class constructor. Deprecated in PHP7.
*
* @deprecated since Moodle 3.1
*/
public function latex() {
debugging('Use of class name as constructor is deprecated', DEBUG_DEVELOPER);
self::__construct();
}
/**
* Accessor function for support_platform field.
* @return boolean value of supported_platform
*/
function supported() {
return $this->supported_platform;
}
/**
* 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 ) {
global $CFG;
$formula = filter_tex_sanitize_formula($formula);
// $fontsize don't affects to formula's size. $density can change size
$doc = "\\documentclass[{$fontsize}pt]{article}\n";
$doc .= get_config('filter_tex', 'latexpreamble');
$doc .= "\\pagestyle{empty}\n";
$doc .= "\\begin{document}\n";
//dlnsk $doc .= "$ {$formula} $\n";
if (preg_match("/^[[:space:]]*\\\\begin\\{(gather|align|alignat|multline).?\\}/i",$formula)) {
$doc .= "$formula\n";
} else {
$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/png
* @param string $formula TeX formula
* @param string $filename filename for output (including extension)
* @param int $fontsize font size
* @param int $density density value for .ps to .gif/.png 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 ) {
global $CFG;
// quick check - will this work?
$pathlatex = get_config('filter_tex', 'pathlatex');
if (empty($pathlatex)) {
return false;
}
$pathlatex = escapeshellarg(trim($pathlatex, " '\""));
$doc = $this->construct_latex_document( $formula, $fontsize );
// construct some file paths
$convertformat = get_config('filter_tex', 'convertformat');
if (!strpos($filename, ".{$convertformat}")) {
$convertformat = 'png';
}
$filename = str_replace(".{$convertformat}", '', $filename);
$tex = "{$this->temp_dir}/$filename.tex";
$dvi = "{$this->temp_dir}/$filename.dvi";
$ps = "{$this->temp_dir}/$filename.ps";
$img = "{$this->temp_dir}/$filename.{$convertformat}";
// 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 = "$pathlatex --interaction=nonstopmode --halt-on-error $tex";
chdir( $this->temp_dir );
if ($this->execute($command, $log)) { // It allways False on Windows
// return false;
}
// run dvips (.dvi to .ps)
$pathdvips = escapeshellarg(trim(get_config('filter_tex', 'pathdvips'), " '\""));
$command = "$pathdvips -q -E $dvi -o $ps";
if ($this->execute($command, $log )) {
return false;
}
// Run convert on document (.ps to .gif/.png) or run dvisvgm (.ps to .svg).
if ($background) {
$bg_opt = "-transparent \"$background\""; // Makes transparent background
} else {
$bg_opt = "";
}
if ($convertformat == 'svg') {
$pathdvisvgm = escapeshellarg(trim(get_config('filter_tex', 'pathdvisvgm'), " '\""));
$command = "$pathdvisvgm -E $ps -o $img";
} else {
$pathconvert = escapeshellarg(trim(get_config('filter_tex', 'pathconvert'), " '\""));
$command = "$pathconvert -density $density -trim $bg_opt $ps $img";
}
if ($this->execute($command, $log )) {
return false;
}
return $img;
}
/**
* Delete files created in temporary area
* Don't forget to copy the final gif/png before calling this
* @param string $filename file base (no extension)
*/
function clean_up( $filename ) {
global $CFG;
unlink( "{$this->temp_dir}/$filename.tex" );
unlink( "{$this->temp_dir}/$filename.dvi" );
unlink( "{$this->temp_dir}/$filename.ps" );
$convertformat = get_config('filter_tex', 'convertformat');
unlink( "{$this->temp_dir}/$filename.{$convertformat}" );
unlink( "{$this->temp_dir}/$filename.aux" );
unlink( "{$this->temp_dir}/$filename.log" );
return;
}
}