首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Rails中实现Rouge语法突出显示?

如何在Rails中实现Rouge语法突出显示?
EN

Stack Overflow用户
提问于 2016-06-07 00:14:40
回答 1查看 2.5K关注 0票数 15

有一堆教程随处可见,但它们似乎不完整,或者没有完全更新,或者不完全适用于我。

这就是我所做的。

Gemfile:

代码语言:javascript
复制
gem 'rouge'
gem 'redcarpet'

然后我创建了一个config/initializer/rouge.rb

代码语言:javascript
复制
require 'rouge/plugins/redcarpet'

然后我创建了一个名为app/assets/stylesheets/rouge.css.erb的文件

代码语言:javascript
复制
<%= Rouge::Themes::Github.render(:scope => '.highlight') %>

然后在我的app/helpers/application_helper.rb中,我添加了以下内容:

代码语言:javascript
复制
module ApplicationHelper
  class HTML < Redcarpet::Render::HTML
    include Rouge::Plugins::Redcarpet

    def block_code(code, language)
      Rouge.highlight(code, language || 'text', 'html')
    end
  end

  def markdown(text)
    render_options = {
      filter_html: true,
      hard_wrap: true,
      link_attributes: { rel: 'nofollow' }
    }
    renderer = HTML.new(render_options)

    extensions = {
      autolink: true,
      fenced_code_blocks: true,
      lax_spacing: true,
      no_intra_emphasis: true,
      strikethrough: true,
      superscript: true
    }
    Redcarpet::Markdown.new(renderer, extensions).render(text).html_safe
  end
end

然后在我的show.html.erb中,我做了这样的事情:

代码语言:javascript
复制
<%= markdown(@question.body) %>

但这根本行不通。它输出我的ruby代码片段如下:

我如何使这段代码被格式化为Github呢?甚至只是第一步被格式化,然后我如何调整格式呢?

我没有看到页面源代码中包含了样式表,所以我不知道需要调整哪些样式。

编辑1

甚至当我这样做:

代码语言:javascript
复制
            <div class="highlight">
              <%= @question.test_suite %>
            </div>

它呈现如下:

编辑2

我尝试了BoraMa的建议,得到了如下结果:

编辑3

我对BoraMa的回答作了如下修改。

在我的block_code方法中,我按如下方式调用突出显示:

代码语言:javascript
复制
Rouge.highlight(code, 'ruby', 'html')

在我看来我是这样做的:

代码语言:javascript
复制
<%= raw rouge_markdown(<<-'EOF'
                def rouge_me
                  puts "this is a #{'test'} for rouge"
                end
                EOF
                ) %>

这就产生了这样的结果:

注意,我指的是屏幕截图底部的代码片段。

然而,顶部的文本是这样生成的:

代码语言:javascript
复制
          <pre class="highlight ruby">
            <%= rouge_markdown(@question.body) %>
          </pre>

并呈现在屏幕截图中。

编辑4

删除<div class="highlight">后,我看到以下内容:

Aka....nothing正在被呈现。

一旦我将raw添加到view...aka <%= raw rouge_markdown(@question.body) %>

视图呈现如下:

编辑5

以下是各种@question对象的内容:

代码语言:javascript
复制
[1] pry(#<#<Class:0x007fc041b97ce8>>)> @question.body
=> "5.times do\r\n   puts \"Herro Rerl!\"\r\nend"
[1] pry(#<#<Class:0x007fc041b97ce8>>)> @question.body
=> "puts \"Hello World version 9\"\r\nputs \"This comes after version 8.\"\r\nputs \"This comes after version 7.\"\r\nputs \"This comes after version 6.\"\r\nputs \"This comes after version 5.\"\r\nputs \"This comes after version 4.\"\r\nputs \"This comes after version 3.\"\r\nputs \"This comes after version 2.\"\r\nputs \"This definitely comes after version 1.\""

[1] pry(#<#<Class:0x007fc041b97ce8>>)> @question.body
=> "def convert_relation(invited_gender, relation)\r\n case invited_gender\r\n \twhen \"male\"\r\n  \tcase relation\r\n      when \"daughter\", \"son\" then \"dad\"\r\n      when \"mom\", \"dad\" then \"son\"\r\n      when \"grandfather\", \"grandmother\" then \"grandson\"\r\n      when \"sister\", \"brother\" then \"brother\"\r\n      when \"wife\" then \"husband\"\r\n      when \"husband\" then \"husband\"\r\n    end\r\n  when \"female\"\r\n  \tcase relation\r\n      when \"daughter\", \"son\" then \"mom\"\r\n      when \"mom\", \"dad\" then \"daughter\"\r\n      when \"grandfather\", \"grandmother\" then \"granddaughter\"\r\n      when \"sister\", \"brother\" then \"sister\"\r\n      when \"wife\" then \"wife\"\r\n      when \"husband\" then \"wife\"\r\n    end\r\n  end\r\nend\r\n\r\nputs convert_relation(\"male\", \"wife\")"
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-06-09 09:09:54

最初的问题(在解决方案中试图)表明,将在突出显示的问题中使用标记,但事实证明并非如此。因此,这个答案被分成两个不同的部分,一个用于高亮显示纯代码而不加标记,另一个用于带有代码的标记文本。

( A)您希望突出显示纯代码(不涉及标记)

在这种情况下,根据自述文件,使用Rouge突出显示代码所需的全部内容是a lexera formatter。由于突出显示的文本将显示在网页上,您需要HTML格式化程序。对于lexer,您需要事先知道代码使用的是哪种语言(或者您可以尝试从源代码本身猜测它,但对于小型代码片段来说,它似乎不太可靠)。

您可以为高亮显示创建一个简单的助手方法:

代码语言:javascript
复制
module RougeHelper
  def rouge(text, language)
    formatter = Rouge::Formatters::HTML.new(css_class: 'highlight')
    lexer = Rouge::Lexer.find(language)
    formatter.format(lexer.lex(text))
  end
end

然后在模板中,只需使用要突出显示的文本和语言调用此助手:

代码语言:javascript
复制
<%= raw rouge("def rouge_me\n  puts 'hey!'\nend", "ruby") %>

这将使:

要获得Rouge支持的所有语言的列表以及应该传递给rouge助手的相应名称,可以使用以下代码。代码从Rouge获取所有已定义的词汇,并显示它们的标记(即Rouge识别它们的名称):

代码语言:javascript
复制
Rouge::Lexer.all.map(&:tag).sort
# => ["actionscript", "apache", "apiblueprint", "applescript", ..., "xml", "yaml"]

当在选择框中向用户显示要选择的语言时,您可以(而且可能应该)使用此列表。请注意,每个lexer还定义了titledesc方法,这些方法将为您提供一个可读的名称,并对每个方法进行简短的描述。您可能希望使用这些信息来显示给用户。

注意事项:您应该去掉初始化器、自定义的HTML类和包装在rouge调用周围的div (所有这些在您最初的尝试中都有)。除了上面的代码之外,您唯一需要的是CSS规则,这些规则已经正确地包含在网页中了。

( B)突出显示的文本是带有代码块的标记文本。

与您试图使其工作的几处不同:

  1. 不需要初始化程序,我认为您可以删除它(但是如果您不想在后面的帮助器中require所有文件,我想您可以离开它)。
  2. 从helper类中删除block_code方法,通过包含标记插件已经完成了同样的工作。
  3. 从模板中删除<div class="highlight">包装器div,只需使用其中的助手即可。Rouge在“突出显示”类中添加了自己的包装器,另一个div似乎混淆了它。

尝试下面的助手代码。顺便说一句,我将代码从ApplicationHelper移到单独的RougeHelper (但这不是必需的更改):

代码语言:javascript
复制
module RougeHelper
  require 'redcarpet'
  require 'rouge'
  require 'rouge/plugins/redcarpet'

  class HTML < Redcarpet::Render::HTML
    include Rouge::Plugins::Redcarpet
  end

  def rouge_markdown(text)
    render_options = {
        filter_html: true,
        hard_wrap: true,
        link_attributes: { rel: 'nofollow' }
    }
    renderer = HTML.new(render_options)

    extensions = {
        autolink: true,
        fenced_code_blocks: true,
        lax_spacing: true,
        no_intra_emphasis: true,
        strikethrough: true,
        superscript: true
    }
    markdown = Redcarpet::Markdown.new(renderer, extensions)
    markdown.render(text)
  end
end

然后,在模板中,我试图突出显示一个测试红宝石代码:

代码语言:javascript
复制
<%= raw rouge_markdown(<<-'EOF'
```ruby

def rouge_me

“这是胭脂的#{‘测试’}”

结束

代码语言:javascript
复制
EOF
) %>

请注意,我需要手动指定语言,这使我使用3个backticks方式来分隔代码,而不是空格缩进。我不知道为什么代码语言自动检测在这里不起作用,也许这是一个太短的代码。

最后,这为我很好地呈现了这些颜色:

票数 14
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37668675

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档