readability-rb 0.4.0 → 0.6.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.
- checksums.yaml +4 -4
- data/README.md +2 -0
- data/lib/readability/document.rb +1 -1
- data/lib/readability/metadata.rb +11 -9
- data/lib/readability/utils.rb +4 -4
- data/lib/readability/version.rb +1 -1
- data/lib/readability.rb +7 -4
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c451d1e4e2e12c168b323f813a36594c25177e7a8fa4c1999cd55fd652128413
|
|
4
|
+
data.tar.gz: be5c5fe5aef9cc1186c25112f6e3ca11220aec7b4cb122682092fe3db14c4008
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 210bd7531212e4c9ad91ec6da99e3bd0a74eb1dd62040b646bc7e90a07daadc13e19c9681d2bd6c7e2412c2ef3f30752671b52472f22b26fbc263eaf2f473e64
|
|
7
|
+
data.tar.gz: 692bcc0189b89d1b440d7a5bf0cf4bd53a313ef30cebab92ca93d2c6f6d88a81fb531d1cabe85c07487748467e17a1e591b6f32237b5f01ed89eb14f7f5ea329
|
data/README.md
CHANGED
|
@@ -92,6 +92,8 @@ result = Readability.parse(html, serializer: ->(el) { el.to_html })
|
|
|
92
92
|
| `allowed_video_regex` | Regex for allowed video embed URLs | built-in |
|
|
93
93
|
| `link_density_modifier` | Adjust link density calculation | `0` |
|
|
94
94
|
| `serializer` | Lambda to serialize the content element | `inner_html` |
|
|
95
|
+
| `max_attributes` | Max attributes per element at parse time | `1000` |
|
|
96
|
+
| `max_tree_depth` | Max document tree depth at parse time (`-1` to disable) | `1000` |
|
|
95
97
|
|
|
96
98
|
## Contributing
|
|
97
99
|
|
data/lib/readability/document.rb
CHANGED
data/lib/readability/metadata.rb
CHANGED
|
@@ -41,7 +41,7 @@ module Readability
|
|
|
41
41
|
|
|
42
42
|
if parsed.is_a?(Array)
|
|
43
43
|
parsed = parsed.find do |it|
|
|
44
|
-
Array(it["@type"]).any? { |t| t.match?(JSON_LD_ARTICLE_TYPES) }
|
|
44
|
+
Array(it["@type"]).any? { |t| t.is_a?(String) && t.match?(JSON_LD_ARTICLE_TYPES) }
|
|
45
45
|
end
|
|
46
46
|
next unless parsed
|
|
47
47
|
end
|
|
@@ -64,6 +64,8 @@ module Readability
|
|
|
64
64
|
end
|
|
65
65
|
end
|
|
66
66
|
|
|
67
|
+
# Unlike JS, accept an array @type, which schema.org allows. JS calls
|
|
68
|
+
# @type.match, which throws for an array, so it skips the script.
|
|
67
69
|
next if !parsed || !parsed["@type"] || !Array(parsed["@type"]).any? { |t| t.is_a?(String) && t.match?(JSON_LD_ARTICLE_TYPES) }
|
|
68
70
|
|
|
69
71
|
metadata = {}
|
|
@@ -88,13 +90,13 @@ module Readability
|
|
|
88
90
|
|
|
89
91
|
if parsed["author"]
|
|
90
92
|
if parsed["author"].is_a?(Hash) && parsed["author"]["name"].is_a?(String)
|
|
91
|
-
metadata["byline"] = parsed["author"]["name"]
|
|
93
|
+
metadata["byline"] = js_trim(parsed["author"]["name"])
|
|
92
94
|
elsif parsed["author"].is_a?(Array) &&
|
|
93
|
-
parsed["author"][0] &&
|
|
95
|
+
parsed["author"][0].is_a?(Hash) &&
|
|
94
96
|
parsed["author"][0]["name"].is_a?(String)
|
|
95
97
|
metadata["byline"] = parsed["author"]
|
|
96
|
-
.select { |author| author && author["name"].is_a?(String) }
|
|
97
|
-
.map { |author| author["name"]
|
|
98
|
+
.select { |author| author.is_a?(Hash) && author["name"].is_a?(String) }
|
|
99
|
+
.map { |author| js_trim(author["name"]) }
|
|
98
100
|
.join(", ")
|
|
99
101
|
end
|
|
100
102
|
end
|
|
@@ -110,8 +112,8 @@ module Readability
|
|
|
110
112
|
if parsed["datePublished"].is_a?(String)
|
|
111
113
|
metadata["date_published"] = parsed["datePublished"].strip
|
|
112
114
|
end
|
|
113
|
-
rescue
|
|
114
|
-
#
|
|
115
|
+
rescue => e
|
|
116
|
+
# Skip malformed JSON or JSON with an unexpected shape, as JS does
|
|
115
117
|
log(e.message) if respond_to?(:log, true)
|
|
116
118
|
end
|
|
117
119
|
end
|
|
@@ -225,7 +227,7 @@ module Readability
|
|
|
225
227
|
if matches
|
|
226
228
|
# Convert to lowercase, and remove any whitespace
|
|
227
229
|
name = matches[0].downcase.gsub(/\s/, "")
|
|
228
|
-
values[name] = content
|
|
230
|
+
values[name] = js_trim(content)
|
|
229
231
|
end
|
|
230
232
|
end
|
|
231
233
|
|
|
@@ -234,7 +236,7 @@ module Readability
|
|
|
234
236
|
if content
|
|
235
237
|
# Convert to lowercase, remove whitespace, convert dots to colons
|
|
236
238
|
name = name.downcase.gsub(/\s/, "").gsub(".", ":")
|
|
237
|
-
values[name] = content
|
|
239
|
+
values[name] = js_trim(content)
|
|
238
240
|
end
|
|
239
241
|
end
|
|
240
242
|
end
|
data/lib/readability/utils.rb
CHANGED
|
@@ -33,10 +33,10 @@ module Readability
|
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
# JS-compatible trim that also strips Unicode whitespace like \u00A0 (NBSP)
|
|
36
|
-
# JS's String.prototype.trim() strips all Unicode whitespace
|
|
36
|
+
# JS's String.prototype.trim() strips all Unicode whitespace and \uFEFF (BOM).
|
|
37
37
|
# Ruby's String#strip only removes ASCII whitespace.
|
|
38
38
|
def js_trim(str)
|
|
39
|
-
str.gsub(/\A[\
|
|
39
|
+
str.gsub(/\A[[:space:]\uFEFF]+|[[:space:]\uFEFF]+\z/, "")
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
# Port of _getInnerText (JS line 2084)
|
|
@@ -211,9 +211,9 @@ module Readability
|
|
|
211
211
|
end
|
|
212
212
|
|
|
213
213
|
# Port of _isUrl (JS line 442)
|
|
214
|
+
# JS's URL constructor accepts any absolute URL, so any scheme counts.
|
|
214
215
|
def is_url?(str)
|
|
215
|
-
|
|
216
|
-
uri.is_a?(URI::HTTP) || uri.is_a?(URI::HTTPS)
|
|
216
|
+
!URI.parse(str).scheme.nil?
|
|
217
217
|
rescue URI::InvalidURIError, URI::InvalidComponentError
|
|
218
218
|
false
|
|
219
219
|
end
|
data/lib/readability/version.rb
CHANGED
data/lib/readability.rb
CHANGED
|
@@ -15,13 +15,16 @@ require_relative "readability/document"
|
|
|
15
15
|
require_relative "readability/readerable"
|
|
16
16
|
|
|
17
17
|
module Readability
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
DEFAULT_MAX_ATTRIBUTES = 1000
|
|
19
|
+
DEFAULT_MAX_TREE_DEPTH = 1000
|
|
20
|
+
|
|
21
|
+
def self.parse(html, url: nil, max_attributes: DEFAULT_MAX_ATTRIBUTES, max_tree_depth: DEFAULT_MAX_TREE_DEPTH, **options)
|
|
22
|
+
doc = Nokogiri::HTML5(html, max_attributes: max_attributes, max_tree_depth: max_tree_depth)
|
|
20
23
|
Document.new(doc, url: url, **options).parse
|
|
21
24
|
end
|
|
22
25
|
|
|
23
|
-
def self.readerable?(html, **options)
|
|
24
|
-
doc = Nokogiri::HTML5(html)
|
|
26
|
+
def self.readerable?(html, max_attributes: DEFAULT_MAX_ATTRIBUTES, max_tree_depth: DEFAULT_MAX_TREE_DEPTH, **options)
|
|
27
|
+
doc = Nokogiri::HTML5(html, max_attributes: max_attributes, max_tree_depth: max_tree_depth)
|
|
25
28
|
Readerable.probably_readerable?(doc, **options)
|
|
26
29
|
end
|
|
27
30
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: readability-rb
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.6.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andy Croll
|
|
@@ -58,14 +58,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
58
58
|
requirements:
|
|
59
59
|
- - ">="
|
|
60
60
|
- !ruby/object:Gem::Version
|
|
61
|
-
version: '3.
|
|
61
|
+
version: '3.3'
|
|
62
62
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
63
63
|
requirements:
|
|
64
64
|
- - ">="
|
|
65
65
|
- !ruby/object:Gem::Version
|
|
66
66
|
version: '0'
|
|
67
67
|
requirements: []
|
|
68
|
-
rubygems_version:
|
|
68
|
+
rubygems_version: 4.0.20
|
|
69
69
|
specification_version: 4
|
|
70
70
|
summary: Extract readable article content from HTML pages
|
|
71
71
|
test_files: []
|