Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,16 @@ TruncateHtml.configure do |config|
config.break_token = '<!-- truncate -->'
end
```

You can specify at which `:break_token` occurance to truncate the HTML. By default it is
the very first occurance of `:break_token`. When there is no `:break_token` then
`:break_token_at_count` has no effect.

```ruby
TruncateHtml.configure do |config|
config.break_token = '</p>'
config.break_token_at_count = 3
```
Installation
------------

Expand Down
2 changes: 1 addition & 1 deletion lib/truncate_html/configuration.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module TruncateHtml
class Configuration
attr_accessor :length, :omission, :word_boundary, :break_token
attr_accessor :length, :omission, :word_boundary, :break_token, :break_token_at_count
end

class << self
Expand Down
20 changes: 12 additions & 8 deletions lib/truncate_html/html_truncator.rb
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
module TruncateHtml
class HtmlTruncator

def initialize(original_html, options = {})
@original_html = original_html
length = options[:length] || TruncateHtml.configuration.length
@omission = options[:omission] || TruncateHtml.configuration.omission
@word_boundary = (options.has_key?(:word_boundary) ? options[:word_boundary] : TruncateHtml.configuration.word_boundary)
@break_token = options[:break_token] || TruncateHtml.configuration.break_token || nil
@chars_remaining = length - @omission.length
@original_html = original_html
length = options[:length] || TruncateHtml.configuration.length
@omission = options[:omission] || TruncateHtml.configuration.omission
@word_boundary = (options.has_key?(:word_boundary) ? options[:word_boundary] : TruncateHtml.configuration.word_boundary)
@break_token = options[:break_token] || TruncateHtml.configuration.break_token || nil
@break_token_at_count = options[:break_token_at_count] || TruncateHtml.configuration.break_token_at_count || 1
@chars_remaining = length - @omission.length
@open_tags, @closing_tags, @truncated_html = [], [], ['']
end

def truncate
return @omission if @chars_remaining < 0

break_token_counter = 0
@original_html.html_tokens.each do |token|
if @chars_remaining <= 0 || truncate_token?(token)
break_token_counter += 1 if truncate_token?(token)

if @chars_remaining <= 0 || @break_token_at_count == break_token_counter
close_open_tags
break
else
Expand Down
12 changes: 12 additions & 0 deletions spec/truncate_html/html_truncator_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,18 @@ def truncate(html, opts = {})
end
end

context 'when break_token_at_count not set for break_token' do
it 'truncates at first break token' do
truncate('This is line one. This is line <break /> two.', break_token: '<break />').should == 'This is line one. This is line'
end
end

context 'when break_token_at_count is set for break_token' do
it 'truncates at specified break_token occurance' do
truncate('This is line one. This is line <break /> two. This <break /> is line <break /> three.', break_token: '<break />', break_token_at_count: 3).should == 'This is line one. This is line <break /> two. This <break /> is line'
end
end

context 'a string with comments' do
it 'does not duplicate comments (issue #32)' do
truncate('<h1>hello <!-- stuff --> and <!-- la --> goodbye</h1>', length: 15).should ==
Expand Down