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