Подсветка синтаксиса с помощью CodeRay и Markdown (RDiscount) в приложении на Rails 3 - PullRequest
4 голосов
/ 22 октября 2010

Я пытаюсь добавить подсветку синтаксиса в свой блог, который в настоящее время использует RDiscount.Я конвертирую Markdown в HTML с помощью RDiscount, затем анализирую блоки кода HTML с помощью CodeRay, чтобы добавить подсветку синтаксиса.Это то, что я до сих пор:

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>

В результате кодблоки оборачиваются дважды.

<code><pre>
<div class="CodeRay">
<div class="code">
<pre>
def function(param1, param2)
  puts param1
  param2.each do |a|
    a.hello :world
  end
end

Что мне делать вместо этого?

1 Ответ

2 голосов
/ 29 октября 2010

В вашем методе render_body вызовите метод coderay() перед вызовом метода markdown().При использовании метода 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 теперь должна выглядеть примерно так

<code><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> 
...