truncate_html_sentence 0.5.6

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.
Files changed (45) hide show
  1. data/.gitignore +7 -0
  2. data/.travis.yml +4 -0
  3. data/Gemfile +4 -0
  4. data/Gemfile.lock +92 -0
  5. data/History.txt +40 -0
  6. data/LICENSE +21 -0
  7. data/README.markdown +83 -0
  8. data/Rakefile +50 -0
  9. data/VERSION +1 -0
  10. data/init.rb +1 -0
  11. data/lib/app/helpers/truncate_html_helper.rb +9 -0
  12. data/lib/truncate_html.rb +13 -0
  13. data/lib/truncate_html/configuration.rb +14 -0
  14. data/lib/truncate_html/html_string.rb +41 -0
  15. data/lib/truncate_html/html_truncator.rb +80 -0
  16. data/lib/truncate_html/version.rb +3 -0
  17. data/spec/helpers/truncate_html_helper_spec.rb +44 -0
  18. data/spec/rails_root/Gemfile +6 -0
  19. data/spec/rails_root/Gemfile.lock +86 -0
  20. data/spec/rails_root/app/controllers/application_controller.rb +10 -0
  21. data/spec/rails_root/app/helpers/application_helper.rb +3 -0
  22. data/spec/rails_root/config/application.rb +14 -0
  23. data/spec/rails_root/config/boot.rb +13 -0
  24. data/spec/rails_root/config/database.yml +22 -0
  25. data/spec/rails_root/config/environment.rb +5 -0
  26. data/spec/rails_root/config/environments/development.rb +17 -0
  27. data/spec/rails_root/config/environments/production.rb +28 -0
  28. data/spec/rails_root/config/environments/test.rb +29 -0
  29. data/spec/rails_root/config/initializers/backtrace_silencers.rb +7 -0
  30. data/spec/rails_root/config/initializers/inflections.rb +10 -0
  31. data/spec/rails_root/config/initializers/mime_types.rb +5 -0
  32. data/spec/rails_root/config/initializers/new_rails_defaults.rb +19 -0
  33. data/spec/rails_root/config/initializers/session_store.rb +15 -0
  34. data/spec/rails_root/config/locales/en.yml +5 -0
  35. data/spec/rails_root/config/routes.rb +43 -0
  36. data/spec/rails_root/init.rb +1 -0
  37. data/spec/rails_root/lib/app/helpers/truncate_html_helper.rb +7 -0
  38. data/spec/rails_root/lib/tasks/rspec.rake +144 -0
  39. data/spec/spec.opts +2 -0
  40. data/spec/spec_helper.rb +11 -0
  41. data/spec/truncate_html/configuration_spec.rb +17 -0
  42. data/spec/truncate_html/html_string_spec.rb +67 -0
  43. data/spec/truncate_html/html_truncator_spec.rb +143 -0
  44. data/truncate_html.gemspec +21 -0
  45. metadata +153 -0
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
@@ -0,0 +1,11 @@
1
+ ENV["RAILS_ENV"] ||= 'test'
2
+ rails_root = File.expand_path('../rails_root', __FILE__)
3
+ require rails_root + '/config/environment.rb'
4
+
5
+ require 'rspec/rails'
6
+
7
+ require File.expand_path('../../lib/truncate_html', __FILE__)
8
+
9
+ RSpec.configure do |config|
10
+ config.mock_with :rspec
11
+ end
@@ -0,0 +1,17 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper')
2
+
3
+ describe TruncateHtml::Configuration do
4
+
5
+ describe 'self.configure' do
6
+
7
+ it 'yields the configuration object' do
8
+ lambda do
9
+ TruncateHtml.configure do |config|
10
+ config.should be_kind_of(TruncateHtml::Configuration)
11
+ throw :yay_it_yielded
12
+ end
13
+ end.should throw_symbol(:yay_it_yielded)
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,67 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper')
2
+
3
+ describe TruncateHtml::HtmlString do
4
+
5
+ def html_string(original_string)
6
+ TruncateHtml::HtmlString.new(original_string)
7
+ end
8
+
9
+ describe '#html_tokens' do
10
+ it 'returns each token in the string as an array element removing any consecutive whitespace from the string' do
11
+ html = '<h1>Hi there</h1> <p>This is sweet!</p>'
12
+ html_string(html).html_tokens.should == ['<h1>', 'Hi', ' ', 'there', '</h1>', ' ', '<p>', 'This', ' ', 'is', ' ', 'sweet!', '</p>']
13
+ end
14
+ end
15
+
16
+ describe '#html_tag?' do
17
+ it 'returns false when the string parameter is not an html tag' do
18
+ html_string('no tags').should_not be_html_tag
19
+ end
20
+
21
+ it 'returns true when the string parameter is an html tag' do
22
+ html_string('<img src="foo">').should be_html_tag
23
+ html_string('</img>').should be_html_tag
24
+ end
25
+ end
26
+
27
+ describe '#open_tag?' do
28
+ it 'returns true if the tag is an open tag' do
29
+ html_string('<a>').should be_open_tag
30
+ end
31
+
32
+ context 'the tag is an open tag, and has whitespace and html properties' do
33
+ it 'returns true if it has single quotes' do
34
+ html_string(" <a href='http://awesomeful.net' >").should be_open_tag
35
+ end
36
+
37
+ it 'returns true if it has double quotes' do
38
+ html_string(' <a href="http://awesomeful.net">').should be_open_tag
39
+ end
40
+ end
41
+
42
+ it 'returns false if the tag is a close tag' do
43
+ html_string('</a>').should_not be_open_tag
44
+ end
45
+
46
+ it 'returns false if the string is not an html tag' do
47
+ html_string('foo bar').should_not be_open_tag
48
+ end
49
+
50
+ it 'returns false if it is a <script> tag' do
51
+ html_string('<script>').should_not be_open_tag
52
+ end
53
+ end
54
+
55
+ describe '#matching_close_tag' do
56
+ tag_pairs = { '<a>' => '</a>',
57
+ ' <div>' => '</div>',
58
+ '<h1>' => '</h1>',
59
+ '<a href="foo">' => '</a>' }
60
+
61
+ tag_pairs.each do |open_tag, close_tag|
62
+ it "closes a #{open_tag} and returns #{close_tag}" do
63
+ html_string(open_tag).matching_close_tag.should == close_tag
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,143 @@
1
+ # Encoding: UTF-8
2
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper')
3
+
4
+ describe TruncateHtml::HtmlTruncator do
5
+
6
+ def truncate(html, opts = {})
7
+ html_string = TruncateHtml::HtmlString.new(html)
8
+ TruncateHtml::HtmlTruncator.new(html_string).truncate(opts)
9
+ end
10
+
11
+ context 'when the word_boundary option is set to false' do
12
+ it 'truncates to the exact length specified' do
13
+ truncate('<div>123456789</div>', :length => 5, :omission => '', :word_boundary => false).should == '<div>12345</div>'
14
+ end
15
+
16
+ it 'retains the tags within the text' do
17
+ html = 'some text <span class="caps">CAPS</span> some text'
18
+ truncate(html, :length => 25, :word_boundary => false).should == 'some text <span class="caps">CAPS</span> some te...'
19
+ end
20
+
21
+ context 'and a custom omission value is passed' do
22
+ it 'retains the omission text' do
23
+ truncate_html("testtest", :length => 10, :omission => '..', :word_boundary => false).should == 'testtest..'
24
+ end
25
+
26
+ it 'handles multibyte characters' do
27
+ truncate_html("prüfenprüfen", :length => 8, :omission => '..', :word_boundary => false). should == 'prüfen..'
28
+ end
29
+ end
30
+ end
31
+
32
+ context 'when the word_boundary option is a custom value (for splitting on sentences)' do
33
+ it 'truncates to the end of the nearest sentence' do
34
+ truncate_html('hello there. or maybe not?', :length => 16, :omission => '', :word_boundary => /\S[\.\?\!]/).should == 'hello there.'
35
+ end
36
+ end
37
+
38
+ it "includes the omission text's length in the returned truncated html" do
39
+ truncate('a b c', :length => 4, :omission => '...').should == 'a...'
40
+ end
41
+
42
+ it "includes omission even on the edge (issue #18)" do
43
+ opts = { :word_boundary => false, :length => 12 }
44
+ truncate('One two three', opts).should == 'One two t...'
45
+ end
46
+
47
+ it "never returns a string longer than :length" do
48
+ truncate("test this shit", :length => 10).should == 'test...'
49
+ end
50
+
51
+ it 'supports omissions longer than the maximum length' do
52
+ lambda { truncate('', :length => 1, :omission => '...') }.should_not raise_error
53
+ end
54
+
55
+ it 'returns the omission when the specified length is smaller than the omission' do
56
+ truncate('a b c', :length => 2, :omission => '...').should == '...'
57
+ end
58
+
59
+ it 'treats script tags as strings with no length' do
60
+ input_html = "<p>I have a script <script type = text/javascript>document.write('lum dee dum');</script> and more text</p>"
61
+ expected_out = "<p>I have a script <script type = text/javascript>document.write('lum dee dum');</script> and...</p>"
62
+ truncate(input_html, :length => 23).should == expected_out
63
+ end
64
+
65
+ it 'in the middle of a link, truncates and closes the <a>, and closes any remaining open tags' do
66
+ html = '<div><ul><li>Look at <a href = "foo">this</a> link </li></ul></div>'
67
+ expected = '<div><ul><li>Look at <a href = "foo">this...</a></li></ul></div>'
68
+ truncate(html, :length => 15).should == expected
69
+ end
70
+
71
+ %w(! @ # $ % ^ & * \( \) - _ + = [ ] { } \ | , . / ?).each do |char|
72
+ context "when the html has a #{char} character after a closing tag" do
73
+ it 'places the punctuation after the tag without any whitespace' do
74
+ html = "<p>Look at <strong>this</strong>#{char} More words here</p>"
75
+ expected = "<p>Look at <strong>this</strong>#{char}...</p>"
76
+ truncate(html, :length => 19).should == expected
77
+ end
78
+ end
79
+ end
80
+
81
+ context 'when the html has a non punctuation character after a closing tag' do
82
+ it 'leaves a whitespace between the closing tag and the following word character' do
83
+ html = '<p>Look at <a href = "awesomeful.net">this</a> link for randomness</p>'
84
+ expected = '<p>Look at <a href = "awesomeful.net">this</a> link...</p>'
85
+ truncate(html, :length => 21).should == expected
86
+ end
87
+ end
88
+
89
+ it 'handles multibyte characters and leaves them in the result' do
90
+ html = '<p>Look at our multibyte characters ā ž <a href = "awesomeful.net">this</a> link for randomness ā ž</p>'
91
+ truncate(html, :length => html.length).should == html
92
+ end
93
+
94
+ #unusual, but just covering my ass
95
+ it 'recognizes the multiline html properly' do
96
+ html = <<-END_HTML
97
+ <div id="foo"
98
+ class="bar">
99
+ This is ugly html.
100
+ </div>
101
+ END_HTML
102
+ truncate(html, :length => 12).should == ' <div id="foo" class="bar"> This is...</div>'
103
+ end
104
+
105
+ %w(br hr img).each do |unpaired_tag|
106
+ context "when the html contains a #{unpaired_tag} tag" do
107
+
108
+ context "and the #{unpaired_tag} does not have the closing slash" do
109
+ it "does not close the #{unpaired_tag} tag" do
110
+ html = "<div>Some before. <#{unpaired_tag}>and some after</div>"
111
+ html_caps = "<div>Some before. <#{unpaired_tag.capitalize}>and some after</div>"
112
+ truncate(html, :length => 19).should == "<div>Some before. <#{unpaired_tag}>and...</div>"
113
+ truncate(html_caps, :length => 19).should == "<div>Some before. <#{unpaired_tag.capitalize}>and...</div>"
114
+ end
115
+ end
116
+
117
+ context "and the #{unpaired_tag} does have the closing slash" do
118
+ it "does not close the #{unpaired_tag} tag" do
119
+ html = "<div>Some before. <#{unpaired_tag} />and some after</div>"
120
+ html_caps = "<div>Some before. <#{unpaired_tag.capitalize} />and some after</div>"
121
+ truncate(html, :length => 19).should == "<div>Some before. <#{unpaired_tag} />and...</div>"
122
+ truncate(html_caps, :length => 19).should == "<div>Some before. <#{unpaired_tag.capitalize} />and...</div>"
123
+ end
124
+ end
125
+
126
+ end
127
+ end
128
+
129
+ it 'does not truncate quotes off when input contains chinese characters' do
130
+ html = "<p>“我现在使用的是中文的拼音。”<br>
131
+ 测试一下具体的truncate<em>html功能。<br>
132
+ “我现在使用的是中文的拼音。”<br>
133
+ 测试一下具体的truncate</em>html功能。<br>
134
+ “我现在使用的是中文的拼音。”<br>
135
+ 测试一下具体的truncate<em>html功能。<br>
136
+ “我现在使用的是中文的拼音。”<br>
137
+ 测试一下具体的truncate</em>html功能。</p>"
138
+
139
+ result = truncate(html, :omission => "", :length => 50)
140
+ result.should include "<p>“我现在使用的是中文的拼音。”<br>"
141
+ end
142
+
143
+ end
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "truncate_html/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "truncate_html"
7
+ s.version = TruncateHtml::VERSION
8
+ s.authors = ["Harold Giménez"]
9
+ s.email = ["harold.gimenez@gmail.com"]
10
+ s.homepage = "https://github.com/hgimenez/truncate_html"
11
+ s.summary = %q{Uses an API similar to Rails' truncate helper to truncate HTML and close any lingering open tags.}
12
+ s.description = %q{Truncates html so you don't have to}
13
+
14
+ s.files = `git ls-files`.split("\n")
15
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
+ s.require_paths = ["lib"]
18
+
19
+ s.add_development_dependency "rspec-rails", "~> 2.9"
20
+ s.add_development_dependency "rails", "~> 3.0.3"
21
+ end
metadata ADDED
@@ -0,0 +1,153 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: truncate_html_sentence
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.6
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Harold Giménez
9
+ - Nick Plante
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2013-01-02 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rspec-rails
17
+ requirement: !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ~>
21
+ - !ruby/object:Gem::Version
22
+ version: '2.9'
23
+ type: :development
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ~>
29
+ - !ruby/object:Gem::Version
30
+ version: '2.9'
31
+ - !ruby/object:Gem::Dependency
32
+ name: rails
33
+ requirement: !ruby/object:Gem::Requirement
34
+ none: false
35
+ requirements:
36
+ - - ~>
37
+ - !ruby/object:Gem::Version
38
+ version: 3.0.3
39
+ type: :development
40
+ prerelease: false
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ~>
45
+ - !ruby/object:Gem::Version
46
+ version: 3.0.3
47
+ description: Truncates html so you don't have to
48
+ email:
49
+ - harold.gimenez@gmail.com
50
+ - nap@zerosum.org
51
+ executables: []
52
+ extensions: []
53
+ extra_rdoc_files: []
54
+ files:
55
+ - .gitignore
56
+ - .travis.yml
57
+ - Gemfile
58
+ - Gemfile.lock
59
+ - History.txt
60
+ - LICENSE
61
+ - README.markdown
62
+ - Rakefile
63
+ - VERSION
64
+ - init.rb
65
+ - lib/app/helpers/truncate_html_helper.rb
66
+ - lib/truncate_html.rb
67
+ - lib/truncate_html/configuration.rb
68
+ - lib/truncate_html/html_string.rb
69
+ - lib/truncate_html/html_truncator.rb
70
+ - lib/truncate_html/version.rb
71
+ - spec/helpers/truncate_html_helper_spec.rb
72
+ - spec/rails_root/.bundle/config
73
+ - spec/rails_root/Gemfile
74
+ - spec/rails_root/Gemfile.lock
75
+ - spec/rails_root/app/controllers/application_controller.rb
76
+ - spec/rails_root/app/helpers/application_helper.rb
77
+ - spec/rails_root/config/application.rb
78
+ - spec/rails_root/config/boot.rb
79
+ - spec/rails_root/config/database.yml
80
+ - spec/rails_root/config/environment.rb
81
+ - spec/rails_root/config/environments/development.rb
82
+ - spec/rails_root/config/environments/production.rb
83
+ - spec/rails_root/config/environments/test.rb
84
+ - spec/rails_root/config/initializers/backtrace_silencers.rb
85
+ - spec/rails_root/config/initializers/inflections.rb
86
+ - spec/rails_root/config/initializers/mime_types.rb
87
+ - spec/rails_root/config/initializers/new_rails_defaults.rb
88
+ - spec/rails_root/config/initializers/session_store.rb
89
+ - spec/rails_root/config/locales/en.yml
90
+ - spec/rails_root/config/routes.rb
91
+ - spec/rails_root/init.rb
92
+ - spec/rails_root/lib/app/helpers/truncate_html_helper.rb
93
+ - spec/rails_root/lib/tasks/rspec.rake
94
+ - spec/spec.opts
95
+ - spec/spec_helper.rb
96
+ - spec/truncate_html/configuration_spec.rb
97
+ - spec/truncate_html/html_string_spec.rb
98
+ - spec/truncate_html/html_truncator_spec.rb
99
+ - truncate_html.gemspec
100
+ homepage: https://github.com/zapnap/truncate_html
101
+ licenses: []
102
+ post_install_message:
103
+ rdoc_options: []
104
+ require_paths:
105
+ - lib
106
+ required_ruby_version: !ruby/object:Gem::Requirement
107
+ none: false
108
+ requirements:
109
+ - - ! '>='
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ required_rubygems_version: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ requirements: []
119
+ rubyforge_project:
120
+ rubygems_version: 1.8.24
121
+ signing_key:
122
+ specification_version: 3
123
+ summary: Uses an API similar to Rails' truncate helper to truncate HTML and close
124
+ any lingering open tags.
125
+ test_files:
126
+ - spec/helpers/truncate_html_helper_spec.rb
127
+ - spec/rails_root/.bundle/config
128
+ - spec/rails_root/Gemfile
129
+ - spec/rails_root/Gemfile.lock
130
+ - spec/rails_root/app/controllers/application_controller.rb
131
+ - spec/rails_root/app/helpers/application_helper.rb
132
+ - spec/rails_root/config/application.rb
133
+ - spec/rails_root/config/boot.rb
134
+ - spec/rails_root/config/database.yml
135
+ - spec/rails_root/config/environment.rb
136
+ - spec/rails_root/config/environments/development.rb
137
+ - spec/rails_root/config/environments/production.rb
138
+ - spec/rails_root/config/environments/test.rb
139
+ - spec/rails_root/config/initializers/backtrace_silencers.rb
140
+ - spec/rails_root/config/initializers/inflections.rb
141
+ - spec/rails_root/config/initializers/mime_types.rb
142
+ - spec/rails_root/config/initializers/new_rails_defaults.rb
143
+ - spec/rails_root/config/initializers/session_store.rb
144
+ - spec/rails_root/config/locales/en.yml
145
+ - spec/rails_root/config/routes.rb
146
+ - spec/rails_root/init.rb
147
+ - spec/rails_root/lib/app/helpers/truncate_html_helper.rb
148
+ - spec/rails_root/lib/tasks/rspec.rake
149
+ - spec/spec.opts
150
+ - spec/spec_helper.rb
151
+ - spec/truncate_html/configuration_spec.rb
152
+ - spec/truncate_html/html_string_spec.rb
153
+ - spec/truncate_html/html_truncator_spec.rb