# Highlighting Haskell with SHJS

Posted on 14 October 2010 by Nicolas Wu

I like to have colourful syntax highlighting, since I find it makes it quicker to read code: a lot of the parsing in my head gets done by simply looking at the colour of some fragment of syntax, and that helps me get the gist of what’s going on quickly.

## SHJS

If you want to highlight code for your website, then you might consider using SHJS, a JavaScript program that does syntax highlighting on the client side.

SHJS takes its syntax rules from a GNU Src-Highlite file, and produces JavaScript that marks up your HTML with classes that can then be coloured by a CSS file. This means that any language supported by GNU source-highlight can get highlighted consistently on your website.

There are a number of basic classes that are highlighted by SHJS:

keyword    type        usertype
string     regexp      specialchar
comment    number      preproc
symbol     function    cbracket
predef_var predef_func classname
todo

The Haskell definition file supplied by default has the comment “Quick and dirty Haskell highlight rules for GNU Source-highlight and SHJS”, which doesn’t sound like good news to me. As a result, I’ve written my own haskell.lang file that’s a lot more comprehensive.

To demonstrate how SHJS highlights code, here are a few snippets, some of which come from Johan Tibell’s Haskell Style Guide.

Simple code:

> fibs :: [Int]
> fibs = fibs' + fibs''
>   where
>     fibs'  = 1 : fibs''
>     fibs'' = 0 : fibs

Data declarations:

> data Tree a = Branch a (Tree a) (Tree a)
>             | Leaf

Records:

> data Person = Person
>     { firstName :: String  -- ^ First name
>     , lastName  :: String  -- ^ Last name
>     , age       :: Int     -- ^ Age
>     } deriving (Eq, Show)

Some do notation:

> main :: IO ()
> main = do putStrLn "Hello World!"
>           return ()

A type signature:

> div :: Int -> Int -> Int

Language pragmas:

> {-# LANGUAGE pragma #-}
> id :: a -> a
> id x = x
> {-# INLINE id #-}

Class definitions:

> class Functor f where
>   fmap :: (a -> b) -> f a -> f b

Constants:

> True False 1 0x0010 3.1415 "A string!" 'A'

> -- None of the following symbols should be parsed as comments:
> --> <-- ->- --<-
> {- multiple
>    line
>    comments {- should allow nesting -}  -}

Hopefully the examples above should cover most of the cases you’ll be interested in, but here’s a summary of features of the script I wrote:

• Operators are supported (++, !, >>= and any other combination of legal operator characters)
• Special symbols are recognised (=>, <-, ->, ::, ..)
• Unicode support for →, ←, ∷, ‥,⇒, ∀, ∃ and others
• Support for qualified module functions (List.sort, etc)
• Support for qualified module types
• Support for literate code (using > and \begin{code} \end{code})
• Support for literate specifications (using < and \begin{spec} \end{spec})

## Setup

Setting up SHJS to work on your website should be really easy. You’ll probably need most of these files:

You should include the CSS file in the header of your HTML, and place the scripts at the end of the body, so that they are the last things to load on a page:

<html>
<link rel="stylesheet" type="text/css" href="$root/css/sh_style.min.css" /> ... </head> <body> ... <script type="text/javascript" src="$root/js/sh_main.min.js" > </script>
<script type="text/javascript" src="$root/js/sh_haskell.min.js" > </script> <script type="text/javascript" src="$root/js/sh_init.min.js" > </script>