Pietro Passarelli

use fenced code blocks in jekyll

Why?

First, thing first, why? I use markdown a lot, pretty much instead of using word, I write in markdown and export mostly into rtf, .docx, or .pdf using pandoc (blog post on this workflowto come soon), and being able to just draft something, without having to think about whether I need to use liquid tags or fended blocks, depending on whether I will then publish it onto my jekyll site (jekyll is a static site generator).

So decided to install a plugin from the jekyll site to enable it, but it wasn’t quiet working, enche the post here.

Fenced code blocks and liquid tags

Let’s look at how to use fenced code blocks instead of liquid tags in jekyll. But first, what’s what?

These are liquid tags and their default way for jekyll to display code with syntax hilight:


{% highlight ruby %}
print “hello world”
{% endhighlight %}

these are fenced code blocks


```ruby

print "hello world"

```


and both would render the code like this

print "hello world"

Quick install

1.gem install redcarpet

in terminal:

gem install redcarpet

2.add redcarpet plugin in your jekyll project.

Then you need to add redcarpet2 plugin in your jekyll project. which as simple as saving redcarpet2_markdown.rb in the _plugins folder(if you don’t have the folder, just create one and remember te _).

require 'fileutils'
require 'digest/md5'
require 'redcarpet'
require 'albino'

PYGMENTS_CACHE_DIR = File.expand_path('../../_cache', __FILE__)
FileUtils.mkdir_p(PYGMENTS_CACHE_DIR)

class Redcarpet2Markdown < Redcarpet::Render::HTML
  def block_code(code, lang)
    lang = lang || "text"
    path = File.join(PYGMENTS_CACHE_DIR, "#{lang}-#{Digest::MD5.hexdigest code}.html")
    cache(path) do
      colorized = Albino.colorize(code, lang.downcase)
      add_code_tags(colorized, lang)
    end
  end

  def add_code_tags(code, lang)
    code.sub(/<pre>/, "<pre><code class=\"#{lang}\">").
         sub(/<\/pre>/, "</code></pre>")
  end

  def cache(path)
    if File.exist?(path)
      File.read(path)
    else
      content = yield
      File.open(path, 'w') {|f| f.print(content) }
      content
    end
  end
end

class Jekyll::MarkdownConverter
  def extensions
    Hash[ *@config['redcarpet']['extensions'].map {|e| [e.to_sym, true] }.flatten ]
  end

  def markdown
    @markdown ||= Redcarpet::Markdown.new(Redcarpet2Markdown.new(extensions), extensions)
  end

  def convert(content)
    return super unless @config['markdown'] == 'redcarpet2'
    markdown.render(content)
  end
end

3.change config file

then in your config _config.yml file you need to add:

markdown: redcarpet
redcarpet:
  extensions: ["no_intra_emphasis", "fenced_code_blocks", "autolink", "strikethrough", "superscript"]

…and your done.

End notes

I took most of these installation steps are taken from stack overflow however there the sudgestion was to write in the config file markdown: redcarpet2 and it wasn’t working for me, so I found that it has been raised elsewhere that you can just write markdown: redcarpet and it works just fine.

Also, I’ve noticed that with this set up you can use both liquid tags and fenced blocks.

Updated

Github does nto support redcarpet anymore, uses kramdown by the default so I followed this to update and retain same settings described above.

Updating from redcarpet and Pygments to Kramdown and Rouge on Github Pages

In a nutshell

in _config.yml change this

highlighter: pygments
markdown: redcarpet
redcarpet:
  extensions: ["no_intra_emphasis", "fenced_code_blocks", "tables", "with_toc_data"]

to this

highlighter: rouge
markdown: kramdown
kramdown:
  input: GFM
  auto_ids: true
  syntax_highlighter: rouge