Syntax Highlighting Markdown in Rails

This post is to help you add syntax highlighting to your markdown in a rails app. I prefer to use [Redcarpet] for markdown processing, and [Rouge] for syntax highlighting. This is a complete ruby solution, I believe its the [fastest], and somewhat easy to implement.

1. Add the redcarpet Gem

Add the redcarpet gem.

# Gemfile

gem "redcarpet"

2. Create MarkdownParser Class

Create a MarkdownParser class to handle parsing our markdown.

# app/models/markdown_parser.rb

class MarkdownParser
  require "redcarpet"

  def initialize(markdown)
    @markdown = markdown
  end

  def markdown_to_html
    processor.render(@markdown).html_safe
  end

  def processor
    Redcarpet::Markdown.new(renderer, extensions = {})
  end

  def renderer
    Redcarpet::Render::HTML
  end
end

3. Add the rouge-rails Gem

Add the rouge-rails gem.

# Gemfile

gem "rouge-rails"

4. Create a RougeRenderer Class

Create a RougeRenderer class to handle syntax highlighting.

# app/models/rouge_renderer.rb

class RougeRenderer < Redcarpet::Render::HTML
  require "rouge"
  require "rouge/plugins/redcarpet"

  include Rouge::Plugins::Redcarpet
end

5. Use RougeRenderer to Render

Use the RougeRenderer class as the Redcarpet markdown renderer.

# app/models/markdown_parser.rb

class MarkdownParser

  ...

  def renderer
    RougeRenderer.new(render_options = {})
  end
end

6. Set Stylesheets

There are a couple of ways to add the code styles to you rails app. I like to use the rouge rougify CLI command to generate a stylesheet. The CLI command should let you generate any theme found in the rouge gem's themes.

For example, to generate a github stylesheet:

$ rougify style github > app/assets/stylesheets/github.css

Then add it to your application.scss file.

// app/assets/stylesheets/application.scss

@import "github";

You can also copy a stylesheet from here, but be aware of how the classes are scoped. You will have to set up Rogue to handle themes.

7. Use It

You can pass the markdown parser a file:

# app/views/some_view.html.erb

<% file = File.read("path/to/file.md") %>
<%= MarkdownParser.new(file).markdown_to_html %>

Or you can directly pass text to the markdown parser:

# app/views/some_view.html.erb

<%= MarkdownParser.new("#heading ```code {} ```").markdown_to_html %>

Resources: