]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/plugin/PhpHighlight.php
Patches (for 'wrap' option?) by Martin Geisler.
[SourceForge/phpwiki.git] / lib / plugin / PhpHighlight.php
1 <?php // -*-php-*-
2 rcs_id('$Id: PhpHighlight.php,v 1.6 2002-11-25 19:53:23 dairiki Exp $');
3 /**
4  * A plugin that runs the highlight_string() function in PHP on it's
5  * arguments to pretty-print PHP code.
6  *
7  * Usage:
8  * <?plugin PhpHighlight default='#FF0000' comment='#0000CC'
9  * code that should be highlighted
10  * ?>
11  *
12  * You do not have to add '<?php' and '?>' to the code - the plugin
13  * does this automatically if you do not set wrap to 0.
14  *
15  * If you do set wrap to 0, then you'll have to start and stop PHP
16  * mode in the source yourself, or you wont see any highlighting. But
17  * you cannot use '<?php' and '?>' in the source, because this
18  * interferes with PhpWiki, you'll have use '< ?php' and '? >'
19  * instead.
20  *
21  * Author: Martin Geisler <gimpster@gimpster.com>.
22  *
23  * Added compatibility for PHP < 4.2.0, where the highlight_string()
24  * function has no second argument.
25  * Added ability to override colors defined in php.ini --Carsten Klapp
26  */
27
28 class WikiPlugin_PhpHighlight
29 extends WikiPlugin
30 {
31     // Four required functions in a WikiPlugin.
32
33     function getName () {
34         return _("PhpHighlight");
35     }
36
37     function getDescription () {
38         return _("PHP syntax highlighting");
39
40     }
41     // Establish default values for each of this plugin's arguments.
42     function getDefaultArguments() {
43         // TODO: results of ini_get() should be static for multiple
44         // invocations of plugin on one WikiPage
45         return array('source'  => false,
46                      'wrap'    => true,
47                      'string'  => ini_get("highlight.string"),  //'#00CC00',
48                      'comment' => ini_get("highlight.comment"), //'#FF9900',
49                      'keyword' => ini_get("highlight.keyword"), //'#006600',
50                      'bg'      => ini_get("highlight.bg"),      //'#FFFFFF',
51                      'default' => ini_get("highlight.default"), //'#0000CC',
52                      'html'    => ini_get("highlight.html")     //'#000000'
53                      );
54     }
55
56     function run($dbi, $argstr, $request) {
57
58         extract($this->getArgs($argstr, $request));
59
60         if (!function_exists('version_compare')
61             || version_compare(phpversion(), '4.2.0', 'lt')) {
62             // trigger_error(sprintf(_("%s requires PHP version %s or newer."),
63             //                      $this->getName(), "4.2.0"), E_USER_NOTICE);
64             /* return unhighlighted text as if <verbatim> were used */
65             // return HTML::pre($argstr); // early return
66             $has_old_php = true;
67         }
68
69         $this->sanify_colors($string, $comment, $keyword, $bg, $default, $html);
70         $this->set_colors($string, $comment, $keyword, $bg, $default, $html);
71
72         if ($wrap) {
73             /* Wrap with "<?php\n" and "\n?>" required by
74              * highlight_string(): */
75             $source = "<?php\n" . $source . "\n?>";
76         } else {
77             $source = str_replace(array('< ?php', '? >'),
78                                   array('<?php', '?>'), $source);
79         }
80
81         if (!empty($has_old_php)) {
82             ob_start();
83             highlight_string($source);
84             $str = ob_get_contents();
85             ob_end_clean();
86         } else {
87             $str = highlight_string($source, true);
88         }
89
90         if ($wrap)
91             /* Remove "<?php\n" and "\n?>" again: */
92             $str = str_replace(array('&lt;?php<br />', '?&gt;'), '', $str);
93
94         /**
95          * We might have made some empty font tags. (The following
96          * str_replace string does not produce results on my system,
97          * maybe a php bug? '<font color="$color"></font>')
98          */
99         foreach (array($string, $comment, $keyword, $bg, $default, $html) as $color) {
100             $search = "<font color=\"$color\"></font>";
101             $str = str_replace($search, '', $str);
102         }
103
104         /* restore default colors in case of multiple invocations of
105            this plugin on one page */
106         $this->restore_colors();
107         return new RawXml($str);
108     }
109
110     function handle_plugin_args_cruft(&$argstr, &$args) {
111         $args['source'] = $argstr;
112     }
113
114     /**
115      * Make sure color argument is valid
116      * See http://www.w3.org/TR/REC-html40/types.html#h-6.5
117      */
118     function sanify_colors($string, $comment, $keyword, $bg, $default, $html) {
119         static $html4colors = array("black", "silver", "gray", "white",
120                                     "maroon", "red", "purple", "fuchsia",
121                                     "green", "lime", "olive", "yellow",
122                                     "navy", "blue", "teal", "aqua");
123         /* max(strlen("fuchsia"), strlen("#00FF00"), ... ) = 7 */
124         static $MAXLEN = 7;
125         foreach (array($string, $comment, $keyword, $bg, $default, $html) as $color) {
126             $length = strlen($color);
127             //trigger_error(sprintf(_("DEBUG: color '%s' is length %d."), $color, $length), E_USER_NOTICE);
128             if (($length == 7 || $length == 4) && substr($color, 0, 1) == "#"
129             && "#" == preg_replace("/[a-fA-F0-9]/", "", $color)
130              ) {
131                 //trigger_error(sprintf(_("DEBUG: color '%s' appears to be hex."), $color), E_USER_NOTICE);
132                 // stop checking, ok to go
133             } elseif (($length < $MAXLEN + 1) && in_array($color, $html4colors)) {
134                 //trigger_error(sprintf(_("DEBUG color '%s' appears to be an HTML 4 color."), $color), E_USER_NOTICE);
135                 // stop checking, ok to go
136             } else {
137                 trigger_error(sprintf(_("Invalid color: %s"),
138                                       $color), E_USER_NOTICE);
139                 // FIXME: also change color to something valid like "black" or ini_get("highlight.xxx")
140             }
141         }
142     }
143
144     function set_colors($string, $comment, $keyword, $bg, $default, $html) {
145         // set highlight colors
146         $this->oldstring = ini_set('highlight.string', $string);
147         $this->oldcomment = ini_set('highlight.comment', $comment);
148         $this->oldkeyword = ini_set('highlight.keyword', $keyword);
149         $this->oldbg = ini_set('highlight.bg', $bg);
150         $this->olddefault = ini_set('highlight.default', $default);
151         $this->oldhtml = ini_set('highlight.html', $html);
152     }
153
154     function restore_colors() {
155         // restore previous default highlight colors
156         ini_set('highlight.string', $this->oldstring);
157         ini_set('highlight.comment', $this->oldcomment);
158         ini_set('highlight.keyword', $this->oldkeyword);
159         ini_set('highlight.bg', $this->oldbg);
160         ini_set('highlight.default', $this->olddefault);
161         ini_set('highlight.html', $this->oldhtml);
162     }
163
164 };
165
166 // For emacs users
167 // Local Variables:
168 // mode: php
169 // tab-width: 8
170 // c-basic-offset: 4
171 // c-hanging-comment-ender-p: nil
172 // indent-tabs-mode: nil
173 // End:
174 ?>