4 * Copyright (C) Copyright 2004 Pierrick Meignen
6 * This file is part of PhpWiki.
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.
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.
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
24 * This is a simple version of the original TexToPng plugin which uses
25 * the powerful plugincached mechanism.
26 * TeX2png uses its own much simplier static cache in images/tex.
28 * @author: Pierrick Meignen
29 * TODO: use url helpers, windows fixes
30 * use a better imagepath
34 // LaTeX2HTML ftp://ftp.dante.de/tex-archive/support/latex2html
36 class WikiPlugin_TeX2png
39 var $imagepath = 'images/tex';
40 var $latexbin = '/usr/bin/latex';
41 var $dvipsbin = '/usr/bin/dvips';
42 var $pstoimgbin = '/usr/bin/pstoimg';
48 function getDescription () {
49 return _("Convert Tex mathematicals expressions to cached png files." .
50 " This is for small text");
53 function getVersion() {
54 return preg_replace("/[Revision: $]/", '',"\$Revision$");
57 function getDefaultArguments() {
58 return array('text' => "$$(a + b)^2 = a^2 + 2 ab + b^2$$");
61 function parseArgStr($argstr) {
62 // modified from WikiPlugin.php
67 $qq_p = '" ( (?:[^"\\\\]|\\\\.)* ) "';
68 //"<--kludge for brain-dead syntax coloring
69 $q_p = "' ( (?:[^'\\\\]|\\\\.)* ) '";
70 $gt_p = "_\\( $opt_ws $qq_p $opt_ws \\)";
71 $argspec_p = "($arg_p) $opt_ws ($op_p) $opt_ws (?: $qq_p|$q_p|$gt_p|($word_p))";
76 while (preg_match("/^$opt_ws $argspec_p $opt_ws/x", $argstr, $m)) {
77 @ list(,$arg,$op,$qq_val,$q_val,$gt_val,$word_val) = $m;
78 $argstr = substr($argstr, strlen($m[0]));
80 // Remove quotes from string values.
82 // we don't remove backslashes in tex formulas
83 // $val = stripslashes($qq_val);
86 $val = stripslashes($q_val);
88 $val = _(stripslashes($gt_val));
96 // NOTE: This does work for multiple args. Use the
97 // separator character defined in your webserver
98 // configuration, usually & or & (See
99 // http://www.htmlhelp.com/faq/cgifaq.4.html)
100 // e.g. <plugin RecentChanges days||=1 show_all||=0 show_minor||=0>
101 // url: RecentChanges?days=1&show_all=1&show_minor=0
102 assert($op == '||=');
103 $defaults[$arg] = $val;
108 $this->handle_plugin_args_cruft($argstr, $args);
111 return array($args, $defaults);
114 function createTexFile($texfile, $text) {
115 // this is the small latex file
116 // which contains only the mathematical
118 $fp = fopen($texfile, 'w');
119 $str = "\documentclass{article}\n";
120 $str .= "\usepackage{amsfonts}\n";
121 $str .= "\usepackage{amssymb}\n";
122 // Here tou can add some package in order
123 // to produce more sophisticated output
124 $str .= "\pagestyle{empty}\n";
125 $str .= "\begin{document}\n";
126 $str .= $text . "\n";
127 $str .= "\end{document}";
133 function createPngFile($imagepath, $imagename) {
134 // to create dvi file from the latex file
135 $commandes = $this->latexbin . " temp.tex;";
136 exec("cd $imagepath;$commandes");
137 // to create png file from the dvi file
138 // there is no option but it is possible
139 // to add one (scale for example)
140 if (file_exists("$imagepath/temp.dvi")){
141 $commandes = $this->dvipsbin . " temp.dvi -o temp.ps;";
142 $commandes .= $this->pstoimgbin . " -type png -margins 0,0 ";
143 $commandes .= "-crop a -geometry 600x300 ";
144 $commandes .= "-aaliastext -color 1 -scale 1.5 ";
145 $commandes .= "temp.ps -o " . $imagename;
146 exec("cd $imagepath;$commandes");
147 unlink("$imagepath/temp.dvi");
148 unlink("$imagepath/temp.ps");
150 echo _(" (syntax error for latex) ");
151 // to clean the directory
152 unlink("$imagepath/temp.tex");
153 unlink("$imagepath/temp.aux");
154 unlink("$imagepath/temp.log");
158 function isMathExp(&$text) {
159 // this function returns
160 // 0 : text is too long or not a mathematical expression
161 // 1 : text is $xxxxxx$ hence in line
162 // 2 : text is $$xxxx$$ hence centered
163 $last = strlen($text) - 1;
165 $text = "Too long !";
167 } elseif($last <= 1 || strpos($text, '$') != 0){
169 } elseif(strpos($text, '$', 1) == $last)
172 strpos($text, '$', 1) == 1 &&
173 strpos($text, '$', 2) == $last - 1)
178 function tex2png($text) {
179 // the name of the png cached file
180 $imagename = md5($text) . ".png";
181 $url = $this->imagepath . "/$imagename";
183 if(!file_exists($url)){
184 if(is_writable($this->imagepath)){
185 $texfile = $this->imagepath . "/temp.tex";
186 $this->createTexFile($texfile, $text);
187 $this->createPngFile($this->imagepath, $imagename);
189 $error_html = _("TeX imagepath not writable.");
190 trigger_error($error_html, E_USER_NOTICE);
194 // there is always something in the html page
195 // even if the tex directory doesn't exist
196 // or mathematical expression is wrong
197 switch($this->isMathExp($text)) {
198 case 0: // not a mathematical expression
199 $html = HTML::tt(array('class'=>'tex',
200 'style'=>'color:red;'), $text);
202 case 1: // an inlined mathematical expression
203 $html = HTML::img(array('class'=>'tex',
207 case 2: // mathematical expression on separate line
208 $html = HTML::img(array('class'=>'tex',
211 $html = HTML::div(array('align' => 'center'), $html);
220 function run($dbi, $argstr, &$request, $basepage) {
222 if ((function_exists('ImageTypes') and (ImageTypes() & IMG_PNG))
223 or function_exists("ImagePNG"))
225 // we have gd & png so go ahead.
226 extract($this->getArgs($argstr, $request));
227 return $this->tex2png($text);
229 // we don't have png and/or gd.
230 $error_html = _("Sorry, this version of PHP cannot create PNG image files.");
231 $link = "http://www.php.net/manual/pl/ref.image.php";
232 $error_html .= sprintf(_("See %s"), $link) .".";
233 trigger_error($error_html, E_USER_NOTICE);
244 // c-hanging-comment-ender-p: nil
245 // indent-tabs-mode: nil