all dojo4's rails application use markdown in some fashion. following is the setup we have for the shiniest of shiny markdown configurations:
step one is suck in the require gems
# Gemfile
gem 'redcarpet'
gem 'pygments.rb'
next, you might want a good utility method that wraps up a syntax highlighting class and common calling conventions
# file: lib/util.rb
module Util
# teh markdown support
class SyntaxHighlighting < Redcarpet::Render::HTML
def block_code(code, language)
language = 'ruby' if language.to_s.strip.empty?
Pygments.highlight(code, :lexer => language, :options => {:encoding => 'utf-8'})
end
end
def markdown(*args, &block)
@markdown ||=
Redcarpet::Markdown.new(
SyntaxHighlighting,
:no_intra_emphasis => true,
:tables => true,
:fenced_code_blocks => true,
:autolink => true,
:strikethrough => true,
:lax_html_blocks => true,
:space_after_headers => true,
:superscript => true
)
if args.empty? and block.nil?
@markdown
else
source = args.join
return nil if source.blank?
@markdown.render(source, &block).strip.sub(/\A<p>/,'').sub(/<\/p>\Z/,'').html_safe
end
end
extend self
end
okay cool. you are now setup to process markdown, with syntax highlighting, like so:
Util.markdown(" * this\n* is\n * a\n* list ")
but, you know that's kind of expensive and we generally avoid doing it in the view. instead, we cache both the raw markdown and markdown formatted markdown on our objects. don't forget that you need to keep the raw markdown if you want to let the user re-edit it...
# file : app/models/post.rb
class Post
include Mongoid::Document
field :body_source, :type => String
field :body, :type => String
before_save do |post|
if post.body_source.blank?
post.body = nil
else
post.body = Util.markdown(post.body_source)
end
end
def to_html
body.html_safe
end
end
one last awesome tidbit: some of us like writing simple views in markdown. this initializer will let you create 'app/views/foo.md' and have rails just do the right thing, including processing the markdown through erb first which allows looping, conditionals, etc...
# file: config/initializers/markdown_templates.rb
module MarkdownTemplateHandler
def self.erb
@erb ||= ActionView::Template.registered_template_handler(:erb)
end
def self.markdown(*args, &block)
Util.markdown(*args, &block)
end
def self.call(template)
template = erb.call(template)
"MarkdownTemplateHandler.markdown.render(begin;#{ template };end).html_safe"
end
end
ActionView::Template.register_template_handler(:md, MarkdownTemplateHandler)
ActionView::Template.register_template_handler(:markdown, MarkdownTemplateHandler)
let's you do
# file: app/views/markdown-is-awesome.md
* this
* is
* a
* list
and
<% ['so', 'is', 'this'].each do |word| %>
* <%= word %>
<% end %>
and there you have it: rails markdown-fu for with pygments powered syntax highlighting