Module: Ro::Text

Extended by:
Text
Included in:
Text
Defined in:
lib/ro/text.rb

Constant Summary collapse

%r{
  (?: ((?:ed2k|ftp|http|https|irc|mailto|news|gopher|nntp|telnet|webcal|xmpp|callto|feed|svn|urn|aim|rsync|tag|ssh|sftp|rtsp|afs|file):)// | www\.\w )
  [^\s<\u00A0"]+
}ix
[/<[^>]+$/, /^[^>]*>/, /<a\b.*?>/i, /<\/a>/i]
AUTO_EMAIL_LOCAL_RE =
/[\w.!#\$%&'*\/=?^`{|}~+-]/
AUTO_EMAIL_RE =
/(?<!#{AUTO_EMAIL_LOCAL_RE})[\w.!#\$%+-]\.?#{AUTO_EMAIL_LOCAL_RE}*@[\w-]+(?:\.[\w-]+)+/
BRACKETS =
{ ']' => '[', ')' => '(', '}' => '{' }
WORD_PATTERN =
'\p{Word}'

Instance Method Summary collapse

Instance Method Details

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.



77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/ro/text.rb', line 77

def auto_link_email_addresses(text)
  text.gsub(AUTO_EMAIL_RE) do
    text = $&

    if auto_linked?($`, $')
      text
    else
      email = escape_html(text)
      "<a href='mailto:#{ email }'>#{ email }</a>"
    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.



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/ro/text.rb', line 47

def auto_link_urls(text)
  text.gsub(AUTO_LINK_RE) do
    scheme, href = $1, $&
    punctuation = []
    trailing_gt = ""

    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

      # don't include trailing &gt; entities as part of the URL
      trailing_gt = $& if href.sub!(/&gt;$/, '')
      href = 'http://' + href unless scheme
      link = escape_html(href)
      "<a href='#{ link }'>#{ link }</a>" + punctuation.reverse.join('') + trailing_gt
    end
  end
end

#auto_linked?(left, right) ⇒ Boolean

Detects already linked context or position in the middle of a tag

Returns:

  • (Boolean)


91
92
93
94
# File 'lib/ro/text.rb', line 91

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

#escape_html(text) ⇒ Object



26
27
28
# File 'lib/ro/text.rb', line 26

def escape_html(text)
  CGI.escapeHTML(text)
end

#lines_for(text) ⇒ Object



22
23
24
# File 'lib/ro/text.rb', line 22

def lines_for(text)
  text.strip.gsub(/\n/, "<br />\n")
end

#paragraphs_for(text) ⇒ Object



17
18
19
20
# File 'lib/ro/text.rb', line 17

def paragraphs_for(text)
  paragraphs = text.split(%r`\n\n+`).map{|chunk| lines_for(chunk)}
  paragraphs.map{|p| "<p>\n#{ p }\n</p>"}.join("\n\n").strip
end

#render(text) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
# File 'lib/ro/text.rb', line 5

def render(text)
  text = text.to_s.strip
  return '' if text.empty?

  text = escape_html(text)
  text = auto_link_urls(text)
  text = auto_link_email_addresses(text)
  text = paragraphs_for(text)

  return text
end