Escape hashtags in emails
Custom Redcarpet renderer to escape hashtags (but not legitimate headers) in emails before Markdown processing. Prevents hashtags from being rendered as H1 headers. This also leaves open the possibility of parsing hashtags into clickable links in the future. fixes #3325
This commit is contained in:
parent
f68f14aa5b
commit
c2bc7272fb
6 changed files with 82 additions and 4 deletions
2
Gemfile
2
Gemfile
|
|
@ -29,7 +29,7 @@ gem 'twitter', '2.0.2'
|
|||
|
||||
# mail
|
||||
|
||||
gem 'markerb', '~> 1.0.0'
|
||||
gem 'markerb', :git => 'git://github.com/plataformatec/markerb.git'
|
||||
gem 'messagebus_ruby_api', '1.0.3'
|
||||
gem 'airbrake'
|
||||
gem 'newrelic_rpm'
|
||||
|
|
|
|||
11
Gemfile.lock
11
Gemfile.lock
|
|
@ -30,6 +30,13 @@ GIT
|
|||
rspec (>= 1.3.1)
|
||||
selenium-webdriver (>= 0.1.3)
|
||||
|
||||
GIT
|
||||
remote: git://github.com/plataformatec/markerb.git
|
||||
revision: 93b1e8bea9b8fa89ef930f78ba562f596c022198
|
||||
specs:
|
||||
markerb (1.0.0)
|
||||
redcarpet (>= 2.0)
|
||||
|
||||
GEM
|
||||
remote: http://rubygems.org/
|
||||
specs:
|
||||
|
|
@ -243,8 +250,6 @@ GEM
|
|||
i18n (>= 0.4.0)
|
||||
mime-types (~> 1.16)
|
||||
treetop (~> 1.4.8)
|
||||
markerb (1.0.0)
|
||||
redcarpet (>= 2.0)
|
||||
messagebus_ruby_api (1.0.3)
|
||||
mime-types (1.18)
|
||||
mini_magick (3.4)
|
||||
|
|
@ -490,7 +495,7 @@ DEPENDENCIES
|
|||
jquery-rails
|
||||
json
|
||||
linecache (= 0.46)
|
||||
markerb (~> 1.0.0)
|
||||
markerb!
|
||||
messagebus_ruby_api (= 1.0.3)
|
||||
mini_magick (= 3.4)
|
||||
mobile-fu
|
||||
|
|
|
|||
3
config/initializers/markerb.rb
Normal file
3
config/initializers/markerb.rb
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
require Rails.root.join("lib", "diaspora", "markdownify_email")
|
||||
|
||||
Rails.application.config.markerb.renderer = Diaspora::Markdownify::Email
|
||||
25
lib/diaspora/markdownify_email.rb
Normal file
25
lib/diaspora/markdownify_email.rb
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
require Rails.root.join("app", "models", "acts_as_taggable_on", "tag")
|
||||
|
||||
module Diaspora
|
||||
module Markdownify
|
||||
class Email < Redcarpet::Render::HTML
|
||||
TAG_REGEX = /(?:^|\s)#([#{ActsAsTaggableOn::Tag.tag_text_regexp}]+)/u
|
||||
def preprocess(text)
|
||||
process_tags(text)
|
||||
end
|
||||
|
||||
private
|
||||
def tags(text)
|
||||
text.scan(TAG_REGEX).map { |match| match[0] }
|
||||
end
|
||||
|
||||
def process_tags(text)
|
||||
return text unless text.match(TAG_REGEX)
|
||||
tags(text).each do |tag|
|
||||
text.gsub!(/##{tag}/i, "\\##{tag}")
|
||||
end
|
||||
text
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
36
spec/lib/diaspora/markdownify_email_spec.rb
Normal file
36
spec/lib/diaspora/markdownify_email_spec.rb
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Diaspora::Markdownify::Email do
|
||||
describe '#preprocess' do
|
||||
before do
|
||||
@html = Diaspora::Markdownify::Email.new
|
||||
end
|
||||
|
||||
it 'should escape a hashtag' do
|
||||
markdownified = @html.preprocess("#tag")
|
||||
markdownified.should == "\\#tag"
|
||||
end
|
||||
|
||||
it 'should escape multiple hashtags' do
|
||||
markdownified = @html.preprocess("There are #two #tags")
|
||||
markdownified.should == "There are \\#two \\#tags"
|
||||
end
|
||||
|
||||
it 'should not escape headers' do
|
||||
markdownified = @html.preprocess("# header")
|
||||
markdownified.should == "# header"
|
||||
end
|
||||
end
|
||||
|
||||
describe "Markdown rendering" do
|
||||
before do
|
||||
@markdown = Redcarpet::Markdown.new(Diaspora::Markdownify::Email)
|
||||
@sample_text = "# Header\n\n#messages containing #hashtags should render properly"
|
||||
end
|
||||
|
||||
it 'should render the message' do
|
||||
rendered = @markdown.render(@sample_text).strip
|
||||
rendered.should == "<h1>Header</h1>\n\n<p>#messages containing #hashtags should render properly</p>"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -325,4 +325,13 @@ describe Notifier do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'hashtags' do
|
||||
it 'escapes hashtags' do
|
||||
mails = Notifier.admin("#Welcome to bureaucracy!", [bob])
|
||||
mails.length.should == 1
|
||||
mail = mails.first
|
||||
mail.body.encoded.should match /#Welcome to bureaucracy!/
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Reference in a new issue