4

TL;DR - 我怎样才能使用类似的东西improved_markdown :some_file进行自定义渲染,但仍然像往常一样渲染布局?


通常,要在 Sinatra 中渲染 Markdown,您只需执行以下操作:

markdown :some_file

但我想添加“隔离”语法突出显示的功能,就像你可以在 Github README 文件中做的那样。

```ruby
class Foo
  # etc
end
```

我已经部分工作了。

首先,我安装了Redcarpet并添加了一个使用Pygments.rb进行语法高亮的自定义渲染类:

# create a custom renderer that allows highlighting of code blocks
class HTMLwithPygments < Redcarpet::Render::HTML
  def block_code(code, language)
    Pygments.highlight(code, lexer: language)
  end
end

然后我在一条路线中使用它,如下所示:

# Try to load any Markdown file specified in the URL
get '/*' do
  viewname = params[:splat].first

  if File.exist?("views/#{viewname}.md")

    # Uses my custom rendering class
    # The :fenced_code_blocks option means it will take, for example,
    # the word 'ruby' from ```ruby and pass that as the language
    # argument to my block_code method above  
    markdown_renderer = Redcarpet::Markdown.new(HTMLwithPygments, :fenced_code_blocks => true)

    file_contents = File.read("views/#{viewname}.md")
    markdown_renderer.render(file_contents)

  else
    "Nopers, I can't find it."
  end
end

几乎可以工作。Markdown 呈现为带有附加标记的 HTML 以用于突出显示。

唯一的问题是它不使用我的布局;毕竟,我只是在读取一个文件并返回呈现的字符串。正常的markdown :foo通话将涉及 Tilt 的过程。

我是否必须创建自定义 Tilt 模板引擎才能使其正常工作,还是有更简单的方法?

4

3 回答 3

3

您可以将任意选项传递给该markdown方法(或任何其他渲染方法),它们将被传递给相关的 Tilt 模板。Tilt 的 Redcarpet 模板在创建渲染器时会查找任何提供:renderer的选项,允许您指定自定义选项。

您还可以markdown通过将它们作为第二个参数传递给set :markdown, :option => :value.

但这并不那么简单,因为当前(已发布)版本的 Tilt 无法正确检测您是否安装了 Redcarpet 2。你可以明确地告诉它:

# first ensure we're using the right Redcarpet version
Tilt.register Tilt::RedcarpetTemplate::Redcarpet2, 'markdown', 'mkd', 'md'

# set the appropriate options for markdown
set :markdown, :renderer => HTMLwithPygments,
  :fenced_code_blocks => true, :layout_engine => :haml

现在任何对代码块的调用都markdown应该使用您的自定义代码,并将layout.haml用作布局。

(免责声明:我无法让 Pygments 正常工作(它会导致 Sinatra 每次都崩溃),但这里的其他一切都有效(我使用了一个简单的自定义block_code方法,它只是添加了一条消息,所以我可以知道它正在工作)。

于 2012-08-02T23:24:34.573 回答
0

一种解决方法

我目前正在这样做:

if File.exist?("views/#{viewname}.md") 
  CustomMarkdown.render(File.read("views/#{viewname}.md"))

哪个用途:

module CustomMarkdown
  def self.render(markdown_string)
    content = renderer.render(markdown_string)
    layout.render { content }
  end
  def self.renderer
    @markdown_renderer ||= Redcarpet::Markdown.new(HTMLwithPygments, :fenced_code_blocks => true)
  end
  def self.layout
    # Yes, this is hardcoded; in my simple app, I always use this layout.
    Tilt['haml'].new do
      File.read("views/layout.haml")
    end
  end
end

这工作得体。我注意到没有关键字的围栏块,如下所示:

```
  code of unspecified type
```
# vs
```ruby
  explicitly ruby code
```

... 导致我的 Sinatra 应用程序崩溃。我认为这意味着 Python 层中存在错误,因为我自己无法捕获任何引发的错误。

更新:崩溃发生在rackup config.ru,但不是当我使用乘客时。

于 2012-08-02T20:43:03.043 回答
0

您可以使用 zzak 的Glorify gem 来完成此类工作。

于 2012-08-05T21:48:12.617 回答