module ActionView::Helpers::TextHelper
def highlight(text, phrases, options = {}, &block)
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')
==== Examples
Whether to sanitize +text+ before highlighting. Defaults to true.
[+:sanitize+]
This option is ignored if a block is specified.
phrase, similar to +String#sub+. Defaults to "\1".
The highlighter string. Uses \1 as the placeholder for a
[+:highlighter+]
==== Options
return value will be inserted into the final result.
string. Each occurrence of a phrase will be passed to the block, and its
If a block is specified, it will be used instead of the highlighter
sanitized before highlighting to prevent possible XSS attacks.
expressions. The result will be marked HTML safe. By default, +text+ is
highlighter string. +phrases+ can be one or more strings or regular
Highlights occurrences of +phrases+ in +text+ by formatting them with a
def highlight(text, phrases, options = {}, &block) text = sanitize(text) if options.fetch(:sanitize, true) if text.blank? || phrases.blank? text || "" else patterns = Array(phrases).map { |phrase| Regexp === phrase ? phrase : Regexp.escape(phrase) } pattern = /(#{patterns.join("|")})/i highlighter = options.fetch(:highlighter, '<mark>\1</mark>') unless block text.scan(/<[^>]*|[^<]+/).each do |segment| if !segment.start_with?("<") if block segment.gsub!(pattern, &block) else segment.gsub!(pattern, highlighter) end end end.join end.html_safe end