- Published
- 1 December 2014
- Tagged
I've been tidying up around the place. Do you like it? It feels a lot cleaner to me.
(RSS subscribers are encouraged at this point to follow the link and read the article on the website proper.)
For a while I've wanted to swap out my technically quite nice but aesthetically rather sterile sans-serif body font for a more friendly serif with a bit more readability, so with this slight redesign I've now gone and done that. However, I quickly got annoyed with markdown's generic straight quotes, and started working out how to fix this.
The default answer for turning boring straight quotes into nice typographical quote marks, especially in a markdown-heavy environment, is to pull out John Gruber's SmartyPants. I'm using Redcarpet to render markdown on my site, so it's not too hard to build in SmartyPants support.
Markdown + SmartyPants
Redcarpet's documentation shows you how to include smartypants: you just include Redcarpet::Render::SmartyPants
in your renderer and everything works fine. Since I already have a custom renderer in my nanoc implementation, I simply added SmartyPants to that[1]:
module Redcarpet::Render
class CustomRenderer
include SmartyPants
#...
end
end
To use this renderer in nanoc, you just need to modify your Rules file slightly. Let's say I want to render all my blog posts in markdown with SmartyPants:
compile "/posts/*" do
if !item.binary?
filter :redcarpet, renderer: Redcarpet::Render::CustomRenderer
end
end
Done!
Haml + SmartyPants
There is a problem, and the problem looks like this:
# sample_document.haml
%h1 Haml page
%p This is a haml page, with a haml paragraph.
:markdown
Now I'm filtering a section through markdown, but "these quotes" won't run through SmartyPants.
In cases like this, Haml has its own little markdown-rendering party and doesn't invite Redcarpet or its custom renderer along for the ride. Worse, Haml ends up using Tilt as a templating engine, adding a further layer between us the metal. How can we get into the guts of the rendering process, telling Haml to tell Tilt to tell whatever it's using to render this markdown inside the filter that it should be using SmartyPants?
Thankfully, this is a recurring problem, at least with Sinatra. Cameron Daigle, in the linked post, uses the following code in Sinatra as a means of getting Haml to play nice with SmartyPants:
class Tilt::HamlTemplate
module ::Haml::Filters::Markdown
def render(text)
RDiscount.new(text, :smart).to_html
end
end
end
We can fix this up for nanoc and Redcarpet nice and easy. My code looks like this:
require "tilt"
class Tilt::HamlTemplate
module ::Haml::Filters::Markdown
def render(text)
@renderer ||= Redcarpet::Markdown.new(
Redcarpet::Render::CustomRenderer,
fenced_code_blocks: true,
footnotes: true
)
@renderer.render(text)
end
end
end
I don't even have to tell Redcarpet to use SmartyPants here - its CustomRenderer
knows to use it, and Redcarpet is perfectly happy letting the renderer do whatever it wants. This little code snippet goes into the lib/
folder along with the custom renderer, and you don't need to do anything else. Haml will now route all its markdown-filtered blocks through Redcarpet, and the rest is magic.
This file is stored in
lib/
, in the root of your nanoc site. Files inlib/
are auto-loaded, making this the perfect place to screw around with your nanoc install. ↩︎