1module AutoLinkHelper
 
2  class AutoLinker
 
3    BLANK = "".html_safe
 
4    AUTO_LINK_RE = %r{(?:((?:ftp|http|https|mailto):)//|www\.)[^\s<\u00A0"]+}ix
 
5    AUTO_LINK_CRE = [/<[^>]+$/, /^[^>]*>/, /<a\b.*?>/i, /<\/a>/i]
 
6    AUTO_EMAIL_LOCAL_RE = /[\w.!#\$%&'*\/=?^`{|}~+-]/
 
7    AUTO_EMAIL_RE = /(?<!#{AUTO_EMAIL_LOCAL_RE})[\w.!#\$%+-]\.?#{AUTO_EMAIL_LOCAL_RE}*@[\w-]+(?:\.[\w-]+)+/
 
8    BRACKETS = { "]" => "[", ")" => "(", "}" => "{" }
 
 9
 
10    attr_reader :template, :text, :options, :block
 
11    delegate :sanitize, :mail_to, :content_tag, to: :template
 
 
13    def self.generate(template, text, options = {}, &block)
 
14      new(template, text, options, &block).generate
 
15    end
 
  • Complexity 1 » saikuro
17    def initialize(template, text, options, &block)
 
18      @template = template
 
19      @text = text
 
20      @block = block
 
21      @options = options
 
22    end
 
  • TooManyStatements - has approx 6 statements » reek
  • Complexity 5 » saikuro
24    def generate
 
25      return BLANK if text.blank?
 
 
27      result = \
 
28        case scope
 
29        when :urls
 
30          auto_link_urls(sanitized_text)
 
31        when :email_addresses
 
32          auto_link_email_addresses(sanitized_text)
 
33        else
 
34          auto_link_all(sanitized_text)
 
35        end
 
 
37      sanitize? ? result.html_safe : result
 
38    end
 
 
40    private
 
  • Complexity 1 » saikuro
42    def scope
 
43      options[:link] || :all
 
44    end
 
  • Complexity 2 » saikuro
46    def sanitized_text
 
47      (sanitize? ? sanitize(text, sanitize_options) : text).to_str
 
48    end
 
  • Complexity 2 » saikuro
50    def sanitize?
 
51      return @sanitize if defined?(@sanitize)
 
52      @sanitize = options[:sanitize] != false
 
53    end
 
  • Complexity 1 » saikuro
55    def sanitize_options
 
56      @sanitize_options ||= options[:sanitize_options] || {}
 
57    end
 
  • Complexity 1 » saikuro
59    def html_options
 
60      @html_options ||= options[:html] || {}
 
61    end
 
  • ControlParameter - is controlled by argument 'right' » reek
  • UtilityFunction - doesn't depend on instance state (maybe move it to another class?) » reek
  • Complexity 1 » saikuro
63    def auto_linked?(left, right)
 
64      (left =~ AUTO_LINK_CRE[0] && right =~ AUTO_LINK_CRE[1]) ||
 
65      (left.rindex(AUTO_LINK_CRE[2]) && $' !~ AUTO_LINK_CRE[3])
 
66    end
 
  • Complexity 1 » saikuro
68    def auto_link_all(target)
 
69      auto_link_email_addresses(auto_link_urls(target))
 
70    end
 
  • DuplicateMethodCall - calls 'punctuation.last' 2 times » reek
  • TooManyStatements - has approx 13 statements » reek
  • Complexity 8 » saikuro
72    def auto_link_urls(text)
  • Block cyclomatic complexity is 8. It should be 4 or less. » roodi
73      text.gsub(AUTO_LINK_RE) do
 
74        scheme, href = $1, $&
 
75        punctuation = []
 
 
77        if auto_linked?($`, $')
 
78          # do not change string; URL is already linked
 
79          href
 
80        else
 
81          # don't include trailing punctuation character as part of the URL
 
82          while href.sub!(/[^\p{Word}\/-=&]$/, "")
 
83            punctuation.push $&
 
 
85            if opening = BRACKETS[punctuation.last] and href.scan(opening).size > href.scan(punctuation.last).size
  • Found = in conditional. It should probably be an == » roodi
86              href << punctuation.pop
 
87              break
 
88            end
 
89          end
 
 
91          link_text = block ? block.call(href) : href
 
92          href = "http://" + href unless scheme
 
 
94          if sanitize?
 
95            link_text = sanitize(link_text)
 
96            href      = sanitize(href)
 
97          end
 
 
 99          content_tag(:a, link_text, html_options.merge(href: href), sanitize?) + punctuation.reverse.join("")
 
100        end
 
101      end
 
102    end
 
  • TooManyStatements - has approx 8 statements » reek
  • Complexity 6 » saikuro
104    def auto_link_email_addresses(text)
  • Block cyclomatic complexity is 5. It should be 4 or less. » roodi
105      text.gsub(AUTO_EMAIL_RE) do
 
106        text = $&
 
 
108        if auto_linked?($`, $')
 
109          text.html_safe
 
110        else
 
111          display_text = block ? block.call(text) : text
 
 
113          if sanitize?
 
114            text         = sanitize(text)
 
115            display_text = sanitize(display_text) unless text == display_text
 
116          end
 
 
118          mail_to text, display_text, html_options
 
119        end
 
120      end
 
121    end
 
122  end
 
  • Complexity 1 » saikuro
124  def auto_link(text, options = {}, &block)
 
125    AutoLinker.generate(self, text, options, &block)
 
126  end
 
127end