]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/plugin/TexToPng.php
rcs_id no longer makes sense with Subversion global version number
[SourceForge/phpwiki.git] / lib / plugin / TexToPng.php
1 <?php // -*-php-*-
2 // rcs_id('$Id$');
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
20  * along with PhpWiki; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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  |
74  |  Source
75  |
76  *----------------------------------------------------------------------*/
77
78 // check boolean constants
79
80    if (!defined('TexToPng_debug'))       { define('TexToPng_debug', false); }
81    if (!defined('TexToPng_antialias'))   { define('TexToPng_antialias', false); }
82    if (!defined('TexToPng_transparent')) { define('TexToPng_transparent', false); }
83
84 /*-----------------------------------------------------------------------
85  | WikiPlugin_TexToPng
86  *----------------------------------------------------------------------*/
87
88 require_once "lib/WikiPluginCached.php";
89
90 class WikiPlugin_TexToPng extends WikiPluginCached
91 {
92     function getPluginType() {
93         return PLUGIN_CACHED_IMG_ONDEMAND;
94     }
95
96     function getName() {
97         return "TexToPng";
98     }
99
100     function getDescription() {
101         return _("Converts TeX to an image. May be used to embed formulas in PhpWiki.");
102     }
103
104     function getDefaultArguments() {
105         return array('tex'          => "",
106                      'magstep'      => TexToPng_magstep,
107                      'img'          => 'png',
108                      'subslash'     => 'off',
109                      'antialias'    => TexToPng_antialias   ? 'on' : 'off',
110                      'transparent'  => TexToPng_transparent ? 'on' : 'off',
111                      'center'       => 'off');
112     }
113
114     function getImage($dbi, $argarray, $request) {
115         extract($argarray);
116         $this->checkParams($tex, $magstep, $subslash, $antialias, $transparent);
117         return $this->TexToImg($tex, $magstep, $antialias, $transparent);
118     } // run
119
120     function getExpire($dbi, $argarray, $request) {
121         return '0';
122     }
123
124     function getImageType($dbi, $argarray, $request) {
125         extract($argarray);
126         return $img;
127     }
128
129     function getAlt($dbi, $argarray, $request) {
130         extract($argarray);
131         return $tex;
132     }
133
134     function embedImg($url,$dbi,$argarray,$request) {
135         $html = HTML::img( array(
136             'src'   => $url,
137             'alt'   => htmlspecialchars($this->getAlt($dbi,$argarray,$request))
138             ));
139         if ($argarray['center']=='on')
140             return HTML::div( array('style' => 'text-align:center;'), $html);
141         return $html;
142     }
143
144     /* -------------------- error handling ---------------------------- */
145
146     function dbg( $out ) {
147         // test if verbose debug info is selected
148         if (TexToPng_debug) {
149             $this->complain( $out."\n" );
150         } else {
151             if (!$this->_errortext) {
152                 // yeah, I've been told to be quiet, but obviously
153                 // an error occured. So at least complain silently.
154                 $this->complain(' ');
155             }
156         }
157
158     } // dbg
159
160     /* -------------------- parameter handling ------------------------ */
161
162     function helptext() {
163         $aa= TexToPng_antialias  ?'on(default)$|$off':'on$|$off(default)';
164         $tp= TexToPng_transparent?'on(default)$|$off':'on$|$off(default)';
165         $help =
166           '/settabs/+/indent&$<$?plugin /bf{Tex} & [{/tt transparent}] & = "png(default)$|$jpeg$|$gif"& /cr'."\n".
167           '/+&$<$?plugin /bf{TexToPng} & /hfill {/tt tex}           & = "/TeX/  commands"& /cr'."\n".
168           '/+&                         & /hfill [{/tt img}]         & = "png(default)$|$jpeg$|$gif"& /cr'."\n".
169           '/+&                         & /hfill [{/tt magstep}]     & = "0 to 5 ('.TexToPng_magstep.' default)"& /cr'."\n".
170           '/+&                         & /hfill [{/tt center}]      & = "on$|$off(default)"& /cr'."\n".
171           '/+&                         & /hfill [{/tt subslash}]    & = "on$|$off(default)"& /cr'."\n".
172           '/+&                         & /hfill [{/tt antialias}]   & = "'.$aa.'"& /cr'."\n".
173           '/+&                         & /hfill [{/tt transparent}] & = "'.$tp.'"&?$>$ /cr'."\n";
174
175         return strtr($help, '/', '\\' );
176     } // helptext
177
178
179     function checkParams( &$tex, &$magstep, $subslash, &$aalias, &$transp ) {
180
181         if ($subslash=='on') {
182             // WORKAROUND for backslashes
183             $tex = strtr($tex,'/','\\');
184         }
185
186         // ------- check parameters
187         $def = $this->getDefaultArguments();
188
189         if ($tex=='') { $tex = $this->helptext(); }
190
191         if ($magstep < 0 || $magstep > 5 ) { $magstep = $def["magstep"]; }
192         // calculate magnification factor
193         $magstep = floor(10*pow(1.2,$magstep))/10;
194
195         $aalias = $aalias != 'off';
196         $transp = $transp != 'off';
197
198     } // checkParams
199
200     /* ------------------ image creation ------------------------------ */
201
202     function execute($cmd,$complainvisibly=false) {
203         exec($cmd, $errortxt, $returnval);
204         $ok = $returnval == 0;
205
206         if (!$ok) {
207             if (!$complainvisibly) {
208                  $this->dbg('Error during execution of '.$cmd );
209             };
210             while (list($key,$value)=each($errortxt)) {
211                 if ($complainvisibly) {
212                     $this->complain( $value."\n" );
213                 } else {
214                     $this->dbg( $value );
215                 }
216             }
217         }
218         return $ok;
219     } // execute
220
221     /* ---------------------------------------------------------------- */
222
223     function createTexFile($texfile,$texstr) {
224         if ($ok=($fp=fopen($texfile, 'w'))!=0 ) {
225             // prepare .tex file
226             $texcommands =
227                 '\nopagenumbers'   . "\n" .
228                 '\hoffset=0cm'     . "\n" .
229                 '\voffset=0cm'     . "\n" .
230             //    '\hsize=20cm'    . "\n" .
231             //    '\vsize=10ex'    . "\n" .
232                 $texstr            . "\n" .
233                 '\vfill\eject'     . "\n" .
234                 '\end'             . "\n\n";
235
236             $ok = fwrite($fp, $texcommands);
237             $ok = fclose($fp) && $ok;  // close anyway
238         }
239         if (!$ok) {
240             $this->dbg('could not write .tex file: ' . $texstr);
241         }
242         return $ok;
243     } // createTexFile
244
245     /* ---------------------------------------------------------------- */
246
247     function TexToImg($texstr, $scale, $aalias, $transp) {
248         //$cacheparams = $GLOBALS['CacheParams'];
249         $tempfiles = $this->tempnam('TexToPng');
250         $img = 0; // $size = 0;
251
252         // procuce options for pstoimg
253         $options =
254            ($aalias ? '-aaliastext -color 8 ' : '-color 1 ') .
255            ($transp ? '-transparent ' : '') .
256            '-scale ' . $scale . ' ' .
257            '-type png -crop btlr -geometry 600x150 -margins 0,0';
258
259         // rely on intelligent bool interpretation
260         $ok= $tempfiles &&
261              $this->createTexFile($tempfiles.'.tex',$texstr) &&
262              $this->execute('cd '.$cacheparams['cache_dir'].'; '.
263                             "$texbin ".$tempfiles.'.tex',true) &&
264              $this->execute("$dvipsbin -o".$tempfiles.'.ps '.$tempfiles.'.dvi') &&
265              $this->execute("$pstoimgbin $options"
266                             .' -out '.$tempfiles.'.png '.
267                             $tempfiles.'.ps'               ) &&
268              file_exists( $tempfiles.'.png' );
269
270         if ($ok) {
271             if (!($img = ImageCreateFromPNG( $tempfiles.'.png' ))) {
272                 $this->dbg("Could not open just created image file: $tempfiles");
273                 $ok = false;
274             }
275         }
276
277         // clean up tmpdir; in debug mode only if no error occured
278
279         if ( !TexToPng_debug || (TexToPng_debug && $ok))  {
280             if ($tempfiles) {
281                 unlink($tempfiles);
282                 unlink($tempfiles . '.ps');
283                 unlink($tempfiles . '.tex');
284                 //unlink($tempfiles . '.aux');
285                 unlink($tempfiles . '.dvi');
286                 unlink($tempfiles . '.log');
287                 unlink($tempfiles . '.png');
288             }
289         }
290
291         if ($ok) {
292             return $img;
293         }
294         return false;
295     } // TexToImg
296 } // WikiPlugin_TexToPng
297
298 // For emacs users
299 // Local Variables:
300 // mode: php
301 // tab-width: 4
302 // c-basic-offset: 4
303 // c-hanging-comment-ender-p: nil
304 // indent-tabs-mode: nil
305 // End:
306 ?>