class Autolinker::TextHelper
Constants
- AUTO_EMAIL_LOCAL_RE
- AUTO_EMAIL_RE
- AUTO_LINK_CRE
regexps for determining context, used high-volume
- AUTO_LINK_RE
- BOOLEAN_ATTRIBUTES
- BRACKETS
- PRE_CONTENT_STRINGS
- WORD_PATTERN
Public Instance Methods
Turns all URLs and e-mail addresses into clickable links. The :link
option will limit what should be linked. You can add HTML
attributes to the links using :html
. Possible values for :link
are :all
(default), :email_addresses
, and :urls
. If a block is given, each URL and e-mail address is yielded and the result is used as the link text. By default the text given is sanitized, you can override this behaviour setting the :sanitize
option to false, or you can add options to the sanitization of the text using the :sanitize_options
option hash.
Examples¶ ↑
auto_link("Go to http://www.rubyonrails.org and say hello to david@loudthinking.com") # => "Go to <a href=\"http://www.rubyonrails.org\">http://www.rubyonrails.org</a> and # say hello to <a href=\"mailto:david@loudthinking.com\">david@loudthinking.com</a>" auto_link("Visit http://www.loudthinking.com/ or e-mail david@loudthinking.com", :link => :urls) # => "Visit <a href=\"http://www.loudthinking.com/\">http://www.loudthinking.com/</a> # or e-mail david@loudthinking.com" auto_link("Visit http://www.loudthinking.com/ or e-mail david@loudthinking.com", :link => :email_addresses) # => "Visit http://www.loudthinking.com/ or e-mail <a href=\"mailto:david@loudthinking.com\">david@loudthinking.com</a>" post_body = "Welcome to my new blog at http://www.myblog.com/. Please e-mail me at me@email.com." auto_link(post_body, :html => { :target => '_blank' }) do |text| truncate(text, :length => 15) end # => "Welcome to my new blog at <a href=\"http://www.myblog.com/\" target=\"_blank\">http://www.m...</a>. Please e-mail me at <a href=\"mailto:me@email.com\">me@email.com</a>."
You can still use auto_link
with the old API that accepts the link
as its optional second parameter and the html_options
hash as its optional third parameter:
post_body = "Welcome to my new blog at http://www.myblog.com/. Please e-mail me at me@email.com." auto_link(post_body, :urls) # => "Welcome to my new blog at <a href=\"http://www.myblog.com/\">http://www.myblog.com</a>. Please e-mail me at me@email.com." auto_link(post_body, :all, :target => "_blank") # => "Welcome to my new blog at <a href=\"http://www.myblog.com/\" target=\"_blank\">http://www.myblog.com</a>. Please e-mail me at <a href=\"mailto:me@email.com\">me@email.com</a>."
# File lib/autolinker/text_helper.rb, line 43 def auto_link(text, *args, &block) #link = :all, html = {}, &block) return '' if text.nil? || text.empty? options = args.size == 2 ? {} : extract_options!(args) # this is necessary because the old auto_link API has a Hash as its last parameter unless args.empty? options[:link] = args[0] || :all options[:html] = args[1] || {} end options = { :link => :all, :html => {} }.merge(options) sanitize_options = options[:sanitize_options] || {} sanitize = (options[:sanitize] != false) text = conditional_sanitize(text, sanitize, sanitize_options).to_str case options[:link].to_sym when :all then auto_link_email_addresses(auto_link_urls(text, options[:html], options, &block), options[:html], &block) when :email_addresses then auto_link_email_addresses(text, options[:html], &block) when :urls then auto_link_urls(text, options[:html], options, &block) end end
Private Instance Methods
Turns all email addresses into clickable links. If a block is given, each email is yielded and the result is used as the link text.
# File lib/autolinker/text_helper.rb, line 120 def auto_link_email_addresses(text, html_options = {}, options = {}) text.gsub(AUTO_EMAIL_RE) do text = $& if auto_linked?($`, $') text else display_text = (block_given?) ? yield(text) : text unless options[:sanitize] == false text = sanitize(text) display_text = sanitize(display_text) unless text == display_text end mail_to text, display_text, html_options end end end
Turns all urls into clickable links. If a block is given, each url is yielded and the result is used as the link text.
# File lib/autolinker/text_helper.rb, line 87 def auto_link_urls(text, link_attributes = {}, options = {}) text.gsub(AUTO_LINK_RE) do scheme, href = $1, $& punctuation = [] if auto_linked?($`, $') # do not change string; URL is already linked href else # don't include trailing punctuation character as part of the URL while href.sub!(/[^#{WORD_PATTERN}\/-]$/, '') punctuation.push $& if opening = BRACKETS[punctuation.last] and href.scan(opening).size > href.scan(punctuation.last).size href << punctuation.pop break end end link_text = block_given? ? yield(href) : href href = 'http://' + href unless scheme unless options[:sanitize] == false link_text = sanitize(link_text) href = sanitize(href) end #"<a href='#{link_attributes.merge('href' => href)}'>#{link_text}</a>" content_tag(:a, link_text, link_attributes.merge('href' => href), !!options[:sanitize]) + punctuation.reverse.join('') end end end
Detects already linked context or position in the middle of a tag
# File lib/autolinker/text_helper.rb, line 147 def auto_linked?(left, right) (left =~ AUTO_LINK_CRE[0] and right =~ AUTO_LINK_CRE[1]) or (left.rindex(AUTO_LINK_CRE[2]) and $' !~ AUTO_LINK_CRE[3]) end
# File lib/autolinker/text_helper.rb, line 152 def conditional_sanitize(target, condition, sanitize_options = {}) condition ? sanitize(target, sanitize_options) : target end
# File lib/autolinker/text_helper.rb, line 160 def content_tag(name, content_or_options_with_block = nil, options = nil, escape = true, &block) if block_given? options = content_or_options_with_block if content_or_options_with_block.is_a?(Hash) content_tag_string(name, capture(&block), options, escape) else content_tag_string(name, content_or_options_with_block, options, escape) end end
# File lib/autolinker/text_helper.rb, line 169 def content_tag_string(name, content, options, escape = true) tag_options = tag_options(options, escape) if options "<#{name}#{tag_options}>#{PRE_CONTENT_STRINGS[name.to_sym]}#{escape ? ERB::Util.h(content) : content}</#{name}>" end
# File lib/autolinker/text_helper.rb, line 138 def extract_options!(args) if args.last.is_a?(Hash) args.pop else {} end end
Creates a mailto link tag to the specified email_address
, which is also used as the name of the link unless name
is specified. Additional HTML
attributes for the link can be passed in html_options
.
mail_to
has several methods for hindering email harvesters and customizing the email itself by passing special keys to html_options
.
Options¶ ↑
-
:encode
- This key will accept the strings “javascript” or “hex”. Passing “javascript” will dynamically create and encode the mailto link then eval it into the DOM of the page. This method will not show the link on the page if the user has JavaScript disabled. Passing “hex” will hex encode theemail_address
before outputting the mailto link. -
:replace_at
- When the linkname
isn’t provided, theemail_address
is used for the link label. You can use this option to obfuscate theemail_address
by substituting the @ sign with the string given as the value. -
:replace_dot
- When the linkname
isn’t provided, theemail_address
is used for the link label. You can use this option to obfuscate theemail_address
by substituting the . in the email with the string given as the value. -
:subject
- Preset the subject line of the email. -
:body
- Preset the body of the email. -
:cc
- Carbon Copy additional recipients on the email. -
:bcc
- Blind Carbon Copy additional recipients on the email.
Examples¶ ↑
mail_to "me@domain.com" # => <a href="mailto:me@domain.com">me@domain.com</a> mail_to "me@domain.com", "My email", :encode => "javascript" # => <script type="text/javascript">eval(decodeURIComponent('%64%6f%63...%27%29%3b'))</script> mail_to "me@domain.com", "My email", :encode => "hex" # => <a href="mailto:%6d%65@%64%6f%6d%61%69%6e.%63%6f%6d">My email</a> mail_to "me@domain.com", nil, :replace_at => "_at_", :replace_dot => "_dot_", :class => "email" # => <a href="mailto:me@domain.com" class="email">me_at_domain_dot_com</a> mail_to "me@domain.com", "My email", :cc => "ccaddress@domain.com", :subject => "This is an example email" # => <a href="mailto:me@domain.com?cc=ccaddress@domain.com&subject=This%20is%20an%20example%20email">My email</a>
# File lib/autolinker/text_helper.rb, line 250 def mail_to(email_address, name = nil, html_options = {}) email_address = ERB::Util.html_escape(email_address) encode = html_options.delete("encode").to_s extras = %w{ cc bcc body subject }.map { |item| option = html_options.delete(item) || next "#{item}=#{Rack::Utils.escape(option).gsub("+", "%20")}" }.compact extras = extras.empty? ? '' : '?' + ERB::Util.html_escape(extras.join('&')) email_address_obfuscated = email_address.to_str email_address_obfuscated.gsub!(/@/, html_options.delete("replace_at")) if html_options.key?("replace_at") email_address_obfuscated.gsub!(/\./, html_options.delete("replace_dot")) if html_options.key?("replace_dot") case encode when "javascript" string = '' html = content_tag("a", name || email_address_obfuscated, html_options.merge("href" => "mailto:#{email_address}#{extras}")) html = escape_javascript(html.to_str) "document.write('#{html}');".each_byte do |c| string << sprintf("%%%x", c) end "<script type=\"#{Mime::JS}\">eval(decodeURIComponent('#{string}'))</script>" when "hex" email_address_encoded = email_address_obfuscated.unpack('C*').map { |c| sprintf("&#%d;", c) }.join string = 'mailto:'.unpack('C*').map { |c| sprintf("&#%d;", c) }.join + email_address.unpack('C*').map { |c| char = c.chr char =~ /\w/ ? sprintf("%%%x", c) : char }.join content_tag "a", name || email_address_encoded, html_options.merge("href" => "#{string}#{extras}") else content_tag "a", name || email_address_obfuscated, html_options.merge("href" => "mailto:#{email_address}#{extras}") end end
# File lib/autolinker/text_helper.rb, line 156 def sanitize(html, options = {}) Autolinker::HTML::Sanitizer.new.sanitize(html, options) end
# File lib/autolinker/text_helper.rb, line 184 def tag_options(options, escape = true) unless options.nil? || options.empty? attrs = [] options.each_pair do |key, value| if key.to_s == 'data' && value.is_a?(Hash) value.each do |k, v| unless v.is_a?(String) || v.is_a?(Symbol) || v.is_a?(BigDecimal) v = v.to_json end v = ERB::Util.html_escape(v) if escape attrs << %(data-#{k.to_s.dasherize}="#{v}") end elsif BOOLEAN_ATTRIBUTES.include?(key) attrs << %(#{key}="#{key}") if value elsif !value.nil? final_value = value.is_a?(Array) ? value.join(" ") : value final_value = ERB::Util.html_escape(final_value) if escape attrs << %(#{key}="#{final_value}") end end " #{attrs.sort * ' '}" unless attrs.empty? end end