I’m trying to add some syntax highlighting to my blog that currently uses RDiscount. I am converting the Markdown to HTML with RDiscount then parsing the HTML code blocks with CodeRay to add syntax highlighting. This is what I have so far:
class Post < ActiveRecord::Base
before_save :render_body
def render_body
self.rendered_body = coderay(markdown(self.body))
end
def markdown(text)
RDiscount.new(text).to_html
end
def coderay(text)
text.gsub(/\<code( lang="(.+?)")?\>(.+?)\<\/code\>/m) do
CodeRay.scan($3, $2).div(:css => :class)
end
end
end
And in my view:
<%= raw @post.rendered_body %>
Using this markdown:
<code lang="ruby">
def function(param1, param2)
puts param1
param2.each do |a|
a.hello :world
end
end
</code>
The result is that the code blocks are being wrapped twice.
<pre>
<div class="CodeRay">
<div class="code">
<pre>
def function(param1, param2)
puts param1
param2.each do |a|
a.hello :world
end
end
</pre>
</div>
</div>
</pre>
What should I do instead?
In your
render_bodymethod call thecoderay()method before calling themarkdown()method. Using themarkdownmethod first was generating some extra html and this confusedCodeRaycausing bad output.My tests assumed you had the raw data that looked something like this in the markdown source
Here’s the complete class I used to test it. Note I didn’t use
:css => :classoption because I didn’t have the css to test it.Your final output assuming the
:css => :classoption should now look something like this