На Ruby on Rails, как сделать подсветку синтаксиса с помощью Markdown (RDiscount / BlueCloth) с CodeRay? - PullRequest
2 голосов
/ 14 марта 2011

Я знаю, что есть Railscast и ASCIIcast для использования 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> и , обернутые вокруг (чтобы CodeRay мог работать) ...

но что если это Markdown, тогда «4 отступа», как и в StackOverflow, сначала нужно будет сначала преобразовать в формат <code> и .

Так что в этомпохоже, что мы можем использовать

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

, поэтому сначала он получает формат <code> и для использования CodeRay, а затем просто подставляет /<code>.*? / m с результатами CodeRay.

Это правильный способ сделать это?Но если то, что у нас есть на самом деле <code> и в коде с "4 пробелами с отступом", то это фактически захлебнет эту обработку, потому что теперь есть вложенный <code>, поэтому первый <code> получитсовпал, пропустив второй <code> как просто содержимое для CodeRay, а затем сопоставив первый и оставив второй висящим там без обработки.Как это можно сделать - может быть, у CodeRay есть некоторые опции Markdown?

1 Ответ

1 голос
/ 14 марта 2011

Есть крошечный камень под названием lesstile , который помогает с этим.Однако я не хотел использовать этот гем, поэтому я извлек основные функциональные возможности, которые сводятся к следующему:

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.

...