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…</strong></p>'
|
16
|
+
# truncate_html '<p>Hello & Goodbye</p>', :length => 7 # => '<p>Hello &…</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] || '…'
|
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.
|
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: []
|