]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/plugin/PhpHighlight.php
rcs_id no longer makes sense with Subversion global version number
[SourceForge/phpwiki.git] / lib / plugin / PhpHighlight.php
1 <?php // -*-php-*-
2 // rcs_id('$Id$');
3 /**
4  * Copyright 1999, 2000, 2001, 2002 $ThePhpWikiProgrammingTeam
5  * Copyright 2009 Marc-Etienne Vargenau, Alcatel-Lucent
6  *
7  * This file is part of PhpWiki.
8  *
9  * PhpWiki is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * PhpWiki is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with PhpWiki; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  */
23
24 /**
25  * A plugin that runs the highlight_string() function in PHP on it's
26  * arguments to pretty-print PHP code.
27  *
28  * Usage:
29  * <?plugin PhpHighlight default='#FF0000' comment='#0000CC'
30  * code that should be highlighted
31  * ?>
32  *
33  * You do not have to add '<?php' and '?>' to the code - the plugin
34  * does this automatically if you do not set wrap to 0.
35  *
36  * If you do set wrap to 0, then you'll have to start and stop PHP
37  * mode in the source yourself, or you wont see any highlighting. But
38  * you cannot use '<?php' and '?>' in the source, because this
39  * interferes with PhpWiki, you'll have use '< ?php' and '? >'
40  * instead.
41  *
42  * Author: Martin Geisler <gimpster@gimpster.com>.
43  *
44  * Added compatibility for PHP < 4.2.0, where the highlight_string()
45  * function has no second argument.
46  * Added ability to override colors defined in php.ini --Carsten Klapp
47  *
48  * Known Problems:
49  *   <?plugin PhpHighlight
50  *   testing[somearray];
51  *   testing~[badworkaround~];
52  *   ?>
53  * will swallow "[somearray]"
54  */
55
56 class WikiPlugin_PhpHighlight
57 extends WikiPlugin
58 {
59     // Four required functions in a WikiPlugin.
60
61     function getName () {
62         return _("PhpHighlight");
63     }
64
65     function getDescription () {
66         return _("PHP syntax highlighting");
67     }
68
69     // Establish default values for each of this plugin's arguments.
70     function getDefaultArguments() {
71         // TODO: results of ini_get() should be static for multiple
72         // invocations of plugin on one WikiPage
73         return array('wrap'    => true,
74                      'string'  => ini_get("highlight.string"),  //'#00CC00',
75                      'comment' => ini_get("highlight.comment"), //'#FF9900',
76                      'keyword' => ini_get("highlight.keyword"), //'#006600',
77                      'bg'      => ini_get("highlight.bg"),      //'#FFFFFF',
78                      'default' => ini_get("highlight.default"), //'#0000CC',
79                      'html'    => ini_get("highlight.html")     //'#000000'
80                      );
81     }
82
83     function run($dbi, $argstr, &$request, $basepage) {
84
85         extract($this->getArgs($argstr, $request));
86         $source =& $this->source;
87
88         $this->sanify_colors($string, $comment, $keyword, $bg, $default, $html);
89         $this->set_colors($string, $comment, $keyword, $bg, $default, $html);
90
91         if ($wrap) {
92             /* Wrap with "<?php\n" and "\n?>" required by
93              * highlight_string(): */
94             $source = "<?php\n" . $source . "\n?>";
95         } else {
96             $source = str_replace(array('< ?php', '? >'),
97                                   array('<?php', '?>'), $source);
98         }
99
100         if (!check_php_version(4,2,0)) {
101             ob_start();
102             highlight_string($source);
103             $str = ob_get_contents();
104             ob_end_clean();
105         } else {
106             $str = highlight_string($source, true);
107         }
108
109         if ($wrap)
110             /* Remove "<?php\n" and "\n?>" again: */
111             $str = str_replace(array('&lt;?php<br />', '?&gt;'), '', $str);
112
113         /* We might have made some empty font tags. */
114         foreach (array($string, $comment, $keyword, $bg, $default, $html) as $color) {
115             $search = "<font color=\"$color\"></font>";
116             $str = str_replace($search, '', $str);
117         }
118         /* Remove also empty span tags. */
119         foreach (array($string, $comment, $keyword, $bg, $default, $html) as $color) {
120             $search = "<span style=\"color: $color\"></span>";
121             $str = str_replace($search, '', $str);
122         }
123
124         /* restore default colors in case of multiple invocations of
125            this plugin on one page */
126         $this->restore_colors();
127         return new RawXml($str);
128     }
129
130     function handle_plugin_args_cruft(&$argstr, &$args) {
131         $this->source = $argstr;
132     }
133
134     /**
135      * Make sure color argument is valid
136      * See http://www.w3.org/TR/REC-html40/types.html#h-6.5
137      */
138     function sanify_colors($string, $comment, $keyword, $bg, $default, $html) {
139         static $html4colors = array("black", "silver", "gray", "white",
140                                     "maroon", "red", "purple", "fuchsia",
141                                     "green", "lime", "olive", "yellow",
142                                     "navy", "blue", "teal", "aqua");
143         /* max(strlen("fuchsia"), strlen("#00FF00"), ... ) = 7 */
144         static $MAXLEN = 7;
145         foreach (array($string, $comment, $keyword, $bg, $default, $html) as $color) {
146             $length = strlen($color);
147             //trigger_error(sprintf(_("DEBUG: color '%s' is length %d."), $color, $length), E_USER_NOTICE);
148             if (($length == 7 || $length == 4) && substr($color, 0, 1) == "#"
149             && "#" == preg_replace("/[a-fA-F0-9]/", "", $color)
150              ) {
151                 //trigger_error(sprintf(_("DEBUG: color '%s' appears to be hex."), $color), E_USER_NOTICE);
152                 // stop checking, ok to go
153             } elseif (($length < $MAXLEN + 1) && in_array($color, $html4colors)) {
154                 //trigger_error(sprintf(_("DEBUG color '%s' appears to be an HTML 4 color."), $color), E_USER_NOTICE);
155                 // stop checking, ok to go
156             } else {
157                 trigger_error(sprintf(_("Invalid color: %s"),
158                                       $color), E_USER_NOTICE);
159                 // FIXME: also change color to something valid like "black" or ini_get("highlight.xxx")
160             }
161         }
162     }
163
164     function set_colors($string, $comment, $keyword, $bg, $default, $html) {
165         // set highlight colors
166         $this->oldstring = ini_set('highlight.string', $string);
167         $this->oldcomment = ini_set('highlight.comment', $comment);
168         $this->oldkeyword = ini_set('highlight.keyword', $keyword);
169         $this->oldbg = ini_set('highlight.bg', $bg);
170         $this->olddefault = ini_set('highlight.default', $default);
171         $this->oldhtml = ini_set('highlight.html', $html);
172     }
173
174     function restore_colors() {
175         // restore previous default highlight colors
176         ini_set('highlight.string', $this->oldstring);
177         ini_set('highlight.comment', $this->oldcomment);
178         ini_set('highlight.keyword', $this->oldkeyword);
179         ini_set('highlight.bg', $this->oldbg);
180         ini_set('highlight.default', $this->olddefault);
181         ini_set('highlight.html', $this->oldhtml);
182     }
183
184 };
185
186 // For emacs users
187 // Local Variables:
188 // mode: php
189 // tab-width: 8
190 // c-basic-offset: 4
191 // c-hanging-comment-ender-p: nil
192 // indent-tabs-mode: nil
193 // End:
194 ?>