When setting up this blog, which is powered by WordPress, I knew that there were going to be a lot of posts about code. In order to make the code readable, I wanted to implement some sort of syntax highlighting. I eventually came across a great plugin called Simple Syntax, which is powered by the GeSHi highlighter engine. However, it needed a few modifications before it did exactly what I wanted it to do.
The first thing I wanted to do was enclose my code in blocks that could scroll left and right, up and down, so that long blocks of code didn’t take up a huge amount of space, and so that wide blocks of code didn’t wrap or reach outside of the content area.
After putting my waders on and going through some of the code, I found the function that generates the headers for my code blocks. With Simply Syntax, the file is “SimpleSyntax/geshi/geshi.php”. Do a text search for “function header” and you’ll get the code block we’re going to hack:
function header () { // Get attributes needed $attributes = $this->get_attributes(); $ol_attributes = ''; if ($this->line_numbers_start != 1) { $ol_attributes .= ' start="' . $this->line_numbers_start . '"'; } // Get the header HTML $header = $this->format_header_content(); if (GESHI_HEADER_NONE == $this->header_type) { if ($this->line_numbers != GESHI_NO_LINE_NUMBERS) { return "$header<ol$ol_attributes>"; } return $header; } // Work out what to return and do it if ($this->line_numbers != GESHI_NO_LINE_NUMBERS) { if ($this->header_type == GESHI_HEADER_PRE) { return "<pre$attributes>$header<ol$ol_attributes>"; } elseif ($this->header_type == GESHI_HEADER_DIV) { return "<div$attributes>$header<ol$ol_attributes>"; } } else { if ($this->header_type == GESHI_HEADER_PRE) { return "<pre$attributes>$header"; } elseif ($this->header_type == GESHI_HEADER_DIV) { return "<div$attributes>$header"; } } }
The first thing to do is make our code blocks part of a certain class, so that we can style them with CSS. Just add “class=\”code\”" to the following parts of the header function (we also have to remove the $attributes variable from the header. If not, it’s going to add its own class tags, which we don’t want):
// Work out what to return and do it if ($this->line_numbers != GESHI_NO_LINE_NUMBERS) { if ($this->header_type == GESHI_HEADER_PRE) { return "<pre class=\"code\">$header<ol$ol_attributes>"; } elseif ($this->header_type == GESHI_HEADER_DIV) { return "<div$attributes>$header<ol$ol_attributes>"; } } else { if ($this->header_type == GESHI_HEADER_PRE) { return "<pre class=\"code\">$header"; } elseif ($this->header_type == GESHI_HEADER_DIV) { return "<div$attributes>$header"; } }
Alright, now that our code blocks have their own class, let’s add the CSS to put them into blocks:
.code { background-color: #f0f0f0; border: 1px solid #C3CED9; padding: 0px 0px 0 0; width: 100%; color: #000; text-align: left; font-size:1.00em; overflow:auto; }
So now our code is put into nice blocks that scroll horizontally (if you want, you can change the width to a fixed pixel amount. 100% worked best for this layout). But, if you post a block of code with many lines, it’s going to make a very tall code block. What we want to do is determine the number of lines in a block of code, and, if it’s above a certain number, fix the height of the code block so that it scrolls vertically.
Back to our “header” function, here’s the code that will count the number of lines in a code block:
substr_count($this->source,"\n")
So all we have to do is check to see if this code returns a number above a certain value and, if it does, set a variable that will contain our height-fixing code.
if (substr_count($this->source,"\n") > 30){ $maxsize = " style=\"height: 300px;\""; }
Kid stuff. Now we just add our $maxsize variable to the headers, and we’re done. Here’s the final code:
function header () { // hack to fix height if certain number of lines if (substr_count($this->source,"\n") > 30){ $maxsize = " style=\"height: 300px;\""; } $ol_attributes = ''; if ($this->line_numbers_start != 1) { $ol_attributes .= ' start="' . $this->line_numbers_start . '"'; } // Get the header HTML $header = $this->format_header_content(); if (GESHI_HEADER_NONE == $this->header_type) { if ($this->line_numbers != GESHI_NO_LINE_NUMBERS) { return "$header<ol$ol_attributes>"; } return $header; } // Work out what to return and do it if ($this->line_numbers != GESHI_NO_LINE_NUMBERS) { if ($this->header_type == GESHI_HEADER_PRE) { return "<pre$maxsize class=\"code\">$header<ol$ol_attributes>"; } elseif ($this->header_type == GESHI_HEADER_DIV) { return "<div$attributes>$header<ol$ol_attributes>"; } } else { if ($this->header_type == GESHI_HEADER_PRE) { return "<pre$maxsize class=\"code\">$header"; } elseif ($this->header_type == GESHI_HEADER_DIV) { return "<div$attributes>$header"; } } }






