我正在尝试向我目前使用RDiscount的博客添加一些语法突出显示.我正在使用RDiscount将Markdown转换为
HTML,然后使用CodeRay解析HTML代码块以添加语法突出显示.这是我到目前为止:
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
在我看来:
<%= raw @post.rendered_body %>
使用此降价:
<code lang="ruby">
def function(param1, param2)
puts param1
param2.each do |a|
a.hello :world
end
end
</code>
结果是代码块被包装两次.
<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>
我该怎么做呢?
最佳答案 在render_body方法中,在调用markdown()方法之前调用coderay()方法.首先使用markdown方法生成一些额外的html,这个混乱的CodeRay导致输出错误.
我的测试假设您在降价源中看到了类似这样的原始数据
<code lang="ruby">
def function(param1, param2)
puts param1
param2.each do |a|
a.hello :world
end
end
</code>
这是我用来测试它的完整类.注意我没有使用:css => :class选项,因为我没有css来测试它.
class Post < ActiveRecord::Base
before_save :render_body
def render_body
self.rendered_body = markdown(coderay(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
end
end
end
您的最终输出假设为:css => :class选项现在应该看起来像这样
<div class="CodeRay">
<div class="code"><pre>
<span class="r">def</span> <span class="fu">function</span>(param1, param2)
puts param1
param2.each <span class="r">do</span> |a|
a.hello <span class="sy">:world</span>
<span class="r">end</span>
<span class="r">end</span>
</pre></div>
</div>