Reputation: 151136
I am aware there is a Railscast and ASCIIcast for using Textile (RedCloth) with CodeRay, and the way it is done is by a helper:
module ApplicationHelper
def coderay(text)
text.gsub(/\<code( lang="(.+?)")?\>(.+?)\<\/code\>/m) do
CodeRay.scan($3, $2).div(:css => :class)
end
end
end
and
<%= textilize(coderay(@article.content)) %>
so the assumption is that the @article.content
already has <code>
and </code>
wrapped around (so that CodeRay can work)...
but what if it is Markdown, then the "4 space indentation", like on StackOverflow, will first need to be converted to <code>
and </code>
format first.
So in this case, seems like we can use
<%= coderay(Markdown.new(@article.content).to_html).html_safe #html_safe for Rails 3 %>
so it first gets the <code>
and </code>
format for CodeRay to use, and then just basically substitute /<code>.*?</code>/m
with the CodeRay results.
Is this a proper way to do it? But if what we actually have <code>
and </code>
on the "4 space indented" code, then it will actually choke this processing, because now there is nested <code>
, so the first <code>
will get matched, skipping the second <code>
as just content for CodeRay, and then match the first </code>
and leave the second </code>
dangling there unprocessed. How can this be done -- maybe CodeRay has some Markdown options?
Upvotes: 2
Views: 1298
Reputation: 1932
There is a tiny gem called lesstile that helps with this. I didn't feel like using the gem though, so I extracted the core functionality, which boils down to this:
options = {
:code_formatter => lambda {|code, lang|
CodeRay.scan(CGI::unescapeHTML(code), lang).html.div
}
}
text += "\n" unless (text.rindex("\n") == text.size - 1)
text.gsub!(/\r\n/, "\n")
output = ""
while match = text.match(/---\s*?([\w\s\._+()-]*?)\s*?\n(.*?)---\n/m)
captures = match.captures
code = captures[1]
lang = captures[0].blank? ? nil : captures[0].downcase.strip.intern
output +=
options[:text_formatter][match.pre_match] +
options[:code_formatter][code, lang]
text = match.post_match
end
output += options[:text_formatter][text.chomp]
You can denote code in your textile/markdown by using "---" to encase it and optionally add the language, like "---ruby", like this:
---ruby
def hi
print "hi"
end
---
Works perfectly fine with Markdown.
Upvotes: 1