Extracted auto_link and auto_mailto to a module.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@9063 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
Jean-Philippe Lang 2012-03-04 10:04:46 +00:00
parent b4f22b93e9
commit 739820141a
4 changed files with 66 additions and 56 deletions

View File

@ -80,19 +80,77 @@ module Redmine
end
end
module LinksHelper
AUTO_LINK_RE = %r{
( # leading text
<\w+.*?>| # leading HTML tag, or
[^=<>!:'"/]| # leading punctuation, or
^ # beginning of line
)
(
(?:https?://)| # protocol spec, or
(?:s?ftps?://)|
(?:www\.) # www.*
)
(
(\S+?) # url
(\/)? # slash
)
((?:&gt;)?|[^\w\=\/;\(\)]*?) # post
(?=<|\s|$)
}x unless const_defined?(:AUTO_LINK_RE)
# Destructively remplaces urls into clickable links
def auto_link!(text)
text.gsub!(AUTO_LINK_RE) do
all, leading, proto, url, post = $&, $1, $2, $3, $6
if leading =~ /<a\s/i || leading =~ /![<>=]?/
# don't replace URL's that are already linked
# and URL's prefixed with ! !> !< != (textile images)
all
else
# Idea below : an URL with unbalanced parethesis and
# ending by ')' is put into external parenthesis
if ( url[-1]==?) and ((url.count("(") - url.count(")")) < 0 ) )
url=url[0..-2] # discard closing parenth from url
post = ")"+post # add closing parenth to post
end
tag = content_tag('a', proto + url, :href => "#{proto=="www."?"http://www.":proto}#{url}", :class => 'external')
%(#{leading}#{tag}#{post})
end
end
end
# Destructively remplaces email addresses into clickable links
def auto_mailto!(text)
text.gsub!(/([\w\.!#\$%\-+.]+@[A-Za-z0-9\-]+(\.[A-Za-z0-9\-]+)+)/) do
mail = $1
if text.match(/<a\b[^>]*>(.*)(#{Regexp.escape(mail)})(.*)<\/a>/)
mail
else
content_tag('a', mail, :href => "mailto:#{mail}", :class => "email")
end
end
end
end
# Default formatter module
module NullFormatter
class Formatter
include ActionView::Helpers::TagHelper
include ActionView::Helpers::TextHelper
include ActionView::Helpers::UrlHelper
include Redmine::WikiFormatting::LinksHelper
def initialize(text)
@text = text
end
def to_html(*args)
simple_format(auto_link(CGI::escapeHTML(@text)))
t = CGI::escapeHTML(@text)
auto_link!(t)
auto_mailto!(t)
simple_format(t)
end
end

View File

@ -23,6 +23,10 @@ module Redmine
module Textile
class Formatter < RedCloth3
include ActionView::Helpers::TagHelper
include Redmine::WikiFormatting::LinksHelper
alias :inline_auto_link :auto_link!
alias :inline_auto_mailto :auto_mailto!
# auto_link rule after textile rules so that it doesn't break !image_url! tags
RULES = [:textile, :block_markdown_rule, :inline_auto_link, :inline_auto_mailto]
@ -124,58 +128,6 @@ module Redmine
end
end
end
AUTO_LINK_RE = %r{
( # leading text
<\w+.*?>| # leading HTML tag, or
[^=<>!:'"/]| # leading punctuation, or
^ # beginning of line
)
(
(?:https?://)| # protocol spec, or
(?:s?ftps?://)|
(?:www\.) # www.*
)
(
(\S+?) # url
(\/)? # slash
)
((?:&gt;)?|[^\w\=\/;\(\)]*?) # post
(?=<|\s|$)
}x unless const_defined?(:AUTO_LINK_RE)
# Turns all urls into clickable links (code from Rails).
def inline_auto_link(text)
text.gsub!(AUTO_LINK_RE) do
all, leading, proto, url, post = $&, $1, $2, $3, $6
if leading =~ /<a\s/i || leading =~ /![<>=]?/
# don't replace URL's that are already linked
# and URL's prefixed with ! !> !< != (textile images)
all
else
# Idea below : an URL with unbalanced parethesis and
# ending by ')' is put into external parenthesis
if ( url[-1]==?) and ((url.count("(") - url.count(")")) < 0 ) )
url=url[0..-2] # discard closing parenth from url
post = ")"+post # add closing parenth to post
end
tag = content_tag('a', proto + url, :href => "#{proto=="www."?"http://www.":proto}#{url}", :class => 'external')
%(#{leading}#{tag}#{post})
end
end
end
# Turns all email addresses into clickable links (code from Rails).
def inline_auto_mailto(text)
text.gsub!(/([\w\.!#\$%\-+.]+@[A-Za-z0-9\-]+(\.[A-Za-z0-9\-]+)+)/) do
mail = $1
if text.match(/<a\b[^>]*>(.*)(#{Regexp.escape(mail)})(.*)<\/a>/)
mail
else
content_tag('a', mail, :href => "mailto:#{mail}", :class => "email")
end
end
end
end
end
end

View File

@ -940,7 +940,7 @@ RAW
def test_default_formatter
with_settings :text_formatting => 'unknown' do
text = 'a *link*: http://www.example.net/'
assert_equal '<p>a *link*: <a href="http://www.example.net/">http://www.example.net/</a></p>', textilizable(text)
assert_equal '<p>a *link*: <a class="external" href="http://www.example.net/">http://www.example.net/</a></p>', textilizable(text)
end
end

View File

@ -36,8 +36,8 @@ and an email address foo@example.net
DIFF
expected = <<-EXPECTED
<p>This is a sample *text* with a link: <a href="http://www.redmine.org">http://www.redmine.org</a><br />
and an email address <a href="mailto:foo@example.net">foo@example.net</a></p>
<p>This is a sample *text* with a link: <a class="external" href="http://www.redmine.org">http://www.redmine.org</a><br />
and an email address <a class="email" href="mailto:foo@example.net">foo@example.net</a></p>
EXPECTED
assert_equal expected.gsub(%r{[\r\n\t]}, ''), Redmine::WikiFormatting::NullFormatter::Formatter.new(raw).to_html.gsub(%r{[\r\n\t]}, '')