]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/plugin/TexToPng.php
Let us put some abstraction
[SourceForge/phpwiki.git] / lib / plugin / TexToPng.php
1 <?php
2
3 /**
4  * Copyright 1999, 2000, 2001, 2002 $ThePhpWikiProgrammingTeam
5  * Copyright (C) 2002 Johannes Große
6  *
7  * This file is part of PhpWiki.
8  *
9  * PhpWiki is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * PhpWiki is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License along
20  * with PhpWiki; if not, write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22  */
23
24 // +---------------------------------------------------------------------+
25 // | TexToPng.php                                                        |
26 // +---------------------------------------------------------------------+
27 // | This is a WikiPlugin that surrounds tex commands given as parameter |
28 // | with a page description and renders it using several existing       |
29 // | engines into a gif, png or jpeg file.                               |
30 // | TexToPng is usage example for WikiPluginCached.                     |
31 // |                                                                     |
32 // | You may copy this code freely under the conditions of the GPL       |
33 // +---------------------------------------------------------------------+
34
35 /*-----------------------------------------------------------------------
36  | CONFIGURATION
37  *----------------------------------------------------------------------*/
38 // needs (la)tex, dvips, gs, netpbm, libpng
39 // LaTeX2HTML ftp://ftp.dante.de/tex-archive/support/latex2html
40 $texbin = '/usr/bin/tex';
41 $dvipsbin = '/usr/bin/dvips';
42 $pstoimgbin = '/usr/bin/pstoimg';
43
44 // output mere debug messages (should be set to false in a stable
45 // version)
46 define('TexToPng_debug', false);
47
48 /*-----------------------------------------------------------------------
49  | OPTION DEFAULTS
50  *----------------------------------------------------------------------*/
51 /*----
52  | use antialias for rendering;
53  | anitalias: blurs, _looks better_, needs twice space, renders slowlier
54  |                                                                      */
55 define('TexToPng_antialias', true);
56
57 /*----
58  | Use transparent background; dont combine with antialias on a dark
59  | background. Seems to have a bug: produces strange effects for some
60  | ps-files (almost non readable,blurred output) even when directly
61  | invoked from shell. So its probably a pstoimg bug.
62  |                                                                      */
63 define('TexToPng_transparent', false);
64
65 /*----
66  | default value for rescaling
67  | allowed range: 0 - 5 (integer)
68  |                                                                      */
69 define('TexToPng_magstep', 3);
70
71 /*-----------------------------------------------------------------------
72  |
73  |  Source
74  |
75  *----------------------------------------------------------------------*/
76
77 // check boolean constants
78
79 if (!defined('TexToPng_debug')) {
80     define('TexToPng_debug', false);
81 }
82 if (!defined('TexToPng_antialias')) {
83     define('TexToPng_antialias', false);
84 }
85 if (!defined('TexToPng_transparent')) {
86     define('TexToPng_transparent', false);
87 }
88
89 /*-----------------------------------------------------------------------
90  | WikiPlugin_TexToPng
91  *----------------------------------------------------------------------*/
92
93 require_once 'lib/WikiPluginCached.php';
94
95 class WikiPlugin_TexToPng extends WikiPluginCached
96 {
97     function getPluginType()
98     {
99         return PLUGIN_CACHED_IMG_ONDEMAND;
100     }
101
102     function getDescription()
103     {
104         return _("Converts TeX to an image. May be used to embed formulas in PhpWiki.");
105     }
106
107     function getDefaultArguments()
108     {
109         return array('tex' => "",
110             'magstep' => TexToPng_magstep,
111             'img' => 'png',
112             'subslash' => 'off',
113             'antialias' => TexToPng_antialias ? 'on' : 'off',
114             'transparent' => TexToPng_transparent ? 'on' : 'off',
115             'center' => 'off');
116     }
117
118     protected function getImage($dbi, $argarray, $request)
119     {
120         extract($argarray);
121         $this->checkParams($tex, $magstep, $subslash, $antialias, $transparent);
122         return $this->TexToImg($tex, $magstep, $antialias, $transparent);
123     }
124
125     protected function getMap($dbi, $argarray, $request)
126     {
127     }
128
129     function getExpire($dbi, $argarray, $request)
130     {
131         return '0';
132     }
133
134     function getImageType($dbi, $argarray, $request)
135     {
136         extract($argarray);
137         return $img;
138     }
139
140     function getAlt($dbi, $argarray, $request)
141     {
142         extract($argarray);
143         return $tex;
144     }
145
146     function embedImg($url, $dbi, $argarray, $request)
147     {
148         $html = HTML::img(array(
149             'src' => $url,
150             'alt' => htmlspecialchars($this->getAlt($dbi, $argarray, $request))
151         ));
152         if ($argarray['center'] == 'on')
153             return HTML::div(array('style' => 'text-align:center;'), $html);
154         return $html;
155     }
156
157     /* -------------------- error handling ---------------------------- */
158
159     function dbg($out)
160     {
161         // test if verbose debug info is selected
162         if (TexToPng_debug) {
163             $this->complain($out . "\n");
164         } else {
165             if (!$this->_errortext) {
166                 // yeah, I've been told to be quiet, but obviously
167                 // an error occured. So at least complain silently.
168                 $this->complain(' ');
169             }
170         }
171
172     } // dbg
173
174     /* -------------------- parameter handling ------------------------ */
175
176     function helptext()
177     {
178         $aa = TexToPng_antialias ? 'on(default)$|$off' : 'on$|$off(default)';
179         $tp = TexToPng_transparent ? 'on(default)$|$off' : 'on$|$off(default)';
180         $help =
181             '/settabs/+/indent&$<$?plugin /bf{Tex} & [{/tt transparent}] & = "png(default)$|$jpeg$|$gif"& /cr' . "\n" .
182                 '/+&$<$?plugin /bf{TexToPng} & /hfill {/tt tex}           & = "/TeX/  commands"& /cr' . "\n" .
183                 '/+&                         & /hfill [{/tt img}]         & = "png(default)$|$jpeg$|$gif"& /cr' . "\n" .
184                 '/+&                         & /hfill [{/tt magstep}]     & = "0 to 5 (' . TexToPng_magstep . ' default)"& /cr' . "\n" .
185                 '/+&                         & /hfill [{/tt center}]      & = "on$|$off(default)"& /cr' . "\n" .
186                 '/+&                         & /hfill [{/tt subslash}]    & = "on$|$off(default)"& /cr' . "\n" .
187                 '/+&                         & /hfill [{/tt antialias}]   & = "' . $aa . '"& /cr' . "\n" .
188                 '/+&                         & /hfill [{/tt transparent}] & = "' . $tp . '"&?$>$ /cr' . "\n";
189
190         return strtr($help, '/', '\\');
191     } // helptext
192
193     function checkParams(&$tex, &$magstep, $subslash, &$aalias, &$transp)
194     {
195
196         if ($subslash == 'on') {
197             // WORKAROUND for backslashes
198             $tex = strtr($tex, '/', '\\');
199         }
200
201         // ------- check parameters
202         $def = $this->getDefaultArguments();
203
204         if ($tex == '') {
205             $tex = $this->helptext();
206         }
207
208         if ($magstep < 0 || $magstep > 5) {
209             $magstep = $def["magstep"];
210         }
211         // calculate magnification factor
212         $magstep = floor(10 * pow(1.2, $magstep)) / 10;
213
214         $aalias = $aalias != 'off';
215         $transp = $transp != 'off';
216
217     } // checkParams
218
219     /* ------------------ image creation ------------------------------ */
220
221     function execute($cmd, $complainvisibly = false)
222     {
223         exec($cmd, $errortxt, $returnval);
224         $ok = $returnval == 0;
225
226         if (!$ok) {
227             if (!$complainvisibly) {
228                 $this->dbg('Error during execution of ' . $cmd);
229             }
230             ;
231             while (list($key, $value) = each($errortxt)) {
232                 if ($complainvisibly) {
233                     $this->complain($value . "\n");
234                 } else {
235                     $this->dbg($value);
236                 }
237             }
238         }
239         return $ok;
240     } // execute
241
242     /* ---------------------------------------------------------------- */
243
244     function createTexFile($texfile, $texstr)
245     {
246         if ($ok = ($fp = fopen($texfile, 'w')) != 0) {
247             // prepare .tex file
248             $texcommands =
249                 '\nopagenumbers' . "\n" .
250                     '\hoffset=0cm' . "\n" .
251                     '\voffset=0cm' . "\n" .
252                     //    '\hsize=20cm'    . "\n" .
253                     //    '\vsize=10ex'    . "\n" .
254                     $texstr . "\n" .
255                     '\vfill\eject' . "\n" .
256                     '\end' . "\n\n";
257
258             $ok = fwrite($fp, $texcommands);
259             $ok = fclose($fp) && $ok; // close anyway
260         }
261         if (!$ok) {
262             $this->dbg('could not write .tex file: ' . $texstr);
263         }
264         return $ok;
265     } // createTexFile
266
267     /* ---------------------------------------------------------------- */
268
269     function TexToImg($texstr, $scale, $aalias, $transp)
270     {
271         //$cacheparams = $GLOBALS['CacheParams'];
272         $tempfiles = $this->tempnam('TexToPng');
273         $img = 0; // $size = 0;
274
275         // procuce options for pstoimg
276         $options =
277             ($aalias ? '-aaliastext -color 8 ' : '-color 1 ') .
278                 ($transp ? '-transparent ' : '') .
279                 '-scale ' . $scale . ' ' .
280                 '-type png -crop btlr -geometry 600x150 -margins 0,0';
281
282         // rely on intelligent bool interpretation
283         $ok = $tempfiles &&
284             $this->createTexFile($tempfiles . '.tex', $texstr) &&
285             $this->execute('cd ' . $cacheparams['cache_dir'] . '; ' .
286                 "$texbin " . $tempfiles . '.tex', true) &&
287             $this->execute("$dvipsbin -o" . $tempfiles . '.ps ' . $tempfiles . '.dvi') &&
288             $this->execute("$pstoimgbin $options"
289                 . ' -out ' . $tempfiles . '.png ' .
290                 $tempfiles . '.ps') &&
291             file_exists($tempfiles . '.png');
292
293         if ($ok) {
294             if (!($img = ImageCreateFromPNG($tempfiles . '.png'))) {
295                 $this->dbg("Could not open just created image file: $tempfiles");
296                 $ok = false;
297             }
298         }
299
300         // clean up tmpdir; in debug mode only if no error occured
301
302         if (!TexToPng_debug || (TexToPng_debug && $ok)) {
303             if ($tempfiles) {
304                 unlink($tempfiles);
305                 unlink($tempfiles . '.ps');
306                 unlink($tempfiles . '.tex');
307                 //unlink($tempfiles . '.aux');
308                 unlink($tempfiles . '.dvi');
309                 unlink($tempfiles . '.log');
310                 unlink($tempfiles . '.png');
311             }
312         }
313
314         if ($ok) {
315             return $img;
316         }
317         return false;
318     } // TexToImg
319 }
320
321 // Local Variables:
322 // mode: php
323 // tab-width: 8
324 // c-basic-offset: 4
325 // c-hanging-comment-ender-p: nil
326 // indent-tabs-mode: nil
327 // End: