mylaboratory
Title image
 
Home
 
Software
 
Raytracer
 
Recipes
 
Photos
 
Mashup
 

PHP Code Highlighter

This code snippet produces the syntax-highlighted PHP code boxes seen on these pages. It uses PHP's own highlighter to colour the text then inserts code to add the line numbers and a little button to switch to a non-line-broken, number-free version which is better suited to copying and pasting.

If first generates a random number to create a unique ID for the block. The code is then coloured using PHP's highlight_file() function. This function also replaces tabs and spaces with non-breaking spaces. The code is output into a div that scrolls when the lines are too long. The block is initially hidden.

The code then replaces '&nbsp;' with normal spaces so that lines wrap properly, replaces double spaces with '&nbsp; ' so that tabbed regions render properly (as html compresses all whitespace otherwise). The string is then exploded along the line-breaks and then reformed with line numbers inserted. The str_pad() function inserts zeros so that all line numbers are the same length. Finally the last line is attached and the line number of the first line inserted after the initial <code> tag and the string is output.

The <div> containing the string Alt has the onclick HTML attribute attached to a JavaScript function called toggleDisplay(idx) which switches between the two different code display modes.

Alt
<?php
    
function phpHighlight($fname)
    {
        
$box rand(032000);    //generate random number to identify block
        
$code highlight_file($fnametrue);    //highlight code file using PHP's routine and store in string
        
echo "<div class=\"phpaltouterbox\" id=\"codeblock".$box."\"><div class=\"phpaltinnerbox\"><div class=\"phptoggle\" style=\"margin: 10px 10px 0px 0px;\" onclick=\"toggleDisplay(".$box.")\">Alt</div>\n<pre>".$code."</pre>\n</div></div>\n";    //output without line numbers of word wrapping
        
$code str_replace("&nbsp;"" "$code);    //replace non-breaking spaces with normal ones
        
$code str_replace("  "" &nbsp;"$code);    //replace double-spaces with '&nbsp; '
        
$lines explode("<br />"$code);        //break into lines
        
$nlines count($lines)-1;        //count number of lines
        
$lnlength strlen($nlines);    //count the number of digits in this number
        
$output "";
        for (
$i 0$i $nlines; ++$i)    //for each line add a line number and put the break back in
            
$output .= $lines[$i]."<br />\n<span class=\"lineno\">&nbsp;".str_pad((2+$i), $lnlength'0'STR_PAD_LEFT)."&nbsp;</span>&nbsp;";
        
$output .= $lines[$i];    //attach final line
        
$coloured "<code><span class=\"lineno\">&nbsp;".str_pad('1'$lnlength'0'STR_PAD_LEFT)."&nbsp;</span>".substr($output6);    //insert line number of the first line
        
echo "<div class=\"phpbox\" id=\"altcodeblock".$box."\"><div class=\"phptoggle\" onclick=\"toggleDisplay(".$box.")\">Alt</div>\n".$coloured."\n</div>\n";
    }
?>
Alt
 01  <?php
 02      
function phpHighlight($fname)
 03      {
 04          
$box = rand(0, 32000);    //generate random number to identify block
 05          
$code = highlight_file($fname, true);    //highlight code file using PHP's routine and store in string
 06          
echo "<div class=\"phpaltouterbox\" id=\"codeblock".$box."\"><div class=\"phpaltinnerbox\"><div class=\"phptoggle\" style=\"margin: 10px 10px 0px 0px;\" onclick=\"toggleDisplay(".$box.")\">Alt</div>\n<pre>".$code."</pre>\n</div></div>\n";    //output without line numbers of word wrapping
 07          
$code = str_replace("&nbsp;", " ", $code);    //replace non-breaking spaces with normal ones
 08          
$code = str_replace("  ", " &nbsp;", $code);    //replace double-spaces with '&nbsp; '
 09          
$lines = explode("<br />", $code);        //break into lines
 10          
$nlines = count($lines)-1;        //count number of lines
 11          
$lnlength = strlen($nlines);    //count the number of digits in this number
 12          
$output = "";
 13          for (
$i = 0; $i < $nlines; ++$i)    //for each line add a line number and put the break back in
 14              
$output .= $lines[$i]."<br />\n<span class=\"lineno\">&nbsp;".str_pad((2+$i), $lnlength, '0', STR_PAD_LEFT)."&nbsp;</span>&nbsp;";
 15          
$output .= $lines[$i];    //attach final line
 16          
$coloured = "<code><span class=\"lineno\">&nbsp;".str_pad('1', $lnlength, '0', STR_PAD_LEFT)."&nbsp;</span>".substr($output, 6);    //insert line number of the first line
 17          
echo "<div class=\"phpbox\" id=\"altcodeblock".$box."\"><div class=\"phptoggle\" onclick=\"toggleDisplay(".$box.")\">Alt</div>\n".$coloured."\n</div>\n";
 18      }
 19  
?>
 20  

The CSS classes for the tags above are (The colours of the box are set in a different part of my CSS file, but are not important to this example.):

div.phpbox { line-height: 1.0; margin: 0px 10px 0px 10px; padding: 10px 10px 10px 10px; font-family: courier new, courier, freemono, monospace; font-size: 85%; }
div.phpaltouterbox { margin: 0px 0px 0px 0px; overflow: hidden; display: none; padding: 0px 10px 0px 10px; margin: 0px 0px 0px 0px; }
div.phpaltinnerbox { line-height: 1.0; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px; overflow: scroll; width: 99.75%; font-family: courier new, courier, freemono, monospace; font-size: 85%; }
div.phpaltouterbox pre { margin: 0px 0px 0px 0px; padding: 10px 10px 10px 10px; }
span.lineno { background-color: #cccccc; color: #000000; }
div.phptoggle { float: right; border: 1px solid #008800; background-color: #C4F2C6; padding: 2px 5px 2px 5px; cursor: pointer; }

The JavaScript required to show and hide the boxes is fairly self-explanitory:

<script type="text/javascript">
//	<![CDATA[
function toggleDisplay(idx)
{
	if (document.getElementById("codeblock"+idx).style.display == "block")
	{
		document.getElementById("codeblock"+idx).style.display = "none";
		document.getElementById("altcodeblock"+idx).style.display = "block";
	}
	else
	{
		document.getElementById("altcodeblock"+idx).style.display = "none";
		document.getElementById("codeblock"+idx).style.display = "block";
	}
}
//	]]>
</script>

Download the source file:

If you have any comments or suggestions please e-mail me at code@ my domain.

Bottom image