A Solution to the Syntax Highlighting Problem

Posted September 4, 2007

I have good news and bad news.

Bad news first. There is no pre-existing way of integrating syntax highlighting and RedCloth. Jeff Hardy and Evgeny suggested a few Javascript-based solutions, but I’d rather keep this server-side and Ruby-licious. So no luck there.

Now for the good news. It turns out to be really easy to hack something up that does just that. RedCloth is reasonably extensible, and for those cases where it’s not a little Patch Adams does the trick.

So my blog now has syntax highlighting. You can use it, too, in the comments. It works just like I mentioned before: a dollar sign followed by the name of the syntax to highlight. It can either come immediately before a block of code:

'Twas brillig, and the slithy toves
Did gyre and gimble in the wabe.

$ruby
  def jabberwock.burble
    jaws.bite!
    claws.catch!
  end

All mimsy were the borogoves,
And the mome raths outgrabe.

Or just at the top of the document, so it affects all blocks of code:

$ruby

He took his vorpal sword in hand:
Long time the manxome foe he sought --

  class VorpalSword < Sword
    def swing
      puts "snicker-snack!" 
      super
    end
  end

So rested he 'neath the Tumtum tree,
And stood a while in thought.

  boy.slay(jabberwock)
  boy.beamish = true
  Date.today.frabjous = true

And as in uffish thought he stood,
The Jabberwock, with eyes of flame,
Came whiffling through the tulgey wood

I decided to go with CodeRay rather than Syntax for a couple reasons. The main reason is that CodeRay just supports more syntaxes that are generally more useful. While I don’t anticipate needing Delphi highlighting anytime soon, C, Javascript, and XHTML could definitely come in handy.

Also, CodeRay has the added benefit of having the weight of Pastie behind it. This means that people are much more likely to make new syntaxes, especially since there are bounties out for some of them.

I imagine people have two questions at this point: what’s the syntax look like, and where’s the code? Well, I’d like to kill two birds with one stone and just paste in coderay.rb, but unfortunately RedCloth doesn’t play nice with pre tags in code (I’m pretty sure this isn’t brought on by my code).

Instead, I’ll pastie codecloth.rb and show off my old reclambda function:

Update: As I’ve found bugs with CodeCloth, I haven’t updated the pastie. If you want the latest version, get it from svn://nex-3.com/nex3/trunk/lib/codecloth.rb.

def reclambda
  lambda do |f|
    f.call(f)
  end.call(lambda do |f|
             lambda do |this|
               lambda do |*args|
                 yield(this, *args)
               end
             end.call(lambda { |x| f.call(f).call(x) })
           end)
end

Also, check out the new formatting for code blocks. That pale yellow was bothering me.

satta said October 31, 2007:

Looks like CodeCloth has problems when highlighting C code that contains preprocessor directives like #include, which are recognized as header formatting. Removing the ”#” results in no problems at all.

Nathan said October 31, 2007:

I’ve noticed that, as well. It’s actually RedCloth not recognizing it as a code block (so, not my fault :-D). It works if you wrap it with <pre> tags, though.

Anonymous said April 23, 2008:

Holy snap you crazy crazy man!

def whatever
  is_this_code? > @your_code
end
function hasLanguage(lang) {
  return lang in LANGUAGES;
}

Do you xnow that this isn’t code?

.question
  %h2 How do you do with HAML?
  %h1 Looks like coderay needs a new friend

Make your comments snazzy with Textile!