diff --git a/app/logical/d_text.rb b/app/logical/d_text.rb index 39daefbb1..c40b63343 100644 --- a/app/logical/d_text.rb +++ b/app/logical/d_text.rb @@ -2,7 +2,7 @@ require 'cgi' require 'uri' class DText - MENTION_REGEXP = /(?:^| )@\S+/ + MENTION_REGEXP = /(?<=^| )@\S+/ def self.u(string) CGI.escape(string) @@ -38,7 +38,26 @@ class DText str.gsub!(/&/, "&") str.gsub!(//, ">") + str.gsub!(/\n/m, "
") unless options[:ignore_newlines] + str.gsub!(/\[b\](.+?)\[\/b\]/i, '\1') + str.gsub!(/\[i\](.+?)\[\/i\]/i, '\1') + str.gsub!(/\[s\](.+?)\[\/s\]/i, '\1') + str.gsub!(/\[u\](.+?)\[\/u\]/i, '\1') + str.gsub!(/\[tn\](.+?)\[\/tn\]/i, '

\1

') + + str = parse_mentions(str) + str = parse_links(str) + str = parse_aliased_wiki_links(str) + str = parse_wiki_links(str) + str = parse_post_links(str) + str = parse_id_links(str) + str + end + + def self.parse_mentions(str) str.gsub!(MENTION_REGEXP) do |name| + next name unless name =~ /[a-z0-9]/i + if name =~ /([:;,.!?\)\]<>])$/ name.chop! ch = $1 @@ -48,18 +67,6 @@ class DText '' + name + '' + ch end - str.gsub!(/\n/m, "
") unless options[:ignore_newlines] - str.gsub!(/\[b\](.+?)\[\/b\]/i, '\1') - str.gsub!(/\[i\](.+?)\[\/i\]/i, '\1') - str.gsub!(/\[s\](.+?)\[\/s\]/i, '\1') - str.gsub!(/\[u\](.+?)\[\/u\]/i, '\1') - str.gsub!(/\[tn\](.+?)\[\/tn\]/i, '

\1

') - - str = parse_links(str) - str = parse_aliased_wiki_links(str) - str = parse_wiki_links(str) - str = parse_post_links(str) - str = parse_id_links(str) str end diff --git a/test/unit/dtext_test.rb b/test/unit/dtext_test.rb index d89f6f9b0..fd82b2727 100644 --- a/test/unit/dtext_test.rb +++ b/test/unit/dtext_test.rb @@ -5,6 +5,13 @@ class DTextTest < ActiveSupport::TestCase DText.parse(s) end + def test_mentions + assert_equal('

@bob

', p("@bob")) + assert_equal('

hi @bob

', p("hi @bob")) + assert_equal('

this is not @.@ @_@ @bob

', p("this is not @.@ @_@ @bob")) + assert_equal('

multiple @bob @anna

', p("multiple @bob @anna")) + end + def test_sanitize_heart assert_equal('

<3

', p("<3")) end