Code snippet formatting with GeSHi
In this snippet I will show you how to format code using a combination of the Generic String Highlighter (GeSHi) class and custom PHP and CSS. The first objective is to figure out the best way to include code in an HTML document. I decided the best way was to put the code in a seperate text file and read its contents with PHP. This way we can parse it line by line, and also link to the file on the page for people who want to access it.
The function returns an HTML list and puts each line of the code text in a list item. Then, using the GeSHi class it highlights the code according to the language specified. For more information on using GeSHi, check out their website. At the end of the list, it adds another list item with a link to the source text file.
The function: codify()
- // GeSHi class - http://qbnz.com/highlighter
- require_once('geshi/geshi.php');
- // formats code from file $uri and highlights according to language $lang (using the GeSHi)
- function codify($htmlid,$uri,$lang,$line_numbers=true,$show_uri=true) {
- $dir = "/sourcecode/"; // default dir
- $lines = file(ABSDIR.$dir.$uri); // put lines of file into array
- $list = ($line_numbers)? 'ol' : 'ul'; // ordered or unordered list, whether or not you want line numbers
- $ret = "<pre><$list id=\"$htmlid\" class=\"code-list $lang\">";
- if (!empty($lines)) {
- foreach ($lines as $line) {
- $line = rtrim($line); // get rid of whitespace at the end of each line
- $line = str_replace("\t"," ",$line); // replace tabs with 4 spaces
- $geshi =& new GeSHi($line, $lang); // create GeSHi code highlighting object
- $geshi->enable_classes();
- $line = $geshi->parse_code(); // apply GeSHi highlighting
- $line = preg_replace("@</?pre.*>@U","",$line); // remove <pre>s created by GeSHi
- $ret .= "<li><span>$line</span></li>\n";
- }
- if ($show_uri) $ret .= "<li class=\"code-list-source\"><span>source file: <a href=\"$dir$uri\" title=\"$uri\">$uri</a></span></li>\n";
- } else $ret .= "<li class=\"error tc\">Cannot read contents of $uri</li>\n";
- $ret .= "</$list></pre>\n";
- return $ret;
- }
- source file: code-highlighting.txt
codify() takes 5 arguments (2 of which are optional):
$htmlid— The HTMLidyou would like to give the list.$uri— The location of the source text.$lang— The language (so GeSHi knows what color scheme to use).$line_numbers(optional) — Whether or not line numbers should be displayed$show_uri(optional) — Whether or not the source text should be linked at the end.
It returns an HTML unordered or ordered list, depending on whether or not you wanted line numbers.
Below is an example of using codify(). The result of this call is exactly what you see.
- <?=codify('code-highlighting-call','code-highlighting-call.txt','php',false);?>
- source file: code-highlighting-call.txt
Styling the list
To make the code presentable (besides the GeSHi CSS, which you must remember to include), we will also have to style the list with our own CSS. In codify() we gave the list a class of code-list for this purpose. Here's the CSS zakness.com uses to style codify'd lists:
- .code-list {
- padding: 0.5em;
- background: #fafafa;
- }
- ol.code-list {
- border-left: 2.8em solid #111;
- padding-bottom: 0.2em;
- }
- .code-list li {
- margin: 0 0 -2.1em 0;
- padding: 0;
- line-height: 1.4em;
- color: #fff;
- font-size: 0.8em;
- }
- .code-list li>span {
- color: #484340;
- font-size: 1.2em;
- }
- .code-list li>span span {
- font-size: 1em;
- }
- li.code-list-source {
- color: #111;
- }
- li.code-list-source span {
- padding: 0.2em 1em 0.5em 0;
- color: #a0a0a0 !important;
- text-align: right;
- display: block;
- font: 1.2em "Lucida Grande", Verdana, Tahoma, Arial, sans-serif;
- }
- pre {
- white-space: -moz-pre-wrap; /* Mozilla */
- white-space: -o-pre-wrap; /* Opera 7 */
- word-wrap: break-word; /* IE */
- }
- source file: code-highlighting-css.txt
In order to style the line numbers of the ordered list, we have to wrap the contents of each list item in their own <span> and give the <li> and <span> different font colors. It was also necessary to use proprietary style rules on the pre tag to fix line breaks. This has been tested in IE7, Firefox 2.0+, Camino, and Safari.