While writing a future blog post on Openbox, I had some troubles with code Markdown rendering in HAML.
A few months ago Ryan Bates released a Railscast on Markdown with Redcarpet. Redcarpet is awesome, but for this blog I needed a bit more flexibility on my Markdown and I chose to use Kramdown.
The problem you face with both Redcarpet or Kramdown is that when you render your generated HTML containing some code, your code will be completely wrongly formated. Something like this
def foo
bar = "bar"
foobar = "foobar"
end
See, wrong indentation.
Plus when you’re using Kramdown there is no automatic lang element in the pre tag, so Albino does not know what to colorize.
Solution(s)
From this Railscast, I have extracted these 2 helpers methods:
def markdown(text)
options = [:hard_wrap, :filter_html, :autolink, :no_intraemphasis, :fenced_code, :gh_blockcode]
syntax_highlighter(Redcarpet.new(text, *options).to_html).html_safe
end
def syntax_highlighter(html)
doc = Nokogiri::HTML(html)
doc.search("//pre[@lang]").each do |pre|
pre.replace Albino.colorize(pre.text.rstrip, pre[:lang])
end
doc.to_s
end
When rendering your view you’ll use
= markdown(@article.content)
For the first problem, the wrong indentation, you have to add a preserve(HTML) to the call:
def markdown(text)
options = [:hard_wrap, :filter_html, :autolink, :no_intraemphasis, :fenced_code, :gh_blockcode]
preserve(syntax_highlighter(Redcarpet.new(text, *options).to_html).html_safe)
end
For the second problem, passing a lang element to the pre tag with Kramdown, all you have to do is add the lang using an ials block and everything will be working smoothly.