├── .gitignore ├── .travis.yml ├── Gemfile ├── Gemfile.lock ├── History.txt ├── LICENSE ├── README.md ├── Rakefile ├── VERSION ├── init.rb ├── lib ├── app │ └── helpers │ │ └── truncate_html_helper.rb ├── truncate_html.rb └── truncate_html │ ├── configuration.rb │ ├── html_string.rb │ ├── html_truncator.rb │ └── version.rb ├── spec ├── helpers │ └── truncate_html_helper_spec.rb ├── rails_root │ ├── .bundle │ │ └── config │ ├── Gemfile │ ├── Gemfile.lock │ ├── app │ │ ├── controllers │ │ │ └── application_controller.rb │ │ └── helpers │ │ │ └── application_helper.rb │ ├── config │ │ ├── application.rb │ │ ├── boot.rb │ │ ├── database.yml │ │ ├── environment.rb │ │ ├── environments │ │ │ ├── development.rb │ │ │ ├── production.rb │ │ │ └── test.rb │ │ ├── initializers │ │ │ ├── backtrace_silencers.rb │ │ │ ├── inflections.rb │ │ │ ├── mime_types.rb │ │ │ ├── new_rails_defaults.rb │ │ │ └── session_store.rb │ │ ├── locales │ │ │ └── en.yml │ │ └── routes.rb │ ├── init.rb │ └── lib │ │ ├── app │ │ └── helpers │ │ │ └── truncate_html_helper.rb │ │ └── tasks │ │ └── rspec.rake ├── spec.opts ├── spec_helper.rb └── truncate_html │ ├── configuration_spec.rb │ ├── html_string_spec.rb │ ├── html_truncator_spec.rb │ └── truncate_html_spec.rb └── truncate_html.gemspec /.gitignore: -------------------------------------------------------------------------------- 1 | pkg 2 | coverage 3 | profiling 4 | tmp 5 | spec/rails_root/log/* 6 | log/*.log 7 | .bundle 8 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: ruby 2 | rvm: 3 | - 1.9.2 4 | - 1.9.3 5 | - 2.0.0 6 | - jruby-19mode # JRuby in 1.9 mode 7 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "http://rubygems.org" 2 | 3 | # Specify your gem's dependencies in truncate_html.gemspec 4 | gemspec 5 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: . 3 | specs: 4 | truncate_html (0.9.3) 5 | 6 | GEM 7 | remote: http://rubygems.org/ 8 | specs: 9 | actionmailer (3.2.13) 10 | actionpack (= 3.2.13) 11 | mail (~> 2.5.3) 12 | actionpack (3.2.13) 13 | activemodel (= 3.2.13) 14 | activesupport (= 3.2.13) 15 | builder (~> 3.0.0) 16 | erubis (~> 2.7.0) 17 | journey (~> 1.0.4) 18 | rack (~> 1.4.5) 19 | rack-cache (~> 1.2) 20 | rack-test (~> 0.6.1) 21 | sprockets (~> 2.2.1) 22 | activemodel (3.2.13) 23 | activesupport (= 3.2.13) 24 | builder (~> 3.0.0) 25 | activerecord (3.2.13) 26 | activemodel (= 3.2.13) 27 | activesupport (= 3.2.13) 28 | arel (~> 3.0.2) 29 | tzinfo (~> 0.3.29) 30 | activeresource (3.2.13) 31 | activemodel (= 3.2.13) 32 | activesupport (= 3.2.13) 33 | activesupport (3.2.13) 34 | i18n (= 0.6.1) 35 | multi_json (~> 1.0) 36 | arel (3.0.2) 37 | builder (3.0.4) 38 | diff-lcs (1.2.2) 39 | erubis (2.7.0) 40 | hike (1.2.1) 41 | i18n (0.6.1) 42 | journey (1.0.4) 43 | json (1.7.7) 44 | mail (2.5.3) 45 | i18n (>= 0.4.0) 46 | mime-types (~> 1.16) 47 | treetop (~> 1.4.8) 48 | mime-types (1.22) 49 | multi_json (1.7.2) 50 | polyglot (0.3.3) 51 | rack (1.4.5) 52 | rack-cache (1.2) 53 | rack (>= 0.4) 54 | rack-ssl (1.3.3) 55 | rack 56 | rack-test (0.6.2) 57 | rack (>= 1.0) 58 | rails (3.2.13) 59 | actionmailer (= 3.2.13) 60 | actionpack (= 3.2.13) 61 | activerecord (= 3.2.13) 62 | activeresource (= 3.2.13) 63 | activesupport (= 3.2.13) 64 | bundler (~> 1.0) 65 | railties (= 3.2.13) 66 | railties (3.2.13) 67 | actionpack (= 3.2.13) 68 | activesupport (= 3.2.13) 69 | rack-ssl (~> 1.3.2) 70 | rake (>= 0.8.7) 71 | rdoc (~> 3.4) 72 | thor (>= 0.14.6, < 2.0) 73 | rake (10.0.4) 74 | rdoc (3.12.2) 75 | json (~> 1.4) 76 | rspec-core (2.13.1) 77 | rspec-expectations (2.13.0) 78 | diff-lcs (>= 1.1.3, < 2.0) 79 | rspec-mocks (2.13.0) 80 | rspec-rails (2.13.0) 81 | actionpack (>= 3.0) 82 | activesupport (>= 3.0) 83 | railties (>= 3.0) 84 | rspec-core (~> 2.13.0) 85 | rspec-expectations (~> 2.13.0) 86 | rspec-mocks (~> 2.13.0) 87 | sprockets (2.2.2) 88 | hike (~> 1.2) 89 | multi_json (~> 1.0) 90 | rack (~> 1.0) 91 | tilt (~> 1.1, != 1.3.0) 92 | thor (0.18.1) 93 | tilt (1.3.6) 94 | treetop (1.4.12) 95 | polyglot 96 | polyglot (>= 0.3.1) 97 | tzinfo (0.3.37) 98 | 99 | PLATFORMS 100 | ruby 101 | 102 | DEPENDENCIES 103 | rails (~> 3.2.13) 104 | rspec-rails (~> 2.13) 105 | truncate_html! 106 | -------------------------------------------------------------------------------- /History.txt: -------------------------------------------------------------------------------- 1 | == 0.5.1 2011-04-08 2 | * Ensure resulting string's length is never greater than supplied length (csquared) 3 | 4 | == 0.5.0 2011-01-26 5 | * Multibyte support. (smix, parndt) 6 | 7 | == 0.4.0 2010-03-30 8 | * Rails 3 support. This breaks rails 2 support. 9 | 10 | == 0.3.2 2010-03-23 11 | * Fix for autoloading of classes in older Rails versions. (kball) 12 | * Fix issue #5: autoloading of default configuration. 13 | 14 | == 0.3.1 2010-02-03 15 | * Fixed minor typo on the word_boundary option name. 16 | 17 | == 0.3.0 2010-02-02 18 | * Added the ability to set global configuration parameters 19 | * Added the word_boundry option 20 | 21 | == 0.2.2 2009-12-23 22 | * Fix issue #4: Handle case when supplied length is smaller than omission. (ghazel) 23 | 24 | == 0.2.1 2009-12-18 25 | * Fix issue #3: Handle case when input html contins a script tag. 26 | 27 | == 0.2.0 2009-11-23 28 | * Fix issue #2: The omission text's length is now included in the returned 29 | string's calculation. This is more consistent with the rails truncate 30 | helper's behavior. 31 | 32 | == 0.1.2 2009-09-25 33 | * Fix issue #1: Handle case when input html is nil. (bcardarella) 34 | 35 | == 0.1.1 2009-08-25 36 | * Fixed issue with regex which would not recognize tags that contain slashes. 37 | * Other refactoring and improvements to spec coverage. 38 | 39 | == 0.1.0 2009-08-03 40 | * Wrote truncate_html. Initial release. 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2009 - 2010 Harold A. Giménez 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | TruncateHtml 2 | ============ 3 | 4 | [](http://travis-ci.org/hgmnz/truncate_html) 5 | [](https://codeclimate.com/github/hgmnz/truncate_html) 6 | 7 | truncate_html cuts off a string of HTML and takes care of closing any lingering open tags. There are many ways to solve this. This library does not have any dependencies, and [parses HTML using regular expressions](http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454). 8 | 9 | It can be used with or without Rails. 10 | 11 | Example 12 | ------- 13 | 14 | ```ruby 15 | some_html = '' 16 | truncate_html(some_html, length: 15, omission: '...(continued)') 17 | => 18 | ``` 19 | 20 | A few notes: 21 | 22 | * By default, it will truncate on word boundary. 23 | To truncate the HTML string strictly at the specified length, pass in the `word_boundary: false` option. 24 | * If the input HTML is nil, it will return an empty string. 25 | * The omission text's length does count toward the resulting string's length. 26 | * ` and more text
" 71 | expected_out = "I have a script and...
" 72 | truncate(input_html, :length => 23).should == expected_out 73 | end 74 | 75 | it 'in the middle of a link, truncates and closes the , and closes any remaining open tags' do 76 | html = 'Look at this#{char} More words here
" 85 | expected = "Look at this#{char}...
" 86 | truncate(html, :length => 19).should == expected 87 | end 88 | end 89 | end 90 | 91 | context 'when the html has a non punctuation character after a closing tag' do 92 | it 'leaves a whitespace between the closing tag and the following word character' do 93 | html = 'Look at this link for randomness
' 94 | expected = 'Look at this link...
' 95 | truncate(html, :length => 21).should == expected 96 | end 97 | end 98 | 99 | it 'handles multibyte characters and leaves them in the result' do 100 | html = 'Look at our multibyte characters ā ž this link for randomness ā ž
' 101 | truncate(html, :length => html.length).should == html 102 | end 103 | 104 | #unusual, but just covering my ass 105 | it 'recognizes the multiline html properly' do 106 | html = <<-END_HTML 107 | 111 | END_HTML 112 | truncate(html, :length => 12).should == ' ' 113 | end 114 | 115 | %w(br hr img).each do |unpaired_tag| 116 | context "when the html contains a #{unpaired_tag} tag" do 117 | 118 | context "and the #{unpaired_tag} does not have the closing slash" do 119 | it "does not close the #{unpaired_tag} tag" do 120 | html = "“我现在使用的是中文的拼音。”
141 | 测试一下具体的truncatehtml功能。
142 | “我现在使用的是中文的拼音。”
143 | 测试一下具体的truncatehtml功能。
144 | “我现在使用的是中文的拼音。”
145 | 测试一下具体的truncatehtml功能。
146 | “我现在使用的是中文的拼音。”
147 | 测试一下具体的truncatehtml功能。
“我现在使用的是中文的拼音。”
"
151 | end
152 |
153 | context 'when the break_token option is set as ' do
154 | it 'does not truncate abnormally if the break_token is not present' do
155 | truncate('This is line one. This is line two.', :length => 30, :break_token => '').should == 'This is line one. This is...'
156 | end
157 | it 'does not truncate abnormally if the break_token is present, but beyond the length param' do
158 | truncate('This is line one. This is line two.', :length => 30, :break_token => '').should == 'This is line one. This is...'
159 | end
160 | it 'truncates before the length param if the break_token is before the token at "length"' do
161 | truncate('This is line one. This is line two.', :length => 30, :break_token => '').should == 'This is line one.'
162 | end
163 | end
164 |
165 | context 'when the break_token option is customized as a comment' do
166 | it 'does not truncate abnormally if the break_token is not present' do
167 | truncate('This is line one. This is line two.', :length => 30, :break_token => '').should == 'This is line one. This is...'
168 | end
169 | it 'does not truncate abnormally if the break_token is present, but beyond the length param' do
170 | truncate('This is line one. This is line two.', :length => 30, :break_token => '').should == 'This is line one. This is...'
171 | end
172 | it 'truncates before the length param if the break_token is before the token at "length"' do
173 | truncate('This is line one. This is line two.', :length => 30, :break_token => '').should == 'This is line one.'
174 | end
175 | end
176 |
177 | context 'when the break_token option is customized as an html tag' do
178 | it 'does not truncate abnormally if the break_token is not present' do
179 | truncate('This is line one. This is line two.', :length => 30, :break_token => '