Since this blog's main subject is development it's unavoidable I'll show snippets of code in my posts. And I like my code to be syntax-highlighted, so it's natural that I noticed and downloaded the GeSHi plugin for Habari before I even installed Habari: I considered it that much of an essential part of my blogging toolbox.
I'm a great fan of GeSHi, which is used in many OSS projects, including Wikka Wiki (where I'm a member of the development crew). The latest stable version of GeSHi, which is 1.0.8.1 as I'm writing this, comes with support for an impressive number of languages out of the box, and it's possible to write (and submit!) your own as well, if you're missing what you need (and know the syntax well, of course).
Setting up the plugin
The plugin is straightforward to install: just put it in your plugins directory and activate it: it doesn't have any configuration. One thing I immediately liked about this simple and straightforward plugin is that is does not come with GeSHI itself: that way you can make sure you have the latest and greatest, even if the plugin hasn't been updated for a while. It comes with a little documentation file which outlines how to integrate GeSHi with the plugin: it expects to see the main GeSHi class in a subdirectory 'geshi' in (habari)/3rdparty/. That's not quite how I did it, because I don't like duplicating software all over my server. Here's what I did:
First of all, I got the latest version, and unpacked it into a subdirectory of /var/www/ where I keep shared source code; it creates a geshi directory, and I renamed that by adding its version number so I can quickly see what I have (and easily go back to an earlier version if ever needed); then I made a geshi symlink to that — like so:
[root@vps src]# cd /var/www/src/packages/3rdparty [root@vps 3rdparty]# tar xvzf /usr/local/src/GeSHi-1.0.8.1.tar.gz … [root@vps 3rdparty]# mv geshi geshi-1.0.8.1 [root@vps 3rdparty]# ln -s geshi-1.0.8.1 geshi
The next step was to "put it in" a geshi directory under (habari)/3rdparty/. But, as you can see in the screenshot above, my Habari code base itself also lives in that shared source directory structure under /var/www/ (more about that in a later post). That doesn't make any difference for this exercise: I just went to the 3rdparty directory in my Habari code base and from there created a symlink to the geshi symlink:
[root@vps 3rdparty]# cd /var/www/src/packages/3rdparty [root@vps 3rdparty]# cd habari/3rdparty [root@vps 3rdparty]# pwd /var/www/src/packages/3rdparty/habari/3rdparty [root@vps 3rdparty]# ln -s /var/www/src/packages/3rdparty/geshi geshi
Tweaking the plugin
GeSHI options
As I said, the plugin doesn't have any configuration. It sets up two (sensible) options (enable classes, which provides class attributes as hooks for styling, and enable fancy line numbers). If you want extra (or different) options, just edit the geshipaint() function in the plugin, and add your own options. I haven't done that (yet) as I'm happy with the current options.
Stylesheet
The documentation also points out that GeSHI comes with a little tool to generate a stylesheet for a language. The plugin assumes such a stylesheet geshi.css is located in the main geshi directory, and helpfully injects it in the page head section. That's fine, but I work with different languages and normally just use a generic color scheme for all code highlighting — and GeSHi doesn't come with a default stylesheet either. Including non-existing files is not very useful, so in the theme_header() function I changed:
return "<link rel=\"stylesheet\" type=\"text/css\" media=\"screen\" href=\"" . Site::get_url('habari') . "/3rdparty/geshi/geshi.css\"/>";
$css_path = Site::get_url( 'habari' ) . '/3rdparty/geshi/geshi.css'; // include link if the stylesheet exists return '<link rel="stylesheet" type="text/css" media="screen" href="' . $css_path . '"/>'; } else { return ''; }
$mycode = str_replace($mymatches[0][$i], '<div class="geshi">' . $geshi->parse_code() . '</div>' , $mycode);
/* --- syntax highlighting code - GeSHi --- */ div.geshi pre { margin: 0 1em !important; overflow: auto; background-color: #ffe; border: 1px dotted #ccc; } div.geshi pre ol li { margin-bottom: 0; /* override .entry-content ol li */ font-family: "Lucida Console", Monaco, monospace; /*outline: 1px dotted red;*/ /* DEBUG */ } div.geshi pre ol li.li2 { background-color: #ffd; /* gentle zebra stripes */ } div.geshi pre ol li div { margin: 0; /* override .entry-content div */ } div.geshi .br0 { color: #6C6; } div.geshi .co0 { color: #808080; font-style: italic; } /* comment */ div.geshi .co1 { color: #808080; font-style: italic; } div.geshi .co2 { color: #808080; font-style: italic; } div.geshi .coMULTI { color: #808080; font-style: italic; } /* multi-line comment */ div.geshi .es0 { color: #009; font-weight: bold; } div.geshi .kw1 { color: #b1b100; } /* keyword */ div.geshi .kw2 { color: #000; font-weight: bold; } div.geshi .kw3 { color: #006; } div.geshi .kw4 { color: #933; } div.geshi .kw5 { color: #00F; } div.geshi .me0 { color: #060; } div.geshi .nu0 { color: #C6C; } /* number */ div.geshi .re0 { color: #00F; } div.geshi .re1 { color: #00F; } div.geshi .re2 { color: #00F; } div.geshi .re4 { color: #099; } div.geshi .sc0 { color: #0BD; } div.geshi .sc1 { color: #DB0; } div.geshi .sc2 { color: #090; } div.geshi .st0 { color: #F00; } div.geshi .sy0 { color: #F00; } /* symbol */
Marker tags
Finally, the plugin also assumes you enclose your GeSHi-highlightable code within
All of which you can see in operation in my earlier post Searching for Subversion and, of course, this one!


There's an easier way to make GeSHi use a special class for its code. Starting with 1.0.8 the behaviour of
The second comment goes to your stylesheet: That one is not fully complete as some languages (like e.g. Java5) have more than 5 Keyword Groups (in case of java5 there are about 150 ;-)). So you might want to complete this stylesheet ;-)
Regards,
BenBE.
Ben, thanks for that useful comment.
The set_overall_class() would be a good one to add to the settings, or better yet, make configurable for the plugin. (That's another thing I'd like to do now that I'm getting a little more familiar with how Habari works.)
As to the stylesheet, I know it's not complete! But, 150 extra classes...? They may be needed for Java, but I don't use Java. What I did was start with what I had in my own stylesheet for Wikka Wiki, and add a few more I came across in the code I've used here so far. I'll just keep adding classes as needed, but I don't use all that many languages — it should soon enough become "locally complete". Your local completeness will surely be different from mine, though. :)
Finally, thanks for demonstrating that the syntax highlighting works in comments, too!
...Suddenly I remembered inputfilter.php which I'd had to edit for the first installation of the GeSHi plugin. There it was: a lot of whitelisted HTML tags — with h1 through h6 conspicuously missing — ever...
Hmm, very cognitive post.
Is this theme good unough for the Digg?