David Corbacho

Syntax Highlighting in Drupal

Syntax highlighting improves the readability of the code.

There are multiple ways to add this feature to Drupal, so there is no excuse to mistreat your readers. Let's go through some solutions for syntax highlighting, dividing them in server-side and Javascript solutions. See the conclusions at the end.

Using Text Formats (Filters) at server-side

Code Filter. (module for Drupal 6 & 7).

  • For PHP code. It will only highlight the code written between <?php ?> tags , and apply the PHP core function highlight_string() to it.
  • Applies automatically a <blockquote> wrapper, making impossible to use it for inline elements.
  • It's used in drupal.org, but the development of the module got frozen. Even removing a simple TRUE from the code it has been stuck in the issue queue for 2 years.
  • It's not easy skin-able, since it uses inline CSS. In the other hand, the style will survive through RSS feeds.
  • It has some limitations that drupal.org is suffering: Impossible to nest code tags and if you are highlighting big chunks of code, you need to change the pcre.backtrack_limit (I commented this solution in the original issue).
  • Few colors (compared to other solutions). For example numbers, names of functions, variables, etc... all are highlighted with same color. It's sad for being a specialized PHP code function.

GeSHi Filter (module for Drupal 6 & 7)

  • This module integrates the GeSHi library into Drupal, and offer many different options.
  • The GeSHi library can highlight 201 languages and it has different themes.
  • It has nice extra features aside syntax highlighting. For example adding links to the language documentation (PHP or even Drupal functions), adding line numbering, etc.

JavaScript based solutions, aka client-side:

Google prettify (Sandbox module for Drupal 7)

Update[ 6th of March 2013] Jesse commented that there is a second module that reached full-project status, called Prettify.

  • A JavaScript library by Google used by sites like stackoverflow and code.google.com.
  • There is only a sandbox project to integrate it with Drupal (some day it may be a first-class module: http://drupal.org/node/1235102 ).
  • How to use it? You need to add a special class prettyprint to the code container. Example <pre class="prettyprint">.
  • Heuristics used for autodetection of the language. Optionally you can specify the language using class names.
  • There is no automatic markdown integration (<pre><code> tags without class). Here is a cou-ple of JavaScript hacks to add the needed class.
  • Line-numbering implemented.

Syntax Highlighter (module for Drupal 6 and 7)

  • Based on the Alex Gorbatchev library SyntaxHighlighter.
  • It's really complete JavaScript library with tons of options, many of them also implemented in the module.
  • Different languages (called brushes), so you can choose what "brushes" to load, reducing the weight.
  • Autoloading: Dynamic loading of JavaScript files needed, depending on the languages used in the current page.
  • Well maintained.
    Cons:
  • Even it's supposed to be a non-intrusive library, the module is implemented in a way that will require a filter to work, and demanding you to wrap your code in {syntaxhighlighter SYNTAXHIGHLIGHTER-OPTIONS}.
  • Also you could use the following syntax: <pre class="brush:php;gutter:false">, but this won't work for Filtered HTML. And still, for Full HTML you will need to encode yourself some of the HTML entities... too much work.
  • This intrusive implementation is done in a way to avoid problems later when nesting code, etc. to make a clean separation of the code you want to highlight.
  • The disadvantage I see is that if at any moment you decide to stop using this module, you will have to remove from your content these special tags, or they will become visible. After some google-fu I found easily an ugly SyntaxHighlighter divorce. Screenshot.

Example:

Highlight.js (No module integration)

Highlight.js is a JavaScript library by Ivan Sagalaev that will highlight your code automatically in a non-intrusive way.

  • You can choose what languages to load (light weight).
  • Heuristics for auto-detection of language.
  • It works automatically on <pre><code> (It's the default Markdown output for code elements) and is the recomended way of formatting your code in HTML5
  • Well maintained. After several years, Ivan keeps improving this tool without bloating it.
  • Non-intrusive. If some day you stop using it, still the code is nicely wrapped in <pre><code>, so here syntax highlighting is a extra feature and not something you are married to.
  • In case you need, you could add class names recommended in HTML5: language-html, language-php
  • You can select what languages to download from the library, so it will result in a small size (in my case 9 languages, 14 Kb)
  • Heuristics: Autodetection of the code language used.
  • Optionally CDN provided.

Cons:
* Not line numbering. I don't need it, but others could found this a minus point. The author stated that he prefers a not-bloated lightweight library.

(This is not an image as previously)

/**
 * The default group for module JavaScript code added to the page.
 */
define('JS_DEFAULT', 0);

function drupal_js_defaults($data = NULL) {
  return array(
    'type' => 'file',
    'group' => JS_DEFAULT,
    'every_page' => FALSE,
    'weight' => 0,
    'scope' => 'header',
    'cache' => TRUE,
    'defer' => FALSE,
    'preprocess' => TRUE,
    'version' => NULL,
    'data' => $data,
  );
}

Conclusions

For a server-side solution I will choose GeSHi filter, or Code Filter if you don't care about its limitations. If you use Markdown, or you want something simple that works out of the box without messing up Filters, use Highlight.js adding it manually. Also Google Prettify is a simple and robust solution. Finally if you want cool extra options and a ready-made Drupal module, use the excellent Syntax Highlighter, but you will be married to it forever.

For a fast-test in your site of the Highlight.js library, add in the bottom of your page.tpl.php these 2 lines of code to see if works for you. Only for test. There are better ways to add JavaScript to your Drupal site ;)

<script src="http://yandex.st/highlightjs/6.0/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>

Update 2013.

Pedro Cambra points out that there is already a Highlight.js module. Grab it. Also there is a new syntax highlight library Prism.js that was not analyzed in this article. I like it a lot, and it has a module too. Check it out.