Skip to content

July 28, 2009

18

CSS SyntaxHighlighter 2.0: short tutorial on how to create your own syntax highlighter

by Joe Kuan

Introduction

This is a tutorial showing you how to create your own syntax highlighter using CSS SyntaxHighlighter 2.0. Before reading this tutorial you need to know regular expression pretty well. Secondly, you need to know the nature of your syntax constructs and use the already made highlighter scripts as references.

  • Is it a progamming language with keywords, functions, value? References: shBrushJava.js, shBrushCpp.js shBrushBash.js, etc.
  • Is it some kind of configuration file with name and value pairs? References: shBrushCss.js, shBrushXml.js
  • Is it some kind of output? References: shBrushDiff.js

The concept of SyntaxHighlighter

Let examine, shBrushBash.js, here is a trimmed version of the code

SyntaxHighlighter.brushes.Bash = function()
{
    var keywords =  'if fi then elif ....';
    var commands =  'alias apropos ....;
    this.regexList = [
        { regex: SyntaxHighlighter.regexLib.singleLinePerlComments,     css: 'comments' },      // one line comments
        { regex: SyntaxHighlighter.regexLib.doubleQuotedString,         css: 'string' },        // double quoted strings
        { regex: new RegExp(this.getKeywords(keywords), 'gm'),          css: 'keyword' },       // keywords
        { regex: new RegExp(this.getKeywords(commands), 'gm'),          css: 'functions' }      // commands
        ];
}
SyntaxHighlighter.brushes.Bash.prototype    = new SyntaxHighlighter.Highlighter();
SyntaxHighlighter.brushes.Bash.aliases      = ['bash', 'shell'];

SyntaxHighlighter uses the Template pattern for defining the common attributes. For instance, the Bash method adds another brush object in the SyntaxHighligher.brushes field. Inside this new brush object, it has the regexList which contains a list of syntax highlight rule objects which is composed of matching rule and the CSS property. The prototype field acts as a function object (functor) – Highlighter and it’s highlight function process the regexList field. So the SyntaxHighlighter.highlight function (which is called at the top level) finds the brush name called by the user and matches against all the brushes’ alias name. If there is a brush object matches the name, then calls the brush object’s Highlighter.highlight method.

The main concept of creating your own syntax highlighter is that you have to define your own pattern matching rules to what already defined in the CSS file. Note that you don’t have to cover all the definitions in the file, but the value of ‘css : ‘ defined in shBrushXXX.js must also exist in the CSS file. For example, in shThemeDefault.css, it is defined with the following names:

  • comments, keyword, string, preprocessor, variable, value, functions, constants, script, color1, color2, color3

Secondly, mapping strings to a CSS property can be achieved by specifying regular expression for certain string patterns or pre-defined a group of specific strings and use getKeyWords method to bind it. For instance, this.regexList = [ { regex: new RegExp(this.getKeywords(“Adam Bob Eve”), ‘gm’), css : ‘names’ } ].

In theory, you can add more CSS rules if you need to as long as you have crafted the conditions (regular expression/getKeywords) to associate with it.

Create my own SyntaxHighlighter

In my case, I need to syntax highlight our license file which has name and value pairs. Following is some of the content:

!  WARNING - Do not edit this file.  Doing so will invalidate the key!
!
ID                   : 5076
Version              : 2.0
Issuer               : frp
Customer             : iTrinegy
Sub Customer         : INE-LCD
Issue Date           : 23-Mar-2009
Start Date           : 23-Mar-2009
Expiry Date          : 22-Sep-2009
Grace Period         : 7
Node                 : 00:30:18:A3:E1:AD

! Product
!
Product Title        : Itheon Network Emulator
Product              : INE-X-X
Components           : Emulator

! Component Group Definitions
!
Component Definition :  Start
Emulator             : Netmon:Detector,arp=YES,config=YES,ethernet=YES-
                      ,graphdata=YES,hub=YES,interfaces=2,iplib=YES,ipv4=YES-
                      ,ipv6=YES,ipv6icmp=YES,ipv6igmp=YES,MaxSameProcesses=2-
                      ,nbcli=YES,nblib=YES,netemu=YES,procdump=YES,pseudo=YES-
                      ,udp=YES,Version=4
Component Definition : End
Checksum             : 2f79-cbf2-d1d0-091d-9ee6-7569-a3af-0108

The main syntax highlight will be

  • the separator for name and value pairs is the FIRST ‘:’ encounter (See the line Node and the Emulator)
  • comment is started with ‘!’ til the end of the line

As for the CSS rules, all I need is to map: comments, keyword and string. So the SyntaxHighlighter for the license file would be:

SyntaxHighlighter.brushes.iTrinegy_Lic = function()
{
    this.regexList = [
        { regex: /^!.*$/gm,    css: 'comments' }      // one line comments
        ,{ regex: /^[\w \t]*(?=:)/gm,       css: 'keyword' }      // keywords
        ,{ regex: /:(?=[ \t]+)/gm,       css: 'color2' }      // separator
        ,{ regex: /(?:[ \t]*)\S|,.*$/gm,       css: 'string' }      // string
        ];
};
SyntaxHighlighter.brushes.iTrinegy_Lic.prototype    = new SyntaxHighlighter.Highlighter();
SyntaxHighlighter.brushes.iTrinegy_Lic.aliases      = ['itrinegy_lic'];

For the comment, it is easy – simply match any line started with ‘!’ character. For the keywords, match any strings with space(s) followed by a ‘:’ character but excluding the ‘:’ from the matched string. For the separators, match the ‘:’ character followed by any space(s). Finally for the string rule, there are two conditions in the regular expression. First part matches any strings after the ‘:’ character, second part match any lines started with a comma til the end of the line.

Then in the php, simply display the content of the license file:

<textarea id=view_license class='brush: itrinegy_lic;toolbar: true'>
<?php
if (file_exists("/home/viewedge/key/appliance.key")) {
  $lic_content = file_get_contents("/home/viewedge/key/appliance.key");
  echo $lic_content;
}
?>
</textarea>

Following is the screen shot of the new syntax highlighting for the License file which does make the content a lot easier to read comparing to the plain display.
syntaxhighlighter of the license file

I work for iTrinegy and here are my other Syntax Highlighter blogs

Advertisements
18 Comments Post a comment
  1. Sep 23 2009

    Great post with a nice clean simple example and use-case.

    Before you start creating your own SyntaxHighlighter brush javascript file, you may want to have a look on my list of “all” available brushes: http://www.undermyhat.org/blog/2009/09/list-of-brushes-syntaxhighligher/

    Do you think I should include the brush you demonstrated here, or is it only used in legacy software? Might be a good starting point for some INI file highlighter (php.ini, old-style win.ini).

    (PS: I got “discarded” on an empty page , without the comment submitted, when I tried this through a logged in session, why’s that?)

    Reply
  2. Jette Nielsen
    Jan 1 2010

    I am posting a lot of command line stuff on my webpage. I am using the plain brush, since all I want is the line numbers and no syntax highlighting. But I need to be able to create bold text. Would it be possible to edit the javascript to make it translate [b]sometext[/b] to sometext

    Reply
    • Joe Kuan
      Jan 1 2010

      It should work as long as you got the regular expression right in the SyntaxHighlighter.brushes.Plain and value of css field also defined in the corresponding CSS file.

      Reply
  3. Jette Nielsen
    Jan 14 2010

    Thank you for answering… I finally got time to have I look at this again… I can figure out the regex, but I also need to remove the [b] codes afterwards. How do I manage this?

    Reply
  4. Jette Nielsen
    Feb 7 2010

    I need to be able to make any string bold (not special keywords, but literally ANY string). I have added this in shBrushPlain.js

    this.regexList = [
    { regex: /<strong>(.*)<\/strong>/gmi, css: ‘bold’}
    ];

    This will give me bold tekst, but the strong-tag is also visible to the reader, because the source looks like this:

    <strong>jobs</strong>

    How do I remove the strong-tag? I tried to replace it (inspired by shBrushBash.js) but I cant get it to replace _after_ the formatting is done.

    Reply
  5. Tal Galili
    Apr 21 2010

    Hi there,
    Is there an easy way to turn a Geshi brush to a syntax highlighter brush ?

    Thanks,
    Tal

    Reply
    • Joe Kuan
      Apr 21 2010

      Not that I know of. I think you have to do it manually because both tackle the syntax highlighting from very different angle. Syntax Highlighter is heavy regex matching with css rules, whereas the other one (I think) has a lot of predefined macros.

      Reply
  6. Tal Galili
    Apr 22 2010

    Hi Joe,
    Thanks for the update – I’ll see what I do then.

    Best,
    Tal

    Reply
  7. Feb 4 2011

    I’d also be interested in a way of make some part of the code bold for added emphasis. It would be great to have this feature available.

    Stefano R.

    Reply
  8. George
    Mar 22 2011

    Hello ,
    My code don’t work(no highlighting in browser):
    /* html file */

    test

        !  WARNING - Do not edit this file.  Doing so will invalidate the key!
    	!
    	ID                   : 5076
    	Version              : 2.0
    	Issuer               : fr
        Customer             : iTrinegy
    	Sub Customer         : INE-LCD
    	Issue Date           : 23-Mar-2009
    	Start Date           : 23-Mar-2009
    	Expiry Date          : 22-Sep-2009
        Grace Period         : 7
    	Node                 : 00:30:18:A3:E1:AD
    
    	! Product
    	!
    	Product Title        : Itheon Network Emulator
    	Product              : INE-X-X
    	Components           : Emulator
    
    	! Component Group Definitions
    	!
    	Component Definition :  Start
    	Emulator             : Netmon:Detector,arp=YES,config=YES,ethernet=YES-
    	                      ,graphdata=YES,hub=YES,interfaces=2,iplib=YES,ipv4=YES-
    	                      ,ipv6=YES,ipv6icmp=YES,ipv6igmp=YES,MaxSameProcesses=2-
    	                      ,nbcli=YES,nblib=YES,netemu=YES,procdump=YES,pseudo=YES-
    	                      ,udp=YES,Version=4
    	Component Definition : End
    	Checksum             : 2f79-cbf2-d1d0-091d-9ee6-7569-a3af-0108
        

    /* iTrinegy_Lic.js */

    ;(function()
    {
    // CommonJS
    typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null;

    function Brush()
    {

    this.regexList = [
    { regex: /^!.*$/gm, css: 'comments' } // one line comments
    ,{ regex: /^[\w \t]*(?=:)/gm, css: 'keyword' } // keywords
    ,{ regex: /:(?=[ \t]+)/gm, css: 'color2' } // separator
    ,{ regex: /(?:[ \t]*)\S|,.*$/gm, css: 'string' } // string
    ];
    }

    Brush.prototype = new SyntaxHighlighter.Highlighter();
    Brush.aliases = ['itrinegy_lic'];

    SyntaxHighlighter.brushes.iTrinegy_Lic = Brush;

    // CommonJS
    typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
    })();

    Please help

    Reply
  9. Aug 28 2012

    I am missing AspectJ syntax and want to create abrush for it. I do not know anything about JavaScript, but quite something about regex, so maybe I can manage. I have one question though: AspectJ is a superset of Java, so I would like to extend the existing Java brush without code duplication, just adding new keywords and some exceptions which should take precedence over inherited rules. Is there a concept like inheritance for SyntaxHighlighter brushes?

    Reply
    • Joe Kuan
      Sep 3 2012

      I am really sorry for the late reply, been insanely busy.

      I haven’t been using SyntaxHighlighter for a long time. Javascript does support inheritance through prototype property, however you may find the language a bit strange to start with because there is no class concept in the Javascript. Function itself is an object.

      As far as I can see, you should be able to extend from the Java brush, change the properties in the regexList and give the new name to the aliases. Give it a try, it shouldn’t be too much.

      There is another popular Javascript syntax highlighter – prettify, you may want to have a look at that as well.

      Thanks
      Joe

      Reply
  10. Sep 2 2014

    Great example with custom regular expressions. Your example helped me solve a problem writing my own custom brush regex.

    Reply

Trackbacks & Pingbacks

  1. All Syntax Highlighter brushes collected, described and downloadable | Under My Hat
  2. Donovan's Blog » FileMaker Syntax Highlighting

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Note: HTML is allowed. Your email address will never be published.

Subscribe to comments

%d bloggers like this: