How I added heading anchors with Middleman

I really like being able to link directly to certain parts of web page. Unfortunately, many page authors fail to add the necessary anchors to make this possible. Until recently, this included me!

Here is how I remedied the situation.

Outputting headings with id attributes looked like it should've already been supported out of the box. I could see a toc_data option, but for some reason this didn't work for me, so I created a custom Markdown renderer instead.

1
2
3
4
5
6
7
require "middleman-core/renderers/redcarpet"

class CustomRenderer < Middleman::Renderers::MiddlemanRedcarpetHTML
  def header(text, header_level)
    "<h%s id=\"%s\">%s</h%s>" % [header_level, text.parameterize, text, header_level]
  end
end

I inherit from the default renderer so that I can replace the header implementation to add the necessary id attributes.

I required it in my config.rb and then configured Redcarpet to use the new renderer.

1
2
3
4
set :markdown,
  fenced_code_blocks: true,
  smartypants: true,
  renderer: CustomRenderer

There we have it. Heading tags now have ids, so we can link directly to them.