3 * Copyright © 1999, 2000, 2001, 2002 $ThePhpWikiProgrammingTeam
4 * Copyright © 2002 Johannes Große
6 * This file is part of PhpWiki.
8 * PhpWiki is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * PhpWiki is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with PhpWiki; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 * SPDX-License-Identifier: GPL-2.0-or-later
26 // +---------------------------------------------------------------------+
28 // +---------------------------------------------------------------------+
29 // | This is a WikiPlugin that surrounds tex commands given as parameter |
30 // | with a page description and renders it using several existing |
31 // | engines into a gif, png or jpeg file. |
32 // | TexToPng is usage example for WikiPluginCached. |
34 // | You may copy this code freely under the conditions of the GPL |
35 // +---------------------------------------------------------------------+
37 /*-----------------------------------------------------------------------
39 *----------------------------------------------------------------------*/
40 // needs (la)tex, dvips, gs, netpbm, libpng
41 // LaTeX2HTML ftp://ftp.dante.de/tex-archive/support/latex2html
43 // output mere debug messages (should be set to false in a stable
45 define('TexToPng_debug', false);
47 /*-----------------------------------------------------------------------
49 *----------------------------------------------------------------------*/
51 | use antialias for rendering;
52 | anitalias: blurs, _looks better_, needs twice space, renders slowlier
54 define('TexToPng_antialias', true);
57 | Use transparent background; dont combine with antialias on a dark
58 | background. Seems to have a bug: produces strange effects for some
59 | ps-files (almost non readable,blurred output) even when directly
60 | invoked from shell. So its probably a pstoimg bug.
62 define('TexToPng_transparent', false);
65 | default value for rescaling
66 | allowed range: 0 - 5 (integer)
68 define('TexToPng_magstep', 3);
70 /*-----------------------------------------------------------------------
74 *----------------------------------------------------------------------*/
76 /*-----------------------------------------------------------------------
78 *----------------------------------------------------------------------*/
80 require_once 'lib/WikiPluginCached.php';
82 class WikiPlugin_TexToPng extends WikiPluginCached
86 function getPluginType()
88 return PLUGIN_CACHED_IMG_ONDEMAND;
91 function getDescription()
93 return _("Converts TeX to an image. May be used to embed formulas in PhpWiki.");
96 function getDefaultArguments()
98 return array('tex' => "",
99 'magstep' => TexToPng_magstep,
102 'antialias' => TexToPng_antialias ? 'on' : 'off',
103 'transparent' => TexToPng_transparent ? 'on' : 'off',
107 protected function getImage($dbi, $argarray, $request)
110 $this->checkParams($tex, $magstep, $subslash, $antialias, $transparent);
111 return $this->TexToImg($tex, $magstep, $antialias, $transparent);
114 protected function getMap($dbi, $argarray, $request)
116 trigger_error('pure virtual', E_USER_ERROR);
119 protected function getHtml($dbi, $argarray, $request, $basepage)
121 trigger_error('pure virtual', E_USER_ERROR);
124 function getExpire($dbi, $argarray, $request)
129 function getImageType($dbi, $argarray, $request)
135 function getAlt($dbi, $argarray, $request)
141 function embedImg($url, $dbi, $argarray, $request)
143 $html = HTML::img(array(
145 'alt' => htmlspecialchars($this->getAlt($dbi, $argarray, $request))
147 if ($argarray['center'] == 'on')
148 return HTML::div(array('style' => 'text-align:center;'), $html);
152 /* -------------------- error handling ---------------------------- */
156 // test if verbose debug info is selected
157 if (TexToPng_debug) {
158 $this->complain($out . "\n");
160 if (!$this->_errortext) {
161 // yeah, I've been told to be quiet, but obviously
162 // an error occurred. So at least complain silently.
163 $this->complain(' ');
169 /* -------------------- parameter handling ------------------------ */
173 $aa = TexToPng_antialias ? 'on(default)$|$off' : 'on$|$off(default)';
174 $tp = TexToPng_transparent ? 'on(default)$|$off' : 'on$|$off(default)';
176 '/settabs/+/indent&$<$?plugin /bf{Tex} & [{/tt transparent}] & = "png(default)$|$jpeg$|$gif"& /cr' . "\n" .
177 '/+&$<$?plugin /bf{TexToPng} & /hfill {/tt tex} & = "/TeX/ commands"& /cr' . "\n" .
178 '/+& & /hfill [{/tt img}] & = "png(default)$|$jpeg$|$gif"& /cr' . "\n" .
179 '/+& & /hfill [{/tt magstep}] & = "0 to 5 (' . TexToPng_magstep . ' default)"& /cr' . "\n" .
180 '/+& & /hfill [{/tt center}] & = "on$|$off(default)"& /cr' . "\n" .
181 '/+& & /hfill [{/tt subslash}] & = "on$|$off(default)"& /cr' . "\n" .
182 '/+& & /hfill [{/tt antialias}] & = "' . $aa . '"& /cr' . "\n" .
183 '/+& & /hfill [{/tt transparent}] & = "' . $tp . '"&?$>$ /cr' . "\n";
185 return strtr($help, '/', '\\');
188 function checkParams(&$tex, &$magstep, $subslash, &$aalias, &$transp)
191 if ($subslash == 'on') {
192 // WORKAROUND for backslashes
193 $tex = strtr($tex, '/', '\\');
196 // ------- check parameters
197 $def = $this->getDefaultArguments();
200 $tex = $this->helptext();
203 if ($magstep < 0 || $magstep > 5) {
204 $magstep = $def["magstep"];
206 // calculate magnification factor
207 $magstep = floor(10 * pow(1.2, $magstep)) / 10;
209 $aalias = $aalias != 'off';
210 $transp = $transp != 'off';
214 /* ------------------ image creation ------------------------------ */
216 function execute($cmd, $complainvisibly = false)
218 exec($cmd, $errortxt, $returnval);
219 $ok = $returnval == 0;
222 if (!$complainvisibly) {
223 $this->dbg('Error during execution of ' . $cmd);
226 foreach ($errortxt as $key => $value) {
227 if ($complainvisibly) {
228 $this->complain($value . "\n");
237 /* ---------------------------------------------------------------- */
239 function createTexFile($texfile, $texstr)
241 if ($ok = ($fp = fopen($texfile, 'w')) != 0) {
244 '\nopagenumbers' . "\n" .
245 '\hoffset=0cm' . "\n" .
246 '\voffset=0cm' . "\n" .
247 // '\hsize=20cm' . "\n" .
248 // '\vsize=10ex' . "\n" .
250 '\vfill\eject' . "\n" .
253 $ok = fwrite($fp, $texcommands);
254 $ok = fclose($fp) && $ok; // close anyway
257 $this->dbg('could not write .tex file: ' . $texstr);
262 /* ---------------------------------------------------------------- */
264 function TexToImg($texstr, $scale, $aalias, $transp)
266 $texbin = '/usr/bin/tex';
267 $dvipsbin = '/usr/bin/dvips';
268 $pstoimgbin = '/usr/bin/pstoimg';
269 $cache_dir = '/tmp/cache';
270 $tempfiles = $this->tempnam('TexToPng');
271 $img = 0; // $size = 0;
273 // produce options for pstoimg
275 ($aalias ? '-aaliastext -color 8 ' : '-color 1 ') .
276 ($transp ? '-transparent ' : '') .
277 '-scale ' . $scale . ' ' .
278 '-type png -crop btlr -geometry 600x150 -margins 0,0';
280 // rely on intelligent bool interpretation
282 $this->createTexFile($tempfiles . '.tex', $texstr) &&
283 $this->execute('cd ' . $cache_dir . '; ' .
284 "$texbin " . $tempfiles . '.tex', true) &&
285 $this->execute("$dvipsbin -o" . $tempfiles . '.ps ' . $tempfiles . '.dvi') &&
286 $this->execute("$pstoimgbin $options"
287 . ' -out ' . $tempfiles . '.png ' .
288 $tempfiles . '.ps') &&
289 file_exists($tempfiles . '.png');
292 if (!($img = imagecreatefrompng($tempfiles . '.png'))) {
293 $this->dbg("Could not open just created image file: $tempfiles");
298 // clean up tmpdir; in debug mode only if no error occured
300 if (!TexToPng_debug || (TexToPng_debug && $ok)) {
302 if (file_exists($tempfiles)) {
305 if (file_exists($tempfiles . '.ps')) {
306 unlink($tempfiles . '.ps');
308 if (file_exists($tempfiles . '.tex')) {
309 unlink($tempfiles . '.tex');
311 if (file_exists($tempfiles . '.dvi')) {
312 unlink($tempfiles . '.dvi');
314 if (file_exists($tempfiles . '.log')) {
315 unlink($tempfiles . '.log');
317 if (file_exists($tempfiles . '.png')) {
318 unlink($tempfiles . '.png');