linkify-it-rb 1.0.0.3 → 1.1.1.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 +14 -3
- data/lib/linkify-it-rb/index.rb +53 -7
- data/lib/linkify-it-rb/re.rb +15 -3
- data/lib/linkify-it-rb/version.rb +1 -1
- data/spec/linkify-it-rb/test_spec.rb +38 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5f47c7eb9a5b7f156b03e9b1ab2ca228bbcddd02
|
4
|
+
data.tar.gz: b5a2df2ecb0fad2c059e461da03b12a97641c975
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 57d20b3c3c4aedad32e3958496bae64cd6959c2e4a2b04f90fa1dfbefb5da7ecd6099f3f5e892bbceb680eca029b418c8c02b8f68415fd2dfe8d6616c8189a08
|
7
|
+
data.tar.gz: 978dc051818bd21fc1dcc788df060fe647a7efcd5c61033c4603c36f076fd07b3596e8c984e162dbf11278066ab0430701698fbae25dc02358ce427b908409ab
|
data/README.md
CHANGED
@@ -46,10 +46,11 @@ Usage examples
|
|
46
46
|
```ruby
|
47
47
|
linkify = Linkify.new
|
48
48
|
|
49
|
-
# add unoffocial `.
|
50
|
-
linkify.tlds('.
|
49
|
+
# add unoffocial `.onion` domain.
|
50
|
+
linkify.tlds('.onion', true) # Add unofficial `.onion` domain
|
51
51
|
linkify.add('git:', 'http:') # Add `git:` ptotocol as "alias"
|
52
52
|
linkify.add('ftp:', null) # Disable `ftp:` ptotocol
|
53
|
+
linkify.set({fuzzyIP: true}) # Enable IPs in fuzzy links (without schema)
|
53
54
|
|
54
55
|
linkify.test('Site github.com!'))
|
55
56
|
=> true
|
@@ -83,7 +84,7 @@ linkify.add('@', {
|
|
83
84
|
API
|
84
85
|
---
|
85
86
|
|
86
|
-
### LinkifyIt.new(schemas)
|
87
|
+
### LinkifyIt.new(schemas, options)
|
87
88
|
|
88
89
|
Creates new linkifier instance with optional additional schemas.
|
89
90
|
|
@@ -105,6 +106,13 @@ By default understands:
|
|
105
106
|
- _normalize_ - optional block to normalize text & url of matched result
|
106
107
|
(for example, for twitter mentions).
|
107
108
|
|
109
|
+
`options`:
|
110
|
+
|
111
|
+
- __fuzzyLink__ - recognige URL-s without `http(s):` prefix. Default `true`.
|
112
|
+
- __fuzzyIP__ - allow IPs in fuzzy links above. Can conflict with some texts
|
113
|
+
like version numbers. Default `false`.
|
114
|
+
- __fuzzyEmail__ - recognize emails without `mailto:` prefix.
|
115
|
+
|
108
116
|
|
109
117
|
### .test(text)
|
110
118
|
|
@@ -157,6 +165,9 @@ If list is replaced, then exact match for 2-chars root zones will be checked.
|
|
157
165
|
Add new rule with `schema` prefix. For definition details see constructor
|
158
166
|
description. To disable existing rule use `.add(name, nil)`
|
159
167
|
|
168
|
+
### .set(options)
|
169
|
+
|
170
|
+
Override default options. Missed properties will not be changed.
|
160
171
|
|
161
172
|
## License
|
162
173
|
|
data/lib/linkify-it-rb/index.rb
CHANGED
@@ -4,9 +4,18 @@ class Linkify
|
|
4
4
|
attr_accessor :__index__, :__last_index__, :__text_cache__, :__schema__, :__compiled__
|
5
5
|
attr_accessor :re, :bypass_normalizer
|
6
6
|
|
7
|
+
# RE pattern for 2-character tlds (autogenerated by ./support/tlds_2char_gen.js)
|
8
|
+
TLDS_2CH_SRC_RE = 'a[cdefgilmnoqrstuwxz]|b[abdefghijmnorstvwyz]|c[acdfghiklmnoruvwxyz]|d[ejkmoz]|e[cegrstu]|f[ijkmor]|g[abdefghilmnpqrstuwy]|h[kmnrtu]|i[delmnoqrst]|j[emop]|k[eghimnprwyz]|l[abcikrstuvy]|m[acdeghklmnopqrstuvwxyz]|n[acefgilopruz]|om|p[aefghklmnrstwy]|qa|r[eosuw]|s[abcdeghijklmnortuvxyz]|t[cdfghjklmnortvwz]|u[agksyz]|v[aceginu]|w[fs]|y[et]|z[amw]'
|
9
|
+
|
7
10
|
# DON'T try to make PRs with changes. Extend TLDs with LinkifyIt.tlds() instead
|
8
11
|
TLDS_DEFAULT = 'biz|com|edu|gov|net|org|pro|web|xxx|aero|asia|coop|info|museum|name|shop|рф'.split('|')
|
9
12
|
|
13
|
+
DEFAULT_OPTIONS = {
|
14
|
+
fuzzyLink: true,
|
15
|
+
fuzzyEmail: true,
|
16
|
+
fuzzyIP: false
|
17
|
+
}
|
18
|
+
|
10
19
|
DEFAULT_SCHEMAS = {
|
11
20
|
'http:' => {
|
12
21
|
validate: lambda do |text, pos, obj|
|
@@ -56,6 +65,14 @@ class Linkify
|
|
56
65
|
}
|
57
66
|
}
|
58
67
|
|
68
|
+
# not needed
|
69
|
+
#------------------------------------------------------------------------------
|
70
|
+
# def isOptionsObj(obj)
|
71
|
+
# return Object.keys(obj || {}).reduce(function (acc, k) {
|
72
|
+
# return acc || defaultOptions.hasOwnProperty(k);
|
73
|
+
# }, false);
|
74
|
+
# end
|
75
|
+
|
59
76
|
#------------------------------------------------------------------------------
|
60
77
|
def escapeRE(str)
|
61
78
|
return str.gsub(/[\.\?\*\+\^\$\[\]\\\(\)\{\}\|\-]/, "\\$&")
|
@@ -91,12 +108,13 @@ class Linkify
|
|
91
108
|
|
92
109
|
# Define dynamic patterns
|
93
110
|
tlds = @__tlds__.dup
|
94
|
-
tlds.push(
|
111
|
+
tlds.push(TLDS_2CH_SRC_RE) if (!@__tlds_replaced__)
|
95
112
|
tlds.push(@re[:src_xn])
|
96
113
|
|
97
114
|
@re[:src_tlds] = tlds.join('|')
|
98
115
|
@re[:email_fuzzy] = Regexp.new(LinkifyRe::TPL_EMAIL_FUZZY.gsub('%TLDS%', @re[:src_tlds]), true)
|
99
116
|
@re[:link_fuzzy] = Regexp.new(LinkifyRe::TPL_LINK_FUZZY.gsub('%TLDS%', @re[:src_tlds]), true)
|
117
|
+
@re[:link_no_ip_fuzzy] = Regexp.new(LinkifyRe::TPL_LINK_NO_IP_FUZZY.gsub('%TLDS%', @re[:src_tlds]), true)
|
100
118
|
@re[:host_fuzzy_test] = Regexp.new(LinkifyRe::TPL_HOST_FUZZY_TEST.gsub('%TLDS%', @re[:src_tlds]), true)
|
101
119
|
|
102
120
|
#
|
@@ -237,7 +255,7 @@ class Linkify
|
|
237
255
|
|
238
256
|
|
239
257
|
|
240
|
-
# new LinkifyIt(schemas)
|
258
|
+
# new LinkifyIt(schemas, options)
|
241
259
|
# - schemas (Object): Optional. Additional schemas to validate (prefix/validator)
|
242
260
|
#
|
243
261
|
# Creates new linkifier instance with optional additional schemas.
|
@@ -260,12 +278,30 @@ class Linkify
|
|
260
278
|
# or `RegExp`.
|
261
279
|
# - _normalize_ - optional function to normalize text & url of matched result
|
262
280
|
# (for example, for @twitter mentions).
|
281
|
+
#
|
282
|
+
# `options`:
|
283
|
+
#
|
284
|
+
# - __fuzzyLink__ - recognige URL-s without `http(s):` prefix. Default `true`.
|
285
|
+
# - __fuzzyIP__ - allow IPs in fuzzy links above. Can conflict with some texts
|
286
|
+
# like version numbers. Default `false`.
|
287
|
+
# - __fuzzyEmail__ - recognize emails without `mailto:` prefix.
|
288
|
+
#
|
263
289
|
#------------------------------------------------------------------------------
|
264
|
-
def initialize(schemas = {})
|
290
|
+
def initialize(schemas = {}, options = {})
|
265
291
|
# if (!(this instanceof LinkifyIt)) {
|
266
|
-
# return new LinkifyIt(schemas);
|
292
|
+
# return new LinkifyIt(schemas, options);
|
267
293
|
# }
|
268
294
|
|
295
|
+
#--- not needed, if you want to pass options, then must also pass schemas
|
296
|
+
# if options.empty?
|
297
|
+
# if (isOptionsObj(schemas)) {
|
298
|
+
# options = schemas;
|
299
|
+
# schemas = {};
|
300
|
+
# }
|
301
|
+
# }
|
302
|
+
|
303
|
+
@__opts__ = DEFAULT_OPTIONS.merge(options)
|
304
|
+
|
269
305
|
# Cache last tested result. Used to skip repeating steps on next `match` call.
|
270
306
|
@__index__ = -1
|
271
307
|
@__last_index__ = -1 # Next scan position
|
@@ -299,6 +335,16 @@ class Linkify
|
|
299
335
|
return self
|
300
336
|
end
|
301
337
|
|
338
|
+
# chainable
|
339
|
+
# LinkifyIt#set(options)
|
340
|
+
# - options (Object): { fuzzyLink|fuzzyEmail|fuzzyIP: true|false }
|
341
|
+
#
|
342
|
+
# Set recognition options for links without schema.
|
343
|
+
#------------------------------------------------------------------------------
|
344
|
+
def set(options)
|
345
|
+
@__opts__.merge!(options)
|
346
|
+
return self
|
347
|
+
end
|
302
348
|
|
303
349
|
# LinkifyIt#test(text) -> Boolean
|
304
350
|
#
|
@@ -328,12 +374,12 @@ class Linkify
|
|
328
374
|
end
|
329
375
|
|
330
376
|
# guess schemaless links
|
331
|
-
if (@__compiled__['http:'])
|
377
|
+
if (@__opts__[:fuzzyLink] && @__compiled__['http:'])
|
332
378
|
tld_pos = text.index(@re[:host_fuzzy_test])
|
333
379
|
if !tld_pos.nil?
|
334
380
|
# if tld is located after found link - no need to check fuzzy pattern
|
335
381
|
if (@__index__ < 0 || tld_pos < @__index__)
|
336
|
-
if ((ml = text.match(@re[:link_fuzzy])) != nil)
|
382
|
+
if ((ml = text.match(@__opts__[:fuzzyIP] ? @re[:link_fuzzy] : @re[:link_no_ip_fuzzy])) != nil)
|
337
383
|
|
338
384
|
shift = ml.begin(0) + ml[1].length
|
339
385
|
|
@@ -348,7 +394,7 @@ class Linkify
|
|
348
394
|
end
|
349
395
|
|
350
396
|
# guess schemaless emails
|
351
|
-
if (@__compiled__['mailto:'])
|
397
|
+
if (@__opts__[:fuzzyEmail] && @__compiled__['mailto:'])
|
352
398
|
at_pos = text.index('@')
|
353
399
|
if !at_pos.nil?
|
354
400
|
# We can't skip this check, because this cases are possible:
|
data/lib/linkify-it-rb/re.rb
CHANGED
@@ -39,8 +39,11 @@ module LinkifyRe
|
|
39
39
|
'\\"(?:(?!' + SRC_Z_CC + '|["]).)+\\"|' +
|
40
40
|
"\\'(?:(?!" + SRC_Z_CC + "|[']).)+\\'|" +
|
41
41
|
"\\'(?=" + SRC_PSEUDO_LETTER + ').|' + # allow `I'm_king` if no pair found
|
42
|
-
'\\.{2,3}[a-zA-Z0-9
|
43
|
-
|
42
|
+
'\\.{2,3}[a-zA-Z0-9%/]|' + # github has ... in commit range links. Restrict to
|
43
|
+
# - english
|
44
|
+
# - percent-encoded
|
45
|
+
# - parts of file path
|
46
|
+
# until more examples found.
|
44
47
|
'\\.(?!' + SRC_Z_CC + '|[.]).|' +
|
45
48
|
'\\-(?!' + SRC_Z_CC + '|--(?:[^-]|$))(?:[-]+|.)|' + # `---` => long dash, terminate
|
46
49
|
'\\,(?!' + SRC_Z_CC + ').|' + # allow `,,,` in paths
|
@@ -90,11 +93,15 @@ module LinkifyRe
|
|
90
93
|
'(?:(?:(?:' + SRC_DOMAIN + ')\\.)+(?:%TLDS%))' +
|
91
94
|
')'
|
92
95
|
|
96
|
+
TPL_HOST_NO_IP_FUZZY =
|
97
|
+
'(?:(?:(?:' + SRC_DOMAIN + ')\\.)+(?:%TLDS%))'
|
98
|
+
|
93
99
|
SRC_HOST_STRICT = SRC_HOST + SRC_HOST_TERMINATOR
|
94
100
|
TPL_HOST_FUZZY_STRICT = TPL_HOST_FUZZY + SRC_HOST_TERMINATOR
|
95
101
|
SRC_HOST_PORT_STRICT = SRC_HOST + SRC_PORT + SRC_HOST_TERMINATOR
|
96
102
|
TPL_HOST_PORT_FUZZY_STRICT = TPL_HOST_FUZZY + SRC_PORT + SRC_HOST_TERMINATOR
|
97
|
-
|
103
|
+
TPL_HOST_PORT_NO_IP_FUZZY_STRICT = TPL_HOST_NO_IP_FUZZY + SRC_PORT + SRC_HOST_TERMINATOR
|
104
|
+
|
98
105
|
#------------------------------------------------------------------------------
|
99
106
|
# Main rules
|
100
107
|
|
@@ -107,4 +114,9 @@ module LinkifyRe
|
|
107
114
|
'(^|(?![.:/\\-_@])(?:[$+<=>^`|]|' + SRC_Z_P_CC + '))' +
|
108
115
|
'((?![$+<=>^`|])' + TPL_HOST_PORT_FUZZY_STRICT + SRC_PATH + ')'
|
109
116
|
|
117
|
+
TPL_LINK_NO_IP_FUZZY =
|
118
|
+
# Fuzzy link can't be prepended with .:/\- and non punctuation.
|
119
|
+
# but can start with > (markdown blockquote)
|
120
|
+
'(^|(?![.:/\\-_@])(?:[$+<=>^`|]|' + SRC_Z_P_CC + '))' +
|
121
|
+
'((?![$+<=>^`|])' + TPL_HOST_PORT_NO_IP_FUZZY_STRICT + SRC_PATH + ')'
|
110
122
|
end
|
@@ -3,7 +3,7 @@ fixture_dir = File.join(File.dirname(__FILE__), 'fixtures')
|
|
3
3
|
#------------------------------------------------------------------------------
|
4
4
|
describe 'links' do
|
5
5
|
|
6
|
-
l = Linkify.new
|
6
|
+
l = Linkify.new({}, {fuzzyIP: true})
|
7
7
|
l.bypass_normalizer = true # kill the normalizer
|
8
8
|
|
9
9
|
skipNext = false
|
@@ -218,4 +218,41 @@ describe 'API' do
|
|
218
218
|
expect(l.test('@@invalid')).to eq false
|
219
219
|
end
|
220
220
|
|
221
|
+
#------------------------------------------------------------------------------
|
222
|
+
it 'set option: fuzzyLink' do
|
223
|
+
l = Linkify.new({}, { fuzzyLink: false })
|
224
|
+
|
225
|
+
expect(l.test('google.com.')).to eq false
|
226
|
+
|
227
|
+
l.set({ fuzzyLink: true })
|
228
|
+
|
229
|
+
expect(l.test('google.com.')).to eq true
|
230
|
+
expect(l.match('google.com.')[0].text).to eq 'google.com'
|
231
|
+
end
|
232
|
+
|
233
|
+
|
234
|
+
#------------------------------------------------------------------------------
|
235
|
+
it 'set option: fuzzyEmail' do
|
236
|
+
l = Linkify.new({}, { fuzzyEmail: false })
|
237
|
+
|
238
|
+
expect(l.test('foo@bar.com.')).to eq false
|
239
|
+
|
240
|
+
l.set({ fuzzyEmail: true })
|
241
|
+
|
242
|
+
expect(l.test('foo@bar.com.')).to eq true
|
243
|
+
expect(l.match('foo@bar.com.')[0].text).to eq 'foo@bar.com'
|
244
|
+
end
|
245
|
+
|
246
|
+
#------------------------------------------------------------------------------
|
247
|
+
it 'set option: fuzzyIP' do
|
248
|
+
l = Linkify.new
|
249
|
+
|
250
|
+
expect(l.test('1.1.1.1.')).to eq false
|
251
|
+
|
252
|
+
l.set({ fuzzyIP: true })
|
253
|
+
|
254
|
+
expect(l.test('1.1.1.1.')).to eq true
|
255
|
+
expect(l.match('1.1.1.1.')[0].text).to eq '1.1.1.1'
|
256
|
+
end
|
257
|
+
|
221
258
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: linkify-it-rb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brett Walker
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-
|
12
|
+
date: 2015-06-20 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: uc.micro-rb
|