2

我知道有一个RailscastASCIIcast用于将 Textile (RedCloth) 与 CodeRay 一起使用,它的完成方式是由一个助手:

module ApplicationHelper    
  def coderay(text)  
    text.gsub(/\<code( lang="(.+?)")?\>(.+?)\<\/code\>/m) do  
      CodeRay.scan($3, $2).div(:css => :class)  
    end  
  end  
end  

<%= textilize(coderay(@article.content)) %>

所以假设是@article.content已经拥有<code></code>包裹(以便CodeRay可以工作)......

但是如果是 Markdown,那么像 StackOverflow 上的“4 空格缩进”,首先需要先转换为<code>格式</code>

所以在这种情况下,似乎我们可以使用

<%= coderay(Markdown.new(@article.content).to_html).html_safe  #html_safe for Rails 3 %>  

所以它首先获取 CodeRay 使用的 <code></code>格式,然后基本上/<code>.*?</code>/m用 CodeRay 结果替换。

这是一个正确的方法吗?但是如果我们实际上有<code></code>4空格缩进”代码,那么它实际上会阻塞这个处理,因为现在有嵌套<code>,所以第一个<code>将被匹配,跳过第二个<code>作为CodeRay的内容,然后匹配首先</code>,让第二个</code>悬空未处理。如何做到这一点——也许 CodeRay 有一些 Markdown 选项?

4

1 回答 1

1

有一种叫做lesstile的小宝石可以帮助解决这个问题。不过我不想使用 gem,所以我提取了核心功能,归结为:

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]

您可以使用“---”来表示您的纺织品/降价代码中的代码,并可选择添加语言,如“---ruby”,如下所示:

---ruby
def hi
  print "hi"
end
---

与 Markdown 完美配合。

于 2011-03-14T01:03:12.880 回答