##// END OF EJS Templates
Extracted auto_link and auto_mailto to a module....
Jean-Philippe Lang -
r8943:739820141a4b
parent child
Show More
@@ -80,19 +80,77 module Redmine
80 end
80 end
81 end
81 end
82
82
83 module LinksHelper
84 AUTO_LINK_RE = %r{
85 ( # leading text
86 <\w+.*?>| # leading HTML tag, or
87 [^=<>!:'"/]| # leading punctuation, or
88 ^ # beginning of line
89 )
90 (
91 (?:https?://)| # protocol spec, or
92 (?:s?ftps?://)|
93 (?:www\.) # www.*
94 )
95 (
96 (\S+?) # url
97 (\/)? # slash
98 )
99 ((?:&gt;)?|[^\w\=\/;\(\)]*?) # post
100 (?=<|\s|$)
101 }x unless const_defined?(:AUTO_LINK_RE)
102
103 # Destructively remplaces urls into clickable links
104 def auto_link!(text)
105 text.gsub!(AUTO_LINK_RE) do
106 all, leading, proto, url, post = $&, $1, $2, $3, $6
107 if leading =~ /<a\s/i || leading =~ /![<>=]?/
108 # don't replace URL's that are already linked
109 # and URL's prefixed with ! !> !< != (textile images)
110 all
111 else
112 # Idea below : an URL with unbalanced parethesis and
113 # ending by ')' is put into external parenthesis
114 if ( url[-1]==?) and ((url.count("(") - url.count(")")) < 0 ) )
115 url=url[0..-2] # discard closing parenth from url
116 post = ")"+post # add closing parenth to post
117 end
118 tag = content_tag('a', proto + url, :href => "#{proto=="www."?"http://www.":proto}#{url}", :class => 'external')
119 %(#{leading}#{tag}#{post})
120 end
121 end
122 end
123
124 # Destructively remplaces email addresses into clickable links
125 def auto_mailto!(text)
126 text.gsub!(/([\w\.!#\$%\-+.]+@[A-Za-z0-9\-]+(\.[A-Za-z0-9\-]+)+)/) do
127 mail = $1
128 if text.match(/<a\b[^>]*>(.*)(#{Regexp.escape(mail)})(.*)<\/a>/)
129 mail
130 else
131 content_tag('a', mail, :href => "mailto:#{mail}", :class => "email")
132 end
133 end
134 end
135 end
136
83 # Default formatter module
137 # Default formatter module
84 module NullFormatter
138 module NullFormatter
85 class Formatter
139 class Formatter
86 include ActionView::Helpers::TagHelper
140 include ActionView::Helpers::TagHelper
87 include ActionView::Helpers::TextHelper
141 include ActionView::Helpers::TextHelper
88 include ActionView::Helpers::UrlHelper
142 include ActionView::Helpers::UrlHelper
143 include Redmine::WikiFormatting::LinksHelper
89
144
90 def initialize(text)
145 def initialize(text)
91 @text = text
146 @text = text
92 end
147 end
93
148
94 def to_html(*args)
149 def to_html(*args)
95 simple_format(auto_link(CGI::escapeHTML(@text)))
150 t = CGI::escapeHTML(@text)
151 auto_link!(t)
152 auto_mailto!(t)
153 simple_format(t)
96 end
154 end
97 end
155 end
98
156
@@ -23,6 +23,10 module Redmine
23 module Textile
23 module Textile
24 class Formatter < RedCloth3
24 class Formatter < RedCloth3
25 include ActionView::Helpers::TagHelper
25 include ActionView::Helpers::TagHelper
26 include Redmine::WikiFormatting::LinksHelper
27
28 alias :inline_auto_link :auto_link!
29 alias :inline_auto_mailto :auto_mailto!
26
30
27 # auto_link rule after textile rules so that it doesn't break !image_url! tags
31 # auto_link rule after textile rules so that it doesn't break !image_url! tags
28 RULES = [:textile, :block_markdown_rule, :inline_auto_link, :inline_auto_mailto]
32 RULES = [:textile, :block_markdown_rule, :inline_auto_link, :inline_auto_mailto]
@@ -124,58 +128,6 module Redmine
124 end
128 end
125 end
129 end
126 end
130 end
127
128 AUTO_LINK_RE = %r{
129 ( # leading text
130 <\w+.*?>| # leading HTML tag, or
131 [^=<>!:'"/]| # leading punctuation, or
132 ^ # beginning of line
133 )
134 (
135 (?:https?://)| # protocol spec, or
136 (?:s?ftps?://)|
137 (?:www\.) # www.*
138 )
139 (
140 (\S+?) # url
141 (\/)? # slash
142 )
143 ((?:&gt;)?|[^\w\=\/;\(\)]*?) # post
144 (?=<|\s|$)
145 }x unless const_defined?(:AUTO_LINK_RE)
146
147 # Turns all urls into clickable links (code from Rails).
148 def inline_auto_link(text)
149 text.gsub!(AUTO_LINK_RE) do
150 all, leading, proto, url, post = $&, $1, $2, $3, $6
151 if leading =~ /<a\s/i || leading =~ /![<>=]?/
152 # don't replace URL's that are already linked
153 # and URL's prefixed with ! !> !< != (textile images)
154 all
155 else
156 # Idea below : an URL with unbalanced parethesis and
157 # ending by ')' is put into external parenthesis
158 if ( url[-1]==?) and ((url.count("(") - url.count(")")) < 0 ) )
159 url=url[0..-2] # discard closing parenth from url
160 post = ")"+post # add closing parenth to post
161 end
162 tag = content_tag('a', proto + url, :href => "#{proto=="www."?"http://www.":proto}#{url}", :class => 'external')
163 %(#{leading}#{tag}#{post})
164 end
165 end
166 end
167
168 # Turns all email addresses into clickable links (code from Rails).
169 def inline_auto_mailto(text)
170 text.gsub!(/([\w\.!#\$%\-+.]+@[A-Za-z0-9\-]+(\.[A-Za-z0-9\-]+)+)/) do
171 mail = $1
172 if text.match(/<a\b[^>]*>(.*)(#{Regexp.escape(mail)})(.*)<\/a>/)
173 mail
174 else
175 content_tag('a', mail, :href => "mailto:#{mail}", :class => "email")
176 end
177 end
178 end
179 end
131 end
180 end
132 end
181 end
133 end
@@ -940,7 +940,7 RAW
940 def test_default_formatter
940 def test_default_formatter
941 with_settings :text_formatting => 'unknown' do
941 with_settings :text_formatting => 'unknown' do
942 text = 'a *link*: http://www.example.net/'
942 text = 'a *link*: http://www.example.net/'
943 assert_equal '<p>a *link*: <a href="http://www.example.net/">http://www.example.net/</a></p>', textilizable(text)
943 assert_equal '<p>a *link*: <a class="external" href="http://www.example.net/">http://www.example.net/</a></p>', textilizable(text)
944 end
944 end
945 end
945 end
946
946
@@ -36,8 +36,8 and an email address foo@example.net
36 DIFF
36 DIFF
37
37
38 expected = <<-EXPECTED
38 expected = <<-EXPECTED
39 <p>This is a sample *text* with a link: <a href="http://www.redmine.org">http://www.redmine.org</a><br />
39 <p>This is a sample *text* with a link: <a class="external" href="http://www.redmine.org">http://www.redmine.org</a><br />
40 and an email address <a href="mailto:foo@example.net">foo@example.net</a></p>
40 and an email address <a class="email" href="mailto:foo@example.net">foo@example.net</a></p>
41 EXPECTED
41 EXPECTED
42
42
43 assert_equal expected.gsub(%r{[\r\n\t]}, ''), Redmine::WikiFormatting::NullFormatter::Formatter.new(raw).to_html.gsub(%r{[\r\n\t]}, '')
43 assert_equal expected.gsub(%r{[\r\n\t]}, ''), Redmine::WikiFormatting::NullFormatter::Formatter.new(raw).to_html.gsub(%r{[\r\n\t]}, '')
General Comments 0
You need to be logged in to leave comments. Login now