Static syntax highlighter for WordPress

I was using highlight.js by Ivan Sagalaev for syntax highlighting in this blog. It is light weight JavaScript plugin with no external dependencies. It was doing good job, however I was more interested in static syntax highlighting using only CSS and no JavaScript involved. The reason was to reduce the page rendering as well as load time specially for mobile devices.


tl;dr;

Let us understand how syntax highlight done:

If you inspect the HTML of code highlighted by any syntax highlighter you will find that it is wrapping the syntax keywords through span with class and preserving the white-space through pre tags. For example, the highlight.js is making following HTML manipulation in content

Original Code:

<pre><code class="javascript">function helloWorld (){
    alert('Hello World');
}</code></pre>

Manipulated code by JavaScript in runtime:

<pre><code class="hljs JavaScript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">helloWorld</span><span class="hljs-params">()</span></span>{
    alert(<span class="hljs-string">'Hello World'</span>);
}</code></pre>

The above HTML snipped with xcode theme will display:

function helloWorld(){
alert('Hello World');
}

My initial approach

As we know that JavaScript plugin is making changes in code in runtime, the simple (but not easy) approach was to create a local HTML page with highlight.js plugin and write code in it, and then open this file in browser and copy the generated code through browser’s debugger panel.

Debugger view for Highlight.js

This approach had two flaws:

  1. I need to create a file and write all the code to be highlighted there and then copy+paste. This may be convenient on my home laptop but what if I’m writing blog through tablet device! Even on desktop, what if I’m using some public computer, then I need to setup highlight.js first and that could be become tedious.
  2. If I want to make changes in code later, then I have to go through entire process again

Final approach

Once initial approach was over ruled, the next step was to generate the required code through server-side, and in my case through PHP as I’m using WordPress CMS.

Before I started to write the php-port of the highlight.js I searched and found another superb php library highlight.php by Geert Bergman, a port of highlight.js to PHP. Now all I had to do was to integrate it with my WordPress theme.

I could have (and now I think should have) written it as a plugin, however as a lazy programmer I opted a hurried method :).

How I did it

I copied the Highlight folder from the github repository of highlight.php project to my WordPress theme and added following lines in function.php to create a WordPress shortcode:

// Load the Highlight class from 'Highlight' folder

require_once("Highlight/Autoloader.php");
spl_autoload_register("Highlight\\Autoloader::load");
$hl = new Highlight\Highlighter();

// Create a shortcode 'highlight'

// which will parse the content

// and generate highlighted code

function theme_highlighter( $atts, $content = "" ) {
global $hl;

if(isset($atts['lang'])){
$r = $hl-&gt;highlight($atts['lang'], $content);
}else{
$hl-&gt;setAutodetectLanguages(array("javascript", "html", "css", "php"));
$r = $hl-&gt;highlightAuto($content);
}

return '
<pre><code class="hljs">'.trim($r-&gt;value).'</code></pre>
';

}
add_shortcode( 'highlight', 'theme_highlighter' );

// Do not let wordPress to transform the quotes to smart quotes,

// apostrophes, dashes, ellipses, the trademark symbol,

// and the multiplication symbol for the content of shortcode

function shortcodes_to_exempt_from_wptexturize(){
$shortcodes[] = 'highlight';
return $shortcodes;

}
add_filter('no_texturize_shortcodes', 'shortcodes_to_exempt_from_wptexturize');

// Do not let WordPress change double line-breaks in the text into HTML paragraphs

remove_filter( 'the_content', 'wpautop' );
add_filter( 'the_content', 'wpautop' , 99 );
add_filter( 'the_content', 'shortcode_unautop', 100 );

// I have included the highlight.js theme in my template style.css

// but it can loaded separately like this:

wp_enqueue_style( 'highlight', get_template_directory_uri() . '/css/xcode.css' );

How to use it

[highlight lang="javascript"]
function helloWorld(){
    alert('Hello World');
}
[/highlight]

Leave a Reply

Your email address will not be published. Required fields are marked *