]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/plugin/PhpHighlight.php
Activated Id substitution for Subversion
[SourceForge/phpwiki.git] / lib / plugin / PhpHighlight.php
1 <?php // -*-php-*-
2 rcs_id('$Id$');
3 /**
4  Copyright 1999, 2000, 2001, 2002 $ThePhpWikiProgrammingTeam
5
6  This file is part of PhpWiki.
7
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.
12
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.
17
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
21  */
22
23 /**
24  * A plugin that runs the highlight_string() function in PHP on it's
25  * arguments to pretty-print PHP code.
26  *
27  * Usage:
28  * <?plugin PhpHighlight default='#FF0000' comment='#0000CC'
29  * code that should be highlighted
30  * ?>
31  *
32  * You do not have to add '<?php' and '?>' to the code - the plugin
33  * does this automatically if you do not set wrap to 0.
34  *
35  * If you do set wrap to 0, then you'll have to start and stop PHP
36  * mode in the source yourself, or you wont see any highlighting. But
37  * you cannot use '<?php' and '?>' in the source, because this
38  * interferes with PhpWiki, you'll have use '< ?php' and '? >'
39  * instead.
40  *
41  * Author: Martin Geisler <gimpster@gimpster.com>.
42  *
43  * Added compatibility for PHP < 4.2.0, where the highlight_string()
44  * function has no second argument.
45  * Added ability to override colors defined in php.ini --Carsten Klapp
46  *
47  * Known Problems:
48  *   <?plugin PhpHighlight
49  *   testing[somearray];
50  *   testing~[badworkaround~];
51  *   ?>
52  * will swallow "[somearray]"
53  */
54
55 class WikiPlugin_PhpHighlight
56 extends WikiPlugin
57 {
58     // Four required functions in a WikiPlugin.
59
60     function getName () {
61         return _("PhpHighlight");
62     }
63
64     function getDescription () {
65         return _("PHP syntax highlighting");
66
67     }
68
69     function getVersion() {
70         return preg_replace("/[Revision: $]/", '',
71                             "\$Revision: 1.9 $");
72     }
73
74     // Establish default values for each of this plugin's arguments.
75     function getDefaultArguments() {
76         // TODO: results of ini_get() should be static for multiple
77         // invocations of plugin on one WikiPage
78         return array('wrap'    => true,
79                      'string'  => ini_get("highlight.string"),  //'#00CC00',
80                      'comment' => ini_get("highlight.comment"), //'#FF9900',
81                      'keyword' => ini_get("highlight.keyword"), //'#006600',
82                      'bg'      => ini_get("highlight.bg"),      //'#FFFFFF',
83                      'default' => ini_get("highlight.default"), //'#0000CC',
84                      'html'    => ini_get("highlight.html")     //'#000000'
85                      );
86     }
87
88     function run($dbi, $argstr, &$request, $basepage) {
89
90         extract($this->getArgs($argstr, $request));
91         $source =& $this->source;
92
93         $this->sanify_colors($string, $comment, $keyword, $bg, $default, $html);
94         $this->set_colors($string, $comment, $keyword, $bg, $default, $html);
95
96         if ($wrap) {
97             /* Wrap with "<?php\n" and "\n?>" required by
98              * highlight_string(): */
99             $source = "<?php\n" . $source . "\n?>";
100         } else {
101             $source = str_replace(array('< ?php', '? >'),
102                                   array('<?php', '?>'), $source);
103         }
104
105         if (!check_php_version(4,2,0)) {
106             ob_start();
107             highlight_string($source);
108             $str = ob_get_contents();
109             ob_end_clean();
110         } else {
111             $str = highlight_string($source, true);
112         }
113
114         if ($wrap)
115             /* Remove "<?php\n" and "\n?>" again: */
116             $str = str_replace(array('&lt;?php<br />', '?&gt;'), '', $str);
117
118         /**
119          * We might have made some empty font tags. (The following
120          * str_replace string does not produce results on my system,
121          * maybe a php bug? '<font color="$color"></font>')
122          */
123         foreach (array($string, $comment, $keyword, $bg, $default, $html) as $color) {
124             $search = "<font color=\"$color\"></font>";
125             $str = str_replace($search, '', $str);
126         }
127
128         /* restore default colors in case of multiple invocations of
129            this plugin on one page */
130         $this->restore_colors();
131         return new RawXml($str);
132     }
133
134     function handle_plugin_args_cruft(&$argstr, &$args) {
135         $this->source = $argstr;
136     }
137
138     /**
139      * Make sure color argument is valid
140      * See http://www.w3.org/TR/REC-html40/types.html#h-6.5
141      */
142     function sanify_colors($string, $comment, $keyword, $bg, $default, $html) {
143         static $html4colors = array("black", "silver", "gray", "white",
144                                     "maroon", "red", "purple", "fuchsia",
145                                     "green", "lime", "olive", "yellow",
146                                     "navy", "blue", "teal", "aqua");
147         /* max(strlen("fuchsia"), strlen("#00FF00"), ... ) = 7 */
148         static $MAXLEN = 7;
149         foreach (array($string, $comment, $keyword, $bg, $default, $html) as $color) {
150             $length = strlen($color);
151             //trigger_error(sprintf(_("DEBUG: color '%s' is length %d."), $color, $length), E_USER_NOTICE);
152             if (($length == 7 || $length == 4) && substr($color, 0, 1) == "#"
153             && "#" == preg_replace("/[a-fA-F0-9]/", "", $color)
154              ) {
155                 //trigger_error(sprintf(_("DEBUG: color '%s' appears to be hex."), $color), E_USER_NOTICE);
156                 // stop checking, ok to go
157             } elseif (($length < $MAXLEN + 1) && in_array($color, $html4colors)) {
158                 //trigger_error(sprintf(_("DEBUG color '%s' appears to be an HTML 4 color."), $color), E_USER_NOTICE);
159                 // stop checking, ok to go
160             } else {
161                 trigger_error(sprintf(_("Invalid color: %s"),
162                                       $color), E_USER_NOTICE);
163                 // FIXME: also change color to something valid like "black" or ini_get("highlight.xxx")
164             }
165         }
166     }
167
168     function set_colors($string, $comment, $keyword, $bg, $default, $html) {
169         // set highlight colors
170         $this->oldstring = ini_set('highlight.string', $string);
171         $this->oldcomment = ini_set('highlight.comment', $comment);
172         $this->oldkeyword = ini_set('highlight.keyword', $keyword);
173         $this->oldbg = ini_set('highlight.bg', $bg);
174         $this->olddefault = ini_set('highlight.default', $default);
175         $this->oldhtml = ini_set('highlight.html', $html);
176     }
177
178     function restore_colors() {
179         // restore previous default highlight colors
180         ini_set('highlight.string', $this->oldstring);
181         ini_set('highlight.comment', $this->oldcomment);
182         ini_set('highlight.keyword', $this->oldkeyword);
183         ini_set('highlight.bg', $this->oldbg);
184         ini_set('highlight.default', $this->olddefault);
185         ini_set('highlight.html', $this->oldhtml);
186     }
187
188 };
189
190 // $Log: not supported by cvs2svn $
191 // Revision 1.8  2004/02/17 12:11:36  rurban
192 // added missing 4th basepage arg at plugin->run() to almost all plugins. This caused no harm so far, because it was silently dropped on normal usage. However on plugin internal ->run invocations it failed. (InterWikiSearch, IncludeSiteMap, ...)
193 //
194 // Revision 1.7  2003/01/18 22:01:43  carstenklapp
195 // Code cleanup:
196 // Reformatting & tabs to spaces;
197 // Added copyleft, getVersion, getDescription, rcs_id.
198 //
199
200 // For emacs users
201 // Local Variables:
202 // mode: php
203 // tab-width: 8
204 // c-basic-offset: 4
205 // c-hanging-comment-ender-p: nil
206 // indent-tabs-mode: nil
207 // End:
208 ?>