Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 597 lines (546 sloc) 25.536 kb
76f024a @fxn adds missing requires for Object#blank? and Object#present?
fxn authored
1 require 'active_support/core_ext/object/blank'
d57397c @dhh Extracted String#truncate from TextHelper#truncate [DHH]
dhh authored
2 require 'active_support/core_ext/string/filters'
0eacdcf @jeremy Use a consistent load path to avoid double requires. Fix some scattered ...
jeremy authored
3 require 'action_view/helpers/tag_helper'
9853134 @josh Require missing libraries and check for defined ActionController constan...
josh authored
4
db045db @dhh Initial
dhh authored
5 module ActionView
6 module Helpers #:nodoc:
603c853 @josh Don't fallback to just adding "'s" in TextHelper#pluralize, because the ...
josh authored
7 # The TextHelper module provides a set of methods for filtering, formatting
8 # and transforming strings, which can reduce the amount of inline Ruby code in
9 # your views. These helper methods extend ActionView making them callable
b00e6a9 @dhh Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
10 # within your template files.
603c853 @josh Don't fallback to just adding "'s" in TextHelper#pluralize, because the ...
josh authored
11 module TextHelper
12 # The preferred method of outputting text in your views is to use the
13 # <%= "text" %> eRuby syntax. The regular _puts_ and _print_ methods
14 # do not operate as expected in an eRuby code block. If you absolutely must
b00e6a9 @dhh Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
15 # output text within a non-output code block (i.e., <% %>), you can use the concat method.
b34ed9b @dhh Docfix (closes #6393)
dhh authored
16 #
b00e6a9 @dhh Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
17 # ==== Examples
603c853 @josh Don't fallback to just adding "'s" in TextHelper#pluralize, because the ...
josh authored
18 # <%
4d4c8e2 @jeremy Don't pass block binding to concat
jeremy authored
19 # concat "hello"
b00e6a9 @dhh Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
20 # # is the equivalent of <%= "hello" %>
21 #
8e72fd9 @fxn revises an example in the rdoc of TextHelper#concat
fxn authored
22 # if logged_in
4d4c8e2 @jeremy Don't pass block binding to concat
jeremy authored
23 # concat "Logged in!"
b00e6a9 @dhh Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
24 # else
4d4c8e2 @jeremy Don't pass block binding to concat
jeremy authored
25 # concat link_to('login', :action => login)
b00e6a9 @dhh Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
26 # end
27 # # will either display "Logged in!" or a login link
28 # %>
4cbb9db For performance reasons, you can no longer call html_safe! on Strings. I...
Yehuda Katz authored
29 def concat(string)
72f93b5 @jeremy Check whether blocks are called from erb using a special __in_erb_templa...
jeremy authored
30 output_buffer << string
db045db @dhh Initial
dhh authored
31 end
32
4cbb9db For performance reasons, you can no longer call html_safe! on Strings. I...
Yehuda Katz authored
33 def safe_concat(string)
c61ed70 Some more tweaks on <% %>.
Carlhuda authored
34 output_buffer.respond_to?(:safe_concat) ? output_buffer.safe_concat(string) : concat(string)
4cbb9db For performance reasons, you can no longer call html_safe! on Strings. I...
Yehuda Katz authored
35 end
36
7329990 @Manfred Change all calls to String#chars to String#mb_chars. Remove a exception ...
Manfred authored
37 # Truncates a given +text+ after a given <tt>:length</tt> if +text+ is longer than <tt>:length</tt>
618771b @stevestmartin Update truncate documentation / examples to more clearly demonstrate its...
stevestmartin authored
38 # (defaults to 30). The last characters will be replaced with the <tt>:omission</tt> (defaults to "...")
39 # for a total length not exceeding <tt>:length</tt>.
40 #
5e190ef @airblade Truncate helper accepts a :separator for a more legible result [#1807 st...
airblade authored
41 # Pass a <tt>:separator</tt> to truncate +text+ at a natural break.
7329990 @Manfred Change all calls to String#chars to String#mb_chars. Remove a exception ...
Manfred authored
42 #
43 # ==== Examples
44 #
45 # truncate("Once upon a time in a world far far away")
315e895 @fxn revises the documentation of String#truncate and the truncate helper
fxn authored
46 # # => "Once upon a time in a world..."
7329990 @Manfred Change all calls to String#chars to String#mb_chars. Remove a exception ...
Manfred authored
47 #
315e895 @fxn revises the documentation of String#truncate and the truncate helper
fxn authored
48 # truncate("Once upon a time in a world far far away", :length => 17)
49 # # => "Once upon a ti..."
5e190ef @airblade Truncate helper accepts a :separator for a more legible result [#1807 st...
airblade authored
50 #
315e895 @fxn revises the documentation of String#truncate and the truncate helper
fxn authored
51 # truncate("Once upon a time in a world far far away", :lenght => 17, :separator => ' ')
52 # # => "Once upon a..."
7329990 @Manfred Change all calls to String#chars to String#mb_chars. Remove a exception ...
Manfred authored
53 #
315e895 @fxn revises the documentation of String#truncate and the truncate helper
fxn authored
54 # truncate("And they found that many people were sleeping better.", :length => 25, :omission => '... (continued)')
55 # # => "And they f... (continued)"
7329990 @Manfred Change all calls to String#chars to String#mb_chars. Remove a exception ...
Manfred authored
56 #
57 # You can still use <tt>truncate</tt> with the old API that accepts the
58 # +length+ as its optional second and the +ellipsis+ as its
59 # optional third parameter:
60 # truncate("Once upon a time in a world far far away", 14)
315e895 @fxn revises the documentation of String#truncate and the truncate helper
fxn authored
61 # # => "Once upon a..."
7329990 @Manfred Change all calls to String#chars to String#mb_chars. Remove a exception ...
Manfred authored
62 #
618771b @stevestmartin Update truncate documentation / examples to more clearly demonstrate its...
stevestmartin authored
63 # truncate("And they found that many people were sleeping better.", 25, "... (continued)")
315e895 @fxn revises the documentation of String#truncate and the truncate helper
fxn authored
64 # # => "And they f... (continued)"
7329990 @Manfred Change all calls to String#chars to String#mb_chars. Remove a exception ...
Manfred authored
65 def truncate(text, *args)
66 options = args.extract_options!
67 unless args.empty?
68 ActiveSupport::Deprecation.warn('truncate takes an option hash instead of separate ' +
69 'length and omission arguments', caller)
10d9fe4 @clemens Refactored TextHelper#truncate, highlight, excerpt, word_wrap and auto_l...
clemens authored
70
7329990 @Manfred Change all calls to String#chars to String#mb_chars. Remove a exception ...
Manfred authored
71 options[:length] = args[0] || 30
72 options[:omission] = args[1] || "..."
607511c @jeremy Ruby 1.9 compat: truncate and excerpt helpers
jeremy authored
73 end
10d9fe4 @clemens Refactored TextHelper#truncate, highlight, excerpt, word_wrap and auto_l...
clemens authored
74
d57397c @dhh Extracted String#truncate from TextHelper#truncate [DHH]
dhh authored
75 options.reverse_merge!(:length => 30)
76
77 text.truncate(options.delete(:length), options) if text
db045db @dhh Initial
dhh authored
78 end
79
67d5a1a @jeremy Highlight helper highlights one or many terms in a single pass.
jeremy authored
80 # Highlights one or more +phrases+ everywhere in +text+ by inserting it into
10d9fe4 @clemens Refactored TextHelper#truncate, highlight, excerpt, word_wrap and auto_l...
clemens authored
81 # a <tt>:highlighter</tt> string. The highlighter can be specialized by passing <tt>:highlighter</tt>
b00e6a9 @dhh Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
82 # as a single-quoted string with \1 where the phrase is to be inserted (defaults to
83 # '<strong class="highlight">\1</strong>')
b34ed9b @dhh Docfix (closes #6393)
dhh authored
84 #
b00e6a9 @dhh Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
85 # ==== Examples
603c853 @josh Don't fallback to just adding "'s" in TextHelper#pluralize, because the ...
josh authored
86 # highlight('You searched for: rails', 'rails')
67d5a1a @jeremy Highlight helper highlights one or many terms in a single pass.
jeremy authored
87 # # => You searched for: <strong class="highlight">rails</strong>
88 #
b00e6a9 @dhh Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
89 # highlight('You searched for: ruby, rails, dhh', 'actionpack')
603c853 @josh Don't fallback to just adding "'s" in TextHelper#pluralize, because the ...
josh authored
90 # # => You searched for: ruby, rails, dhh
b00e6a9 @dhh Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
91 #
10d9fe4 @clemens Refactored TextHelper#truncate, highlight, excerpt, word_wrap and auto_l...
clemens authored
92 # highlight('You searched for: rails', ['for', 'rails'], :highlighter => '<em>\1</em>')
67d5a1a @jeremy Highlight helper highlights one or many terms in a single pass.
jeremy authored
93 # # => You searched <em>for</em>: <em>rails</em>
603c853 @josh Don't fallback to just adding "'s" in TextHelper#pluralize, because the ...
josh authored
94 #
10d9fe4 @clemens Refactored TextHelper#truncate, highlight, excerpt, word_wrap and auto_l...
clemens authored
95 # highlight('You searched for: rails', 'rails', :highlighter => '<a href="search?q=\1">\1</a>')
96 # # => You searched for: <a href="search?q=rails">rails</a>
97 #
98 # You can still use <tt>highlight</tt> with the old API that accepts the
99 # +highlighter+ as its optional third parameter:
100 # highlight('You searched for: rails', 'rails', '<a href="search?q=\1">\1</a>') # => You searched for: <a href="search?q=rails">rails</a>
101 def highlight(text, phrases, *args)
102 options = args.extract_options!
103 unless args.empty?
104 options[:highlighter] = args[0] || '<strong class="highlight">\1</strong>'
105 end
106 options.reverse_merge!(:highlighter => '<strong class="highlight">\1</strong>')
107
67d5a1a @jeremy Highlight helper highlights one or many terms in a single pass.
jeremy authored
108 if text.blank? || phrases.blank?
109 text
110 else
111 match = Array(phrases).map { |p| Regexp.escape(p) }.join('|')
3c625d6 @josh Ruby 1.9 compat: removed redundant nested repeat operator
josh authored
112 text.gsub(/(#{match})(?!(?:[^<]*?)(?:["'])[^<>]*>)/i, options[:highlighter])
67d5a1a @jeremy Highlight helper highlights one or many terms in a single pass.
jeremy authored
113 end
db045db @dhh Initial
dhh authored
114 end
dfac1ce @dhh Fixed that form helpers would treat string and symbol keys differently i...
dhh authored
115
b8eec5a @Manfred Remove special 1.9 version of excerpt helper.
Manfred authored
116 # Extracts an excerpt from +text+ that matches the first instance of +phrase+.
117 # The <tt>:radius</tt> option expands the excerpt on each side of the first occurrence of +phrase+ by the number of characters
118 # defined in <tt>:radius</tt> (which defaults to 100). If the excerpt radius overflows the beginning or end of the +text+,
119 # then the <tt>:omission</tt> option (which defaults to "...") will be prepended/appended accordingly. The resulting string
120 # will be stripped in any case. If the +phrase+ isn't found, nil is returned.
121 #
122 # ==== Examples
123 # excerpt('This is an example', 'an', :radius => 5)
124 # # => ...s is an exam...
125 #
126 # excerpt('This is an example', 'is', :radius => 5)
127 # # => This is a...
128 #
129 # excerpt('This is an example', 'is')
130 # # => This is an example
131 #
132 # excerpt('This next thing is an example', 'ex', :radius => 2)
133 # # => ...next...
134 #
135 # excerpt('This is also an example', 'an', :radius => 8, :omission => '<chop> ')
136 # # => <chop> is also an example
137 #
138 # You can still use <tt>excerpt</tt> with the old API that accepts the
139 # +radius+ as its optional third and the +ellipsis+ as its
140 # optional forth parameter:
141 # excerpt('This is an example', 'an', 5) # => ...s is an exam...
142 # excerpt('This is also an example', 'an', 8, '<chop> ') # => <chop> is also an example
143 def excerpt(text, phrase, *args)
144 options = args.extract_options!
145 unless args.empty?
146 options[:radius] = args[0] || 100
147 options[:omission] = args[1] || "..."
148 end
149 options.reverse_merge!(:radius => 100, :omission => "...")
10d9fe4 @clemens Refactored TextHelper#truncate, highlight, excerpt, word_wrap and auto_l...
clemens authored
150
b8eec5a @Manfred Remove special 1.9 version of excerpt helper.
Manfred authored
151 if text && phrase
152 phrase = Regexp.escape(phrase)
dfac1ce @dhh Fixed that form helpers would treat string and symbol keys differently i...
dhh authored
153
b8eec5a @Manfred Remove special 1.9 version of excerpt helper.
Manfred authored
154 if found_pos = text.mb_chars =~ /(#{phrase})/i
155 start_pos = [ found_pos - options[:radius], 0 ].max
156 end_pos = [ [ found_pos + phrase.mb_chars.length + options[:radius] - 1, 0].max, text.mb_chars.length ].min
db045db @dhh Initial
dhh authored
157
b8eec5a @Manfred Remove special 1.9 version of excerpt helper.
Manfred authored
158 prefix = start_pos > 0 ? options[:omission] : ""
159 postfix = end_pos < text.mb_chars.length - 1 ? options[:omission] : ""
db045db @dhh Initial
dhh authored
160
b8eec5a @Manfred Remove special 1.9 version of excerpt helper.
Manfred authored
161 prefix + text.mb_chars[start_pos..end_pos].strip + postfix
162 else
163 nil
607511c @jeremy Ruby 1.9 compat: truncate and excerpt helpers
jeremy authored
164 end
165 end
b8eec5a @Manfred Remove special 1.9 version of excerpt helper.
Manfred authored
166 end
db045db @dhh Initial
dhh authored
167
603c853 @josh Don't fallback to just adding "'s" in TextHelper#pluralize, because the ...
josh authored
168 # Attempts to pluralize the +singular+ word unless +count+ is 1. If
169 # +plural+ is supplied, it will use that when count is > 1, otherwise
170 # it will use the Inflector to determine the plural form
b34ed9b @dhh Docfix (closes #6393)
dhh authored
171 #
b00e6a9 @dhh Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
172 # ==== Examples
603c853 @josh Don't fallback to just adding "'s" in TextHelper#pluralize, because the ...
josh authored
173 # pluralize(1, 'person')
b00e6a9 @dhh Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
174 # # => 1 person
175 #
603c853 @josh Don't fallback to just adding "'s" in TextHelper#pluralize, because the ...
josh authored
176 # pluralize(2, 'person')
b00e6a9 @dhh Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
177 # # => 2 people
178 #
603c853 @josh Don't fallback to just adding "'s" in TextHelper#pluralize, because the ...
josh authored
179 # pluralize(3, 'person', 'users')
b00e6a9 @dhh Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
180 # # => 3 users
181 #
182 # pluralize(0, 'person')
183 # # => 0 people
db045db @dhh Initial
dhh authored
184 def pluralize(count, singular, plural = nil)
b235af7 @gabrielmansour Fix pluralization for numbers formatted like '1.00'
gabrielmansour authored
185 "#{count || 0} " + ((count == 1 || count =~ /^1(\.0+)?$/) ? singular : (plural || singular.pluralize))
db045db @dhh Initial
dhh authored
186 end
187
b34ed9b @dhh Docfix (closes #6393)
dhh authored
188 # Wraps the +text+ into lines no longer than +line_width+ width. This method
b00e6a9 @dhh Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
189 # breaks on the first whitespace character that does not exceed +line_width+
190 # (which is 80 by default).
b34ed9b @dhh Docfix (closes #6393)
dhh authored
191 #
b00e6a9 @dhh Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
192 # ==== Examples
193 #
194 # word_wrap('Once upon a time')
195 # # => Once upon a time
196 #
10d9fe4 @clemens Refactored TextHelper#truncate, highlight, excerpt, word_wrap and auto_l...
clemens authored
197 # word_wrap('Once upon a time, in a kingdom called Far Far Away, a king fell ill, and finding a successor to the throne turned out to be more trouble than anyone could have imagined...')
198 # # => Once upon a time, in a kingdom called Far Far Away, a king fell ill, and finding\n a successor to the throne turned out to be more trouble than anyone could have\n imagined...
199 #
200 # word_wrap('Once upon a time', :line_width => 8)
201 # # => Once upon\na time
202 #
203 # word_wrap('Once upon a time', :line_width => 1)
b00e6a9 @dhh Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
204 # # => Once\nupon\na\ntime
10d9fe4 @clemens Refactored TextHelper#truncate, highlight, excerpt, word_wrap and auto_l...
clemens authored
205 #
206 # You can still use <tt>word_wrap</tt> with the old API that accepts the
207 # +line_width+ as its optional second parameter:
208 # word_wrap('Once upon a time', 8) # => Once upon\na time
209 def word_wrap(text, *args)
210 options = args.extract_options!
211 unless args.blank?
212 options[:line_width] = args[0] || 80
213 end
214 options.reverse_merge!(:line_width => 80)
215
9686dcd @dhh Fixed TextHelper#word_wrap for multiline strings with extra carrier retu...
dhh authored
216 text.split("\n").collect do |line|
10d9fe4 @clemens Refactored TextHelper#truncate, highlight, excerpt, word_wrap and auto_l...
clemens authored
217 line.length > options[:line_width] ? line.gsub(/(.{1,#{options[:line_width]}})(\s+|$)/, "\\1\n").strip : line
9686dcd @dhh Fixed TextHelper#word_wrap for multiline strings with extra carrier retu...
dhh authored
218 end * "\n"
c608ebe @dhh Added TextHelper#word_wrap(text, line_length = 80) #1449 [tuxie@dekadanc...
dhh authored
219 end
220
4b33fae @dhh Fixed RedCloth and BlueCloth shouldn't preload. Instead just assume that...
dhh authored
221 # Returns the text with all the Textile[http://www.textism.com/tools/textile] codes turned into HTML tags.
222 #
223 # You can learn more about Textile's syntax at its website[http://www.textism.com/tools/textile].
dba196c @lifo Merge docrails
lifo authored
224 # <i>This method is only available if RedCloth[http://redcloth.org/] is available</i>.
4b33fae @dhh Fixed RedCloth and BlueCloth shouldn't preload. Instead just assume that...
dhh authored
225 #
226 # ==== Examples
227 # textilize("*This is Textile!* Rejoice!")
228 # # => "<p><strong>This is Textile!</strong> Rejoice!</p>"
229 #
230 # textilize("I _love_ ROR(Ruby on Rails)!")
231 # # => "<p>I <em>love</em> <acronym title="Ruby on Rails">ROR</acronym>!</p>"
232 #
233 # textilize("h2. Textile makes markup -easy- simple!")
234 # # => "<h2>Textile makes markup <del>easy</del> simple!</h2>"
235 #
236 # textilize("Visit the Rails website "here":http://www.rubyonrails.org/.)
237 # # => "<p>Visit the Rails website <a href="http://www.rubyonrails.org/">here</a>.</p>"
7dbb2b6 @rizwanreza Support passing Redcloth options via textilize helper [#2973 state:resol...
rizwanreza authored
238 #
239 # textilize("This is worded <strong>strongly</strong>")
240 # # => "<p>This is worded <strong>strongly</strong></p>"
241 #
242 # textilize("This is worded <strong>strongly</strong>", :filter_html)
243 # # => "<p>This is worded &lt;strong&gt;strongly&lt;/strong&gt;</p>"
244 #
245 def textilize(text, *options)
246 options ||= [:hard_breaks]
247
4b33fae @dhh Fixed RedCloth and BlueCloth shouldn't preload. Instead just assume that...
dhh authored
248 if text.blank?
249 ""
250 else
7dbb2b6 @rizwanreza Support passing Redcloth options via textilize helper [#2973 state:resol...
rizwanreza authored
251 textilized = RedCloth.new(text, options)
4b33fae @dhh Fixed RedCloth and BlueCloth shouldn't preload. Instead just assume that...
dhh authored
252 textilized.to_html
db045db @dhh Initial
dhh authored
253 end
254 end
255
4b33fae @dhh Fixed RedCloth and BlueCloth shouldn't preload. Instead just assume that...
dhh authored
256 # Returns the text with all the Textile codes turned into HTML tags,
257 # but without the bounding <p> tag that RedCloth adds.
258 #
259 # You can learn more about Textile's syntax at its website[http://www.textism.com/tools/textile].
dba196c @lifo Merge docrails
lifo authored
260 # <i>This method is only available if RedCloth[http://redcloth.org/] is available</i>.
4b33fae @dhh Fixed RedCloth and BlueCloth shouldn't preload. Instead just assume that...
dhh authored
261 #
262 # ==== Examples
263 # textilize_without_paragraph("*This is Textile!* Rejoice!")
264 # # => "<strong>This is Textile!</strong> Rejoice!"
265 #
266 # textilize_without_paragraph("I _love_ ROR(Ruby on Rails)!")
267 # # => "I <em>love</em> <acronym title="Ruby on Rails">ROR</acronym>!"
268 #
269 # textilize_without_paragraph("h2. Textile makes markup -easy- simple!")
270 # # => "<h2>Textile makes markup <del>easy</del> simple!</h2>"
271 #
272 # textilize_without_paragraph("Visit the Rails website "here":http://www.rubyonrails.org/.)
273 # # => "Visit the Rails website <a href="http://www.rubyonrails.org/">here</a>."
274 def textilize_without_paragraph(text)
275 textiled = textilize(text)
276 if textiled[0..2] == "<p>" then textiled = textiled[3..-1] end
277 if textiled[-4..-1] == "</p>" then textiled = textiled[0..-5] end
278 return textiled
279 end
db045db @dhh Initial
dhh authored
280
4b33fae @dhh Fixed RedCloth and BlueCloth shouldn't preload. Instead just assume that...
dhh authored
281 # Returns the text with all the Markdown codes turned into HTML tags.
282 # <i>This method requires BlueCloth[http://www.deveiate.org/projects/BlueCloth]
283 # to be available</i>.
284 #
285 # ==== Examples
286 # markdown("We are using __Markdown__ now!")
287 # # => "<p>We are using <strong>Markdown</strong> now!</p>"
288 #
289 # markdown("We like to _write_ `code`, not just _read_ it!")
290 # # => "<p>We like to <em>write</em> <code>code</code>, not just <em>read</em> it!</p>"
291 #
292 # markdown("The [Markdown website](http://daringfireball.net/projects/markdown/) has more information.")
293 # # => "<p>The <a href="http://daringfireball.net/projects/markdown/">Markdown website</a>
294 # # has more information.</p>"
295 #
296 # markdown('![The ROR logo](http://rubyonrails.com/images/rails.png "Ruby on Rails")')
297 # # => '<p><img src="http://rubyonrails.com/images/rails.png" alt="The ROR logo" title="Ruby on Rails" /></p>'
298 def markdown(text)
299 text.blank? ? "" : BlueCloth.new(text).to_html
db045db @dhh Initial
dhh authored
300 end
603c853 @josh Don't fallback to just adding "'s" in TextHelper#pluralize, because the ...
josh authored
301
b34ed9b @dhh Docfix (closes #6393)
dhh authored
302 # Returns +text+ transformed into HTML using simple formatting rules.
603c853 @josh Don't fallback to just adding "'s" in TextHelper#pluralize, because the ...
josh authored
303 # Two or more consecutive newlines(<tt>\n\n</tt>) are considered as a
b34ed9b @dhh Docfix (closes #6393)
dhh authored
304 # paragraph and wrapped in <tt><p></tt> tags. One newline (<tt>\n</tt>) is
305 # considered as a linebreak and a <tt><br /></tt> tag is appended. This
603c853 @josh Don't fallback to just adding "'s" in TextHelper#pluralize, because the ...
josh authored
306 # method does not remove the newlines from the +text+.
b00e6a9 @dhh Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
307 #
603c853 @josh Don't fallback to just adding "'s" in TextHelper#pluralize, because the ...
josh authored
308 # You can pass any HTML attributes into <tt>html_options</tt>. These
5bf4cbb @technoweenie Allow the #simple_format text_helper to take an html_options hash for ea...
technoweenie authored
309 # will be added to all created paragraphs.
b00e6a9 @dhh Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
310 # ==== Examples
1b41178 @dhh Docfix (closes #11230) [Henrik N]
dhh authored
311 # my_text = "Here is some basic text...\n...with a line break."
b00e6a9 @dhh Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
312 #
313 # simple_format(my_text)
1b41178 @dhh Docfix (closes #11230) [Henrik N]
dhh authored
314 # # => "<p>Here is some basic text...\n<br />...with a line break.</p>"
b00e6a9 @dhh Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
315 #
1b41178 @dhh Docfix (closes #11230) [Henrik N]
dhh authored
316 # more_text = "We want to put a paragraph...\n\n...right there."
b00e6a9 @dhh Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
317 #
318 # simple_format(more_text)
1b41178 @dhh Docfix (closes #11230) [Henrik N]
dhh authored
319 # # => "<p>We want to put a paragraph...</p>\n\n<p>...right there.</p>"
5bf4cbb @technoweenie Allow the #simple_format text_helper to take an html_options hash for ea...
technoweenie authored
320 #
321 # simple_format("Look ma! A class!", :class => 'description')
322 # # => "<p class='description'>Look ma! A class!</p>"
323 def simple_format(text, html_options={})
324 start_tag = tag('p', html_options, true)
d68f8ba @dhh simple_format returns a safe buffer escaping unsafe input [Santiago Past...
dhh authored
325 text = h(text)
5bf4cbb @technoweenie Allow the #simple_format text_helper to take an html_options hash for ea...
technoweenie authored
326 text.gsub!(/\r\n?/, "\n") # \r\n and \r -> \n
327 text.gsub!(/\n\n+/, "</p>\n\n#{start_tag}") # 2+ newline -> paragraph
328 text.gsub!(/([^\n]\n)(?=[^\n])/, '\1<br />') # 1 newline -> br
329 text.insert 0, start_tag
325fa58 @dhh Safely concat the ending tag to simple_format or it will be escaped
dhh authored
330 text.safe_concat("</p>")
1b93da3 @dhh Added TextHelper#simple_format as a non-dependency text presentation hel...
dhh authored
331 end
db045db @dhh Initial
dhh authored
332
b047929 @lifo Merge with docrails
lifo authored
333 # Turns all URLs and e-mail addresses into clickable links. The <tt>:link</tt> option
b00e6a9 @dhh Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
334 # will limit what should be linked. You can add HTML attributes to the links using
f97832b @lifo Merge docrails
lifo authored
335 # <tt>:html</tt>. Possible values for <tt>:link</tt> are <tt>:all</tt> (default),
603c853 @josh Don't fallback to just adding "'s" in TextHelper#pluralize, because the ...
josh authored
336 # <tt>:email_addresses</tt>, and <tt>:urls</tt>. If a block is given, each URL and
b00e6a9 @dhh Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
337 # e-mail address is yielded and the result is used as the link text.
338 #
339 # ==== Examples
603c853 @josh Don't fallback to just adding "'s" in TextHelper#pluralize, because the ...
josh authored
340 # auto_link("Go to http://www.rubyonrails.org and say hello to david@loudthinking.com")
c92a7ce @dhh Docfix (closes #10493)
dhh authored
341 # # => "Go to <a href=\"http://www.rubyonrails.org\">http://www.rubyonrails.org</a> and
342 # # say hello to <a href=\"mailto:david@loudthinking.com\">david@loudthinking.com</a>"
0369ec7 @dhh Made auto_link the only public method of its clan and added an option to...
dhh authored
343 #
b047929 @lifo Merge with docrails
lifo authored
344 # auto_link("Visit http://www.loudthinking.com/ or e-mail david@loudthinking.com", :link => :urls)
603c853 @josh Don't fallback to just adding "'s" in TextHelper#pluralize, because the ...
josh authored
345 # # => "Visit <a href=\"http://www.loudthinking.com/\">http://www.loudthinking.com/</a>
b00e6a9 @dhh Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
346 # # or e-mail david@loudthinking.com"
adba181 @jeremy The auto_link text helper accepts an optional block to format the link t...
jeremy authored
347 #
b047929 @lifo Merge with docrails
lifo authored
348 # auto_link("Visit http://www.loudthinking.com/ or e-mail david@loudthinking.com", :link => :email_addresses)
b00e6a9 @dhh Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
349 # # => "Visit http://www.loudthinking.com/ or e-mail <a href=\"mailto:david@loudthinking.com\">david@loudthinking.com</a>"
b34ed9b @dhh Docfix (closes #6393)
dhh authored
350 #
b00e6a9 @dhh Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
351 # post_body = "Welcome to my new blog at http://www.myblog.com/. Please e-mail me at me@email.com."
f97832b @lifo Merge docrails
lifo authored
352 # auto_link(post_body, :html => { :target => '_blank' }) do |text|
adba181 @jeremy The auto_link text helper accepts an optional block to format the link t...
jeremy authored
353 # truncate(text, 15)
354 # end
603c853 @josh Don't fallback to just adding "'s" in TextHelper#pluralize, because the ...
josh authored
355 # # => "Welcome to my new blog at <a href=\"http://www.myblog.com/\" target=\"_blank\">http://www.m...</a>.
b00e6a9 @dhh Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
356 # Please e-mail me at <a href=\"mailto:me@email.com\">me@email.com</a>."
603c853 @josh Don't fallback to just adding "'s" in TextHelper#pluralize, because the ...
josh authored
357 #
10d9fe4 @clemens Refactored TextHelper#truncate, highlight, excerpt, word_wrap and auto_l...
clemens authored
358 #
359 # You can still use <tt>auto_link</tt> with the old API that accepts the
360 # +link+ as its optional second parameter and the +html_options+ hash
361 # as its optional third parameter:
362 # post_body = "Welcome to my new blog at http://www.myblog.com/. Please e-mail me at me@email.com."
363 # auto_link(post_body, :urls) # => Once upon\na time
364 # # => "Welcome to my new blog at <a href=\"http://www.myblog.com/\">http://www.myblog.com</a>.
365 # Please e-mail me at me@email.com."
366 #
367 # auto_link(post_body, :all, :target => "_blank") # => Once upon\na time
368 # # => "Welcome to my new blog at <a href=\"http://www.myblog.com/\" target=\"_blank\">http://www.myblog.com</a>.
369 # Please e-mail me at <a href=\"mailto:me@email.com\">me@email.com</a>."
f97832b @lifo Merge docrails
lifo authored
370 def auto_link(text, *args, &block)#link = :all, html = {}, &block)
63c822a Make auto_link handle nil by returning quickly if blank?
Scott Barron authored
371 return '' if text.blank?
10d9fe4 @clemens Refactored TextHelper#truncate, highlight, excerpt, word_wrap and auto_l...
clemens authored
372
373 options = args.size == 2 ? {} : args.extract_options! # this is necessary because the old auto_link API has a Hash as its last parameter
374 unless args.empty?
375 options[:link] = args[0] || :all
376 options[:html] = args[1] || {}
377 end
378 options.reverse_merge!(:link => :all, :html => {})
379
380 case options[:link].to_sym
bda55f8 @akaspick allow options to be passed to email address auto generation
akaspick authored
381 when :all then auto_link_email_addresses(auto_link_urls(text, options[:html], &block), options[:html], &block)
382 when :email_addresses then auto_link_email_addresses(text, options[:html], &block)
10d9fe4 @clemens Refactored TextHelper#truncate, highlight, excerpt, word_wrap and auto_l...
clemens authored
383 when :urls then auto_link_urls(text, options[:html], &block)
0369ec7 @dhh Made auto_link the only public method of its clan and added an option to...
dhh authored
384 end
b305756 @dhh Added TextHelper#auto_link, TextHelper#auto_link_urls, and TextHelper#au...
dhh authored
385 end
603c853 @josh Don't fallback to just adding "'s" in TextHelper#pluralize, because the ...
josh authored
386
b34ed9b @dhh Docfix (closes #6393)
dhh authored
387 # Creates a Cycle object whose _to_s_ method cycles through elements of an
603c853 @josh Don't fallback to just adding "'s" in TextHelper#pluralize, because the ...
josh authored
388 # array every time it is called. This can be used for example, to alternate
389 # classes for table rows. You can use named cycles to allow nesting in loops.
390 # Passing a Hash as the last parameter with a <tt>:name</tt> key will create a
f277e1d @metaskills Added TextHelper#current_cycle to return the current cycle for better de...
metaskills authored
391 # named cycle. The default name for a cycle without a +:name+ key is
392 # <tt>"default"</tt>. You can manually reset a cycle by calling reset_cycle
393 # and passing the name of the cycle. The current cycle string can be obtained
394 # anytime using the current_cycle method.
2fe8610 @dhh Added TextHelper#cycle to cycle over an array of values on each hit (use...
dhh authored
395 #
603c853 @josh Don't fallback to just adding "'s" in TextHelper#pluralize, because the ...
josh authored
396 # ==== Examples
b00e6a9 @dhh Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
397 # # Alternate CSS classes for even and odd numbers...
398 # @items = [1,2,3,4]
399 # <table>
b34ed9b @dhh Docfix (closes #6393)
dhh authored
400 # <% @items.each do |item| %>
401 # <tr class="<%= cycle("even", "odd") -%>">
402 # <td>item</td>
4d007ce Fix text_helper.rb documentation rendering. Closes #4725. [Frederick Ros...
Marcel Molina authored
403 # </tr>
b34ed9b @dhh Docfix (closes #6393)
dhh authored
404 # <% end %>
b00e6a9 @dhh Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
405 # </table>
2fe8610 @dhh Added TextHelper#cycle to cycle over an array of values on each hit (use...
dhh authored
406 #
407 #
b00e6a9 @dhh Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
408 # # Cycle CSS classes for rows, and text colors for values within each row
603c853 @josh Don't fallback to just adding "'s" in TextHelper#pluralize, because the ...
josh authored
409 # @items = x = [{:first => 'Robert', :middle => 'Daniel', :last => 'James'},
410 # {:first => 'Emily', :middle => 'Shannon', :maiden => 'Pike', :last => 'Hicks'},
b00e6a9 @dhh Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
411 # {:first => 'June', :middle => 'Dae', :last => 'Jones'}]
b34ed9b @dhh Docfix (closes #6393)
dhh authored
412 # <% @items.each do |item| %>
2f3eefc Nitpick: the first value should be odd, second is even.
Ryan Bigg authored
413 # <tr class="<%= cycle("odd", "even", :name => "row_class") -%>">
4d007ce Fix text_helper.rb documentation rendering. Closes #4725. [Frederick Ros...
Marcel Molina authored
414 # <td>
b34ed9b @dhh Docfix (closes #6393)
dhh authored
415 # <% item.values.each do |value| %>
e71465b @dhh Avoid RDoc warning
dhh authored
416 # <%# Create a named cycle "colors" %>
b34ed9b @dhh Docfix (closes #6393)
dhh authored
417 # <span style="color:<%= cycle("red", "green", "blue", :name => "colors") -%>">
b00e6a9 @dhh Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
418 # <%= value %>
4d007ce Fix text_helper.rb documentation rendering. Closes #4725. [Frederick Ros...
Marcel Molina authored
419 # </span>
b34ed9b @dhh Docfix (closes #6393)
dhh authored
420 # <% end %>
421 # <% reset_cycle("colors") %>
4d007ce Fix text_helper.rb documentation rendering. Closes #4725. [Frederick Ros...
Marcel Molina authored
422 # </td>
423 # </tr>
b34ed9b @dhh Docfix (closes #6393)
dhh authored
424 # <% end %>
2fe8610 @dhh Added TextHelper#cycle to cycle over an array of values on each hit (use...
dhh authored
425 def cycle(first_value, *values)
426 if (values.last.instance_of? Hash)
427 params = values.pop
428 name = params[:name]
429 else
430 name = "default"
431 end
432 values.unshift(first_value)
433
434 cycle = get_cycle(name)
435 if (cycle.nil? || cycle.values != values)
436 cycle = set_cycle(name, Cycle.new(*values))
437 end
438 return cycle.to_s
439 end
603c853 @josh Don't fallback to just adding "'s" in TextHelper#pluralize, because the ...
josh authored
440
f277e1d @metaskills Added TextHelper#current_cycle to return the current cycle for better de...
metaskills authored
441 # Returns the current cycle string after a cycle has been started. Useful
e033b5d @lifo Merge docrails
lifo authored
442 # for complex table highlighting or any other design need which requires
f277e1d @metaskills Added TextHelper#current_cycle to return the current cycle for better de...
metaskills authored
443 # the current cycle string in more than one place.
444 #
445 # ==== Example
446 # # Alternate background colors
447 # @items = [1,2,3,4]
448 # <% @items.each do |item| %>
449 # <div style="background-color:<%= cycle("red","white","blue") %>">
6ef3546 @lifo Merge docrails
lifo authored
450 # <span style="background-color:<%= current_cycle %>"><%= item %></span>
f277e1d @metaskills Added TextHelper#current_cycle to return the current cycle for better de...
metaskills authored
451 # </div>
452 # <% end %>
453 def current_cycle(name = "default")
454 cycle = get_cycle(name)
455 cycle.current_value unless cycle.nil?
456 end
457
603c853 @josh Don't fallback to just adding "'s" in TextHelper#pluralize, because the ...
josh authored
458 # Resets a cycle so that it starts from the first element the next time
b34ed9b @dhh Docfix (closes #6393)
dhh authored
459 # it is called. Pass in +name+ to reset a named cycle.
b00e6a9 @dhh Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
460 #
461 # ==== Example
462 # # Alternate CSS classes for even and odd numbers...
463 # @items = [[1,2,3,4], [5,6,3], [3,4,5,6,7,4]]
464 # <table>
465 # <% @items.each do |item| %>
466 # <tr class="<%= cycle("even", "odd") -%>">
467 # <% item.each do |value| %>
468 # <span style="color:<%= cycle("#333", "#666", "#999", :name => "colors") -%>">
469 # <%= value %>
470 # </span>
471 # <% end %>
472 #
473 # <% reset_cycle("colors") %>
474 # </tr>
475 # <% end %>
476 # </table>
2fe8610 @dhh Added TextHelper#cycle to cycle over an array of values on each hit (use...
dhh authored
477 def reset_cycle(name = "default")
478 cycle = get_cycle(name)
71234da @jeremy r4487@asus: jeremy | 2006-04-29 12:21:39 -0700
jeremy authored
479 cycle.reset unless cycle.nil?
2fe8610 @dhh Added TextHelper#cycle to cycle over an array of values on each hit (use...
dhh authored
480 end
481
1c057b7 @jamis Update/clean up AP documentation (rdoc)
jamis authored
482 class Cycle #:nodoc:
2fe8610 @dhh Added TextHelper#cycle to cycle over an array of values on each hit (use...
dhh authored
483 attr_reader :values
603c853 @josh Don't fallback to just adding "'s" in TextHelper#pluralize, because the ...
josh authored
484
2fe8610 @dhh Added TextHelper#cycle to cycle over an array of values on each hit (use...
dhh authored
485 def initialize(first_value, *values)
486 @values = values.unshift(first_value)
487 reset
488 end
603c853 @josh Don't fallback to just adding "'s" in TextHelper#pluralize, because the ...
josh authored
489
2fe8610 @dhh Added TextHelper#cycle to cycle over an array of values on each hit (use...
dhh authored
490 def reset
491 @index = 0
492 end
493
f277e1d @metaskills Added TextHelper#current_cycle to return the current cycle for better de...
metaskills authored
494 def current_value
495 @values[previous_index].to_s
496 end
497
2fe8610 @dhh Added TextHelper#cycle to cycle over an array of values on each hit (use...
dhh authored
498 def to_s
499 value = @values[@index].to_s
f277e1d @metaskills Added TextHelper#current_cycle to return the current cycle for better de...
metaskills authored
500 @index = next_index
2fe8610 @dhh Added TextHelper#cycle to cycle over an array of values on each hit (use...
dhh authored
501 return value
502 end
f277e1d @metaskills Added TextHelper#current_cycle to return the current cycle for better de...
metaskills authored
503
504 private
505
506 def next_index
507 step_index(1)
508 end
509
510 def previous_index
511 step_index(-1)
512 end
513
514 def step_index(n)
515 (@index + n) % @values.size
516 end
2fe8610 @dhh Added TextHelper#cycle to cycle over an array of values on each hit (use...
dhh authored
517 end
da0725a @technoweenie move TextHelper#sanitize config options to the TextHelper module so it c...
technoweenie authored
518
db045db @dhh Initial
dhh authored
519 private
2fe8610 @dhh Added TextHelper#cycle to cycle over an array of values on each hit (use...
dhh authored
520 # The cycle helpers need to store the cycles in a place that is
521 # guaranteed to be reset every time a page is rendered, so it
522 # uses an instance variable of ActionView::Base.
523 def get_cycle(name)
71234da @jeremy r4487@asus: jeremy | 2006-04-29 12:21:39 -0700
jeremy authored
524 @_cycles = Hash.new unless defined?(@_cycles)
2fe8610 @dhh Added TextHelper#cycle to cycle over an array of values on each hit (use...
dhh authored
525 return @_cycles[name]
526 end
603c853 @josh Don't fallback to just adding "'s" in TextHelper#pluralize, because the ...
josh authored
527
2fe8610 @dhh Added TextHelper#cycle to cycle over an array of values on each hit (use...
dhh authored
528 def set_cycle(name, cycle_object)
71234da @jeremy r4487@asus: jeremy | 2006-04-29 12:21:39 -0700
jeremy authored
529 @_cycles = Hash.new unless defined?(@_cycles)
2fe8610 @dhh Added TextHelper#cycle to cycle over an array of values on each hit (use...
dhh authored
530 @_cycles[name] = cycle_object
531 end
8e82e29 @madrobby Make TextHelper::auto_link recognize URLs with colons in path correctly,...
madrobby authored
532
bdf91d6 @jamis Make auto_link parse a greater subset of valid url formats.
jamis authored
533 AUTO_LINK_RE = %r{
133ada6 @mislav auto_link: support arbitrary URI schemes like "ftp:" and "file:"
mislav authored
534 (?: ([\w+.:-]+:)// | www\. )
c6c5cd5 @mislav refactor autolink helper. change tests to expect HTML-escaped URLs
mislav authored
535 [^\s<]+
8f0b213 @mislav avoid auto_linking already linked emails; more robust detection of linke...
mislav authored
536 }x
537
538 # regexps for determining context, used high-volume
539 AUTO_LINK_CRE = [/<[^>]+$/, /^[^>]*>/, /<a\b.*?>/i, /<\/a>/i]
540
541 AUTO_EMAIL_RE = /[\w.!#\$%+-]+@[\w-]+(?:\.[\w-]+)+/
b97f4e4 @jamis Fix autolinking to not include trailing tags as part of the URL
jamis authored
542
4f984c9 @mislav auto_link helper: add intelligent ending closing bracket handling. add n...
mislav authored
543 BRACKETS = { ']' => '[', ')' => '(', '}' => '{' }
544
adba181 @jeremy The auto_link text helper accepts an optional block to format the link t...
jeremy authored
545 # Turns all urls into clickable links. If a block is given, each url
b34ed9b @dhh Docfix (closes #6393)
dhh authored
546 # is yielded and the result is used as the link text.
10d9fe4 @clemens Refactored TextHelper#truncate, highlight, excerpt, word_wrap and auto_l...
clemens authored
547 def auto_link_urls(text, html_options = {})
c6c5cd5 @mislav refactor autolink helper. change tests to expect HTML-escaped URLs
mislav authored
548 link_attributes = html_options.stringify_keys
b97f4e4 @jamis Fix autolinking to not include trailing tags as part of the URL
jamis authored
549 text.gsub(AUTO_LINK_RE) do
133ada6 @mislav auto_link: support arbitrary URI schemes like "ftp:" and "file:"
mislav authored
550 scheme, href = $1, $&
11bac70 @cainlevy Ensure auto_link does not ignore multiple trailing punctuations [#2504 s...
cainlevy authored
551 punctuation = []
8f0b213 @mislav avoid auto_linking already linked emails; more robust detection of linke...
mislav authored
552
553 if auto_linked?($`, $')
e033b5d @lifo Merge docrails
lifo authored
554 # do not change string; URL is already linked
4f984c9 @mislav auto_link helper: add intelligent ending closing bracket handling. add n...
mislav authored
555 href
556 else
557 # don't include trailing punctuation character as part of the URL
11bac70 @cainlevy Ensure auto_link does not ignore multiple trailing punctuations [#2504 s...
cainlevy authored
558 while href.sub!(/[^\w\/-]$/, '')
559 punctuation.push $&
560 if opening = BRACKETS[punctuation.last] and href.scan(opening).size > href.scan(punctuation.last).size
561 href << punctuation.pop
562 break
4f984c9 @mislav auto_link helper: add intelligent ending closing bracket handling. add n...
mislav authored
563 end
c6c5cd5 @mislav refactor autolink helper. change tests to expect HTML-escaped URLs
mislav authored
564 end
565
566 link_text = block_given?? yield(href) : href
133ada6 @mislav auto_link: support arbitrary URI schemes like "ftp:" and "file:"
mislav authored
567 href = 'http://' + href unless scheme
c6c5cd5 @mislav refactor autolink helper. change tests to expect HTML-escaped URLs
mislav authored
568
8f0b213 @mislav avoid auto_linking already linked emails; more robust detection of linke...
mislav authored
569 content_tag(:a, link_text, link_attributes.merge('href' => href)) + punctuation.reverse.join('')
480150e @dhh Fixed autolinking to work better in more cases #1013 [Jamis Buck]
dhh authored
570 end
571 end
0369ec7 @dhh Made auto_link the only public method of its clan and added an option to...
dhh authored
572 end
573
adba181 @jeremy The auto_link text helper accepts an optional block to format the link t...
jeremy authored
574 # Turns all email addresses into clickable links. If a block is given,
575 # each email is yielded and the result is used as the link text.
bda55f8 @akaspick allow options to be passed to email address auto generation
akaspick authored
576 def auto_link_email_addresses(text, html_options = {})
8f0b213 @mislav avoid auto_linking already linked emails; more robust detection of linke...
mislav authored
577 text.gsub(AUTO_EMAIL_RE) do
578 text = $&
603c853 @josh Don't fallback to just adding "'s" in TextHelper#pluralize, because the ...
josh authored
579
8f0b213 @mislav avoid auto_linking already linked emails; more robust detection of linke...
mislav authored
580 if auto_linked?($`, $')
09e76e6 @jeremy Autolink behaves well with emails embedded in URLs. Closes #7313.
jeremy authored
581 text
582 else
583 display_text = (block_given?) ? yield(text) : text
bda55f8 @akaspick allow options to be passed to email address auto generation
akaspick authored
584 mail_to text, display_text, html_options
09e76e6 @jeremy Autolink behaves well with emails embedded in URLs. Closes #7313.
jeremy authored
585 end
adba181 @jeremy The auto_link text helper accepts an optional block to format the link t...
jeremy authored
586 end
0369ec7 @dhh Made auto_link the only public method of its clan and added an option to...
dhh authored
587 end
8f0b213 @mislav avoid auto_linking already linked emails; more robust detection of linke...
mislav authored
588
589 # Detects already linked context or position in the middle of a tag
590 def auto_linked?(left, right)
591 (left =~ AUTO_LINK_CRE[0] and right =~ AUTO_LINK_CRE[1]) or
592 (left.rindex(AUTO_LINK_CRE[2]) and $' !~ AUTO_LINK_CRE[3])
593 end
db045db @dhh Initial
dhh authored
594 end
595 end
d3ec1d3 @rmanalan auto_link view helper was failing on URLs with colons after a query para...
rmanalan authored
596 end
Something went wrong with that request. Please try again.