linkify-it-rb 1.0.0.3 → 1.1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|