nokogiri_truncate_html 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,66 @@
1
+ require 'nokogiri'
2
+ require 'cgi'
3
+
4
+ module NokogiriTruncateHtml
5
+ class TruncateFinished < Exception
6
+ end
7
+
8
+ class TruncateDocument < Nokogiri::XML::SAX::Document
9
+
10
+ def initialize
11
+ # We use the xhtml "flavour" so that we can decode
12
+ # apostrophes. That is the only difference between
13
+ # xhtml1 and html4.
14
+ @encoder = HTMLEntities.new('xhtml1')
15
+ @discard_first_element = false
16
+ end
17
+
18
+ def length=(length)
19
+ @length = length
20
+ end
21
+
22
+ def omission=(omission)
23
+ @omission = omission
24
+ end
25
+
26
+ def output
27
+ while @tags.size > 0
28
+ @output << "</#{@tags.pop}>"
29
+ end
30
+ @output
31
+ end
32
+
33
+ def start_document
34
+ @output, @chars_remaining, @tags = '', @length, []
35
+ @discard_first_element = false
36
+ end
37
+
38
+ def characters(string)
39
+ text = @encoder.decode(string)
40
+ @output << CGI.escapeHTML(text[0, @chars_remaining])
41
+ @chars_remaining -= text.length
42
+ if @chars_remaining < 0
43
+ @output << @omission
44
+ raise TruncateFinished
45
+ end
46
+ end
47
+
48
+ def start_element(name, attrs = [])
49
+ unless @discard_first_element
50
+ return if %w(html body).include? name
51
+ return @discard_first_element = true
52
+ end
53
+
54
+ if %w(br embed hr img input param).include? name
55
+ @output << "<#{name}#{' ' if attrs.size > 0 }#{attrs.map { |attr,val| "#{attr}=\"#{val}\"" }.join(' ')} />"
56
+ else
57
+ @output << "<#{name}#{' ' if attrs.size > 0 }#{attrs.map { |attr,val| "#{attr}=\"#{val}\"" }.join(' ')}>"
58
+ @tags.push name
59
+ end
60
+ end
61
+
62
+ def end_element(name)
63
+ @output << "</#{@tags.pop}>" if @tags.last == name
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,37 @@
1
+ require 'active_support/core_ext/module/attribute_accessors.rb'
2
+ require 'active_support/core_ext/string/output_safety'
3
+ require 'nokogiri_truncate_html/truncate_document'
4
+
5
+ module NokogiriTruncateHtml
6
+ module TruncateHtmlHelper
7
+ mattr_accessor :parser
8
+ mattr_accessor :document
9
+
10
+ # Truncates html respecting tags and html entities.
11
+ #
12
+ # The API is the same as ActionView::Helpers::TextHelper#truncate. It uses Nokogiri and HtmlEntities for entity awareness.
13
+ #
14
+ # Examples:
15
+ # truncate_html '<p>Hello <strong>World</strong></p>', :length => 7 # => '<p>Hello <strong>W&hellip;</strong></p>'
16
+ # truncate_html '<p>Hello &amp; Goodbye</p>', :length => 7 # => '<p>Hello &amp;&hellip;</p>'
17
+ def truncate_html(input, *args)
18
+ self.document ||= TruncateDocument.new#(TruncateHtmlHelper.flavor) #, length, omission)
19
+ self.parser ||= Nokogiri::HTML::SAX::Parser.new(document)
20
+
21
+ # support both 2.2 & earlier APIs
22
+ options = args.extract_options!
23
+ length = options[:length] || args[0] || 30
24
+ omission = options[:omission] || args[1] || '&hellip;'
25
+
26
+ # Adding div around the input is a hack. It gets removed in TruncateDocument.
27
+ input = "<div>#{input}</div>"
28
+ self.document.length = length
29
+ self.document.omission = omission
30
+ begin
31
+ self.parser.parse_memory(input)
32
+ rescue TruncateFinished
33
+ end
34
+ self.document.output.html_safe
35
+ end
36
+ end
37
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nokogiri_truncate_html
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -83,6 +83,8 @@ executables: []
83
83
  extensions: []
84
84
  extra_rdoc_files: []
85
85
  files:
86
+ - lib/nokogiri_truncate_html/truncate_html_helper.rb
87
+ - lib/nokogiri_truncate_html/truncate_document.rb
86
88
  - lib/nokogiri_truncate_html.rb
87
89
  homepage: https://github.com/Springest/truncate_html
88
90
  licenses: []