html_truncator 0.1.2 → 0.2.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/README.md +19 -8
- data/lib/html_truncator.rb +32 -17
- metadata +3 -3
data/README.md
CHANGED
@@ -14,19 +14,19 @@ It's very simple. Install it with rubygems:
|
|
14
14
|
|
15
15
|
Or, if you use bundler, add it to your `Gemfile`:
|
16
16
|
|
17
|
-
gem "html_truncator", :version => "~>0.
|
17
|
+
gem "html_truncator", :version => "~>0.2"
|
18
18
|
|
19
19
|
Then you can use it in your code:
|
20
20
|
|
21
21
|
require "html_truncator"
|
22
22
|
HTML_Truncator.truncate("<p>Lorem ipsum dolor sit amet.</p>", 3)
|
23
|
-
# => "<p>Lorem ipsum dolor
|
23
|
+
# => "<p>Lorem ipsum dolor…</p>"
|
24
24
|
|
25
25
|
The HTML_Truncator class has only one method, `truncate`, with 3 arguments:
|
26
26
|
|
27
27
|
* the HTML-formatted string to truncate
|
28
28
|
* the number of words to keep (real words, tags and attributes aren't count)
|
29
|
-
* the ellipsis (optional, '
|
29
|
+
* some options like the ellipsis (optional, '…' by default).
|
30
30
|
|
31
31
|
And an attribute, `ellipsable_tags`, which lists the tags that can contain the ellipsis
|
32
32
|
(by default: p ol ul li div header article nav section footer aside dd dt dl).
|
@@ -38,33 +38,43 @@ Examples
|
|
38
38
|
A simple example:
|
39
39
|
|
40
40
|
HTML_Truncator.truncate("<p>Lorem ipsum dolor sit amet.</p>", 3)
|
41
|
-
# => "<p>Lorem ipsum dolor
|
41
|
+
# => "<p>Lorem ipsum dolor…</p>"
|
42
42
|
|
43
43
|
If the text is too short to be truncated, it won't be modified:
|
44
44
|
|
45
45
|
HTML_Truncator.truncate("<p>Lorem ipsum dolor sit amet.</p>", 5)
|
46
46
|
# => "<p>Lorem ipsum dolor sit amet.</p>"
|
47
47
|
|
48
|
+
If you prefer, you can have the length in characters instead of words:
|
49
|
+
|
50
|
+
HTML_Truncator.truncate("<p>Lorem ipsum dolor sit amet.</p>", 12, :length_in_chars => true)
|
51
|
+
# => "<p>Lorem ipsum …</p>"
|
52
|
+
|
48
53
|
You can customize the ellipsis:
|
49
54
|
|
50
|
-
HTML_Truncator.truncate("<p>Lorem ipsum dolor sit amet.</p>", 3, " (truncated)")
|
55
|
+
HTML_Truncator.truncate("<p>Lorem ipsum dolor sit amet.</p>", 3, :ellipsis => " (truncated)")
|
51
56
|
# => "<p>Lorem ipsum dolor (truncated)</p>"
|
52
57
|
|
53
58
|
And even have HTML in the ellipsis:
|
54
59
|
|
55
|
-
HTML_Truncator.truncate("<p>Lorem ipsum dolor sit amet.</p>", 3, '<a href="/more-to-read">...</a>')
|
60
|
+
HTML_Truncator.truncate("<p>Lorem ipsum dolor sit amet.</p>", 3, :ellipsis => '<a href="/more-to-read">...</a>')
|
56
61
|
# => "<p>Lorem ipsum dolor<a href="/more-to-read">...</a></p>"
|
57
62
|
|
58
63
|
The ellipsis is put at the right place, inside `<p>`, but not `<i>`:
|
59
64
|
|
60
65
|
HTML_Truncator.truncate("<p><i>Lorem ipsum dolor sit amet.</i></p>", 3)
|
61
|
-
# => "<p><i>Lorem ipsum dolor</i
|
66
|
+
# => "<p><i>Lorem ipsum dolor</i>…</p>"
|
62
67
|
|
63
68
|
You can indicate that a tag can contain the ellipsis but adding it to the ellipsable_tags:
|
64
69
|
|
65
70
|
HTML_Truncator.ellipsable_tags << "blockquote"
|
66
71
|
HTML_Truncator.truncate("<blockquote>Lorem ipsum dolor sit amet.</blockquote>", 3)
|
67
|
-
# => "<blockquote>Lorem ipsum dolor
|
72
|
+
# => "<blockquote>Lorem ipsum dolor…</blockquote>"
|
73
|
+
|
74
|
+
You can know if a string was truncated with the `html_truncated?` method:
|
75
|
+
|
76
|
+
HTML_Truncator.truncate("<p>Lorem ipsum dolor sit amet.</p>", 3).html_truncated?
|
77
|
+
# => true
|
68
78
|
|
69
79
|
|
70
80
|
Alternatives
|
@@ -102,5 +112,6 @@ Credits
|
|
102
112
|
-------
|
103
113
|
|
104
114
|
Thanks to François de Metz for his awesome help!
|
115
|
+
Thanks to [kuroir](https://github.com/kuroir) and [benhutton](https://github.com/benhutton) for their suggestions.
|
105
116
|
|
106
117
|
Copyright (c) 2011 Bruno Michel <bmichel@menfin.info>, released under the MIT license
|
data/lib/html_truncator.rb
CHANGED
@@ -1,11 +1,19 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
require "nokogiri"
|
2
4
|
require "set"
|
3
5
|
|
4
6
|
|
5
7
|
class HTML_Truncator
|
6
|
-
|
8
|
+
DEFAULT_OPTIONS = { :ellipsis => "…", :length_in_chars => false }
|
9
|
+
|
10
|
+
def self.truncate(text, max, opts={})
|
11
|
+
return truncate(text, max, :ellipsis => opts) if String === opts
|
12
|
+
opts = DEFAULT_OPTIONS.merge(opts)
|
7
13
|
doc = Nokogiri::HTML::DocumentFragment.parse(text)
|
8
|
-
doc.truncate(
|
14
|
+
str, _, opts = doc.truncate(max, opts)
|
15
|
+
eval "class <<str; def html_truncated?; #{opts[:was_truncated]} end end"
|
16
|
+
str
|
9
17
|
end
|
10
18
|
|
11
19
|
class <<self
|
@@ -22,28 +30,29 @@ class Nokogiri::HTML::DocumentFragment
|
|
22
30
|
end
|
23
31
|
|
24
32
|
class Nokogiri::XML::Node
|
25
|
-
def truncate(
|
26
|
-
return ["", 1,
|
27
|
-
inner, remaining,
|
33
|
+
def truncate(max, opts)
|
34
|
+
return ["", 1, opts] if max == 0 && !ellipsable?
|
35
|
+
inner, remaining, opts = inner_truncate(max, opts)
|
28
36
|
children.remove
|
29
37
|
add_child Nokogiri::HTML::DocumentFragment.parse(inner)
|
30
|
-
[
|
38
|
+
[to_html(:indent => 0), max - remaining, opts]
|
31
39
|
end
|
32
40
|
|
33
|
-
def inner_truncate(
|
34
|
-
inner, remaining = "",
|
41
|
+
def inner_truncate(max, opts)
|
42
|
+
inner, remaining = "", max
|
35
43
|
self.children.each do |node|
|
36
|
-
txt, nb,
|
44
|
+
txt, nb, opts = node.truncate(remaining, opts)
|
37
45
|
remaining -= nb
|
38
46
|
inner += txt
|
39
47
|
next if remaining >= 0
|
40
48
|
if ellipsable?
|
41
|
-
inner += ellipsis
|
42
|
-
ellipsis = ""
|
49
|
+
inner += opts[:ellipsis]
|
50
|
+
opts[:ellipsis] = ""
|
51
|
+
opts[:was_truncated] = true
|
43
52
|
end
|
44
53
|
break
|
45
54
|
end
|
46
|
-
[inner, remaining,
|
55
|
+
[inner, remaining, opts]
|
47
56
|
end
|
48
57
|
|
49
58
|
def ellipsable?
|
@@ -52,10 +61,16 @@ class Nokogiri::XML::Node
|
|
52
61
|
end
|
53
62
|
|
54
63
|
class Nokogiri::XML::Text
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
64
|
+
def truncate(max, opts)
|
65
|
+
if opts[:length_in_chars]
|
66
|
+
count = content.length
|
67
|
+
return [to_xhtml, count, opts] if count <= max && max > 0
|
68
|
+
[content.slice(0, max), count, opts]
|
69
|
+
else
|
70
|
+
words = content.split
|
71
|
+
count = words.length
|
72
|
+
return [to_xhtml, count, opts] if count <= max && max > 0
|
73
|
+
[words.slice(0, max).join(' '), count, opts]
|
74
|
+
end
|
60
75
|
end
|
61
76
|
end
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
- 1
|
8
7
|
- 2
|
9
|
-
|
8
|
+
- 0
|
9
|
+
version: 0.2.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Bruno Michel
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2011-01-
|
17
|
+
date: 2011-01-28 00:00:00 +01:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|