TL;DR - how can I use something like improved_markdown :some_file
to do custom rendering, but still render the layout as usual?
Normally, to render Markdown in Sinatra, you'd just do:
markdown :some_file
But I'd like to add the ability to do "fenced" syntax highlighting, like you can do in Github README files.
```ruby
class Foo
# etc
end
```
I've got this partially working.
First, I installed Redcarpet and added a custom rendering class that uses Pygments.rb for syntax highlighting:
# 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
Then I used it in a route, like this:
# 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
This almost works. The Markdown is rendered as HTML with additional markup for highlighting purposes.
The only problem is that it does not use my layout; after all, I'm just reading a file and returning the rendered string. The normal markdown :foo
call would involve Tilt in the process.
Do I have to create a custom Tilt template engine to get that to work, or is there an easier way?