- md
- html
class Article < ActiveRecord::Base
include MdToHtml
end
gem 'redcarpet' | |
gem 'pygmentize' |
require 'digest/md5' | |
module MdToHtml | |
extend ActiveSupport::Concern | |
included do | |
before_save :convert_md | |
end | |
private | |
def convert_md | |
markdown = Redcarpet::Markdown.new(PygmentizeHTML, :autolink => true, :space_after_headers => true, :fenced_code_blocks => true) | |
self.html = markdown.render(gfm(self.md)) | |
end | |
# from https://help.github.com/articles/github-flavored-markdown | |
def gfm(text) | |
# Extract pre blocks | |
extractions = {} | |
text.gsub!(%r{<pre>.*?</pre>}m) do |match| | |
md5 = Digest::MD5.hexdigest(match) | |
extractions[md5] = match | |
"{gfm-extraction-#{md5}}" | |
end | |
# prevent foo_bar_baz from ending up with an italic word in the middle | |
text.gsub!(/(^(?! {4}|\t)\w+_\w+_\w[\w_]*)/) do |x| | |
x.gsub('_', '\_') if x.split('').sort.to_s[0..1] == '__' | |
end | |
# in very clear cases, let newlines become <br /> tags | |
text.gsub!(/^[\w\<][^\n]*\n+/) do |x| | |
x =~ /\n{2}/ ? x : (x.strip!; x << " \n") | |
end | |
# Insert pre block extractions | |
text.gsub!(/\{gfm-extraction-([0-9a-f]{32})\}/) do | |
"\n\n" + extractions[$1] | |
end | |
text | |
end | |
end |