class Rad::TextUtils::CustomMarkdown < Rad::TextUtils::Processor def process markdown, env markdown = github_flavoured_markdown markdown markdown = image_box markdown text = custom_markdown markdown call_next text, env end protected def custom_markdown markdown # BlueCloth doesn't apply inside of HTML tags, so we temporarilly replacing it markdown = markdown.gsub('<', 'HTML_BEGIN').gsub('>', 'HTML_END') markdown = markdown.gsub(" \n", "
\n") text = BlueCloth.new(markdown).to_html text = text.gsub(/\A<.+?>/){"#{$&} "}.gsub(/<\/.+?>\Z/){" #{$&}"} text = text.gsub('HTML_BEGIN', '<').gsub('HTML_END', '>') text.gsub(/[\n]+/, "\n") end def github_flavoured_markdown markdown # Extract pre blocks extractions = {} markdown.gsub!(%r{
.*?
}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 markdown.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
tags markdown.gsub!(/^[\w\<\!][^\n]*\n+/) do |x| if x =~ /\>[\n\r]*/ x else x =~ /\n{2}/ ? x : (x.strip!; x << " \n") end end # Insert pre block extractions markdown.gsub!(/\{gfm-extraction-([0-9a-f]{32})\}/) do "\n\n" + extractions[$1] end markdown end # !![img] => [![img_thumb]][img] def image_box markdown img_urls = {} markdown = markdown.gsub(/!!\[(.+?)\]/) do img_key = $1 || '' if url = markdown.scan(/\[#{img_key}\]:\s*([^\s]+)$/).first.try(:first) unless url =~ /\.[^\.]+\.[^\.]+$/ # image.png thumb_img_key = "#{img_key}_thumb" # building url with thumb (foo.png => foo.thumb.png) img_urls[thumb_img_key] = url.sub(/\.([^\.]+)$/){".thumb.#{$1}"} "[![][#{thumb_img_key}]][#{img_key}]" else # image.(icon|thumb|...).png img_key_full = "#{img_key}_full" # building url with thumb (foo.png => foo.thumb.png) img_urls[img_key_full] = url.sub(/\.([^\.]+)\.([^\.]+)$/){".#{$2}"} "[![][#{img_key}]][#{img_key_full}]" end else $& || '' end end unless img_urls.blank? markdown << "\n" markdown << img_urls.to_a.collect{|k, v| "[#{k}]: #{v}"}.join("\n") end markdown end end