Redcarpet 2.3.0 now available!

Robin, Vicent ,and I are happy to announce the release of Redcarpet 2.3.0. Since the last release, we’ve made a lot of bug fixes and closed many issues on Github. Big thanks to all the contributors for the numerous pull requests we have merged and for issues reported.

New features

Underline support

We can now pass a new option to the Redcarpet::Markdown object: :underline. It allows you to parse underscored emphasis as underlines. For example, the code

markdown =, :underline => true)

renders the following markdown

This is *italic* and this is _underline_ when enabled


This is italic and this is underline when enabled

Google-code-prettify support

Passing the :prettify option to a renderer adds a prettyprint class to your code blocks in order to make it work with google-code-prettify.

Org-table like syntax support

Redcarpet now supports + (a plus sign) as line intersections instead of pipes. It can be a pain to translate tables from other markup (if you work with org mode for instance):

| Foo      | Bar            |
| A column | A nice content |

Disable indented code blocks

This version ships with a new options that allows you to disable indented code blocks. You just need to pass the :disable_indented_code_blocks to a new Redcarpet::Markdown object and there you go!

Bug fixes

We’ve made several bug fixes and cleaned up some pieces of code. The main ones are:

  • Add a redcarpet_ prefix to some functions to prevent segmentation faults with libraries which share the same function names, such as older versions of ruby-prof.
  • Mark all symbols as hidden to avoid conflicts with other gems (such as houdini)

There are other changes, of course. Please see the changelog for further information.

Pair Programming with Katrina Owen

On Thursday, April 25th, I was fortunate enough to be able to spend a couple of hours pairing with Katrina Owen on a refactoring for Tracks. Here’s a brief retrospective on that session.

I’ve read various places online that pair programming is more draining mentally than when you’re just working by yourself. I didn’t spend the whole day pairing but that certainly wasn’t the case here. I cannot say enough good things about the session. I haven’t had that much fun coding on something in a long time and I’m so so happy with how the code that we were working on turned out. I also left that session with a ton of new energy for crafting software.

This was my first remote pairing session. Here are some of the things I liked about it:

  • I had the box set up before hand. Vim, shell, tmux (mostly), the code we were going to work on, all done before the pairing session started.
  • I picked something small to work on. All we did as part of this session was extract a single method.

The things I didn’t like:

  • The box was slow. We were only running two tests out of the test suite. They took 20 seconds to run. Normally, I spoil myself on a Retina Macbook Pro which takes 20 seconds to run the whole test suite. We spent a ton of time running the tests.
  • I had more planned that we didn’t get to. Now, this isn’t really a bad thing, I was just hoping that it wouldn’t take as long as it did to extract that method.

And some stuff I learned:

  • If you’re going to extract a method and want to see what will be affected by your method extraction, raise an exception at the beginning of the method and run your full test suite. That will catch all the places the method is called in your tests, which you can use for the next step
  • Take the information from the previous step and create a rake task to only run the tests that are affected by the code you’re changing. Then set up a shortcut in your editor so you can run thoses tests as often as you need to.
  • The faster the test suite, the more fun you’ll have.

To sum it all up, the more you pair with others, the more fun you’ll have coding, the more you’ll learn, and the better your code will be. I simply cannot recommend it enough. Thanks to Katrina for taking some time out of her busy schedule for a pairing session!

Sit Back and Listen. You'll Learn if You Pay Attention.

When was the last time you just sat back and listened to the world that’s going on around you? An hour? A day? A week?

I was listening to an episode of the Ruby Rogues podcast the other day while I was driving home from work. While I was listening, I learned several things about the different people that were on the podcast that I didn’t know before. Then it dawned on me that I’ve been purposely doing this sort of accidental learning for years. I had just never fully realized it until that moment.

While a lot of developers like to slap on some headphones and jam to their favorite bands, I tend to leave my headphones off, just in case I might pick up on something that I hadn’t learned before.

So, one day, just for a little bit, take off the headphones. Sit back, listen to the things going on around you. You never know what you’ll pick up on that you might have missed out on before.

Updates to rack-jekyll are coming soon!

Adão Raul’s rack-jekyll gem is a great piece of Rack middleware to serve out Jekyll sites using any Rack compatible app server.

Sadly, rack-jekyll on RubyGems is seriously outdated. Prior to about a week ago, the master branch on GitHub was using Jekyll 0.11, which is few months out of date now.

Fortunately, the pull requests I’ve submitted to update rack-jekyll to Jekyll 0.12 and to update the other gems that rack-jekyll uses have been merged into master. I’ve also been given push access to the repo so that I can make sure the Jekyll support stays up to date as possible.

I’ve also sent an email asking for a new release, and offering to help push it out to RubyGems if Adão so chooses to have me do that. Hopefully I’ll hear back soon and we can get a much needed update to rack-jekyll done!

Update: rack-jekyll 0.4.0 is now out!

Using twitter-bootstrap-rails without Bundler.require

Myron Marston recently wrote a post recommending the removal of Bundler.require. Go read his post. Go ahead. I’ll wait.

I didn’t find anybody on Google with my same problem, so I’m documenting it here for posterity. (And to partly remind my future self how much of a dumb Rails noob I was when I wrote this post).

The Problem

Removing Bundler.require from config/application.rb explicitly disables part of Rails’ autoloading mechanism. Which means your asset gems don’t get autoloaded, which means you get all sorts of weird errors in your application log, like so:

ActionView::Template::Error ('twitter/bootstrap/bootstrap.less'
wasn't found. (in

And then you pull your hair out googling, and searching on stack overflow for the solution, because surely, in the 2 months since Myron’s post was published, somebody has run into this, right? RIGHT? No, they haven’t, or they’re smarter than me and figured it out on their own.

What the hell do I do now?

I spent what I thought was an exorbitant amount of time trying to figure out why this wasn’t working, what was actually going on, and how to fix it.

The first clue is just before the conclusion of Myron’s post:

Many gems provide rake tasks. If the gem is no longer being loaded at environment boot time, these tasks may not be available. Ripple, for example, provides a handful of rake tasks. To make these tasks available in your application, you’ll need to add load “ripple/railties/ripple.rake” to your Rakefile, which is essentially what the rake_tasks block in Ripple’s railtie does.

The second clue came when I was looking in config/application.rb which is where the require statements for a bunch of railties live.

The solution

The solution is actually really simple. Add

require "less/rails/railstie"
require "twitter-bootstrap-rails"

to config/application.rb and suddenly the error about not behind able to find that bootstrap.less file I mentioned above just disappears.

But wait, there’s more!

I ended up getting a similar error with jQuery.

ActionView::Template::Error (couldn't find file 'jquery' (in

Ok, we’ve been here before. This is simple now. Add

require "jquery-rails"

to config/application.rb and now I am greeted by the empty view I put in place for my default route.