# encoding: utf-8 module Gluttonberg module Public module HtmlTruncate # Does NOT behave identical to current Rails truncate method # you must pass options as a hash not just values # Sample usage: <%= html_truncate(category.description, :length => # 120, :omission => "(continued...)" ) -%>... def html_truncate(html, truncate_length, options={}) if html && html.length < truncate_length html elsif html _html_truncate(html, truncate_length, options) end end private def _html_truncate(html, truncate_length, options={}) text = [] result = [] previous_tags = [] # get all text (including punctuation) and tags and stick them in a hash html.scan(/<\/?[^>]*>|[A-Za-z0-9.,\/&#;\!\+\(\)\-"'?]+/).each { |t| text << t } text.each do |str| if truncate_length > 0 truncate_length -= _prepare_data_structure(result, previous_tags, str) else _close_open_tags(result, previous_tags) end end (result.join(" ") + options[:omission].to_s).html_safe end def _prepare_data_structure(result, previous_tags, str) length_reduced = 0 if str =~ /<\/?[^>]*>/ if str[0..1] != " 0 previous_tag = previous_tags.pop() unless previous_tag =~ /^<(br|hr|input|img|area|base|link|meta)/ tokens = previous_tag.split(" ") if tokens.length == 1 closing_tag = tokens.first.insert(1 , '/') else closing_tag = "#{tokens.first.insert(1 , '/')}>" end result << closing_tag end end end end #HtmlTruncate end end