truncate_html 0.2.2 → 0.3.0
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.
- data/.gitignore +2 -0
 - data/History.txt +2 -2
 - data/README.markdown +19 -9
 - data/Rakefile +19 -0
 - data/VERSION +1 -1
 - data/init.rb +6 -0
 - data/lib/app/helpers/truncate_html_helper.rb +3 -1
 - data/lib/truncate_html.rb +2 -5
 - data/lib/truncate_html/configuration.rb +15 -0
 - data/lib/truncate_html/html_string.rb +35 -0
 - data/lib/truncate_html/html_truncator.rb +43 -50
 - data/spec/helpers/truncate_html_helper_spec.rb +25 -100
 - data/spec/spec_helper.rb +1 -1
 - data/spec/truncate_html/configuration_spec.rb +17 -0
 - data/spec/truncate_html/html_string_spec.rb +76 -0
 - data/spec/truncate_html/html_truncator_spec.rb +86 -46
 - data/truncate_html.gemspec +11 -4
 - metadata +8 -2
 
    
        data/.gitignore
    CHANGED
    
    
    
        data/History.txt
    CHANGED
    
    | 
         @@ -1,5 +1,5 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            == 0.2.2 2009-12-23
         
     | 
| 
       2 
     | 
    
         
            -
             * Fix issue #4: Handle case when supplied length is smaller than omission (ghazel)
         
     | 
| 
      
 2 
     | 
    
         
            +
             * Fix issue #4: Handle case when supplied length is smaller than omission. (ghazel)
         
     | 
| 
       3 
3 
     | 
    
         | 
| 
       4 
4 
     | 
    
         
             
            == 0.2.1 2009-12-18
         
     | 
| 
       5 
5 
     | 
    
         
             
             * Fix issue #3: Handle case when input html contins a script tag.
         
     | 
| 
         @@ -10,7 +10,7 @@ 
     | 
|
| 
       10 
10 
     | 
    
         
             
               helper's behavior.
         
     | 
| 
       11 
11 
     | 
    
         | 
| 
       12 
12 
     | 
    
         
             
            == 0.1.2 2009-09-25
         
     | 
| 
       13 
     | 
    
         
            -
             * Fix issue #1: Handle case when input html is nil.
         
     | 
| 
      
 13 
     | 
    
         
            +
             * Fix issue #1: Handle case when input html is nil. (bcardarella)
         
     | 
| 
       14 
14 
     | 
    
         | 
| 
       15 
15 
     | 
    
         
             
            == 0.1.1 2009-08-25
         
     | 
| 
       16 
16 
     | 
    
         
             
             * Fixed issue with regex which would not recognize <a> tags that contain slashes.
         
     | 
    
        data/README.markdown
    CHANGED
    
    | 
         @@ -3,25 +3,26 @@ TruncateHtml 
     | 
|
| 
       3 
3 
     | 
    
         | 
| 
       4 
4 
     | 
    
         
             
            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/).
         
     | 
| 
       5 
5 
     | 
    
         | 
| 
       6 
     | 
    
         
            -
            The API is very similar to Rails' own truncate method.
         
     | 
| 
      
 6 
     | 
    
         
            +
            The API is very similar to Rails' own <code>truncate()</code> method.
         
     | 
| 
       7 
7 
     | 
    
         | 
| 
       8 
8 
     | 
    
         | 
| 
       9 
9 
     | 
    
         
             
            Example
         
     | 
| 
       10 
10 
     | 
    
         
             
            -------
         
     | 
| 
       11 
11 
     | 
    
         | 
| 
       12 
12 
     | 
    
         
             
                some_html = '<ul><li><a href="http://whatever">This is a link</a></li></ul>'
         
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
     | 
    
         
            -
                  => <ul><li><a href="http://whatever">This is...(continued)</a></li></ul>
         
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
      
 13 
     | 
    
         
            +
                truncate_html(some_html, :length => 15, :omission => '...(continued)')
         
     | 
| 
      
 14 
     | 
    
         
            +
                  => <ul><li><a href="http://whatever">This...(continued)</a></li></ul>
         
     | 
| 
       18 
15 
     | 
    
         | 
| 
       19 
16 
     | 
    
         
             
            A few notes:
         
     | 
| 
       20 
17 
     | 
    
         | 
| 
       21 
     | 
    
         
            -
            * It will truncate on a word boundary.
         
     | 
| 
       22 
18 
     | 
    
         
             
            * The default options are:
         
     | 
| 
       23 
19 
     | 
    
         
             
              * :length => 100
         
     | 
| 
       24 
20 
     | 
    
         
             
              * :omission => '...'
         
     | 
| 
      
 21 
     | 
    
         
            +
            * By default, it will truncate on word boundry. 
         
     | 
| 
      
 22 
     | 
    
         
            +
              To truncate the HTML string strictly at the specified length, pass in the `:word_boundry => false` option.
         
     | 
| 
      
 23 
     | 
    
         
            +
            * If the input HTML is nil, it will return an empty string.
         
     | 
| 
      
 24 
     | 
    
         
            +
            * The omission text's length does count toward the resulting string's length.
         
     | 
| 
      
 25 
     | 
    
         
            +
            * `<script>` tags will pass right through - they will not count toward the resulting string's length, or be truncated.
         
     | 
| 
       25 
26 
     | 
    
         | 
| 
       26 
27 
     | 
    
         
             
            Installation
         
     | 
| 
       27 
28 
     | 
    
         
             
            ------------
         
     | 
| 
         @@ -33,9 +34,9 @@ Add this to your <code>config/environment.rb</code>: 
     | 
|
| 
       33 
34 
     | 
    
         
             
                  :source => 'http://gemcutter.org'
         
     | 
| 
       34 
35 
     | 
    
         | 
| 
       35 
36 
     | 
    
         
             
            Then either
         
     | 
| 
       36 
     | 
    
         
            -
            <code> 
     | 
| 
      
 37 
     | 
    
         
            +
            <code>rake gems:install</code>
         
     | 
| 
       37 
38 
     | 
    
         
             
            or
         
     | 
| 
       38 
     | 
    
         
            -
            <code> 
     | 
| 
      
 39 
     | 
    
         
            +
            <code>gem install truncate_html</code>
         
     | 
| 
       39 
40 
     | 
    
         | 
| 
       40 
41 
     | 
    
         
             
            #### As a plugin:
         
     | 
| 
       41 
42 
     | 
    
         
             
            <code>script/plugin install git://github.com/hgimenez/truncate_html.git</code>
         
     | 
| 
         @@ -50,4 +51,13 @@ Testing 
     | 
|
| 
       50 
51 
     | 
    
         | 
| 
       51 
52 
     | 
    
         
             
            The plugin is tested using RSpec. [Install it](http://wiki.github.com/dchelimsky/rspec/rails) on your app if you wish to run the tests.
         
     | 
| 
       52 
53 
     | 
    
         | 
| 
      
 54 
     | 
    
         
            +
            If you want to hack on this, here's how to set up a development/testing environment:
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
                $ rails truncate_html_base
         
     | 
| 
      
 57 
     | 
    
         
            +
                $ cd truncate_html_base
         
     | 
| 
      
 58 
     | 
    
         
            +
                $ git clone git://github.com/hgimenez/truncate_html.git vendor/plugins/truncate_html
         
     | 
| 
      
 59 
     | 
    
         
            +
                # install RSpec, follow instructions at http://wiki.github.com/dchelimsky/rspec/rails
         
     | 
| 
      
 60 
     | 
    
         
            +
                $ cd vendor/plugins/truncate_html
         
     | 
| 
      
 61 
     | 
    
         
            +
                $ rake spec # all green? Go hack
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
       53 
63 
     | 
    
         
             
            Copyright (c) 2009 Harold A. Giménez, released under the MIT license
         
     | 
    
        data/Rakefile
    CHANGED
    
    | 
         @@ -1,6 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            require 'rake'
         
     | 
| 
       2 
2 
     | 
    
         
             
            require 'spec/rake/spectask'
         
     | 
| 
       3 
3 
     | 
    
         | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
       4 
5 
     | 
    
         
             
            desc 'Default: run specs.'
         
     | 
| 
       5 
6 
     | 
    
         
             
            task :default => :spec
         
     | 
| 
       6 
7 
     | 
    
         | 
| 
         @@ -16,6 +17,24 @@ Spec::Rake::SpecTask.new(:rcov) do |spec| 
     | 
|
| 
       16 
17 
     | 
    
         
             
              spec.rcov = true
         
     | 
| 
       17 
18 
     | 
    
         
             
            end
         
     | 
| 
       18 
19 
     | 
    
         | 
| 
      
 20 
     | 
    
         
            +
            begin
         
     | 
| 
      
 21 
     | 
    
         
            +
              require 'metric_fu'
         
     | 
| 
      
 22 
     | 
    
         
            +
              MetricFu::Configuration.run do |config|
         
     | 
| 
      
 23 
     | 
    
         
            +
                config.metrics  = [:saikuro, :flog, :flay, :reek, :roodi, :rcov]
         
     | 
| 
      
 24 
     | 
    
         
            +
                config.graphs   = [:flog, :flay, :reek, :roodi, :rcov]
         
     | 
| 
      
 25 
     | 
    
         
            +
                config.rcov     = { :environment => 'test',
         
     | 
| 
      
 26 
     | 
    
         
            +
                                    :test_files => ['spec/**/*_spec.rb'],
         
     | 
| 
      
 27 
     | 
    
         
            +
                                    :rcov_opts => ["--sort coverage",
         
     | 
| 
      
 28 
     | 
    
         
            +
                                                   "--text-coverage",
         
     | 
| 
      
 29 
     | 
    
         
            +
                                                   "--profile",
         
     | 
| 
      
 30 
     | 
    
         
            +
                                                   "--exclude /gems/,/Library/"]}
         
     | 
| 
      
 31 
     | 
    
         
            +
                config.graph_engine = :bluff
         
     | 
| 
      
 32 
     | 
    
         
            +
              end
         
     | 
| 
      
 33 
     | 
    
         
            +
            rescue LoadError
         
     | 
| 
      
 34 
     | 
    
         
            +
              puts "Install metric_fu to run code metrics"
         
     | 
| 
      
 35 
     | 
    
         
            +
            end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
       19 
38 
     | 
    
         
             
            begin
         
     | 
| 
       20 
39 
     | 
    
         
             
              require 'jeweler'
         
     | 
| 
       21 
40 
     | 
    
         
             
              Jeweler::Tasks.new do |gem|
         
     | 
    
        data/VERSION
    CHANGED
    
    | 
         @@ -1 +1 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            0. 
     | 
| 
      
 1 
     | 
    
         
            +
            0.3.0
         
     | 
    
        data/init.rb
    CHANGED
    
    
| 
         @@ -1,7 +1,9 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            module TruncateHtmlHelper
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
              def truncate_html(html, options={})
         
     | 
| 
       4 
     | 
    
         
            -
                 
     | 
| 
      
 4 
     | 
    
         
            +
                return '' if html.nil?
         
     | 
| 
      
 5 
     | 
    
         
            +
                html_string = TruncateHtml::HtmlString.new(html)
         
     | 
| 
      
 6 
     | 
    
         
            +
                TruncateHtml::HtmlTruncator.new(html_string).truncate(options)
         
     | 
| 
       5 
7 
     | 
    
         
             
              end
         
     | 
| 
       6 
8 
     | 
    
         | 
| 
       7 
9 
     | 
    
         
             
            end
         
     | 
    
        data/lib/truncate_html.rb
    CHANGED
    
    | 
         @@ -1,9 +1,6 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            path =  File.join(File.dirname(__FILE__), 'app', 'helpers')  
         
     | 
| 
       2 
     | 
    
         
            -
            $LOAD_PATH << path 
         
     | 
| 
       3 
     | 
    
         
            -
            ActiveSupport::Dependencies.load_paths << path 
         
     | 
| 
       4 
     | 
    
         
            -
            ActiveSupport::Dependencies.load_once_paths.delete(path) 
         
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
1 
     | 
    
         
             
            require File.join(File.dirname(__FILE__), 'truncate_html', 'html_truncator')
         
     | 
| 
      
 2 
     | 
    
         
            +
            require File.join(File.dirname(__FILE__), 'truncate_html', 'configuration')
         
     | 
| 
      
 3 
     | 
    
         
            +
            require File.join(File.dirname(__FILE__), 'app', 'helpers', 'truncate_html_helper')
         
     | 
| 
       7 
4 
     | 
    
         | 
| 
       8 
5 
     | 
    
         
             
            ActionView::Base.class_eval do
         
     | 
| 
       9 
6 
     | 
    
         
             
              include TruncateHtmlHelper
         
     | 
| 
         @@ -0,0 +1,15 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module TruncateHtml
         
     | 
| 
      
 2 
     | 
    
         
            +
              class Configuration
         
     | 
| 
      
 3 
     | 
    
         
            +
                attr_accessor :length, :omission, :word_boundry
         
     | 
| 
      
 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 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,35 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module TruncateHtml
         
     | 
| 
      
 2 
     | 
    
         
            +
              class HtmlString < String
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
                UNPAIRED_TAGS = %w(br hr img)
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
                def initialize(original_html)
         
     | 
| 
      
 7 
     | 
    
         
            +
                  super(original_html)
         
     | 
| 
      
 8 
     | 
    
         
            +
                end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                def html_tokens
         
     | 
| 
      
 11 
     | 
    
         
            +
                  scan(/(?:<script.*>.*<\/script>)+|<\/?[^>]+>|[\w\|`~!@#\$%^&*\(\)\-_\+=\[\]{}:;'",\.\/?]+|\s+/).map do
         
     | 
| 
      
 12 
     | 
    
         
            +
                    |token| token.gsub(
         
     | 
| 
      
 13 
     | 
    
         
            +
                      #remove newline characters
         
     | 
| 
      
 14 
     | 
    
         
            +
                        /\n/,''
         
     | 
| 
      
 15 
     | 
    
         
            +
                    ).gsub(
         
     | 
| 
      
 16 
     | 
    
         
            +
                      #clean out extra consecutive whitespace
         
     | 
| 
      
 17 
     | 
    
         
            +
                        /\s+/, ' '
         
     | 
| 
      
 18 
     | 
    
         
            +
                    )
         
     | 
| 
      
 19 
     | 
    
         
            +
                  end.map { |token| HtmlString.new(token) }
         
     | 
| 
      
 20 
     | 
    
         
            +
                end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                def html_tag?
         
     | 
| 
      
 23 
     | 
    
         
            +
                  self =~ /<\/?[^>]+>/ ? true : false
         
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                def open_tag?
         
     | 
| 
      
 27 
     | 
    
         
            +
                  self =~ /<(?!(?:#{UNPAIRED_TAGS.join('|')}|script|\/))[^>]+>/i ? true : false
         
     | 
| 
      
 28 
     | 
    
         
            +
                end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                def matching_close_tag
         
     | 
| 
      
 31 
     | 
    
         
            +
                  gsub(/<(\w+)\s?.*>/, '</\1>').strip
         
     | 
| 
      
 32 
     | 
    
         
            +
                end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
              end
         
     | 
| 
      
 35 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -1,74 +1,67 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            module TruncateHtml
         
     | 
| 
       2 
2 
     | 
    
         
             
              class HtmlTruncator
         
     | 
| 
       3 
3 
     | 
    
         | 
| 
       4 
     | 
    
         
            -
                UNPAIRED_TAGS = %w(br hr img)
         
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
4 
     | 
    
         
             
                def initialize(original_html)
         
     | 
| 
       7 
     | 
    
         
            -
                  @original_html 
     | 
| 
      
 5 
     | 
    
         
            +
                  @original_html  = original_html
         
     | 
| 
       8 
6 
     | 
    
         
             
                end
         
     | 
| 
       9 
7 
     | 
    
         | 
| 
       10 
8 
     | 
    
         
             
                def truncate(options = {})
         
     | 
| 
       11 
     | 
    
         
            -
                   
     | 
| 
       12 
     | 
    
         
            -
                  options[: 
     | 
| 
       13 
     | 
    
         
            -
                  options[: 
     | 
| 
       14 
     | 
    
         
            -
                  @chars_remaining =  
     | 
| 
       15 
     | 
    
         
            -
                  @open_tags,  
     | 
| 
      
 9 
     | 
    
         
            +
                  length        = options[:length]       || TruncateHtml.configuration.length
         
     | 
| 
      
 10 
     | 
    
         
            +
                  @omission     = options[:omission]     || TruncateHtml.configuration.omission
         
     | 
| 
      
 11 
     | 
    
         
            +
                  @word_boundry = (options.has_key?(:word_boundry) ? options[:word_boundry] : TruncateHtml.configuration.word_boundry)
         
     | 
| 
      
 12 
     | 
    
         
            +
                  @chars_remaining = length - @omission.length
         
     | 
| 
      
 13 
     | 
    
         
            +
                  @open_tags, @truncated_html = [], ['']
         
     | 
| 
       16 
14 
     | 
    
         | 
| 
       17 
     | 
    
         
            -
                  html_tokens.each do | 
     | 
| 
      
 15 
     | 
    
         
            +
                  @original_html.html_tokens.each do |token|
         
     | 
| 
      
 16 
     | 
    
         
            +
                    #if truncate_more?(token)
         
     | 
| 
       18 
17 
     | 
    
         
             
                    if @chars_remaining > 0
         
     | 
| 
       19 
     | 
    
         
            -
                       
     | 
| 
       20 
     | 
    
         
            -
                        if open_tag?(str)
         
     | 
| 
       21 
     | 
    
         
            -
                          @open_tags << str
         
     | 
| 
       22 
     | 
    
         
            -
                        else
         
     | 
| 
       23 
     | 
    
         
            -
                          open_tags = remove_latest_open_tag(str)
         
     | 
| 
       24 
     | 
    
         
            -
                        end
         
     | 
| 
       25 
     | 
    
         
            -
                      else
         
     | 
| 
       26 
     | 
    
         
            -
                        @chars_remaining -= str.length
         
     | 
| 
       27 
     | 
    
         
            -
                      end
         
     | 
| 
       28 
     | 
    
         
            -
                      result << str
         
     | 
| 
      
 18 
     | 
    
         
            +
                      process_token(token)
         
     | 
| 
       29 
19 
     | 
    
         
             
                    else
         
     | 
| 
       30 
     | 
    
         
            -
                       
     | 
| 
       31 
     | 
    
         
            -
                      @open_tags.reverse_each do |open_tag|
         
     | 
| 
       32 
     | 
    
         
            -
                        result << matching_close_tag(open_tag)
         
     | 
| 
       33 
     | 
    
         
            -
                      end
         
     | 
| 
      
 20 
     | 
    
         
            +
                      close_open_tags
         
     | 
| 
       34 
21 
     | 
    
         
             
                      break
         
     | 
| 
       35 
22 
     | 
    
         
             
                    end
         
     | 
| 
       36 
23 
     | 
    
         
             
                  end
         
     | 
| 
       37 
     | 
    
         
            -
                   
     | 
| 
      
 24 
     | 
    
         
            +
                  @truncated_html.join
         
     | 
| 
       38 
25 
     | 
    
         
             
                end
         
     | 
| 
       39 
26 
     | 
    
         | 
| 
       40 
     | 
    
         
            -
                 
     | 
| 
       41 
     | 
    
         
            -
                  @original_html.scan(/(?:<script.*>.*<\/script>)+|<\/?[^>]+>|[\w\|`~!@#\$%^&*\(\)\-_\+=\[\]{}:;'",\.\/?]+|\s+/).map do
         
     | 
| 
       42 
     | 
    
         
            -
                    |t| t.gsub(
         
     | 
| 
       43 
     | 
    
         
            -
                      #remove newline characters
         
     | 
| 
       44 
     | 
    
         
            -
                        /\n/,''
         
     | 
| 
       45 
     | 
    
         
            -
                    ).gsub(
         
     | 
| 
       46 
     | 
    
         
            -
                      #clean out extra consecutive whitespace
         
     | 
| 
       47 
     | 
    
         
            -
                        /\s+/, ' '
         
     | 
| 
       48 
     | 
    
         
            -
                    )
         
     | 
| 
       49 
     | 
    
         
            -
                  end
         
     | 
| 
       50 
     | 
    
         
            -
                end
         
     | 
| 
      
 27 
     | 
    
         
            +
                private
         
     | 
| 
       51 
28 
     | 
    
         | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
      
 29 
     | 
    
         
            +
                  def process_token(token)
         
     | 
| 
      
 30 
     | 
    
         
            +
                    append_to_result(token)
         
     | 
| 
      
 31 
     | 
    
         
            +
                    if token.html_tag?
         
     | 
| 
      
 32 
     | 
    
         
            +
                      if token.open_tag?
         
     | 
| 
      
 33 
     | 
    
         
            +
                        @open_tags << token
         
     | 
| 
      
 34 
     | 
    
         
            +
                      else
         
     | 
| 
      
 35 
     | 
    
         
            +
                        remove_latest_open_tag(token)
         
     | 
| 
      
 36 
     | 
    
         
            +
                      end
         
     | 
| 
      
 37 
     | 
    
         
            +
                    else
         
     | 
| 
      
 38 
     | 
    
         
            +
                      @chars_remaining -= (@word_boundry ? token.length : token[0, @chars_remaining].length)
         
     | 
| 
      
 39 
     | 
    
         
            +
                    end
         
     | 
| 
      
 40 
     | 
    
         
            +
                  end
         
     | 
| 
       55 
41 
     | 
    
         | 
| 
       56 
     | 
    
         
            -
             
     | 
| 
       57 
     | 
    
         
            -
             
     | 
| 
       58 
     | 
    
         
            -
             
     | 
| 
      
 42 
     | 
    
         
            +
                  def append_to_result(token)
         
     | 
| 
      
 43 
     | 
    
         
            +
                    if @word_boundry
         
     | 
| 
      
 44 
     | 
    
         
            +
                      @truncated_html << token
         
     | 
| 
      
 45 
     | 
    
         
            +
                    else
         
     | 
| 
      
 46 
     | 
    
         
            +
                      @truncated_html << token[0, @chars_remaining]
         
     | 
| 
      
 47 
     | 
    
         
            +
                    end
         
     | 
| 
      
 48 
     | 
    
         
            +
                  end
         
     | 
| 
       59 
49 
     | 
    
         | 
| 
       60 
     | 
    
         
            -
             
     | 
| 
       61 
     | 
    
         
            -
             
     | 
| 
       62 
     | 
    
         
            -
                     
     | 
| 
       63 
     | 
    
         
            -
                      @ 
     | 
| 
       64 
     | 
    
         
            -
                      break
         
     | 
| 
      
 50 
     | 
    
         
            +
                  def close_open_tags
         
     | 
| 
      
 51 
     | 
    
         
            +
                    @truncated_html[-1] = @truncated_html[-1].rstrip + @omission
         
     | 
| 
      
 52 
     | 
    
         
            +
                    @open_tags.reverse_each do |open_tag|
         
     | 
| 
      
 53 
     | 
    
         
            +
                      @truncated_html << open_tag.matching_close_tag
         
     | 
| 
       65 
54 
     | 
    
         
             
                    end
         
     | 
| 
       66 
55 
     | 
    
         
             
                  end
         
     | 
| 
       67 
     | 
    
         
            -
                end
         
     | 
| 
       68 
56 
     | 
    
         | 
| 
       69 
     | 
    
         
            -
             
     | 
| 
       70 
     | 
    
         
            -
             
     | 
| 
       71 
     | 
    
         
            -
             
     | 
| 
      
 57 
     | 
    
         
            +
                  def remove_latest_open_tag(close_tag)
         
     | 
| 
      
 58 
     | 
    
         
            +
                    (0...@open_tags.length).to_a.reverse.each do |index|
         
     | 
| 
      
 59 
     | 
    
         
            +
                      if @open_tags[index].matching_close_tag == close_tag
         
     | 
| 
      
 60 
     | 
    
         
            +
                        @open_tags.delete_at(index)
         
     | 
| 
      
 61 
     | 
    
         
            +
                        break
         
     | 
| 
      
 62 
     | 
    
         
            +
                      end
         
     | 
| 
      
 63 
     | 
    
         
            +
                    end
         
     | 
| 
      
 64 
     | 
    
         
            +
                  end
         
     | 
| 
       72 
65 
     | 
    
         | 
| 
       73 
66 
     | 
    
         
             
              end
         
     | 
| 
       74 
67 
     | 
    
         
             
            end
         
     | 
| 
         @@ -2,115 +2,40 @@ require File.join(File.dirname(__FILE__), '..', 'spec_helper') 
     | 
|
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            include TruncateHtmlHelper
         
     | 
| 
       4 
4 
     | 
    
         | 
| 
      
 5 
     | 
    
         
            +
            class Truncator
         
     | 
| 
      
 6 
     | 
    
         
            +
              include TruncateHtmlHelper
         
     | 
| 
      
 7 
     | 
    
         
            +
            end
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
       5 
9 
     | 
    
         
             
            describe TruncateHtmlHelper do
         
     | 
| 
       6 
10 
     | 
    
         | 
| 
      
 11 
     | 
    
         
            +
              def truncator
         
     | 
| 
      
 12 
     | 
    
         
            +
                @truncator ||= Truncator.new
         
     | 
| 
      
 13 
     | 
    
         
            +
              end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
       7 
15 
     | 
    
         
             
              it 'is included in ActionView::Base' do
         
     | 
| 
       8 
16 
     | 
    
         
             
                ActionView::Base.included_modules.should include(TruncateHtmlHelper)
         
     | 
| 
       9 
17 
     | 
    
         
             
              end
         
     | 
| 
       10 
18 
     | 
    
         | 
| 
       11 
     | 
    
         
            -
               
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
                  truncate_html('a b c', :length => 4, :omission => '...').should == 'a...'
         
     | 
| 
       15 
     | 
    
         
            -
                end
         
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
     | 
    
         
            -
                it 'supports omissions longer than the maximum length' do
         
     | 
| 
       18 
     | 
    
         
            -
                  lambda { truncate_html('', :length => 1, :omission => '...') }.should_not raise_error
         
     | 
| 
       19 
     | 
    
         
            -
                end
         
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
                it 'returns the omission when the specified length is smaller than the omission' do
         
     | 
| 
       22 
     | 
    
         
            -
                  truncate_html('a b c', :length => 2, :omission => '...').should == '...'
         
     | 
| 
       23 
     | 
    
         
            -
                end
         
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       25 
     | 
    
         
            -
                context 'the input html is nil' do
         
     | 
| 
       26 
     | 
    
         
            -
                  it 'returns an empty string' do
         
     | 
| 
       27 
     | 
    
         
            -
                    truncate_html(nil).should be_empty
         
     | 
| 
       28 
     | 
    
         
            -
                    truncate_html(nil).should be_kind_of(String)
         
     | 
| 
       29 
     | 
    
         
            -
                  end
         
     | 
| 
       30 
     | 
    
         
            -
                end
         
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       32 
     | 
    
         
            -
                context 'the input html contains a script tag' do
         
     | 
| 
       33 
     | 
    
         
            -
                  before(:each) do
         
     | 
| 
       34 
     | 
    
         
            -
                    @input_html = "<p>I have a script <script type=text/javascript>document.write('lum dee dum');</script> and more text</p>"
         
     | 
| 
       35 
     | 
    
         
            -
                    @expected_out = "<p>I have a script <script type=text/javascript>document.write('lum dee dum');</script> and...</p>"
         
     | 
| 
       36 
     | 
    
         
            -
                  end
         
     | 
| 
       37 
     | 
    
         
            -
                  it 'treats the script tag as lengthless string' do
         
     | 
| 
       38 
     | 
    
         
            -
                    truncate_html(@input_html, :length => 23).should == @expected_out
         
     | 
| 
       39 
     | 
    
         
            -
                  end
         
     | 
| 
       40 
     | 
    
         
            -
                end
         
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
     | 
    
         
            -
                context 'truncating in the middle of a link' do
         
     | 
| 
       43 
     | 
    
         
            -
                  before(:each) do
         
     | 
| 
       44 
     | 
    
         
            -
                    @html = '<div><ul><li>Look at <a href="foo">this</a> link </li></ul></div>'
         
     | 
| 
       45 
     | 
    
         
            -
                  end
         
     | 
| 
       46 
     | 
    
         
            -
             
     | 
| 
       47 
     | 
    
         
            -
                  it 'truncates, and closes the <a>, and closes any remaining open tags' do
         
     | 
| 
       48 
     | 
    
         
            -
                    truncate_html(@html, :length => 14).should == '<div><ul><li>Look at <a href="foo">this...</a></li></ul></div>'
         
     | 
| 
       49 
     | 
    
         
            -
                  end
         
     | 
| 
       50 
     | 
    
         
            -
                end
         
     | 
| 
       51 
     | 
    
         
            -
             
     | 
| 
       52 
     | 
    
         
            -
                %w(! @ # $ % ^ & * \( \) - _ + = [ ] { } \ | , . / ?).each do |char|
         
     | 
| 
       53 
     | 
    
         
            -
                  context "when the html has a #{char} character after a closing tag" do
         
     | 
| 
       54 
     | 
    
         
            -
                    before(:each) do
         
     | 
| 
       55 
     | 
    
         
            -
                      @html = "<p>Look at <strong>this</strong>#{char} More words here</p>"
         
     | 
| 
       56 
     | 
    
         
            -
                    end
         
     | 
| 
       57 
     | 
    
         
            -
                    it 'places the punctuation after the tag without any whitespace' do
         
     | 
| 
       58 
     | 
    
         
            -
                      truncate_html(@html, :length => 19).should == "<p>Look at <strong>this</strong>#{char} More...</p>"
         
     | 
| 
       59 
     | 
    
         
            -
                    end
         
     | 
| 
       60 
     | 
    
         
            -
                  end
         
     | 
| 
       61 
     | 
    
         
            -
                end
         
     | 
| 
       62 
     | 
    
         
            -
             
     | 
| 
       63 
     | 
    
         
            -
                context 'when the html has a non punctuation character after a closing tag' do
         
     | 
| 
       64 
     | 
    
         
            -
                  before(:each) do
         
     | 
| 
       65 
     | 
    
         
            -
                    @html = '<p>Look at <a href="awesomeful.net">this</a> link for randomness</p>'
         
     | 
| 
       66 
     | 
    
         
            -
                  end
         
     | 
| 
       67 
     | 
    
         
            -
                  it 'leaves a whitespace between the closing tag and the following word character' do
         
     | 
| 
       68 
     | 
    
         
            -
                    truncate_html(@html, :length => 21).should == '<p>Look at <a href="awesomeful.net">this</a> link...</p>'
         
     | 
| 
       69 
     | 
    
         
            -
                  end
         
     | 
| 
       70 
     | 
    
         
            -
                end
         
     | 
| 
       71 
     | 
    
         
            -
             
     | 
| 
       72 
     | 
    
         
            -
                #unusual, but just covering my ass
         
     | 
| 
       73 
     | 
    
         
            -
                context 'when the HTML tags are multiline' do 
         
     | 
| 
       74 
     | 
    
         
            -
                  before(:each) do
         
     | 
| 
       75 
     | 
    
         
            -
                    @html = <<-END_HTML
         
     | 
| 
       76 
     | 
    
         
            -
                      <div id="foo"
         
     | 
| 
       77 
     | 
    
         
            -
                            class="bar">
         
     | 
| 
       78 
     | 
    
         
            -
                      This is ugly html.
         
     | 
| 
       79 
     | 
    
         
            -
                      </div>
         
     | 
| 
       80 
     | 
    
         
            -
                    END_HTML
         
     | 
| 
       81 
     | 
    
         
            -
                  end
         
     | 
| 
       82 
     | 
    
         
            -
             
     | 
| 
       83 
     | 
    
         
            -
                  it 'recognizes the multiline html properly' do
         
     | 
| 
       84 
     | 
    
         
            -
                    truncate_html(@html, :length => 12).should == ' <div id="foo" class="bar"> This is...</div>'
         
     | 
| 
       85 
     | 
    
         
            -
                  end
         
     | 
| 
       86 
     | 
    
         
            -
                end
         
     | 
| 
       87 
     | 
    
         
            -
             
     | 
| 
       88 
     | 
    
         
            -
                %w(br hr img).each do |unpaired_tag|
         
     | 
| 
       89 
     | 
    
         
            -
                  context "when the html contains a #{unpaired_tag} tag" do
         
     | 
| 
      
 19 
     | 
    
         
            +
              before(:each) do
         
     | 
| 
      
 20 
     | 
    
         
            +
                @html_truncator_mock = mock(TruncateHtml::HtmlTruncator)
         
     | 
| 
      
 21 
     | 
    
         
            +
              end
         
     | 
| 
       90 
22 
     | 
    
         | 
| 
       91 
     | 
    
         
            -
             
     | 
| 
       92 
     | 
    
         
            -
             
     | 
| 
       93 
     | 
    
         
            -
             
     | 
| 
       94 
     | 
    
         
            -
             
     | 
| 
       95 
     | 
    
         
            -
             
     | 
| 
       96 
     | 
    
         
            -
                      it "does not close the #{unpaired_tag} tag" do
         
     | 
| 
       97 
     | 
    
         
            -
                        truncate_html(@html, :length => 19).should == "<div>Some before. <#{unpaired_tag}>and...</div>"
         
     | 
| 
       98 
     | 
    
         
            -
                        truncate_html(@html_caps, :length => 19).should == "<div>Some before. <#{unpaired_tag.capitalize}>and...</div>"
         
     | 
| 
       99 
     | 
    
         
            -
                      end
         
     | 
| 
       100 
     | 
    
         
            -
                    end
         
     | 
| 
      
 23 
     | 
    
         
            +
              it 'creates an instance of HtmlTruncator and calls truncate() on it' do
         
     | 
| 
      
 24 
     | 
    
         
            +
                @html_truncator_mock.stub!(:truncate)
         
     | 
| 
      
 25 
     | 
    
         
            +
                TruncateHtml::HtmlTruncator.should_receive(:new).and_return(@html_truncator_mock)
         
     | 
| 
      
 26 
     | 
    
         
            +
                truncator.truncate_html('foo')
         
     | 
| 
      
 27 
     | 
    
         
            +
              end
         
     | 
| 
       101 
28 
     | 
    
         | 
| 
       102 
     | 
    
         
            -
             
     | 
| 
       103 
     | 
    
         
            -
             
     | 
| 
       104 
     | 
    
         
            -
             
     | 
| 
       105 
     | 
    
         
            -
             
     | 
| 
       106 
     | 
    
         
            -
             
     | 
| 
       107 
     | 
    
         
            -
                      it "does not close the #{unpaired_tag} tag" do
         
     | 
| 
       108 
     | 
    
         
            -
                        truncate_html(@html, :length => 19).should == "<div>Some before. <#{unpaired_tag} />and...</div>"
         
     | 
| 
       109 
     | 
    
         
            -
                        truncate_html(@html_caps, :length => 19).should == "<div>Some before. <#{unpaired_tag.capitalize} />and...</div>"
         
     | 
| 
       110 
     | 
    
         
            -
                      end
         
     | 
| 
       111 
     | 
    
         
            -
                    end
         
     | 
| 
      
 29 
     | 
    
         
            +
              it 'calls truncate() on the HtmlTruncator object' do
         
     | 
| 
      
 30 
     | 
    
         
            +
                TruncateHtml::HtmlTruncator.stub!(:new).and_return(@html_truncator_mock)
         
     | 
| 
      
 31 
     | 
    
         
            +
                @html_truncator_mock.should_receive(:truncate).with({}).once
         
     | 
| 
      
 32 
     | 
    
         
            +
                truncator.truncate_html('foo')
         
     | 
| 
      
 33 
     | 
    
         
            +
              end
         
     | 
| 
       112 
34 
     | 
    
         | 
| 
       113 
     | 
    
         
            -
             
     | 
| 
      
 35 
     | 
    
         
            +
              context 'the input html is nil' do
         
     | 
| 
      
 36 
     | 
    
         
            +
                it 'returns an empty string' do
         
     | 
| 
      
 37 
     | 
    
         
            +
                  truncator.truncate_html(nil).should be_empty
         
     | 
| 
      
 38 
     | 
    
         
            +
                  truncator.truncate_html(nil).should be_kind_of(String)
         
     | 
| 
       114 
39 
     | 
    
         
             
                end
         
     | 
| 
       115 
40 
     | 
    
         
             
              end
         
     | 
| 
       116 
41 
     | 
    
         | 
    
        data/spec/spec_helper.rb
    CHANGED
    
    
| 
         @@ -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,76 @@ 
     | 
|
| 
      
 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 
     | 
    
         
            +
                before(:each) do
         
     | 
| 
      
 11 
     | 
    
         
            +
                  @html = '<h1>Hi there</h1> <p>This          is sweet!</p>'
         
     | 
| 
      
 12 
     | 
    
         
            +
                end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                it 'returns each token in the string as an array element removing any consecutive whitespace from the string' do
         
     | 
| 
      
 15 
     | 
    
         
            +
                  html_string(@html).html_tokens.should == ['<h1>', 'Hi', ' ', 'there', '</h1>', ' ', '<p>', 'This', ' ', 'is', ' ', 'sweet!', '</p>']
         
     | 
| 
      
 16 
     | 
    
         
            +
                end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
              end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
              describe '#html_tag?' do
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                it 'returns false when the string parameter is not an html tag' do
         
     | 
| 
      
 23 
     | 
    
         
            +
                  html_string('no tags').html_tag?.should be_false
         
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                it 'returns true when the string parameter is an html tag' do
         
     | 
| 
      
 27 
     | 
    
         
            +
                  html_string('<img src="foo">').html_tag?.should be_true
         
     | 
| 
      
 28 
     | 
    
         
            +
                  html_string('</img>').html_tag?.should be_true
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
              end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
              describe '#open_tag?' do
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                it 'returns true if the tag is an open tag' do
         
     | 
| 
      
 36 
     | 
    
         
            +
                  html_string('<a>').open_tag?.should be_true
         
     | 
| 
      
 37 
     | 
    
         
            +
                end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                context 'the tag is an open tag, and has whitespace and html properties' do
         
     | 
| 
      
 40 
     | 
    
         
            +
                  it 'returns true if it has single quotes' do
         
     | 
| 
      
 41 
     | 
    
         
            +
                    html_string(" <a href='http://awesomeful.net' >").open_tag?.should be_true
         
     | 
| 
      
 42 
     | 
    
         
            +
                  end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                  it 'returns true if it has double quotes' do
         
     | 
| 
      
 45 
     | 
    
         
            +
                    html_string(' <a href="http://awesomeful.net">').open_tag?.should be_true
         
     | 
| 
      
 46 
     | 
    
         
            +
                  end
         
     | 
| 
      
 47 
     | 
    
         
            +
                end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                it 'returns false if the tag is a close tag' do
         
     | 
| 
      
 50 
     | 
    
         
            +
                  html_string('</a>').open_tag?.should be_false
         
     | 
| 
      
 51 
     | 
    
         
            +
                end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                it 'returns false if the string is not an html tag' do
         
     | 
| 
      
 54 
     | 
    
         
            +
                  html_string('foo bar').open_tag?.should be_false
         
     | 
| 
      
 55 
     | 
    
         
            +
                end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                it 'returns false if it is a <script> tag' do
         
     | 
| 
      
 58 
     | 
    
         
            +
                  html_string('<script>').open_tag?.should be_false
         
     | 
| 
      
 59 
     | 
    
         
            +
                end
         
     | 
| 
      
 60 
     | 
    
         
            +
              end
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
              describe '#matching_close_tag' do
         
     | 
| 
      
 63 
     | 
    
         
            +
                tag_pairs = { '<a>'             => '</a>',
         
     | 
| 
      
 64 
     | 
    
         
            +
                              ' <div>'          => '</div>',
         
     | 
| 
      
 65 
     | 
    
         
            +
                              '<h1>'            => '</h1>',
         
     | 
| 
      
 66 
     | 
    
         
            +
                              '<a href="foo">'  => '</a>' }
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                tag_pairs.each do |open_tag, close_tag|
         
     | 
| 
      
 69 
     | 
    
         
            +
                  it "closes a #{open_tag} and returns #{close_tag}" do
         
     | 
| 
      
 70 
     | 
    
         
            +
                    html_string(open_tag).matching_close_tag.should == close_tag
         
     | 
| 
      
 71 
     | 
    
         
            +
                  end
         
     | 
| 
      
 72 
     | 
    
         
            +
                end
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
              end
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -2,73 +2,113 @@ require File.join(File.dirname(__FILE__), '..', 'spec_helper') 
     | 
|
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            describe TruncateHtml::HtmlTruncator do
         
     | 
| 
       4 
4 
     | 
    
         | 
| 
       5 
     | 
    
         
            -
              def  
     | 
| 
       6 
     | 
    
         
            -
                 
     | 
| 
      
 5 
     | 
    
         
            +
              def truncate(html, opts = {})
         
     | 
| 
      
 6 
     | 
    
         
            +
                html_string = TruncateHtml::HtmlString.new(html)
         
     | 
| 
      
 7 
     | 
    
         
            +
                TruncateHtml::HtmlTruncator.new(html_string).truncate(opts)
         
     | 
| 
       7 
8 
     | 
    
         
             
              end
         
     | 
| 
       8 
9 
     | 
    
         | 
| 
       9 
     | 
    
         
            -
              describe '# 
     | 
| 
       10 
     | 
    
         
            -
                before(:each) do
         
     | 
| 
       11 
     | 
    
         
            -
                  @html = '<h1>Hi there</h1> <p>This          is sweet!</p>'
         
     | 
| 
       12 
     | 
    
         
            -
                end
         
     | 
| 
      
 10 
     | 
    
         
            +
              describe '#truncate' do
         
     | 
| 
       13 
11 
     | 
    
         | 
| 
       14 
     | 
    
         
            -
                 
     | 
| 
       15 
     | 
    
         
            -
                   
     | 
| 
      
 12 
     | 
    
         
            +
                context 'when the word_boundry option is set to false' do
         
     | 
| 
      
 13 
     | 
    
         
            +
                  it 'truncates to the exact length specified' do
         
     | 
| 
      
 14 
     | 
    
         
            +
                    truncate('<div>123456789</div>', :length => 5, :omission => '', :word_boundry => false).should == '<div>12345</div>'
         
     | 
| 
      
 15 
     | 
    
         
            +
                  end
         
     | 
| 
       16 
16 
     | 
    
         
             
                end
         
     | 
| 
       17 
17 
     | 
    
         | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
              describe '#html_tag?' do
         
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
                it 'returns false when the string parameter is not an html tag' do
         
     | 
| 
       23 
     | 
    
         
            -
                  truncator.html_tag?('no tags').should be_false
         
     | 
| 
      
 18 
     | 
    
         
            +
                it "includes the omission text's length in the returned truncated html" do
         
     | 
| 
      
 19 
     | 
    
         
            +
                  truncate('a b c', :length => 4, :omission => '...').should == 'a...'
         
     | 
| 
       24 
20 
     | 
    
         
             
                end
         
     | 
| 
       25 
21 
     | 
    
         | 
| 
       26 
     | 
    
         
            -
                it ' 
     | 
| 
       27 
     | 
    
         
            -
                   
     | 
| 
       28 
     | 
    
         
            -
                  truncator.html_tag?('</img>').should be_true
         
     | 
| 
      
 22 
     | 
    
         
            +
                it 'supports omissions longer than the maximum length' do
         
     | 
| 
      
 23 
     | 
    
         
            +
                  lambda { truncate('', :length => 1, :omission => '...') }.should_not raise_error
         
     | 
| 
       29 
24 
     | 
    
         
             
                end
         
     | 
| 
       30 
25 
     | 
    
         | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
              describe '#open_tag?' do
         
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
     | 
    
         
            -
                it 'returns true if the tag is an open tag' do
         
     | 
| 
       36 
     | 
    
         
            -
                  truncator.open_tag?('<a>').should be_true
         
     | 
| 
      
 26 
     | 
    
         
            +
                it 'returns the omission when the specified length is smaller than the omission' do
         
     | 
| 
      
 27 
     | 
    
         
            +
                  truncate('a b c', :length => 2, :omission => '...').should == '...'
         
     | 
| 
       37 
28 
     | 
    
         
             
                end
         
     | 
| 
       38 
29 
     | 
    
         | 
| 
       39 
     | 
    
         
            -
                 
     | 
| 
       40 
     | 
    
         
            -
                   
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
      
 30 
     | 
    
         
            +
                context 'the input html contains a script tag' do
         
     | 
| 
      
 31 
     | 
    
         
            +
                  before(:each) do
         
     | 
| 
      
 32 
     | 
    
         
            +
                    @input_html = "<p>I have a script <script type=text/javascript>document.write('lum dee dum');</script> and more text</p>"
         
     | 
| 
      
 33 
     | 
    
         
            +
                    @expected_out = "<p>I have a script <script type=text/javascript>document.write('lum dee dum');</script> and...</p>"
         
     | 
| 
      
 34 
     | 
    
         
            +
                  end
         
     | 
| 
      
 35 
     | 
    
         
            +
                  it 'treats the script tag as lengthless string' do
         
     | 
| 
      
 36 
     | 
    
         
            +
                    truncate(@input_html, :length => 23).should == @expected_out
         
     | 
| 
      
 37 
     | 
    
         
            +
                  end
         
     | 
| 
       42 
38 
     | 
    
         
             
                end
         
     | 
| 
       43 
39 
     | 
    
         | 
| 
       44 
     | 
    
         
            -
                 
     | 
| 
       45 
     | 
    
         
            -
                   
     | 
| 
       46 
     | 
    
         
            -
             
     | 
| 
      
 40 
     | 
    
         
            +
                context 'truncating in the middle of a link' do
         
     | 
| 
      
 41 
     | 
    
         
            +
                  before(:each) do
         
     | 
| 
      
 42 
     | 
    
         
            +
                    @html = '<div><ul><li>Look at <a href="foo">this</a> link </li></ul></div>'
         
     | 
| 
      
 43 
     | 
    
         
            +
                  end
         
     | 
| 
       47 
44 
     | 
    
         | 
| 
       48 
     | 
    
         
            -
             
     | 
| 
       49 
     | 
    
         
            -
             
     | 
| 
      
 45 
     | 
    
         
            +
                  it 'truncates, and closes the <a>, and closes any remaining open tags' do
         
     | 
| 
      
 46 
     | 
    
         
            +
                    truncate(@html, :length => 14).should == '<div><ul><li>Look at <a href="foo">this...</a></li></ul></div>'
         
     | 
| 
      
 47 
     | 
    
         
            +
                  end
         
     | 
| 
       50 
48 
     | 
    
         
             
                end
         
     | 
| 
       51 
49 
     | 
    
         | 
| 
       52 
     | 
    
         
            -
                 
     | 
| 
       53 
     | 
    
         
            -
                   
     | 
| 
      
 50 
     | 
    
         
            +
                %w(! @ # $ % ^ & * \( \) - _ + = [ ] { } \ | , . / ?).each do |char|
         
     | 
| 
      
 51 
     | 
    
         
            +
                  context "when the html has a #{char} character after a closing tag" do
         
     | 
| 
      
 52 
     | 
    
         
            +
                    before(:each) do
         
     | 
| 
      
 53 
     | 
    
         
            +
                      @html = "<p>Look at <strong>this</strong>#{char} More words here</p>"
         
     | 
| 
      
 54 
     | 
    
         
            +
                    end
         
     | 
| 
      
 55 
     | 
    
         
            +
                    it 'places the punctuation after the tag without any whitespace' do
         
     | 
| 
      
 56 
     | 
    
         
            +
                      truncate(@html, :length => 19).should == "<p>Look at <strong>this</strong>#{char} More...</p>"
         
     | 
| 
      
 57 
     | 
    
         
            +
                    end
         
     | 
| 
      
 58 
     | 
    
         
            +
                  end
         
     | 
| 
       54 
59 
     | 
    
         
             
                end
         
     | 
| 
       55 
     | 
    
         
            -
              end
         
     | 
| 
       56 
60 
     | 
    
         | 
| 
       57 
     | 
    
         
            -
             
     | 
| 
       58 
     | 
    
         
            -
             
     | 
| 
       59 
     | 
    
         
            -
             
     | 
| 
       60 
     | 
    
         
            -
                   
     | 
| 
       61 
     | 
    
         
            -
                   
     | 
| 
       62 
     | 
    
         
            -
             
     | 
| 
       63 
     | 
    
         
            -
                   
     | 
| 
      
 61 
     | 
    
         
            +
                context 'when the html has a non punctuation character after a closing tag' do
         
     | 
| 
      
 62 
     | 
    
         
            +
                  before(:each) do
         
     | 
| 
      
 63 
     | 
    
         
            +
                    @html = '<p>Look at <a href="awesomeful.net">this</a> link for randomness</p>'
         
     | 
| 
      
 64 
     | 
    
         
            +
                  end
         
     | 
| 
      
 65 
     | 
    
         
            +
                  it 'leaves a whitespace between the closing tag and the following word character' do
         
     | 
| 
      
 66 
     | 
    
         
            +
                    truncate(@html, :length => 21).should == '<p>Look at <a href="awesomeful.net">this</a> link...</p>'
         
     | 
| 
      
 67 
     | 
    
         
            +
                  end
         
     | 
| 
       64 
68 
     | 
    
         
             
                end
         
     | 
| 
       65 
     | 
    
         
            -
              end
         
     | 
| 
       66 
69 
     | 
    
         | 
| 
       67 
     | 
    
         
            -
             
     | 
| 
      
 70 
     | 
    
         
            +
                #unusual, but just covering my ass
         
     | 
| 
      
 71 
     | 
    
         
            +
                context 'when the HTML tags are multiline' do 
         
     | 
| 
      
 72 
     | 
    
         
            +
                  before(:each) do
         
     | 
| 
      
 73 
     | 
    
         
            +
                    @html = <<-END_HTML
         
     | 
| 
      
 74 
     | 
    
         
            +
                      <div id="foo"
         
     | 
| 
      
 75 
     | 
    
         
            +
                            class="bar">
         
     | 
| 
      
 76 
     | 
    
         
            +
                      This is ugly html.
         
     | 
| 
      
 77 
     | 
    
         
            +
                      </div>
         
     | 
| 
      
 78 
     | 
    
         
            +
                    END_HTML
         
     | 
| 
      
 79 
     | 
    
         
            +
                  end
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                  it 'recognizes the multiline html properly' do
         
     | 
| 
      
 82 
     | 
    
         
            +
                    truncate(@html, :length => 12).should == ' <div id="foo" class="bar"> This is...</div>'
         
     | 
| 
      
 83 
     | 
    
         
            +
                  end
         
     | 
| 
      
 84 
     | 
    
         
            +
                end
         
     | 
| 
       68 
85 
     | 
    
         | 
| 
       69 
     | 
    
         
            -
                 
     | 
| 
       70 
     | 
    
         
            -
                   
     | 
| 
       71 
     | 
    
         
            -
             
     | 
| 
      
 86 
     | 
    
         
            +
                %w(br hr img).each do |unpaired_tag|
         
     | 
| 
      
 87 
     | 
    
         
            +
                  context "when the html contains a #{unpaired_tag} tag" do
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
                    context "and the #{unpaired_tag} does not have the closing slash" do
         
     | 
| 
      
 90 
     | 
    
         
            +
                      before(:each) do
         
     | 
| 
      
 91 
     | 
    
         
            +
                        @html = "<div>Some before. <#{unpaired_tag}>and some after</div>"
         
     | 
| 
      
 92 
     | 
    
         
            +
                        @html_caps = "<div>Some before. <#{unpaired_tag.capitalize}>and some after</div>"
         
     | 
| 
      
 93 
     | 
    
         
            +
                      end
         
     | 
| 
      
 94 
     | 
    
         
            +
                      it "does not close the #{unpaired_tag} tag" do
         
     | 
| 
      
 95 
     | 
    
         
            +
                        truncate(@html, :length => 19).should == "<div>Some before. <#{unpaired_tag}>and...</div>"
         
     | 
| 
      
 96 
     | 
    
         
            +
                        truncate(@html_caps, :length => 19).should == "<div>Some before. <#{unpaired_tag.capitalize}>and...</div>"
         
     | 
| 
      
 97 
     | 
    
         
            +
                      end
         
     | 
| 
      
 98 
     | 
    
         
            +
                    end
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
                    context "and the #{unpaired_tag} does have the closing slash" do
         
     | 
| 
      
 101 
     | 
    
         
            +
                      before(:each) do
         
     | 
| 
      
 102 
     | 
    
         
            +
                        @html = "<div>Some before. <#{unpaired_tag} />and some after</div>"
         
     | 
| 
      
 103 
     | 
    
         
            +
                        @html_caps = "<div>Some before. <#{unpaired_tag.capitalize} />and some after</div>"
         
     | 
| 
      
 104 
     | 
    
         
            +
                      end
         
     | 
| 
      
 105 
     | 
    
         
            +
                      it "does not close the #{unpaired_tag} tag" do
         
     | 
| 
      
 106 
     | 
    
         
            +
                        truncate(@html, :length => 19).should == "<div>Some before. <#{unpaired_tag} />and...</div>"
         
     | 
| 
      
 107 
     | 
    
         
            +
                        truncate(@html_caps, :length => 19).should == "<div>Some before. <#{unpaired_tag.capitalize} />and...</div>"
         
     | 
| 
      
 108 
     | 
    
         
            +
                      end
         
     | 
| 
      
 109 
     | 
    
         
            +
                    end
         
     | 
| 
      
 110 
     | 
    
         
            +
             
     | 
| 
      
 111 
     | 
    
         
            +
                  end
         
     | 
| 
       72 
112 
     | 
    
         
             
                end
         
     | 
| 
       73 
113 
     | 
    
         
             
              end
         
     | 
| 
       74 
114 
     | 
    
         | 
    
        data/truncate_html.gemspec
    CHANGED
    
    | 
         @@ -1,15 +1,15 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # Generated by jeweler
         
     | 
| 
       2 
     | 
    
         
            -
            # DO NOT EDIT THIS FILE
         
     | 
| 
       3 
     | 
    
         
            -
            # Instead, edit Jeweler::Tasks in Rakefile, and run  
     | 
| 
      
 2 
     | 
    
         
            +
            # DO NOT EDIT THIS FILE DIRECTLY
         
     | 
| 
      
 3 
     | 
    
         
            +
            # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
         
     | 
| 
       4 
4 
     | 
    
         
             
            # -*- encoding: utf-8 -*-
         
     | 
| 
       5 
5 
     | 
    
         | 
| 
       6 
6 
     | 
    
         
             
            Gem::Specification.new do |s|
         
     | 
| 
       7 
7 
     | 
    
         
             
              s.name = %q{truncate_html}
         
     | 
| 
       8 
     | 
    
         
            -
              s.version = "0. 
     | 
| 
      
 8 
     | 
    
         
            +
              s.version = "0.3.0"
         
     | 
| 
       9 
9 
     | 
    
         | 
| 
       10 
10 
     | 
    
         
             
              s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
         
     | 
| 
       11 
11 
     | 
    
         
             
              s.authors = ["hgimenez"]
         
     | 
| 
       12 
     | 
    
         
            -
              s.date = %q{ 
     | 
| 
      
 12 
     | 
    
         
            +
              s.date = %q{2010-02-02}
         
     | 
| 
       13 
13 
     | 
    
         
             
              s.description = %q{Truncates html so you don't have to}
         
     | 
| 
       14 
14 
     | 
    
         
             
              s.email = %q{harold.gimenez@gmail.com}
         
     | 
| 
       15 
15 
     | 
    
         
             
              s.extra_rdoc_files = [
         
     | 
| 
         @@ -25,9 +25,13 @@ Gem::Specification.new do |s| 
     | 
|
| 
       25 
25 
     | 
    
         
             
                 "install.rb",
         
     | 
| 
       26 
26 
     | 
    
         
             
                 "lib/app/helpers/truncate_html_helper.rb",
         
     | 
| 
       27 
27 
     | 
    
         
             
                 "lib/truncate_html.rb",
         
     | 
| 
      
 28 
     | 
    
         
            +
                 "lib/truncate_html/configuration.rb",
         
     | 
| 
      
 29 
     | 
    
         
            +
                 "lib/truncate_html/html_string.rb",
         
     | 
| 
       28 
30 
     | 
    
         
             
                 "lib/truncate_html/html_truncator.rb",
         
     | 
| 
       29 
31 
     | 
    
         
             
                 "spec/helpers/truncate_html_helper_spec.rb",
         
     | 
| 
       30 
32 
     | 
    
         
             
                 "spec/spec_helper.rb",
         
     | 
| 
      
 33 
     | 
    
         
            +
                 "spec/truncate_html/configuration_spec.rb",
         
     | 
| 
      
 34 
     | 
    
         
            +
                 "spec/truncate_html/html_string_spec.rb",
         
     | 
| 
       31 
35 
     | 
    
         
             
                 "spec/truncate_html/html_truncator_spec.rb",
         
     | 
| 
       32 
36 
     | 
    
         
             
                 "tasks/truncate_html_tasks.rake",
         
     | 
| 
       33 
37 
     | 
    
         
             
                 "truncate_html.gemspec",
         
     | 
| 
         @@ -41,6 +45,8 @@ Gem::Specification.new do |s| 
     | 
|
| 
       41 
45 
     | 
    
         
             
              s.test_files = [
         
     | 
| 
       42 
46 
     | 
    
         
             
                "spec/helpers/truncate_html_helper_spec.rb",
         
     | 
| 
       43 
47 
     | 
    
         
             
                 "spec/spec_helper.rb",
         
     | 
| 
      
 48 
     | 
    
         
            +
                 "spec/truncate_html/configuration_spec.rb",
         
     | 
| 
      
 49 
     | 
    
         
            +
                 "spec/truncate_html/html_string_spec.rb",
         
     | 
| 
       44 
50 
     | 
    
         
             
                 "spec/truncate_html/html_truncator_spec.rb"
         
     | 
| 
       45 
51 
     | 
    
         
             
              ]
         
     | 
| 
       46 
52 
     | 
    
         | 
| 
         @@ -54,3 +60,4 @@ Gem::Specification.new do |s| 
     | 
|
| 
       54 
60 
     | 
    
         
             
              else
         
     | 
| 
       55 
61 
     | 
    
         
             
              end
         
     | 
| 
       56 
62 
     | 
    
         
             
            end
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification 
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: truncate_html
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version 
         
     | 
| 
       4 
     | 
    
         
            -
              version: 0. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.3.0
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors: 
         
     | 
| 
       7 
7 
     | 
    
         
             
            - hgimenez
         
     | 
| 
         @@ -9,7 +9,7 @@ autorequire: 
     | 
|
| 
       9 
9 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       10 
10 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       11 
11 
     | 
    
         | 
| 
       12 
     | 
    
         
            -
            date:  
     | 
| 
      
 12 
     | 
    
         
            +
            date: 2010-02-02 00:00:00 -05:00
         
     | 
| 
       13 
13 
     | 
    
         
             
            default_executable: 
         
     | 
| 
       14 
14 
     | 
    
         
             
            dependencies: []
         
     | 
| 
       15 
15 
     | 
    
         | 
| 
         @@ -31,9 +31,13 @@ files: 
     | 
|
| 
       31 
31 
     | 
    
         
             
            - install.rb
         
     | 
| 
       32 
32 
     | 
    
         
             
            - lib/app/helpers/truncate_html_helper.rb
         
     | 
| 
       33 
33 
     | 
    
         
             
            - lib/truncate_html.rb
         
     | 
| 
      
 34 
     | 
    
         
            +
            - lib/truncate_html/configuration.rb
         
     | 
| 
      
 35 
     | 
    
         
            +
            - lib/truncate_html/html_string.rb
         
     | 
| 
       34 
36 
     | 
    
         
             
            - lib/truncate_html/html_truncator.rb
         
     | 
| 
       35 
37 
     | 
    
         
             
            - spec/helpers/truncate_html_helper_spec.rb
         
     | 
| 
       36 
38 
     | 
    
         
             
            - spec/spec_helper.rb
         
     | 
| 
      
 39 
     | 
    
         
            +
            - spec/truncate_html/configuration_spec.rb
         
     | 
| 
      
 40 
     | 
    
         
            +
            - spec/truncate_html/html_string_spec.rb
         
     | 
| 
       37 
41 
     | 
    
         
             
            - spec/truncate_html/html_truncator_spec.rb
         
     | 
| 
       38 
42 
     | 
    
         
             
            - tasks/truncate_html_tasks.rake
         
     | 
| 
       39 
43 
     | 
    
         
             
            - truncate_html.gemspec
         
     | 
| 
         @@ -69,4 +73,6 @@ summary: Uses an API similar to Rails' truncate helper to truncate HTML and clos 
     | 
|
| 
       69 
73 
     | 
    
         
             
            test_files: 
         
     | 
| 
       70 
74 
     | 
    
         
             
            - spec/helpers/truncate_html_helper_spec.rb
         
     | 
| 
       71 
75 
     | 
    
         
             
            - spec/spec_helper.rb
         
     | 
| 
      
 76 
     | 
    
         
            +
            - spec/truncate_html/configuration_spec.rb
         
     | 
| 
      
 77 
     | 
    
         
            +
            - spec/truncate_html/html_string_spec.rb
         
     | 
| 
       72 
78 
     | 
    
         
             
            - spec/truncate_html/html_truncator_spec.rb
         
     |