truncate_html_sentence 0.5.6

Sign up to get free protection for your applications and to get access to all the features.
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,7 @@
1
+ pkg
2
+ coverage
3
+ profiling
4
+ tmp
5
+ spec/rails_root/log/*
6
+ log/*.log
7
+ .bundle
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.2
4
+ - jruby-19mode # JRuby in 1.9 mode
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in truncate_html.gemspec
4
+ gemspec
@@ -0,0 +1,92 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ truncate_html (0.5.5)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ abstract (1.0.0)
10
+ actionmailer (3.0.3)
11
+ actionpack (= 3.0.3)
12
+ mail (~> 2.2.9)
13
+ actionpack (3.0.3)
14
+ activemodel (= 3.0.3)
15
+ activesupport (= 3.0.3)
16
+ builder (~> 2.1.2)
17
+ erubis (~> 2.6.6)
18
+ i18n (~> 0.4)
19
+ rack (~> 1.2.1)
20
+ rack-mount (~> 0.6.13)
21
+ rack-test (~> 0.5.6)
22
+ tzinfo (~> 0.3.23)
23
+ activemodel (3.0.3)
24
+ activesupport (= 3.0.3)
25
+ builder (~> 2.1.2)
26
+ i18n (~> 0.4)
27
+ activerecord (3.0.3)
28
+ activemodel (= 3.0.3)
29
+ activesupport (= 3.0.3)
30
+ arel (~> 2.0.2)
31
+ tzinfo (~> 0.3.23)
32
+ activeresource (3.0.3)
33
+ activemodel (= 3.0.3)
34
+ activesupport (= 3.0.3)
35
+ activesupport (3.0.3)
36
+ arel (2.0.7)
37
+ builder (2.1.2)
38
+ diff-lcs (1.1.3)
39
+ erubis (2.6.6)
40
+ abstract (>= 1.0.0)
41
+ i18n (0.5.0)
42
+ mail (2.2.15)
43
+ activesupport (>= 2.3.6)
44
+ i18n (>= 0.4.0)
45
+ mime-types (~> 1.16)
46
+ treetop (~> 1.4.8)
47
+ mime-types (1.16)
48
+ polyglot (0.3.1)
49
+ rack (1.2.1)
50
+ rack-mount (0.6.13)
51
+ rack (>= 1.0.0)
52
+ rack-test (0.5.7)
53
+ rack (>= 1.0)
54
+ rails (3.0.3)
55
+ actionmailer (= 3.0.3)
56
+ actionpack (= 3.0.3)
57
+ activerecord (= 3.0.3)
58
+ activeresource (= 3.0.3)
59
+ activesupport (= 3.0.3)
60
+ bundler (~> 1.0)
61
+ railties (= 3.0.3)
62
+ railties (3.0.3)
63
+ actionpack (= 3.0.3)
64
+ activesupport (= 3.0.3)
65
+ rake (>= 0.8.7)
66
+ thor (~> 0.14.4)
67
+ rake (0.8.7)
68
+ rspec (2.9.0)
69
+ rspec-core (~> 2.9.0)
70
+ rspec-expectations (~> 2.9.0)
71
+ rspec-mocks (~> 2.9.0)
72
+ rspec-core (2.9.0)
73
+ rspec-expectations (2.9.1)
74
+ diff-lcs (~> 1.1.3)
75
+ rspec-mocks (2.9.0)
76
+ rspec-rails (2.9.0)
77
+ actionpack (>= 3.0)
78
+ activesupport (>= 3.0)
79
+ railties (>= 3.0)
80
+ rspec (~> 2.9.0)
81
+ thor (0.14.6)
82
+ treetop (1.4.9)
83
+ polyglot (>= 0.3.1)
84
+ tzinfo (0.3.24)
85
+
86
+ PLATFORMS
87
+ ruby
88
+
89
+ DEPENDENCIES
90
+ rails (~> 3.0.3)
91
+ rspec-rails (~> 2.9)
92
+ truncate_html!
@@ -0,0 +1,40 @@
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 <a> 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.
data/LICENSE ADDED
@@ -0,0 +1,21 @@
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.
@@ -0,0 +1,83 @@
1
+ TruncateHtml
2
+ ============
3
+
4
+ [![Build Status](https://secure.travis-ci.org/hgmnz/truncate_html.png?branch=master)](http://travis-ci.org/hgmnz/truncate_html)
5
+ [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/hgmnz/truncate_html)
6
+
7
+ truncate_html is a Rails helper plugin that [cuts off](http://www.youtube.com/watch?v=6XG4DIOA7nU) a string of HTML and takes care of closing any lingering open tags. There are many possible solutions to this. This plugin does not have any dependencies, and does all it's work via [regular expressions](http://xkcd.com/208/).
8
+
9
+ The API is very similar to Rails' own <code>truncate()</code> method.
10
+
11
+
12
+ Example
13
+ -------
14
+
15
+ ```ruby
16
+ some_html = '<ul><li><a href="http://whatever">This is a link</a></li></ul>'
17
+ truncate_html(some_html, :length => 15, :omission => '...(continued)')
18
+ => <ul><li><a href="http://whatever">This...(continued)</a></li></ul>
19
+ ```
20
+
21
+ A few notes:
22
+
23
+ * By default, it will truncate on word boundary.
24
+ To truncate the HTML string strictly at the specified length, pass in the `:word_boundary => false` option.
25
+ * If the input HTML is nil, it will return an empty string.
26
+ * The omission text's length does count toward the resulting string's length.
27
+ * `<script>` tags will pass right through - they will not count toward the resulting string's length, or be truncated.
28
+ * The default options are:
29
+ * :length => 100
30
+ * :omission => '...'
31
+ * :word_boundary => true
32
+
33
+ You may also set global configuration options.
34
+ For example, place the following on a sensible place,
35
+ like `config/initializers/truncate_html.rb`
36
+
37
+ ```ruby
38
+ TruncateHtml.configure do |config|
39
+ config.length = 50
40
+ config.omission = '...(continued)'
41
+ config.word_boundary = false
42
+ end
43
+ ```
44
+
45
+ If you really want, you can even set a custom word boundary regexp.
46
+ For example, to truncate at the end of the nearest sentence:
47
+
48
+ ```ruby
49
+ TruncateHtml.configure do |config|
50
+ config.length = 50
51
+ config.omission = ''
52
+ config.word_boundary = /\S[\.\?\!]/
53
+ end
54
+ ```
55
+
56
+ Installation
57
+ ------------
58
+
59
+ The latest gem version for the Rails 2.x series is 0.3.2.
60
+ To use truncate_html on a Rails 2 app, please install the 0.3.2 version:
61
+
62
+ gem install truncate_html -v 0.3.2
63
+
64
+ For Rails 3, use the latest truncate_html:
65
+
66
+ gem install truncate_html
67
+
68
+ Issues or Suggestions
69
+ ---------------------
70
+
71
+ Found an issue or have a suggestion? Please report it on [Github's issue tracker](http://github.com/hgmnz/truncate_html/issues).
72
+
73
+ Testing
74
+ -------
75
+
76
+ bundle
77
+ rake
78
+
79
+ All green? Go hack.
80
+
81
+ Copyright (c) 2009 - 2010 Harold A. Giménez, released under the MIT license
82
+
83
+ Thanks to all the [contributors](https://github.com/hgmnz/truncate_html/contributors)!
@@ -0,0 +1,50 @@
1
+ require 'rake'
2
+
3
+ begin
4
+ require 'rspec/core'
5
+ require 'rspec/core/rake_task'
6
+ rescue MissingSourceFile
7
+ module RSpec
8
+ module Core
9
+ class RakeTask
10
+ def initialize(name)
11
+ task name do
12
+ # if rspec-rails is a configured gem, this will output helpful material and exit ...
13
+ require File.expand_path(File.dirname(__FILE__) + "/../../config/environment")
14
+ # ... otherwise, do this:
15
+ raise <<-MSG
16
+ #{"*" * 80}
17
+ * You are trying to run an rspec rake task defined in
18
+ * #{__FILE__},
19
+ * but rspec can not be found in vendor/gems, vendor/plugins or system gems.
20
+ #{"*" * 80}
21
+ MSG
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ task :default => :spec
30
+ task :stats => "spec:statsetup"
31
+
32
+ desc "Run RSpec code examples"
33
+ RSpec::Core::RakeTask.new(:spec) do |t|
34
+ t.pattern = "./spec/**/*_spec.rb"
35
+ end
36
+
37
+ namespace :gem do
38
+ desc "Release to rubygems"
39
+ task :release do
40
+ require File.expand_path('lib/truncate_html/version', File.dirname(__FILE__))
41
+ version = TruncateHtml::VERSION
42
+ message = "Bump to version #{version}"
43
+ system "git tag -a -m '#{message}' v#{version}"
44
+ system "git push origin master"
45
+ system "git push origin $(git tag | tail -1)"
46
+ system "gem build truncate_html_sentence.gemspec"
47
+ system "gem push truncate_html_sentence-#{version}.gem"
48
+ system "rm truncate_html_sentence-#{version}.gem"
49
+ end
50
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.5.1
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'truncate_html'
@@ -0,0 +1,9 @@
1
+ module TruncateHtmlHelper
2
+
3
+ def truncate_html(html, options={})
4
+ return '' if html.nil?
5
+ html_string = TruncateHtml::HtmlString.new(html)
6
+ TruncateHtml::HtmlTruncator.new(html_string).truncate(options).html_safe
7
+ end
8
+
9
+ end
@@ -0,0 +1,13 @@
1
+ require File.join(File.dirname(__FILE__), 'truncate_html', 'version')
2
+ require File.join(File.dirname(__FILE__), 'truncate_html', 'html_truncator')
3
+ require File.join(File.dirname(__FILE__), 'truncate_html', 'html_string')
4
+ require File.join(File.dirname(__FILE__), 'truncate_html', 'configuration')
5
+ require File.join(File.dirname(__FILE__), 'app', 'helpers', 'truncate_html_helper')
6
+
7
+ TruncateHtml.configure do |config|
8
+ config.length = 100
9
+ config.omission = '...'
10
+ config.word_boundary = /\S/
11
+ end
12
+
13
+ ActionController::Base.helper(TruncateHtmlHelper)
@@ -0,0 +1,14 @@
1
+ module TruncateHtml
2
+ class Configuration
3
+ attr_accessor :length, :omission, :word_boundary
4
+ end
5
+
6
+ class << self
7
+ attr_accessor :configuration
8
+ end
9
+
10
+ def self.configure
11
+ self.configuration ||= Configuration.new
12
+ yield configuration
13
+ end
14
+ end
@@ -0,0 +1,41 @@
1
+ # encoding: utf-8
2
+ module TruncateHtml
3
+ class HtmlString < String
4
+
5
+ UNPAIRED_TAGS = %w(br hr img).freeze
6
+
7
+ def initialize(original_html)
8
+ super(original_html)
9
+ end
10
+
11
+ def html_tokens
12
+ scan(regex).map do |token|
13
+ HtmlString.new(
14
+ token.gsub(
15
+ /\n/,'' #remove newline characters
16
+ ).gsub(
17
+ /\s+/, ' ' #clean out extra consecutive whitespace
18
+ )
19
+ )
20
+ end
21
+ end
22
+
23
+ def html_tag?
24
+ /<\/?[^>]+>/ === self
25
+ end
26
+
27
+ def open_tag?
28
+ /<(?!(?:#{UNPAIRED_TAGS.join('|')}|script|\/))[^>]+>/i === self
29
+ end
30
+
31
+ def matching_close_tag
32
+ gsub(/<(\w+)\s?.*>/, '</\1>').strip
33
+ end
34
+
35
+ private
36
+ def regex
37
+ /(?:<script.*>.*<\/script>)+|<\/?[^>]+>|[[[:alpha:]]\w\|`~!@#\$%^&*\(\)\-_\+=\[\]{}:;'",\.\/?]+|\s+|[[:punct:]]/
38
+ end
39
+
40
+ end
41
+ end
@@ -0,0 +1,80 @@
1
+ module TruncateHtml
2
+ class HtmlTruncator
3
+
4
+ def initialize(original_html)
5
+ @original_html = original_html
6
+ end
7
+
8
+ def truncate(options = {})
9
+ length = options[:length] || TruncateHtml.configuration.length
10
+ @omission = options[:omission] || TruncateHtml.configuration.omission
11
+ @word_boundary = (options.has_key?(:word_boundary) ? options[:word_boundary] : TruncateHtml.configuration.word_boundary)
12
+ @chars_remaining = length - @omission.length
13
+ @open_tags, @truncated_html = [], ['']
14
+
15
+ return @omission if @chars_remaining < 0
16
+ @original_html.html_tokens.each do |token|
17
+ if @chars_remaining > 0
18
+ process_token(token)
19
+ else
20
+ close_open_tags
21
+ break
22
+ end
23
+ end
24
+
25
+ out = @truncated_html.join
26
+
27
+ if @word_boundary
28
+ term_regexp = Regexp.new("^.*#{@word_boundary.source}")
29
+ match = out.match(term_regexp)
30
+ match ? match[0] : out
31
+ else
32
+ out
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ def process_token(token)
39
+ append_to_result(token)
40
+ if token.html_tag?
41
+ if token.open_tag?
42
+ @open_tags << token
43
+ else
44
+ remove_latest_open_tag(token)
45
+ end
46
+ else
47
+ @chars_remaining -= (@word_boundary ? token.length : token[0, @chars_remaining].length)
48
+ if @chars_remaining <= 0
49
+ @truncated_html[-1] = @truncated_html[-1].rstrip + @omission
50
+ end
51
+ end
52
+ end
53
+
54
+ def append_to_result(token)
55
+ if token.html_tag?
56
+ @truncated_html << token
57
+ elsif @word_boundary
58
+ @truncated_html << token if (@chars_remaining - token.length) >= 0
59
+ else
60
+ @truncated_html << token[0, @chars_remaining]
61
+ end
62
+ end
63
+
64
+ def close_open_tags
65
+ @open_tags.reverse_each do |open_tag|
66
+ @truncated_html << open_tag.matching_close_tag
67
+ end
68
+ end
69
+
70
+ def remove_latest_open_tag(close_tag)
71
+ (0...@open_tags.length).to_a.reverse.each do |index|
72
+ if @open_tags[index].matching_close_tag == close_tag
73
+ @open_tags.delete_at(index)
74
+ break
75
+ end
76
+ end
77
+ end
78
+
79
+ end
80
+ end