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