The code syntax highlighting feature is a must-have for every developer blog or website where a code snippet can be presented. It’s easy to add it when you are using a blog engine like Jekyll or WordPress but you can also easily add it in your own Rails app.
Since I’m building a new blog engine for this website I already tested one solution and I want to share it with you.
We want to have a nice-looking code syntax highlighting but we want also to be able to store the code safely in the database and be able to edit it easily. So here is the full list of our requirements:
- Highlight code
- Easily change highlight theme
- Store safely submitted code
- Edit easily code
- Support highlighting for many languages
The easiest way to safely store code in the database is to use markdown syntax. Such syntax allow us for easy editing and modyfing the logic.
In order to support markdown syntax, we will need a gem called Redcarpet. It’s really simple to use. To demonstrate it, let’s consider following example:
Redcarpet::Markdown.new(Redcarpet::Render::HTML).render("This is *bongos*, indeed.")
the output will be following:
We have to add it to our
and then run
bundle install. From now on, you can write your articles using the markdown syntax and then display it in the view using this code:
<%= Redcarpet::Markdown.new(Redcarpet::Render::HTML, fenced_code_blocks: true).render(@article.content).html_safe %>
Now, when we added the markdown syntax support, we can focus on the syntax highlighting. We will use the Rouge gem which works perfectly with the Redcarpet gem that we have used for the markdown syntax. Let’s just add it to the
Gemfile and hit
As you may notice, we used
Redcarpet::Render::HTML renderer class for the markdown syntax parsing. In order to connect the Rouge with the Redcarpet we have to create our own renderer class. Create a new file called
/lib/blog_render.rb and use following code:
require 'redcarpet' require 'rouge' require 'rouge/plugins/redcarpet' # Custom renderer for Markdown syntax class BlogRender < Redcarpet::Render::HTML include Rouge::Plugins::Redcarpet end
The next thing we need to do is to pass new renderer class to the new instance of
<%= Redcarpet::Markdown.new(BlogRender, fenced_code_blocks: true).render(@article.content).html_safe %>
fenced_code_blocks option allows us to use code blocks you may know from Github. The last step is to update CSS styles. You can copy and paste styles from my gist to have the same theme as on the screenshot below.
From now on, the following text:
```ruby class Service def initialize(object:) @object = object end def call object.id end private attr_reader :object end ```
will be replaced to: