Using Kramdown instead of Maruku

Update January 23rd, 2015: Paul Robert Lloyd improved the converter with his Pypedown plugin. It also sports the Typogruby extension for some visual juice.

Update July 24th, 2014: Matthijs van den Bos improved Juan’s plugin to work with Jekyll 2.x.

Update May 7th, 2014: As of Jekyll version 2.0.0, Kramdown is Jekyll’s default Markdown converter. However, it’s still using CodeRay.

Update August 14th, 2013: The code as shown below is not working with Jekyll versions >= 1.0. See this post how to update your Jekyll installation to version 1.0. Juan Antonio Navarro Pérez kindly put a fixed version of the code on GitHub.

After I messed around with Maruku for some time now, I became fed up with its limitations such as missing fenced code blocks. Without these, you have to use the unwieldy Liquid tags to denote a piece of code. Fortunuately, there are many alternative Markdown converters. To decide which one to use in the future, I came up with this (incomplete) feature matrix:

Fenced code blocks
Jekyll integration
Header IDs
Inline math

At first glance, Kramdown wins hands down (even ahead of my beloved Pandoc). But there is one slight problem: When blogging with Jekyll, you have to use CodeRay for syntax highlighting or none at all. Because I favor Pygments due to the broader range of supported languages, I had to update the Markdown converter plugin that I presented in the last post.

For this, we have to subclass Kramdown’s HTML converter to use Pygments on code blocks:

require 'kramdown'
require 'pygments'
require 'typogruby'

module Kramdown
  module Converter
    class Pygs < Html
      def convert_codeblock(el, indent)
        attr = el.attr.dup
        lang = extract_code_language!(attr)
        if lang
                               :lexer => lang,
                               :options => { :encoding => 'utf-8' })

      def add_code_tags(code)
        code = code.sub(/<pre>/,'<pre><code>')
        code = code.sub(/<\/pre>/,"</code></pre>")

Now, we can replace the Maruku converter with our customized Kramdown converter:

module Jekyll
  class MarkdownConverter < Jekyll::Converter
    def convert(content)

      html =, {
          :auto_ids         => @config['kramdown']['auto_ids'],
          :footnote_nr      => @config['kramdown']['footnote_nr'],
          :entity_output    => @config['kramdown']['entity_output'],
          :toc_levels       => @config['kramdown']['toc_levels'],
          :smart_quotes     => @config['kramdown']['smart_quotes']
      return Typogruby.improve(html)

Note, that Kramdown uses weird dynamic name resolution (the method call to_pygs in this case) to hook the subclassed Pygs class into the conversion process. For my taste, this goes a bit too far but that’s the way it is.