-
-
Notifications
You must be signed in to change notification settings - Fork 358
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
parse: add support for emails without protocol
- Loading branch information
Showing
15 changed files
with
2,610 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
'use strict' | ||
|
||
var decimal = require('is-decimal') | ||
var alphabetical = require('is-alphabetical') | ||
|
||
var plusSign = 43 // '+' | ||
var dash = 45 // '-' | ||
var dot = 46 // '.' | ||
var underscore = 95 // '_' | ||
|
||
module.exports = locate | ||
|
||
// See: <https://github.github.com/gfm/#extended-email-autolink> | ||
function locate(value, fromIndex) { | ||
var self = this | ||
var at | ||
var position | ||
|
||
if (!this.options.gfm) { | ||
return -1 | ||
} | ||
|
||
at = value.indexOf('@', fromIndex) | ||
|
||
if (at === -1) { | ||
return -1 | ||
} | ||
|
||
position = at | ||
|
||
if (position === fromIndex || !isGfmAtext(value.charCodeAt(position - 1))) { | ||
return locate.call(self, value, at + 1) | ||
} | ||
|
||
while (position > fromIndex && isGfmAtext(value.charCodeAt(position - 1))) { | ||
position-- | ||
} | ||
|
||
return position | ||
} | ||
|
||
function isGfmAtext(code) { | ||
return ( | ||
decimal(code) || | ||
alphabetical(code) || | ||
code === plusSign || | ||
code === dash || | ||
code === dot || | ||
code === underscore | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
'use strict' | ||
|
||
var decode = require('parse-entities') | ||
var decimal = require('is-decimal') | ||
var alphabetical = require('is-alphabetical') | ||
var locate = require('../locate/email') | ||
|
||
module.exports = email | ||
email.locator = locate | ||
email.notInLink = true | ||
|
||
var plusSign = 43 // '+' | ||
var dash = 45 // '-' | ||
var dot = 46 // '.' | ||
var atSign = 64 // '@' | ||
var underscore = 95 // '_' | ||
|
||
function email(eat, value, silent) { | ||
var self = this | ||
var gfm = self.options.gfm | ||
var tokenizers = self.inlineTokenizers | ||
var index = 0 | ||
var length = value.length | ||
var firstDot = -1 | ||
var code | ||
var content | ||
var children | ||
var exit | ||
|
||
if (!gfm) { | ||
return | ||
} | ||
|
||
code = value.charCodeAt(index) | ||
|
||
while ( | ||
decimal(code) || | ||
alphabetical(code) || | ||
code === plusSign || | ||
code === dash || | ||
code === dot || | ||
code === underscore | ||
) { | ||
code = value.charCodeAt(++index) | ||
} | ||
|
||
if (index === 0) { | ||
return | ||
} | ||
|
||
if (code !== atSign) { | ||
return | ||
} | ||
|
||
index++ | ||
|
||
while (index < length) { | ||
code = value.charCodeAt(index) | ||
|
||
if ( | ||
decimal(code) || | ||
alphabetical(code) || | ||
code === dash || | ||
code === dot || | ||
code === underscore | ||
) { | ||
index++ | ||
|
||
if (firstDot === -1 && code === dot) { | ||
firstDot = index | ||
} | ||
|
||
continue | ||
} | ||
|
||
break | ||
} | ||
|
||
if ( | ||
firstDot === -1 || | ||
firstDot === index || | ||
code === dash || | ||
code === underscore | ||
) { | ||
return | ||
} | ||
|
||
if (code === dot) { | ||
index-- | ||
} | ||
|
||
content = value.slice(0, index) | ||
|
||
/* istanbul ignore if - never used (yet) */ | ||
if (silent) { | ||
return true | ||
} | ||
|
||
exit = self.enterLink() | ||
|
||
// Temporarily remove all tokenizers except text in url. | ||
self.inlineTokenizers = {text: tokenizers.text} | ||
children = self.tokenizeInline(content, eat.now()) | ||
self.inlineTokenizers = tokenizers | ||
|
||
exit() | ||
|
||
return eat(content)({ | ||
type: 'link', | ||
title: null, | ||
url: 'mailto:' + decode(content, {nonTerminated: false}), | ||
children: children | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,3 +5,5 @@ Also, subdomain should be a part of the link (http://foo.example.com/(hello[worl | |
So should this: mailto:[email protected]. | ||
|
||
And even with underscore http://domain.org/this_is_good. | ||
|
||
All links should work http://a.b, https://c.d, http://e.f, https://g.h. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
example1 ([email protected]) | ||
example1 (mailto:[email protected]) | ||
|
||
Lorem [email protected] ipsum. | ||
|
||
alpha@bravo+charlie.delta isn’t valid, but [email protected] is. | ||
|
||
Valid: [email protected] | ||
|
||
Valid, but the dot is not part of the email: [email protected]. | ||
|
||
Not valid: [email protected] | ||
|
||
Not valid: [email protected]_ | ||
|
||
Not valid: alpha@bravo. | ||
|
||
<[email protected] |
Oops, something went wrong.