module ActionView::Helpers::TextHelper

def concat(string)

%>
# will either display "Logged in!" or a login link
end
concat link_to('login', action: :login)
else
concat "Logged in!"
if logged_in

# is the equivalent of <%= "hello" %>
concat "hello"
<%

output text within a non-output code block (i.e., <% %>), you can use the concat method.
do not operate as expected in an eRuby code block. If you absolutely must
<%= "text" %> eRuby syntax. The regular _puts_ and _print_ methods
The preferred method of outputting text in your views is to use the
def concat(string)
  output_buffer << string
end

def current_cycle(name = "default")

<% end %>

<%= item %>
">
<% @items.each do |item| %>
@items = [1,2,3,4]
# Alternate background colors

the current cycle string in more than one place.
for complex table highlighting or any other design need which requires
Returns the current cycle string after a cycle has been started. Useful
def current_cycle(name = "default")
  cycle = get_cycle(name)
  cycle.current_value if cycle
end

def cut_excerpt_part(part_position, part, separator, options)

def cut_excerpt_part(part_position, part, separator, options)
  return "", "" unless part
  radius   = options.fetch(:radius, 100)
  omission = options.fetch(:omission, "...")
  if separator != ""
    part = part.split(separator)
    part.delete("")
  end
  affix = part.length > radius ? omission : ""
  part =
    if part_position == :first
      part.last(radius)
    else
      part.first(radius)
    end
  if separator != ""
    part = part.join(separator)
  end
  return affix, part
end

def cycle(first_value, *values)

<% end %>


<% reset_cycle("colors") %>
<% end %>

<%= value %>
">
<%# Create a named cycle "colors" %>
<% item.values.each do |value| %>

">
<% @items.each do |item| %>
{first: 'June', middle: 'Dae', last: 'Jones'}]
{first: 'Emily', middle: 'Shannon', maiden: 'Pike', last: 'Hicks'},
@items = x = [{first: 'Robert', middle: 'Daniel', last: 'James'},
# Cycle CSS classes for rows, and text colors for values within each row



<% end %>

<%= item %>
">
<% @items.each do |item| %>

@items = [1,2,3,4]
# Alternate CSS classes for even and odd numbers...

anytime using the current_cycle method.
and passing the name of the cycle. The current cycle string can be obtained
"default". You can manually reset a cycle by calling reset_cycle
named cycle. The default name for a cycle without a +:name+ key is
Passing a Hash as the last parameter with a :name key will create a
classes for table rows. You can use named cycles to allow nesting in loops.
array every time it is called. This can be used for example, to alternate
Creates a Cycle object whose _to_s_ method cycles through elements of an
def cycle(first_value, *values)
  options = values.extract_options!
  name = options.fetch(:name, "default")
  values.unshift(*first_value)
  cycle = get_cycle(name)
  unless cycle && cycle.values == values
    cycle = set_cycle(name, Cycle.new(*values))
  end
  cycle.to_s
end

def excerpt(text, phrase, options = {})

# => ...a very beautiful...
excerpt('This is a very beautiful morning', 'very', separator: ' ', radius: 1)

# => is also an example
excerpt('This is also an example', 'an', radius: 8, omission: ' ')

# => ...next...
excerpt('This next thing is an example', 'ex', radius: 2)

# => This is an example
excerpt('This is an example', 'is')

# => This is a...
excerpt('This is an example', 'is', radius: 5)

# => ...s is an exam...
excerpt('This is an example', 'an', radius: 5)

isn't found, +nil+ is returned.
:separator option to choose the delimitation. The resulting string will be stripped in any case. If the +phrase+
then the :omission option (which defaults to "...") will be prepended/appended accordingly. Use the
defined in :radius (which defaults to 100). If the excerpt radius overflows the beginning or end of the +text+,
The :radius option expands the excerpt on each side of the first occurrence of +phrase+ by the number of characters
Extracts an excerpt from +text+ that matches the first instance of +phrase+.
def excerpt(text, phrase, options = {})
  return unless text && phrase
  separator = options.fetch(:separator, nil) || ""
  case phrase
  when Regexp
    regex = phrase
  else
    regex = /#{Regexp.escape(phrase)}/i
  end
  return unless matches = text.match(regex)
  phrase = matches[0]
  unless separator.empty?
    text.split(separator).each do |value|
      if value.match?(regex)
        phrase = value
        break
      end
    end
  end
  first_part, second_part = text.split(phrase, 2)
  prefix, first_part   = cut_excerpt_part(:first, first_part, separator, options)
  postfix, second_part = cut_excerpt_part(:second, second_part, separator, options)
  affix = [first_part, separator, phrase, separator, second_part].join.strip
  [prefix, affix, postfix].join
end

def get_cycle(name)

uses an instance variable of ActionView::Base.
guaranteed to be reset every time a page is rendered, so it
The cycle helpers need to store the cycles in a place that is
def get_cycle(name)
  @_cycles = Hash.new unless defined?(@_cycles)
  @_cycles[name]
end

def highlight(text, phrases, options = {}, &block)

# => ruby on rails
highlight('ruby on rails', 'rails', sanitize: false)

# => You searched for: rails
highlight('You searched for: rails', 'rails') { |match| link_to(search_path(q: match, match)) }

# => You searched for: rails
highlight('You searched for: rails', 'rails', highlighter: '\1')

# => You searched for: rails
highlight('You searched for: rails', ['for', 'rails'], highlighter: '\1')

# => You searched for: ruby, rails, dhh
highlight('You searched for: ruby, rails, dhh', 'actionpack')

# => You searched for: rails
highlight('You searched for: rails', /for|rails/)

# => You searched for: rails
highlight('You searched for: rails', 'rails')

for :sanitize will turn sanitizing off.
is sanitized to prevent possible XSS attacks. If the input is trustworthy, passing false
\1) or passing a block that receives each matched term. By default +text+
as a single-quoted string with \1 where the phrase is to be inserted (defaults to
a :highlighter string. The highlighter can be specialized by passing :highlighter
Highlights one or more +phrases+ everywhere in +text+ by inserting it into
def highlight(text, phrases, options = {}, &block)
  text = sanitize(text) if options.fetch(:sanitize, true)
  if text.blank? || phrases.blank?
    text || ""
  else
    match = Array(phrases).map do |p|
      Regexp === p ? p.to_s : Regexp.escape(p)
    end.join("|")
    if block_given?
      text.gsub(/(#{match})(?![^<]*?>)/i, &block)
    else
      highlighter = options.fetch(:highlighter, '<mark>\1</mark>')
      text.gsub(/(#{match})(?![^<]*?>)/i, highlighter)
    end
  end.html_safe
end

def pluralize(count, singular, plural_arg = nil, plural: plural_arg, locale: I18n.locale)

# => 2 Personen
pluralize(2, 'Person', locale: :de)

# => 0 people
pluralize(0, 'person')

# => 3 users
pluralize(3, 'person', plural: 'users')

# => 2 people
pluralize(2, 'person')

# => 1 person
pluralize(1, 'person')

See ActiveSupport::Inflector.pluralize
(you must define your own inflection rules for languages other than English).
The word will be pluralized using rules defined for the locale

which defaults to I18n.locale
it will use the Inflector to determine the plural form for the given locale,
+plural+ is supplied, it will use that when count is > 1, otherwise
Attempts to pluralize the +singular+ word unless +count+ is 1. If
def pluralize(count, singular, plural_arg = nil, plural: plural_arg, locale: I18n.locale)
  word = if count == 1 || count.to_s.match?(/^1(\.0+)?$/)
    singular
  else
    plural || singular.pluralize(locale)
  end
  "#{count || 0} #{word}"
end

def reset_cycle(name = "default")


<% end %>

<% reset_cycle("colors") %>

<% end %>

<%= value %>
">
<% item.each do |value| %>
">
<% @items.each do |item| %>

@items = [[1,2,3,4], [5,6,3], [3,4,5,6,7,4]]
# Alternate CSS classes for even and odd numbers...

it is called. Pass in +name+ to reset a named cycle.
Resets a cycle so that it starts from the first element the next time
def reset_cycle(name = "default")
  cycle = get_cycle(name)
  cycle.reset if cycle
end

def safe_concat(string)

def safe_concat(string)
  output_buffer.respond_to?(:safe_concat) ? output_buffer.safe_concat(string) : concat(string)
end

def set_cycle(name, cycle_object)

def set_cycle(name, cycle_object)
  @_cycles = Hash.new unless defined?(@_cycles)
  @_cycles[name] = cycle_object
end

def simple_format(text, html_options = {}, options = {})

# => "

Blinkable! It's true.

"
simple_format("Blinkable! It's true.", {}, sanitize: false)

# => "

Unblinkable.

"
simple_format("Unblinkable.")

# => "

Look ma! A class!

"
simple_format("Look ma! A class!", class: 'description')

# => "

We want to put a paragraph...

\n\n

...right there.

"
simple_format(more_text)

more_text = "We want to put a paragraph...\n\n...right there."

# => "
Here is some basic text...\n
...with a line break.
"
simple_format(my_text, {}, wrapper_tag: "div")

# => "

Here is some basic text...\n
...with a line break.

"
simple_format(my_text)

my_text = "Here is some basic text...\n...with a line break."
==== Examples

* :wrapper_tag - String representing the wrapper tag, defaults to "p"
* :sanitize - If +false+, does not sanitize +text+.
==== Options

will be added to all created paragraphs.
You can pass any HTML attributes into html_options. These

newlines from the +text+.

tag is appended. This method does not remove the
(\n or \r\n) is considered a linebreak and a
considered a paragraph and wrapped in

tags. One newline
Two or more consecutive newlines (\n\n or \r\n\r\n) are
Returns +text+ transformed into HTML using simple formatting rules.

def simple_format(text, html_options = {}, options = {})
  wrapper_tag = options.fetch(:wrapper_tag, :p)
  text = sanitize(text) if options.fetch(:sanitize, true)
  paragraphs = split_paragraphs(text)
  if paragraphs.empty?
    content_tag(wrapper_tag, nil, html_options)
  else
    paragraphs.map! { |paragraph|
      content_tag(wrapper_tag, raw(paragraph), html_options)
    }.join("\n\n").html_safe
  end
end

def split_paragraphs(text)

def split_paragraphs(text)
  return [] if text.blank?
  text.to_str.gsub(/\r\n?/, "\n").split(/\n\n+/).map! do |t|
    t.gsub!(/([^\n]\n)(?=[^\n])/, '\1<br />') || t
  end
end

def truncate(text, options = {}, &block)

# => "Once upon a time in a wo...Continue"
truncate("Once upon a time in a world far far away") { link_to "Continue", "#" }

# => "

Once upon a time in a wo..."
truncate("

Once upon a time in a world far far away

", escape: false)

# => "<p>Once upon a time in a wo..."
truncate("

Once upon a time in a world far far away

")

# => "And they f... (continued)"
truncate("And they found that many people were sleeping better.", length: 25, omission: '... (continued)')

# => "Once upon a..."
truncate("Once upon a time in a world far far away", length: 17, separator: ' ')

# => "Once upon a ti..."
truncate("Once upon a time in a world far far away", length: 17)

# => "Once upon a time in a world..."
truncate("Once upon a time in a world far far away")

may produce invalid HTML (such as unbalanced or incomplete tags).
+false+. Care should be taken if +text+ contains HTML tags or entities, because truncation
The result is marked as HTML-safe, but it is escaped by default, unless :escape is

Pass a block if you want to show extra content when the text is truncated.

Pass a :separator to truncate +text+ at a natural break.

for a total length not exceeding :length.
(defaults to 30). The last characters will be replaced with the :omission (defaults to "...")
Truncates a given +text+ after a given :length if +text+ is longer than :length
def truncate(text, options = {}, &block)
  if text
    length  = options.fetch(:length, 30)
    content = text.truncate(length, options)
    content = options[:escape] == false ? content.html_safe : ERB::Util.html_escape(content)
    content << capture(&block) if block_given? && text.length > length
    content
  end
end

def word_wrap(text, line_width: 80, break_sequence: "\n")

# => Once\r\nupon\r\na\r\ntime
word_wrap('Once upon a time', line_width: 1, break_sequence: "\r\n")

You can also specify a custom +break_sequence+ ("\n" by default)

# => Once\nupon\na\ntime
word_wrap('Once upon a time', line_width: 1)

# => Once\nupon a\ntime
word_wrap('Once upon a time', line_width: 8)

# => Once upon a time, in a kingdom called Far Far Away, a king fell ill, and finding\na successor to the throne turned out to be more trouble than anyone could have\nimagined...
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...')

# => Once upon a time
word_wrap('Once upon a time')

(which is 80 by default).
breaks on the first whitespace character that does not exceed +line_width+
Wraps the +text+ into lines no longer than +line_width+ width. This method
def word_wrap(text, line_width: 80, break_sequence: "\n")
  text.split("\n").collect! do |line|
    line.length > line_width ? line.gsub(/(.{1,#{line_width}})(\s+|$)/, "\\1#{break_sequence}").rstrip : line
  end * break_sequence
end