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