Skip to content
This repository
Browse code

Major improvement on better_truncate

  • Loading branch information...
commit d13e7a5a42c345261d10440ec427eab4bf8cbb47 1 parent 497c11c
Winton Welsh authored

Showing 1 changed file with 47 additions and 4 deletions. Show diff stats Hide diff stats

  1. +47 4 lib/app_helpers/truncate.rb
51 lib/app_helpers/truncate.rb
... ... @@ -1,9 +1,52 @@
  1 +require "hpricot"
  2 +
1 3 module AppHelpers
2   -
3   - def better_truncate(text, length = 80, truncate_string = "...")
  4 +
  5 + # Like the Rails _truncate_ helper but doesn't break HTML tags or entities.
  6 + def better_truncate(text, max_length = 30, ellipsis = "...")
4 7 return if text.nil?
5   - l = length - truncate_string.chars.length
6   - text.chars.length > length ? text[/\A.{#{l}}\w*\;?/m][/.*[\w\;]/m] + truncate_string : text
  8 +
  9 + doc = Hpricot(text.to_s)
  10 + ellipsis_length = Hpricot(ellipsis).inner_text.chars.length
  11 + content_length = doc.inner_text.chars.length
  12 + actual_length = max_length - ellipsis_length
  13 +
  14 + content_length > max_length ? doc.truncate(actual_length).inner_html + ellipsis : text.to_s
  15 + end
  16 +
  17 + module HpricotTruncator
  18 + module NodeWithChildren
  19 + def truncate(max_length)
  20 + return self if inner_text.chars.length <= max_length
  21 + truncated_node = self.dup
  22 + truncated_node.children = []
  23 + each_child do |node|
  24 + remaining_length = max_length - truncated_node.inner_text.chars.length
  25 + break if remaining_length == 0
  26 + truncated_node.children << node.truncate(remaining_length)
  27 + end
  28 + truncated_node
  29 + end
  30 + end
  31 +
  32 + module TextNode
  33 + def truncate(max_length)
  34 + # We're using String#scan because Hpricot doesn't distinguish entities.
  35 + Hpricot::Text.new(content.scan(/&#?[^\W_]+;|./).first(max_length).join)
  36 + end
  37 + end
  38 +
  39 + module IgnoredTag
  40 + def truncate(max_length)
  41 + self
  42 + end
  43 + end
7 44 end
  45 +
  46 + Hpricot::Doc.send(:include, HpricotTruncator::NodeWithChildren)
  47 + Hpricot::Elem.send(:include, HpricotTruncator::NodeWithChildren)
  48 + Hpricot::Text.send(:include, HpricotTruncator::TextNode)
  49 + Hpricot::BogusETag.send(:include, HpricotTruncator::IgnoredTag)
  50 + Hpricot::Comment.send(:include, HpricotTruncator::IgnoredTag)
8 51
9 52 end

0 comments on commit d13e7a5

Please sign in to comment.
Something went wrong with that request. Please try again.