Pygmentizing your Rails app hosted on Heroku

July 28, 2012

This post was originally published in the Rambling Labs Blog on July 28, 2012.

Last week, I watched Ryan Bates’ Syntax Highlighting RailsCast and wanted to apply what I had just learned right away, using pygments.

As you might have noticed, the jQuery Rambling Slider homepage features the new syntax highlighting styling. I’ve spent great part of the day updating the blog posts to use this new syntax highlighting style, to stop relying on GitHub’s gists, but that’s another story.

Now, there are several ways to do this. There are a couple of gems out there, like the pygments.rb mentioned on the RailsCast, that are very helpful. I installed that gem locally and it worked like a charm, but when I tried to upload the changes to Heroku, the site was throwing the following error on the application startup:

Running: rake assets:precompile
rake aborted!
Could not open library '/usr/local/lib/libpython2.7.a': /usr/local/lib/libpython2.7.a: invalid ELF header
(in /tmp/build_12k2jikx5kgsi/app/assets/stylesheets/pygments.css.scss.erb)
Tasks: TOP => assets:precompile:primary
(See full trace by running task with --trace)

I submitted a support ticket to the Heroku guys, and they answered that pygments.rb simply doesn’t work on Heroku. Well, that sucks :(.

Fortunately, there are a couple of workarounds! You could use the pygmentize gem, or you could do what I did using the heroku-pygmentize service.

I added the following helper method to the application_helper.rb:

module ApplicationHelper
  def highlight_code(code, language)
    sha = Digest::SHA1.hexdigest code
    Rails.cache.fetch ['code', language, sha].join('-') do
      Net::HTTP.post_form(PYGMENTIZE_URL, lang: language, code: code).body.html_safe

As you can see, when the highlight_code method is called, an HTTP post request is sent and the result is cached in the application’s cache. Then, you can do something like this on a view:

= highlight_code "gem 'rambling-trie'", :ruby

That sorted it out!

Enjoy your syntax highligthing! :)