]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/plugin/TeX2png.php
Remove history
[SourceForge/phpwiki.git] / lib / plugin / TeX2png.php
1 <?php // -*-php-*-
2 rcs_id('$Id$');
3 /*
4  Copyright 2004 Pierrick Meignen
5 */
6
7 /**
8  * This is a simple version of the original TexToPng plugin which uses 
9  * the powerful plugincached mechanism.
10  * TeX2png uses its own much simplier static cache in images/tex.
11  *
12  * @author: Pierrick Meignen
13  * TODO: use url helpers, windows fixes
14  *       use a better imagepath
15  */
16
17 // needs latex
18 // LaTeX2HTML ftp://ftp.dante.de/tex-archive/support/latex2html
19
20 class WikiPlugin_TeX2png
21 extends WikiPlugin
22 {
23     var $imagepath = 'images/tex';
24     var $latexbin = '/usr/bin/latex';
25     var $dvipsbin = '/usr/bin/dvips';
26     var $pstoimgbin = '/usr/bin/pstoimg';
27
28     function getName () {
29         return _("TeX2png");
30     }
31     
32     function getDescription () {
33         return _("Convert Tex mathematicals expressions to cached png files." .
34                  " This is for small text");
35     }
36     
37     function getVersion() {
38         return preg_replace("/[Revision: $]/", '',"\$Revision$");
39     }
40     
41     function getDefaultArguments() {
42         return array('text' => "$$(a + b)^2 = a^2 + 2 ab + b^2$$");
43     }
44     
45     function parseArgStr($argstr) {
46         // modified from WikiPlugin.php
47         $arg_p = '\w+';
48         $op_p = '(?:\|\|)?=';
49         $word_p = '\S+';
50         $opt_ws = '\s*';
51         $qq_p = '" ( (?:[^"\\\\]|\\\\.)* ) "';
52         //"<--kludge for brain-dead syntax coloring
53         $q_p  = "' ( (?:[^'\\\\]|\\\\.)* ) '";
54         $gt_p = "_\\( $opt_ws $qq_p $opt_ws \\)";
55         $argspec_p = "($arg_p) $opt_ws ($op_p) $opt_ws (?: $qq_p|$q_p|$gt_p|($word_p))";
56         
57         $args = array();
58         $defaults = array();
59         
60         while (preg_match("/^$opt_ws $argspec_p $opt_ws/x", $argstr, $m)) {
61             @ list(,$arg,$op,$qq_val,$q_val,$gt_val,$word_val) = $m;
62             $argstr = substr($argstr, strlen($m[0]));
63             
64             // Remove quotes from string values.
65             if ($qq_val)
66                 // we don't remove backslashes in tex formulas
67                 // $val = stripslashes($qq_val);
68                 $val = $qq_val;
69             elseif ($q_val)
70                 $val = stripslashes($q_val);
71             elseif ($gt_val)
72                 $val = _(stripslashes($gt_val));
73             else
74                 $val = $word_val;
75             
76             if ($op == '=') {
77                 $args[$arg] = $val;
78             }
79             else {
80                 // NOTE: This does work for multiple args. Use the
81                 // separator character defined in your webserver
82                 // configuration, usually & or &amp; (See
83                 // http://www.htmlhelp.com/faq/cgifaq.4.html)
84                 // e.g. <plugin RecentChanges days||=1 show_all||=0 show_minor||=0>
85                 // url: RecentChanges?days=1&show_all=1&show_minor=0
86                 assert($op == '||=');
87                 $defaults[$arg] = $val;
88             }
89         }
90         
91         if ($argstr) {
92             $this->handle_plugin_args_cruft($argstr, $args);
93         }
94         
95         return array($args, $defaults);
96     }
97     
98     function createTexFile($texfile, $text) {
99         // this is the small latex file
100         // which contains only the mathematical
101         // expression
102         $fp = fopen($texfile, 'w');
103         $str = "\documentclass{article}\n";
104         $str .= "\usepackage{amsfonts}\n";
105         $str .= "\usepackage{amssymb}\n";
106         // Here tou can add some package in order 
107         // to produce more sophisticated output 
108         $str .= "\pagestyle{empty}\n";
109         $str .= "\begin{document}\n";
110         $str .= $text . "\n";
111         $str .= "\end{document}";
112         fwrite($fp, $str);
113         fclose($fp);
114         return 0;
115     }
116
117     function createPngFile($imagepath, $imagename) {
118         // to create dvi file from the latex file
119         $commandes = $this->latexbin . " temp.tex;";
120         exec("cd $imagepath;$commandes");
121         // to create png file from the dvi file
122         // there is no option but it is possible
123         // to add one (scale for example)
124         if (file_exists("$imagepath/temp.dvi")){
125             $commandes = $this->dvipsbin . " temp.dvi -o temp.ps;";
126             $commandes .= $this->pstoimgbin . " -type png -margins 0,0 ";
127             $commandes .= "-crop a -geometry 600x300 ";
128             $commandes .= "-aaliastext -color 1 -scale 1.5 ";
129             $commandes .= "temp.ps -o " . $imagename;
130             exec("cd $imagepath;$commandes");
131             unlink("$imagepath/temp.dvi");
132             unlink("$imagepath/temp.ps");
133         } else
134             echo _(" (syntax error for latex) ");
135         // to clean the directory
136         unlink("$imagepath/temp.tex");
137         unlink("$imagepath/temp.aux");
138         unlink("$imagepath/temp.log");
139         return 0;
140     }
141     
142     function isMathExp(&$text) {
143         // this function returns
144         // 0 : text is too long or not a mathematical expression
145         // 1 : text is $xxxxxx$ hence in line
146         // 2 : text is $$xxxx$$ hence centered
147         $last = strlen($text) - 1;
148         if($last >= 250){
149             $text = "Too long !";
150             return 0;
151         } elseif($last <= 1 || strpos($text, '$') != 0){
152             return 0;
153         } elseif(strpos($text, '$', 1) == $last)
154             return 1;
155         elseif($last > 3 && 
156                strpos($text, '$', 1) == 1 && 
157                strpos($text, '$', 2) == $last - 1)
158             return 2;
159         return 0;
160     }
161
162     function tex2png($text) {
163         // the name of the png cached file
164         $imagename = md5($text) . ".png";
165         $url = $this->imagepath . "/$imagename";
166
167         if(!file_exists($url)){
168             if(is_writable($this->imagepath)){
169                 $texfile = $this->imagepath . "/temp.tex";
170                 $this->createTexFile($texfile, $text);     
171                 $this->createPngFile($this->imagepath, $imagename);
172             } else {
173                 $error_html = _("TeX imagepath not writable.");
174                 trigger_error($error_html, E_USER_NOTICE);
175             }
176         }
177
178         // there is always something in the html page
179         // even if the tex directory doesn't exist
180         // or mathematical expression is wrong      
181         switch($this->isMathExp($text)) {
182         case 0: // not a mathematical expression
183             $html = HTML::tt(array('class'=>'tex', 
184                                    'style'=>'color:red;'), $text); 
185             break;
186         case 1: // an inlined mathematical expression
187             $html = HTML::img(array('class'=>'tex', 
188                                     'src' => $url, 
189                                     'alt' => $text)); 
190             break;
191         case 2: // mathematical expression on separate line
192             $html = HTML::img(array('class'=>'tex', 
193                                     'src' => $url, 
194                                     'alt' => $text));
195             $html = HTML::div(array('align' => 'center'), $html); 
196             break;
197         default: 
198             break;
199         }
200         
201         return $html;
202     }
203     
204     function run($dbi, $argstr, &$request, $basepage) {
205         // from text2png.php
206         if ((function_exists('ImageTypes') and (ImageTypes() & IMG_PNG)) 
207             or function_exists("ImagePNG"))
208         {
209             // we have gd & png so go ahead.
210             extract($this->getArgs($argstr, $request));
211             return $this->tex2png($text);
212         } else {
213             // we don't have png and/or gd.
214             $error_html = _("Sorry, this version of PHP cannot create PNG image files.");
215             $link = "http://www.php.net/manual/pl/ref.image.php";
216             $error_html .= sprintf(_("See %s"), $link) .".";
217             trigger_error($error_html, E_USER_NOTICE);
218             return;
219         }
220     }
221 };
222
223 // For emacs users
224 // Local Variables:
225 // mode: php
226 // tab-width: 8
227 // c-basic-offset: 4
228 // c-hanging-comment-ender-p: nil
229 // indent-tabs-mode: nil
230 // End:
231 ?>