If you are like me you are easily allured by any type of programming eye candy and enjoy syntax highlighting a lot. My natural choices for stitching highlighting support to this wannabe blog were limited to these:

The Syntax gem was crossed out of this list as it provides very limited support for language schemes – Ruby only. It ain’t no good for me as I am all about using any effective tool at hand to get the job done – C++, bash, Perl, Python, C#, NSE and probably some others.

Although SyntaxHighligher seemed very yummy any sexily pretty it’s a bit like a duct-tape having other solutions at hand. It may easily be another interesting thing to try out here.

Ultraviolet is incredible. The overall list of supported syntax schemes tops 50. It is capable of using themes from TextMate (which by itself makes me drool pretty easily). And then there is a very handy tm_syntax_highlighting plugin to simplify working with the gem even further.

Alas… it pulls in a number of dependencies among which the ominous Oniguruma library. Compiling it is relatively easy and is limited to the usuals configure/make/make-install and you can find instructions here.

All would be good or great but the impenetrable obstacle I am currently struggling to overcome with Dreamhost and Phusion Passenger. It seems that Passenger is for some reason unable to pick up any additional library paths through setting them in environment – so far I only tried setting LD_LIBRARY_PATH via ENV in environment.rb which fails in solving this. This leaves me in a very awkward state:

libonig.so.2: cannot open shared object file: No such file or directory - /home/user/.gems/gems/oniguruma-1.1.0/lib/oregexp.so

This probably has something to do with Passenger’s configuration at DreamHost and maybe there is a way to fix this but so far it does not seem to work out well. Ryan Heath tried something similar here with similar results and switched back to using Syntax.

Oh well. So this leaves me biting my elbows. But wait – there is CodeRay and it is actually not that bad. The set of supported language schemes is definitely quite limited. The fact that Ryan Bates of Railscasts uses it got me enthusiastic and excited in no time. I gave CodeRay a try.

The solution I have for now is quite basic – I use RedCloth to enable textile in all the content in my blog so I simply want to plug the highlighting into my textilize processing. The code below is pretty self-explanatory.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# in redclothext.rb
require 'coderay'

module RedClothExt
  include WhiteListHelper
  def syntax(text)
    text.gsub!(/<pre(\s*lang\=["']?(\w+)["']?[^>]*)?>(.*?)<\/pre>/m) do
      code = $3.nil? ? $2 : $3
      lang = $2 unless $3.nil?
      html = "<notextile><div class='CodeRay'>" + 
             CodeRay.scan(code, lang).html.numerize.div + 
             "</div></notextile>"
    end
  end
  def whiten(text)
    white_list(text)
  end
end

RedCloth.send(:include, RedClothExt)

Few notes here. The regular expression I have concocted here allows having code snippets embraced in pre as well as having them start with pre class="language-of-choice". This is all to allow having some minimal colorization for unsupported languages.

I am using RedCloth 4.0.3 which I believe has some changes in terms of how extensions should be implemented – I looked in the tests folder of the gem to grasp some basic understanding.

Now in the application helper I have all the RedCloth processing goodness chained in the following sequence – texile, whiten, then syntax:

1
2
3
4
5
6
# in appplication_helper.rb
module ApplicationHelper
  def secure_textilize(text)
    RedCloth.new(text).to_html(:textile, :whiten, :syntax)
  end
end

You may have noticed I am using the white_list plugin here. The reason the syntax method is after sanitize in this sequence – white_list would have obliterated the minimal JavaScript created by CodeRay. The code generated there is for the purpose of toggling the line numbers.

Regarding the CSS – it’s a shameless mix of the one from Railscasts with some colors from UltraViolet’s sunburst.css for brighter glowing colors.

That’s all for now… Hope this is useful for someone. There may be other better solutions – let me know!