Module: Harbor::ViewContext::Helpers::Text

Included in:
Harbor::ViewContext
Defined in:
lib/harbor/view_context/helpers/text.rb

Overview

Text helper which provides common routines such as HTML escaping, or truncating (previewing) long pieces of text (such as photo captions).

Instance Method Summary collapse

Instance Method Details

#h(value, default = nil) ⇒ Object

HTML escape value



14
15
16
17
# File 'lib/harbor/view_context/helpers/text.rb', line 14

def h(value, default = nil)
  # TODO: Remove external dependency!
  Rack::Utils::escape_html(value.blank? ? default : value)
end

#q(value) ⇒ Object

Querystring escape value



8
9
10
11
# File 'lib/harbor/view_context/helpers/text.rb', line 8

def q(value)
  # TODO: Remove external dependency!
  Rack::Utils::escape(value)
end

#truncate(value, character_count = 30, trailing = "…") ⇒ Object

Truncates an object to the specified character count, appending the specified trailing text. The character count includes the length of the trailer. HTML entities are counted as 1 character in trailing.

truncate("Lorem ipsum dolor sit amet, consectetur") # => "Lorem ipsum dolor sit amet, c…"
truncate("Lorem ipsum dolor sit amet, consectetur", 20) # => "Lorem ipsum dolor s…"
truncate("Lorem ipsum dolor sit amet, consectetur", 20, "...") # => "Lorem ipsum dolor..."


29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/harbor/view_context/helpers/text.rb', line 29

def truncate(value, character_count = 30, trailing = "…")
  unless character_count.is_a?(Integer)
    raise ArgumentError.new(
      "Harbor::ViewContext::Helpers::Text#truncate[character_count] must be an Integer, was #{character_count.inspect}"
    )
  end

  unless character_count > 0
    raise ArgumentError.new(
      "Harbor::ViewContext::Helpers::Text#truncate[character_count] must be greater than zero, was #{character_count.inspect}."
    )
  end

  unless trailing.is_a?(String)
    raise ArgumentError.new(
      "Harbor::ViewContext::Helpers::Text#truncate[trailing] must be a String, was #{trailing.inspect}"
    )
  end

  if value.nil?
    ""
  else
    string_form = value.to_s

    if string_form.nil? || string_form.empty?
      ""
    elsif string_form.size <= character_count
      string_form
    else
      # The Regexp match here is to determine if the +trailing+ value is an HTML entity code,
      # in which case we assume it's length is 1, or a textual value, in which case we use the
      # actual size.
      string_form[0, character_count - (trailing =~ /\&\w+\;/ ? 1 : trailing.size)] + trailing
    end
  end
end

#truncate_on_words(value, character_count = 30, trailing = "&hellip;") ⇒ Object

Truncates an object on the nearest word to the specified character count, appending the specified trailing text.

truncate_on_words("Lorem ipsum dolor sit amet, consectetur") # => "Lorem ipsum dolor sit amet&hellip;"
truncate_on_words("Lorem ipsum dolor sit amet, consectetur", 20) # => "Lorem ipsum dolor&hellip;"
truncate_on_words("Lorem ipsum dolor sit amet, consectetur", 20, "...") # => "Lorem ipsum dolor..."

The truncation will always look backwards unless the forward word boundary is within 5% of the specified character count. Thus:

truncate_on_words("Lorem ipsum dolor sit amet, consectetur est.", 38) # => "Lorem ipsum dolor sit amet, consectetur..."


80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/harbor/view_context/helpers/text.rb', line 80

def truncate_on_words(value, character_count = 30, trailing = "&hellip;")
  unless character_count.is_a?(Integer)
    raise ArgumentError.new(
      "Harbor::ViewContext::Helpers::Text#truncate_on_words[character_count] must be an Integer, was #{character_count.inspect}"
    )
  end

  unless character_count > 0
    raise ArgumentError.new(
      "Harbor::ViewContext::Helpers::Text#truncate_on_words[character_count] must be greater than zero, was #{character_count.inspect}."
    )
  end

  unless trailing.is_a?(String)
    raise ArgumentError.new(
      "Harbor::ViewContext::Helpers::Text#truncate_on_words[trailing] must be a String, was #{trailing.inspect}"
    )
  end

  return "" if value.nil?

  truncated_text = value.to_s.dup
  text_length = truncated_text.length

  return value if character_count >= text_length

  leftover = truncated_text.slice!(character_count, text_length)

  if (index = leftover.index(/\W|$/)) && index < (character_count * 0.05).ceil
    truncated_text << leftover.slice(0, index)
  else
    truncated_text = truncated_text[0, truncated_text.rindex(/\W/)]
  end

  # Remove any trailing punctuation.
  truncated_text.slice!(truncated_text.length - 1) if truncated_text[truncated_text.length - 1, 1] =~ /\W/

  truncated_text + trailing
end