class Markdowner MAX_BARE_LINK = 50 def self.h(str) # .to_str is needed because this becomes a SafeBuffer, which breaks gsub # https://github.com/rails/rails/issues/1555 ERB::Util.h(str).to_str.gsub(/<(\/?)(em|u|strike)>/, '<\1\2>') end def self.markdown(string) lines = string.rstrip.split(/\r?\n/) out = "
" inpre = false lines.each do |line| # [ ][ ]blah ->
blahif line.match(/^( |\t)/) if !inpre out << "
" end out << ERB::Util.h(line) << "\n" inpre = true next elsif inpre out << "\n
" inpre = false end line = self.h(line) # lines starting with > are quoted if m = line.match(/^>(.*)/) line = "
" << m[1] << "" end lead = '\A|\s|[><]' trail = '[<>]|\z|\s' # *text* -> text line.gsub!(/(#{lead}|_|~)\*([^\* \t][^\*]*)\*(#{trail}|_|~)/) do |m| "#{$1}" << self.h($2) << "#{$3}" end # _text_ -> text line.gsub!(/(#{lead}|~)_([^_ \t][^_]*)_(#{trail}|~)/) do |m| "#{$1}" << self.h($2) << "#{$3}" end # ~~text~~ ->
")
# collapse things
out.gsub!(/
\n?<\/p>/, "
\n?
\n?/, "
") out.gsub!(/
\n?<\/p>/, "\n") out.gsub!(/
\n?
/, "\n
") out.gsub!(/<\/p>
/, "
\n") out.strip end def self._linkify_text(chunk) chunk.gsub(/ (\A|\s|[:,]) (http(s?):\/\/|www\.) ([^\s]+)/ix) do |m| pre = $1 host_and_path = "#{$2 == "www." ? $2 : ""}#{$4}" post = $5 # remove some chars that might be with a url at the end but aren't # actually part of the url if m = host_and_path.match(/(.*)([,\?;\!\.]+)\z/) host_and_path = m[1] post = "#{m[2]}#{post}" end url = "http#{$3}://#{host_and_path}" url_text = host_and_path if url_text.length > 50 url_text = url_text[0 ... 50] << "..." end "#{pre}#{url_text}#{post}" end end end