formatting code for blog

One of the issues that vexed me for a while when writing this blog was how to format extracts of code when displayed in my posts on this site.

I wanted a formatting system that could be used for a variety of different languages (c++, visual basic, css, php etc) and could be expanded to include new languages such as the code used in programming the arduino – the chip which controls the capeMirror (a language which is based on ‘wiring’ and is a bit like c++). The code formatter also had to be versatile enough to have (and not have) line numbers, different starting line numbers, highlighted keywords etc. Oh, and it had to be simple to use.

The solution I stumbled across in the end was Alex Gorbatchev’s excellent ‘syntax highlighter’.

Having found the right tool, I just had to implement it into WordPress. At this point, I need to acknowledge the work of various coders – matt, Viper007Bond, mdawaffe, FredWu all of whom created a syntax highlighter plus plugin for WordPress whichimplements version 2 of Gorbatchev’s syntax highlighter. However, while the plugin was super easy to use I found that it lost some of the original’s functionality – for example, you couldn’t turn the line numbers off for just one code extract, you had to either turn them on or off for the whole site.

So, necessity being the mother of all invention, I decided to have a go myself. The resulting “plugin” (it’s pretty simple so I think that’s putting it a bit high) is operating on this site.

The method I used divides into the following parts:

1. The main plug-in which needs to be downloaded from the link above. (This is basically a folder which includes all the core files).

2. The php file that I wrote (or amended from the original). If you click here the file will be displayed in a ‘wide screen’ pop up window. You can see that compared to the original, the only tricky bit (which was necessary for the arduino code) was to make sure that the characters ‘<‘ and ‘>’ are replaced before any post is posted within WordPress – this is found in two new functions: function CE_check_for_pre($content) and function CE_find_matches($content).

3. As the file shows, there are a changes that need to ne made to any page that uses this plug-in. The plug-in makes the necessary changes itself, but just as an example the amended page template will look like this pop-up. PS: Please see amends below.

4. Having done that, all that needs to be done to insert code within a post is to include the code within tags like below (you can see options like ‘ruler on/off’ or ‘gutter on/off’ or highlight certain lines):

<pre class="brush: css; gutter: false; highlight: [7]">

Between the tags above and below, the code then goes in here.
The important bit is that the 'brush' defined in the tag above
refers to the appropriate language.
You can then use various settings to remove the line numbers
or highlight particular lines.

</pre>

 

Arduino code

So then, I wanted to create a ‘brush’ for the Arduino code – in other words I needed to define the necessary keywords that are used in the Arduino programming environment.

The ‘brush’ started as an identical copy of the ‘c++’ brush to which I added the necessary Arduino functions. I don’t pretend to have added all of them, but it’s easy to include more as or when it’s necessary. The ‘brushDuino’ (sorry) file looks like this pop-up.

Using it, the Arduino code looks like this:

/*
* Blink
*
* The basic Arduino example. Turns on an LED on for one second,
* then off for one second, and so on... We use pin 13 because,
* depending on your Arduino board, it has either a built-in LED
* or a built-in resistor so that you need only an LED.
*
* http://www.arduino.cc/en/Tutorial/Blink
*/

int ledPin = 13; // LED connected to digital pin 13

void setup() // run once, when the sketch starts
{
pinMode(ledPin, OUTPUT); // sets the digital pin as output
}

void loop() // run over and over again
{
digitalWrite(ledPin, HIGH); // sets the LED on
delay(1000); // waits for a second
digitalWrite(ledPin, LOW); // sets the LED off
delay(1000); // waits for a second
}

Enjoy.

Ben

Post-script 1

In trying to speed up this site, I made a couple of amends to this plug-in. Basically, I wanted to load only those scripts that would actually be used on a page. So the script now runs just before the output of any post (and not in the page header) as I can then read each post’s tags. Only posts with the tag ‘code’ will include the necessary foundational scripts, and then only those codes which are listed as tags will be run (eg a post with tags ‘code’, ‘arduino’ and ‘visual basic’ will run the necessary scripts for ‘visual basic’ and ‘arduino’ only).
I also took off all scripts from the front-page and any gallery pages. Again, to speed things up.

So, the new ‘hook’ looks like this:

// Register the function above with the wp_head 'hook' in WordPress
//add_action('wp_head', 'CE_SH_Header', 1000);
add_action('loop_start', 'CE_SH_Header', 1000);
add_filter( 'content_save_pre', 'CE_check_for_pre', 1 );

The full amended version (with conditional statements) is this:

<?php
/*
Plugin Name: Cape Ealing Syntax Highlighter
Plugin URI: https://capeealing.com/2009/03/formatting-code-blog/
Description: This plugin implements Alex Gorbatchev's Syntax Highlighter into WordPress.
Author: Ben
Version: 1.0
Author URI: https://capeealing.com/
*/

function CE_check_for_pre($content){

// check to see if there's any code for formatting
if (stristr($content,'<pre class=' )){

	$matches1 = CE_find_matches($content);

	$find_these = array('<', '>');
	$replace_with = array('<', '>');

	foreach ($matches1 as $match) {
	     $content = str_replace( $match[1], str_replace($find_these, $replace_with, $match[1]), $content );
	}
}
return $content;
}

function CE_find_matches($content){

		$regex = '#\<pre[^>]*>(.+?)\<\/pre\>#s';
		preg_match_all( $regex, $content, $matches, PREG_SET_ORDER );
		return $matches;
}

function CE_SH_Header()  {

// Only add if not the front page or a 'gallery' category
// There's no code on either page and they are big pages already
if (!is_front_page() && !in_category('gallery')){

if (has_tag('code')){
// Add the necessary information to the header file
echo '<!-- SyntaxHighlighter Info -->';
echo '	<link type="text/css" rel="stylesheet" href="' . get_bloginfo('wpurl') .'/wp-content/plugins/ce_syntaxhighlighter/styles/shCore.css"></link>' . "\n";
echo '	<link type="text/css" rel="stylesheet" href="' . get_bloginfo('wpurl') .'/wp-content/plugins/ce_syntaxhighlighter/styles/shThemeDefault.css"></link>' . "\n";
echo '  <script type="text/javascript" src="' . get_bloginfo('wpurl') .'/wp-content/plugins/ce_syntaxhighlighter/scripts/shCore.js"></script>' . "\n";

if (has_tag('arduino')){
echo '  <script type="text/javascript" src="' . get_bloginfo('wpurl') .'/wp-content/plugins/ce_syntaxhighlighter/scripts/shBrushDuino.js"></script>' . "\n";
}
if (has_tag('cpp')){
echo '  <script type="text/javascript" src="' . get_bloginfo('wpurl') .'/wp-content/plugins/ce_syntaxhighlighter/scripts/shBrushCpp.js"></script>' . "\n";
}
if (has_tag('css')){
echo '  <script type="text/javascript" src="' . get_bloginfo('wpurl') .'/wp-content/plugins/ce_syntaxhighlighter/scripts/shBrushCss.js"></script>' . "\n";
}
if (has_tag('javascript')){
echo '  <script type="text/javascript" src="' . get_bloginfo('wpurl') .'/wp-content/plugins/ce_syntaxhighlighter/scripts/shBrushJScript.js"></script>' . "\n";
}
if (has_tag('php')){
echo '  <script type="text/javascript" src="' . get_bloginfo('wpurl') .'/wp-content/plugins/ce_syntaxhighlighter/scripts/shBrushPhp.js"></script>' . "\n";
}
if (has_tag('text')){
echo '  <script type="text/javascript" src="' . get_bloginfo('wpurl') .'/wp-content/plugins/ce_syntaxhighlighter/scripts/shBrushPlain.js"></script>' . "\n";
}
if (has_tag('visual basic')){
echo '  <script type="text/javascript" src="' . get_bloginfo('wpurl') .'/wp-content/plugins/ce_syntaxhighlighter/scripts/shBrushVb.js"></script>' . "\n";
}
if (has_tag('html')){
echo '  <script type="text/javascript" src="' . get_bloginfo('wpurl') .'/wp-content/plugins/ce_syntaxhighlighter/scripts/shBrushXml.js"></script>' . "\n";
}
echo '  <script type="text/javascript">SyntaxHighlighter.all();</script>' . "\n";

}

}
}

/*
Register the function above with the wp_head 'hook' in WordPress
*/
//add_action('wp_head', 'CE_SH_Header', 1000);
add_action('loop_start', 'CE_SH_Header', 1000);
add_filter( 'content_save_pre', 'CE_check_for_pre', 1 );
?>


Post-script 2

After a bit, I found that some of the code snippets were getting seriously long. To try and get a uniform look to the site, I added the line “max-height: 450px;” to the shCore.css.

I also made a few other amends to the shCore.css.

In the meantime, the new Syntax Highlighter v2.1.364 had been released.

I played around with that and this was my final shCore.css file:

/**
 * SyntaxHighlighter
 * http://alexgorbatchev.com/
 *
 * SyntaxHighlighter is donationware. If you are using it, please donate.
 * http://alexgorbatchev.com/wiki/SyntaxHighlighter:Donate
 *
 * @version
 * 2.1.364 (October 15 2009)
 * 
 * @copyright
 * Copyright (C) 2004-2009 Alex Gorbatchev.
 *
 * @license
 * This file is part of SyntaxHighlighter.
 * 
 * SyntaxHighlighter is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * SyntaxHighlighter is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with SyntaxHighlighter.  If not, see .
 */
.syntaxhighlighter,
.syntaxhighlighter div,
.syntaxhighlighter code,
.syntaxhighlighter table,
.syntaxhighlighter table td,
.syntaxhighlighter table tr,
.syntaxhighlighter table tbody
{
	margin: 0 !important;
	padding: 0 !important;
	border: 0 !important;
	outline: 0 !important;
	background: none !important;
	text-align: left !important;
	float: none !important;
	vertical-align: baseline !important;
	position: static !important;
	left: auto !important;
	top: auto !important;
	right: auto !important;
	bottom: auto !important;
	height: auto !important;
	width: auto !important;
	line-height: 1.1em !important;
	font-family: "Consolas", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace !important;
	font-weight: normal !important;
	font-style: normal !important;
/*	font-size: 1em !important; */
	font-size: 10pt !important; 
	min-height: inherit !important; /* For IE8, FF & WebKit */
	min-height: auto !important; /* For IE7 */
        max-height: 450px !important; 
}

.syntaxhighlighter
{
        clear:both;
	width: 99% !important; /* 99% fixes IE8 horizontal scrollbar */
        max-height: 450px !important;
	margin: 1em 0 1em 0 !important;
/*	padding: 1px !important; /* adds a little border on top and bottom */
        padding-left: 0px !important;
        padding-right: 0px !important;
        padding-top:5px !important;
        padding-bottom:5px !important;
	position: relative !important; 
	overflow-x: hidden !important;
	overflow-y: auto !important;
}

.syntaxhighlighter .bold 
{
	font-weight: bold !important;
}

.syntaxhighlighter .italic 
{
	font-style: italic !important;
}

.syntaxhighlighter .line
{
}

.syntaxhighlighter .no-wrap .line .content
{
	white-space: pre !important;
}

.syntaxhighlighter .line table 
{
	border-collapse: collapse !important;
}

.syntaxhighlighter .line td
{
	vertical-align: top !important;
}

.syntaxhighlighter .line .number
{
	width: 3em !important;
}

.syntaxhighlighter .line .number code
{
	width: 2.7em !important;
	padding-right: .3em !important;
	text-align: right !important;
	display: block !important;
}

.syntaxhighlighter .line .content
{
	padding-left: .5em !important;
}

.syntaxhighlighter .line .spaces
{
}

/* Disable border and margin on the lines when no gutter option is set */
.syntaxhighlighter.nogutter .line .content
{
	border-left: none !important;
}

.syntaxhighlighter .bar
{
	display: none !important;
}

.syntaxhighlighter .bar.show 
{
	display: block !important;
}

.syntaxhighlighter.collapsed .bar
{
	display: block !important;
}

/* Adjust some properties when collapsed */

.syntaxhighlighter.collapsed .lines
{
	display: none !important;
}

.syntaxhighlighter .lines.no-wrap
{
	overflow: auto !important;
	overflow-y: auto !important;
}

/* Styles for the toolbar */

.syntaxhighlighter .toolbar
{
	position: absolute !important;
	right: 0px !important;
	top: 0px !important; 
	font-size: 1px !important;
	padding: 8px 8px 8px 0 !important; /* in px because images don't scale with ems */
}

.syntaxhighlighter.collapsed .toolbar
{
	font-size: 80% !important; 
	padding: .2em 0 .5em .5em !important;
	position: absolute !important;
}

.syntaxhighlighter .toolbar a.item,
.syntaxhighlighter .toolbar .item
{
	display: block !important;
	float: left !important;
	margin-left: 8px !important;
	background-repeat: no-repeat !important;
	overflow: hidden !important;
	text-indent: -5000px !important;
}

.syntaxhighlighter.collapsed .toolbar .item
{
	display: none !important;
}

.syntaxhighlighter.collapsed .toolbar .item.expandSource
{
	background-image: url(magnifier.png) !important;
	display: inline !important;
	text-indent: 0 !important;
	width: auto !important;
	float: none !important;
	height: 16px !important;
	padding-left: 20px !important;
}

.syntaxhighlighter .toolbar .item.viewSource
{
	background-image: url(page_white_code.png) !important;
}

.syntaxhighlighter .toolbar .item.printSource
{
	background-image: url(printer.png) !important;
}

.syntaxhighlighter .toolbar .item.copyToClipboard
{
	text-indent: 0 !important;
	background: none !important;
	overflow: visible !important;
}

.syntaxhighlighter .toolbar .item.about
{
	background-image: url(help.png) !important;
}

/** 
 * Print view.
 * Colors are based on the default theme without background.
 */

.syntaxhighlighter.printing,
.syntaxhighlighter.printing .line.alt1 .content,
.syntaxhighlighter.printing .line.alt2 .content,
.syntaxhighlighter.printing .line.highlighted .number,
.syntaxhighlighter.printing .line.highlighted.alt1 .content,
.syntaxhighlighter.printing .line.highlighted.alt2 .content,
{
	background: none !important;
}

/* Gutter line numbers */
.syntaxhighlighter.printing .line .number
{
	color: #bbb !important;
}

/* Add border to the lines */
.syntaxhighlighter.printing .line .content
{
	color: #000 !important;
}

/* Toolbar when visible */
.syntaxhighlighter.printing .toolbar
{
	display: none !important;
}

.syntaxhighlighter.printing a
{
	text-decoration: none !important;
}

.syntaxhighlighter.printing .plain,
.syntaxhighlighter.printing .plain a
{ 
	color: #000 !important;
}

.syntaxhighlighter.printing .comments,
.syntaxhighlighter.printing .comments a
{ 
	color: #008200 !important;
}

.syntaxhighlighter.printing .string,
.syntaxhighlighter.printing .string a
{
	color: blue !important; 
}

.syntaxhighlighter.printing .keyword
{ 
	color: #069 !important; 
	font-weight: bold !important; 
}

.syntaxhighlighter.printing .preprocessor 
{ 
	color: gray !important; 
}

.syntaxhighlighter.printing .variable 
{ 
	color: #a70 !important; 
}

.syntaxhighlighter.printing .value
{ 
	color: #090 !important; 
}

.syntaxhighlighter.printing .functions
{ 
	color: #ff1493 !important; 
}

.syntaxhighlighter.printing .constants
{ 
	color: #0066CC !important; 
}

.syntaxhighlighter.printing .script
{
	font-weight: bold !important;
}

.syntaxhighlighter.printing .color1,
.syntaxhighlighter.printing .color1 a
{ 
	color: #808080 !important; 
}

.syntaxhighlighter.printing .color2,
.syntaxhighlighter.printing .color2 a
{ 
	color: #ff1493 !important; 
}

.syntaxhighlighter.printing .color3,
.syntaxhighlighter.printing .color3 a
{ 
	color: red !important; 
}

Ben

post a comment...

you must be logged in to post a comment.