class ReeText::Excerpt
def call(text, phrase, **opts)
def call(text, phrase, **opts) options = DEFAULTS.merge(opts) return if is_blank(text) && is_blank(phrase) separator = options[:separator] case phrase when Regexp regex = phrase else regex = /#{Regexp.escape(phrase)}/i end return unless matches = text.match(regex) phrase = matches[0] unless is_blank(separator) 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 cut_excerpt_part(part_position, part, separator, options)
def cut_excerpt_part(part_position, part, separator, options) return "", "" unless part radius = options[:radius] omission = options[:omission] if separator != "" part = part.split(separator) part.delete("") end affix = part.length > radius ? omission : "" part = if part_position == :first last(part, radius) else first(part, radius) end if separator != "" part = part.join(separator) end return affix, part end
def first(string, limit = 1)
def first(string, limit = 1) string[0, limit] || raise(ArgumentError, "negative limit") end
def last(string, limit = 1)
def last(string, limit = 1) string[[string.length - limit, 0].max, limit] || raise(ArgumentError, "negative limit") end