2 rcs_id('$Id: TeX2png.php,v 1.3 2004-11-01 10:43:59 rurban Exp $');
4 Copyright 2004 Pierrick Meignen
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.
12 * @author: Pierrick Meignen
13 * TODO: use url helpers, windows fixes
14 * use a better imagepath
18 // LaTeX2HTML ftp://ftp.dante.de/tex-archive/support/latex2html
20 class WikiPlugin_TeX2png
23 var $imagepath = 'images/tex';
24 var $latexbin = '/usr/bin/latex';
25 var $dvipsbin = '/usr/bin/dvips';
26 var $pstoimgbin = '/usr/bin/pstoimg';
32 function getDescription () {
33 return _("Convert Tex mathematicals expressions to cached png files." .
34 " This is for small text");
37 function getVersion() {
38 return preg_replace("/[Revision: $]/", '',"\$Revision: 1.3 $");
41 function getDefaultArguments() {
42 return array('text' => "$$(a + b)^2 = a^2 + 2 ab + b^2$$");
45 function parseArgStr($argstr) {
46 // modified from WikiPlugin.php
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))";
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]));
64 // Remove quotes from string values.
66 // we don't remove backslashes in tex formulas
67 // $val = stripslashes($qq_val);
70 $val = stripslashes($q_val);
72 $val = _(stripslashes($gt_val));
80 // NOTE: This does work for multiple args. Use the
81 // separator character defined in your webserver
82 // configuration, usually & or & (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
87 $defaults[$arg] = $val;
92 $this->handle_plugin_args_cruft($argstr, $args);
95 return array($args, $defaults);
98 function createTexFile($texfile, $text) {
99 // this is the small latex file
100 // which contains only the mathematical
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}";
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");
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");
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;
149 $text = "Too long !";
151 } elseif($last <= 1 || strpos($text, '$') != 0){
153 } elseif(strpos($text, '$', 1) == $last)
156 strpos($text, '$', 1) == 1 &&
157 strpos($text, '$', 2) == $last - 1)
162 function tex2png($text) {
163 // the name of the png cached file
164 $imagename = md5($text) . ".png";
165 $url = $this->imagepath . "/$imagename";
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);
173 $error_html = _("TeX directory not writable.");
174 trigger_error($error_html, E_USER_NOTICE);
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);
186 case 1: // an inlined mathematical expression
187 $html = HTML::img(array('class'=>'tex',
191 case 2: // mathematical expression on separate line
192 $html = HTML::img(array('class'=>'tex',
195 $html = HTML::div(array('align' => 'center'), $html);
204 function run($dbi, $argstr, &$request, $basepage) {
206 if ((function_exists('ImageTypes') and (ImageTypes() & IMG_PNG))
207 or function_exists("ImagePNG"))
209 // we have gd & png so go ahead.
210 extract($this->getArgs($argstr, $request));
211 return $this->tex2png($text);
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);
223 // $Log: not supported by cvs2svn $
230 // c-hanging-comment-ender-p: nil
231 // indent-tabs-mode: nil