10 August 2012

With a growing amount of example code on this site, it was time to install a syntax highlighter for blog posts. Given how precious time can be, I wanted to make sure that syntax highlighter could be activated quickly using the WYSIWYG within Drupal (I already used CKEditor). I started by installing the Syntax Highlighter Drupal module, which provides integration with the popular Syntax Highlighter tool.

Activating Syntax Highlighter

The basic Syntax Highlighter configuration was straightforward. The steps are well-documented on the module home page, and downloading the JS library separately was the only hassle. I used the autoloading configuration since I use a variety of different programming languages, and that made it so that inserting basic HTML markup would result in very nice syntax highlighting. Here is an example of what would be necessary:

<pre class="brush:jscript">
  document.alert('hello world!');
</pre>

Tip: When working within formatted text like this in CKEditor, hold down the shift key when pressing Enter so that you do not start a new paragraph and lose your <pre> styles.

The Limitation

By default, CKEditor includes a "Formatted" format, which allows you to easily insert a <pre>  tag. However, you are then required to view the source to add the special class attributes that Syntax Highlighter uses for configuration (see "Parameters"). While that is not very difficult, it unfortunately would require me to remember the parameters and search long posts to find the right markup. Really, I'm just lazy enough to want it to be a selection.

Configuring CKEditor to Show Code Style Options

Customizing CKEditor to show a Styles dropdown instead of a Formats dropdown is easy in theory using the tool directly. You would just customize the JS configuration files. However, layering the Drupal best practices on top of it, and suddenly we have more infrastructure to work with (or around). There is a long discussion of different methods people have used to customize their configuration and styles files. Each solution offered came with several people who had problems with it. So my solution might not work for you either... But it worked for me!

  1. As a basis, we'll assume you have the module installed, and the editor displaying. You should also be able to correctly identify which Editor Profile is being used.
  2. We'll also assume that you followed the Syntax Highlighter instructions correctly such that your Input Formats do not strip out the markup after saving a node.
  3. Copy ckeditor.config.js and ckeditor.styles.js to a new location (a custom module, a custom theme, the files directory, etc.)
  4. Edit the relevant Editor Profile:
    1. Expand the "Editor Appearance" fieldset
    2. Remove the "Formats" dropdown (optional)
    3. Add the "Styles" dropdown
    4. Expand the "Advanced options" fieldset
    5. Edit "Custom JavaScript Configuration" to include (leading slashes are important):
      config.customConfig = "/path/to/ckeditor.config.js";
      config.stylesCombo_stylesSet = "drupal:/path/to/ckeditor.styles.js";
  5. Customize your ckeditor.styles.js file. If you hid the Formats dropdown on your toolbar, I would suggest enabling the heading block styles.
  6. Clear your browser cache

Adding the Syntax Highlighter Styles

You can add styles that include classes, as long as you initialize them before the defaul (classless) element:

{ name : 'Code: CSS', element : 'pre', attributes : {'class' : 'brush:css'} },
{ name : 'Formatted', element : 'pre' },

By initializing them first, the style will appear correctly in the dropdown. If you initialize the classless style first, then the style would appear as "Formatted" when you edit.

You can add as many selectable styles as you like. Here is the list of brushes/classes that I started with on my site:

{ name : 'Code: JS', element : 'pre', attributes : {'class' : 'brush:jscript'} },
{ name : 'Code: XML', element : 'pre', attributes : {'class' : 'brush:xml'} },
{ name : 'Code: CSS', element : 'pre', attributes : {'class' : 'brush:css'} },
{ name : 'Code: PHP', element : 'pre', attributes : {'class' : 'brush:php'} },
{ name : 'Code: BASH', element : 'pre', attributes : {'class' : 'brush:bash'} },
{ name : 'Code: SQL', element : 'pre', attributes : {'class' : 'brush:sql'} },
{ name : 'Code: VB', element : 'pre', attributes : {'class' : 'brush:vb'} },
{ name : 'Formatted', element : 'pre' },


blog comments powered by Disqus