butter 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source :gemcutter
2
+
3
+ # Specify your gem's dependencies in butter.gemspec
4
+ gemspec
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path("../lib/butter/version", __FILE__)
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "butter"
6
+ s.version = Butter::VERSION
7
+ s.platform = Gem::Platform::RUBY
8
+ s.authors = "Jonathan Martin"
9
+ s.email = "me@nybblr.com"
10
+ s.homepage = "http://rubygems.org/gems/butter"
11
+ s.summary = "Ever need to shorten some HTML formatted content? Maybe you're trying to show snippets from last week's blog post, or get tired of really long comments on your blog. This gem gives you access to a simple truncation method that uses Nokogiri to truncate in an HTML friendly manner."
12
+ s.description = "Easy HTML string truncation, done with proper markup in mind."
13
+
14
+ s.required_rubygems_version = ">= 1.3.6"
15
+ s.rubyforge_project = "butter"
16
+
17
+ s.add_development_dependency "bundler", ">= 1.0.0"
18
+ s.add_dependency "htmlentities"
19
+ s.add_dependency "nokogiri"
20
+
21
+ s.files = `git ls-files`.split("\n")
22
+ s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
23
+ s.require_path = 'lib'
24
+ end
@@ -0,0 +1,132 @@
1
+ require 'htmlentities'
2
+ require 'nokogiri'
3
+
4
+ module Butter
5
+ # == Info ===========================================================
6
+ # This gem was developed by Jonathan Martin for use on his personal blog, nybblr.com; the original source was coded by Eleo from https://gist.github.com/101410. My intent was to take his excellent implementation and clean it up a bit for Rails usage with more options and extension as a string method. Thanks Eleo!
7
+
8
+ # == Usage ==========================================================
9
+ # "<p>An HTML <i>string</i></p>".truncate_html 2, :tail => "..."
10
+ # => "<p>An HTML...</p>"
11
+ #
12
+ # "<p>An HTML <i>string</i></p>".truncate_html 2, :tail => " &rarr;"
13
+ # => "<p>An HTML &rarr;</p>"
14
+ #
15
+ # "<p>An HTML <i>string</i></p>".truncate_html 2, :strip_html => true
16
+ # => "An HTML..."
17
+
18
+ def truncate_html(num_words = 30, opts = {})
19
+ opts = { :word_cut => true, :tail => "&hellip;", :strip_html => false }.merge(opts)
20
+ tail = HTMLEntities.new.decode opts[:tail]
21
+
22
+ doc = Nokogiri::HTML(self)
23
+
24
+ current = doc.children.first
25
+ count = 0
26
+
27
+ while true
28
+ # we found a text node
29
+ if current.is_a?(Nokogiri::XML::Text)
30
+ count += current.text.split.length
31
+ # we reached our limit, let's get outta here!
32
+ break if count > num_words
33
+ previous = current
34
+ end
35
+
36
+ if current.children.length > 0
37
+ # this node has children, can't be a text node,
38
+ # lets descend and look for text nodes
39
+ current = current.children.first
40
+ elsif !current.next.nil?
41
+ #this has no children, but has a sibling, let's check it out
42
+ current = current.next
43
+ else
44
+ # we are the last child, we need to ascend until we are
45
+ # either done or find a sibling to continue on to
46
+ n = current
47
+ while !n.is_a?(Nokogiri::HTML::Document) and n.parent.next.nil?
48
+ n = n.parent
49
+ end
50
+
51
+ # we've reached the top and found no more text nodes, break
52
+ if n.is_a?(Nokogiri::HTML::Document)
53
+ break;
54
+ else
55
+ current = n.parent.next
56
+ end
57
+ end
58
+ end
59
+
60
+ if count >= num_words
61
+ unless count == num_words
62
+ new_content = current.text.split
63
+
64
+ # If we're here, the last text node we counted eclipsed the number of words
65
+ # that we want, so we need to cut down on words. The easiest way to think about
66
+ # this is that without this node we'd have fewer words than the limit, so all
67
+ # the previous words plus a limited number of words from this node are needed.
68
+ # We simply need to figure out how many words are needed and grab that many.
69
+ # Then we need to -subtract- an index, because the first word would be index zero.
70
+
71
+ # For example, given:
72
+ # <p>Testing this HTML truncater.</p><p>To see if its working.</p>
73
+ # Let's say I want 6 words. The correct returned string would be:
74
+ # <p>Testing this HTML truncater.</p><p>To see...</p>
75
+ # All the words in both paragraphs = 9
76
+ # The last paragraph is the one that breaks the limit. How many words would we
77
+ # have without it? 4. But we want up to 6, so we might as well get that many.
78
+ # 6 - 4 = 2, so we get 2 words from this node, but words #1-2 are indices #0-1, so
79
+ # we subtract 1. If this gives us -1, we want nothing from this node. So go back to
80
+ # the previous node instead.
81
+ index = num_words-(count-new_content.length)-1
82
+ if index >= 0
83
+ new_content = new_content[0..index]
84
+ current.content = new_content.join(' ') + tail
85
+ else
86
+ current = previous
87
+ current.content = current.content + tail
88
+ end
89
+ end
90
+
91
+ # remove everything else
92
+ while !current.is_a?(Nokogiri::HTML::Document)
93
+ while !current.next.nil?
94
+ current.next.remove
95
+ end
96
+ current = current.parent
97
+ end
98
+ end
99
+
100
+ # now we grab the html and not the text.
101
+ # we do first because nokogiri adds html and body tags
102
+ # which we don't want
103
+
104
+ # Strip out the unwanted <p> tag that gets added, if it is present. This is mostly for the sake of markup, since extra <p> tags can throw off styling. In the future, this will need to see if the original code was already wrapped in a plain <p> tag.
105
+
106
+ root = doc.root.children.first
107
+ only_child = root.children.first
108
+
109
+ if root.children.size == 1 and only_child.name == "p" and only_child.attributes.empty?
110
+ truncated = only_child
111
+ else
112
+ truncated = root
113
+ end
114
+
115
+ if opts[:strip_html] == true
116
+ truncated = truncated.inner_text
117
+ else
118
+ truncated = truncated.inner_html
119
+ end
120
+
121
+ if html_safe?
122
+ truncated.html_safe
123
+ else
124
+ truncated
125
+ end
126
+ end
127
+ end
128
+
129
+ # Add method to String class
130
+ class String
131
+ include Butter
132
+ end
@@ -0,0 +1,3 @@
1
+ module Butter
2
+ VERSION = "1.0.0"
3
+ end
metadata ADDED
@@ -0,0 +1,117 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: butter
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease: false
6
+ segments:
7
+ - 1
8
+ - 0
9
+ - 0
10
+ version: 1.0.0
11
+ platform: ruby
12
+ authors:
13
+ - Jonathan Martin
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-06-26 00:00:00 -04:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: bundler
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 23
30
+ segments:
31
+ - 1
32
+ - 0
33
+ - 0
34
+ version: 1.0.0
35
+ type: :development
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: htmlentities
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ hash: 3
46
+ segments:
47
+ - 0
48
+ version: "0"
49
+ type: :runtime
50
+ version_requirements: *id002
51
+ - !ruby/object:Gem::Dependency
52
+ name: nokogiri
53
+ prerelease: false
54
+ requirement: &id003 !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ hash: 3
60
+ segments:
61
+ - 0
62
+ version: "0"
63
+ type: :runtime
64
+ version_requirements: *id003
65
+ description: Easy HTML string truncation, done with proper markup in mind.
66
+ email: me@nybblr.com
67
+ executables: []
68
+
69
+ extensions: []
70
+
71
+ extra_rdoc_files: []
72
+
73
+ files:
74
+ - .gitignore
75
+ - Gemfile
76
+ - Rakefile
77
+ - butter.gemspec
78
+ - lib/butter.rb
79
+ - lib/butter/version.rb
80
+ has_rdoc: true
81
+ homepage: http://rubygems.org/gems/butter
82
+ licenses: []
83
+
84
+ post_install_message:
85
+ rdoc_options: []
86
+
87
+ require_paths:
88
+ - lib
89
+ required_ruby_version: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ hash: 3
95
+ segments:
96
+ - 0
97
+ version: "0"
98
+ required_rubygems_version: !ruby/object:Gem::Requirement
99
+ none: false
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ hash: 23
104
+ segments:
105
+ - 1
106
+ - 3
107
+ - 6
108
+ version: 1.3.6
109
+ requirements: []
110
+
111
+ rubyforge_project: butter
112
+ rubygems_version: 1.3.7
113
+ signing_key:
114
+ specification_version: 3
115
+ summary: Ever need to shorten some HTML formatted content? Maybe you're trying to show snippets from last week's blog post, or get tired of really long comments on your blog. This gem gives you access to a simple truncation method that uses Nokogiri to truncate in an HTML friendly manner.
116
+ test_files: []
117
+