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模板引擎才能使其正常工作,还是有更简单的方法?
答案 0 :(得分: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
方法,只是添加了一条消息,所以我可以告诉它工作)。
答案 1 :(得分: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
,但不是在我使用Passenger时。
答案 2 :(得分:0)
您可以使用zzak的Glorify gem来完成这类工作。