Matt Coneybeare


How to Use CodeRay to Format Code

| Comments

When I decided I wanted to start my CodeBlog, I knew I would be showing a lot of code on my page and I wanted a way to make it nice and pretty looking. I looked at the Syntax gem, even tried it out, but I was unimpressed. I decided to go with CodeRay instead because of its easy setup, multiple language support and it is still being enhanced with more language support.
First you want to install the gem
sudo gem install coderay
Next, you want to add the css to your display.css file. There might be an easier way to get this but I found it by going into the gem directory and running a simple command:
cd /opt/local/lib/ruby/gems/1.8/gems/coderay-
The gem directory might be different for you. Now you just have to take the text you want and format in the controller. I did this by sending text from a form into the controller with certain tags to mark the sections I want formatted. In the form I would type something like the following:
This text won't be formatted
[ code=ruby ] @this.text = (will_be) ? formatted_as : nil unless code=ruby [ /code ]
[ code=c ] printf("This text will be formatted as %s", c); [ /code ]
[ code=html ] <div>This text will be <b>formatted</b> as <i>html</i> [ /code ]
In the example above the [ code=xxx ] tags and the [ /code ] tags don’t have spaces. I had to add those so my own controller wouldn’t pick up the code and try to format it. Here is what it looks like formatted:
This text won’t be formatted
@this.text = (will_be) ? formatted_as : nil unless code=ruby
printf("This text will be formatted as %s", c);
<div>This text will be <b>formatted</b> as <i>html</i>
Next, I have my controller method “preview” call a special function I have in application.rb and pass the text from the form.
def preview
  @post = format_post_content([:post]))
Inside format_post_content I do a lot to manipulate the content
def format_post_content(post)
  html = post.content.blank? ? "" : post.content.clone
  while match = html.match(/\[code=(.+?)\](.+?)\[\/code\]/m)
    m2 = Regexp.escape(match[2])
  post.content_html = html
  return post
It looks complicated but it is actually pretty simple, let me explain:
  • Line 2: Get a clone of the content because I am going to store both the original content and the formatted
  • Line 3: Search for anything with a code tag, get the format and content between the tags
  • Line 4: Escape the code between the code tags because I might have [ ] ( ) | ? or any other symbol that might mess up the regexp
  • Line 5: Substitute the text (including the code tags) that I found in line 3 with…
  • Line 6: … the CodeRay formated version, formatted in…
  • Line 7: … the format specified by [ code=XXX ]. Then I get the html and number it.
Lines 4-7 are wrapped in a while loop that will format all instances of code tags. It took me a while to figure out that I also needed the “m” after each regular expression to keep track of which one we are working with, as well as the (.*?) which makes the searched text as short as possible (meaning it won’t cross-over to the next code tag). It looks a little confusing on lines 5,6, and 7, so here is an example call of the ease of CodeRay on one line:
CodeRay.scan(@post.content, :ruby).html.numerize
That’s it! After my special parsing, it only took 1 line to translate the code into a bunch of spans for the css! The way I implemented it in my function, I can use multiple code fields with multiple languages (like this post) in a simple and easy way. It is also a cinch to edit because I store both the content and the content_html, and editing the stuff in [ code=xxx ] tags is much easier than editing div’s and span’s. If you don’t like the way the code looks out of the box, you can edit the css to be any color/style you wish making CodeRay totally customizable.
Now I just have to tweak the colors to more to my liking…


My name is Matt Coneybeare, I design and develop for the web, iOS (iPhone, iPad and iPod Touch), and MacOS out of New York City. In 2008 I started a software company called Urban Apps that has made some pretty popular apps such as Ambiance and Hourly News. In 2019, I joined the team at Ticket Evolution as a Senior Software Engineer. My current Stack Overflow reputation is about 27k.

I was a Rockstar a decade ago, but then went back to school and collected a Bachelor's Degree in Computer Science from U.C. Berkeley and a MBA from Quantic. Now I am settled down with my beautiful wife Di and our dog Hamachi. When not at my desk, I love exploring New York City as a Yelp Elite, or training for marathons.

Contact information

Matt Coneybeare