Skip to content

Commit a2fac79

Browse files
committed
1 parent aa87cc2 commit a2fac79

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+2663
-12
lines changed

.prettierignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
coverage/
2+
*.html
23
*.json
34
*.md

.remarkignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
test/

from-markdown.js

+120
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
var ccount = require('ccount')
2+
var findAndReplace = require('mdast-util-find-and-replace')
3+
var unicodePunctuation = require('micromark/dist/character/unicode-punctuation')
4+
var unicodeWhitespace = require('micromark/dist/character/unicode-whitespace')
5+
6+
exports.transforms = [transformGfmAutolinkLiterals]
17
exports.enter = {
28
literalAutolink: enterLiteralAutolink,
39
literalAutolinkEmail: enterLiteralAutolinkValue,
@@ -35,3 +41,117 @@ function exitLiteralAutolinkEmail(token) {
3541
function exitLiteralAutolink(token) {
3642
this.exit(token)
3743
}
44+
45+
function transformGfmAutolinkLiterals(tree) {
46+
findAndReplace(
47+
tree,
48+
[
49+
[/(https?:\/\/|www(?=\.))([-.\w]+)([^ \t\r\n]*)/i, findUrl],
50+
[/([-.\w+]+)@([-\w]+(?:\.[-\w]+)+)/, findEmail]
51+
],
52+
{ignore: ['link', 'linkReference']}
53+
)
54+
}
55+
56+
function findUrl($0, protocol, domain, path, match) {
57+
var prefix = ''
58+
var parts
59+
var result
60+
61+
// Not an expected previous character.
62+
if (!previous(match)) {
63+
return false
64+
}
65+
66+
// Treat `www` as part of the domain.
67+
if (/^w/i.test(protocol)) {
68+
domain = protocol + domain
69+
protocol = ''
70+
prefix = 'http://'
71+
}
72+
73+
if (!isCorrectDomain(domain)) {
74+
return false
75+
}
76+
77+
parts = splitUrl(domain + path)
78+
79+
if (!parts[0]) return false
80+
81+
result = {
82+
type: 'link',
83+
title: null,
84+
url: prefix + protocol + parts[0],
85+
children: [{type: 'text', value: protocol + parts[0]}]
86+
}
87+
88+
if (parts[1]) {
89+
result = [result, {type: 'text', value: parts[1]}]
90+
}
91+
92+
return result
93+
}
94+
95+
function findEmail($0, atext, label, match) {
96+
// Not an expected previous character.
97+
if (!previous(match, true) || /[_-]$/.test(label)) {
98+
return false
99+
}
100+
101+
return {
102+
type: 'link',
103+
title: null,
104+
url: 'mailto:' + atext + '@' + label,
105+
children: [{type: 'text', value: atext + '@' + label}]
106+
}
107+
}
108+
109+
function isCorrectDomain(domain) {
110+
var parts = domain.split('.')
111+
112+
if (
113+
parts.length < 2 ||
114+
(parts[parts.length - 1] &&
115+
(/_/.test(parts[parts.length - 1]) ||
116+
!/[a-zA-Z\d]/.test(parts[parts.length - 1]))) ||
117+
(parts[parts.length - 2] &&
118+
(/_/.test(parts[parts.length - 2]) ||
119+
!/[a-zA-Z\d]/.test(parts[parts.length - 2])))
120+
) {
121+
return false
122+
}
123+
124+
return true
125+
}
126+
127+
function splitUrl(url) {
128+
var trail = /[!"&'),.:;<>?\]}]+$/.exec(url)
129+
var closingParenIndex
130+
var openingParens
131+
var closingParens
132+
133+
if (trail) {
134+
url = url.slice(0, trail.index)
135+
trail = trail[0]
136+
closingParenIndex = trail.indexOf(')')
137+
openingParens = ccount(url, '(')
138+
closingParens = ccount(url, ')')
139+
140+
while (closingParenIndex !== -1 && openingParens > closingParens) {
141+
url += trail.slice(0, closingParenIndex + 1)
142+
trail = trail.slice(closingParenIndex + 1)
143+
closingParenIndex = trail.indexOf(')')
144+
closingParens++
145+
}
146+
}
147+
148+
return [url, trail]
149+
}
150+
151+
function previous(match, email) {
152+
var code = match.input.charCodeAt(match.index - 1)
153+
return (
154+
(code !== code || unicodeWhitespace(code) || unicodePunctuation(code)) &&
155+
(!email || code !== 47)
156+
)
157+
}

package.json

+17-5
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,17 @@
3434
"index.js",
3535
"to-markdown.js"
3636
],
37-
"dependencies": {},
37+
"dependencies": {
38+
"ccount": "^1.0.0",
39+
"mdast-util-find-and-replace": "^1.1.0",
40+
"micromark": "^2.11.3"
41+
},
3842
"devDependencies": {
39-
"mdast-util-from-markdown": "^0.8.0",
43+
"hast-util-to-html": "^7.0.0",
44+
"mdast-util-from-markdown": "^0.8.5",
45+
"mdast-util-to-hast": "^10.0.0",
4046
"mdast-util-to-markdown": "^0.6.0",
41-
"micromark-extension-gfm-autolink-literal": "^0.5.0",
47+
"micromark-extension-gfm-autolink-literal": "^0.5.6",
4248
"nyc": "^15.0.0",
4349
"prettier": "^2.0.0",
4450
"remark-cli": "^9.0.0",
@@ -49,7 +55,7 @@
4955
"scripts": {
5056
"format": "remark . -qfo && prettier . -w --loglevel warn && xo --fix",
5157
"test-api": "node test",
52-
"test-coverage": "nyc --reporter lcov tape test.js",
58+
"test-coverage": "nyc --reporter lcov tape test/index.js",
5359
"test": "npm run format && npm run test-coverage"
5460
},
5561
"nyc": {
@@ -68,7 +74,13 @@
6874
},
6975
"xo": {
7076
"prettier": true,
71-
"esnext": false
77+
"esnext": false,
78+
"rules": {
79+
"max-params": "off",
80+
"no-self-compare": "off",
81+
"unicorn/prefer-includes": "off",
82+
"unicorn/prefer-optional-catch-binding": "off"
83+
}
7284
},
7385
"remarkConfig": {
7486
"plugins": [

readme.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ autolink literals in **[mdast][]**.
1414
When parsing (`from-markdown`), must be combined with
1515
[`micromark-extension-gfm-autolink-literal`][extension].
1616

17-
You probably shouldn’t use this package directly, but instead use
18-
[`remark-gfm`][remark-gfm] with **[remark][]**.
17+
You might want to use this package through [`remark-gfm`][remark-gfm] with
18+
**[remark][]**.
1919

2020
## Install
2121

test/algorithm-2.html

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
<p>[https://</p>
2+
<p>[https://a</p>
3+
<p>[https://.</p>
4+
<p>[<a href="https://a">https://a</a>.</p>
5+
<p>[<a href="https://a">https://a</a>..</p>
6+
<p>[<a href="https://a..b">https://a..b</a></p>
7+
<p>[<a href="https://a.b">https://a.b</a></p>
8+
<p>[<a href="https://a.b">https://a.b</a>.</p>
9+
<p>[<a href="https://a.b">https://a.b</a>..</p>
10+
<p>[<a href="https://a.b.c">https://a.b.c</a></p>
11+
<p>[<a href="https://a.b..c">https://a.b..c</a></p>
12+
<p>[https://a.b_.c</p>
13+
<p>[<a href="https://a_.b.c">https://a_.b.c</a></p>
14+
<p>[https://a_.b_.c</p>
15+
<p>[<a href="https://a.b%C2%A9">https://a.b©</a></p>
16+
<p>[http://點看.com</p>
17+
<hr>
18+
<p>[<a href="http://a.b/c">http://a.b/c</a> (space)</p>
19+
<p>[<a href="http://a.b/c">http://a.b/c</a>!</p>
20+
<p>[<a href="http://a.b/c">http://a.b/c</a>"</p>
21+
<p>[<a href="http://a.b/c#">http://a.b/c#</a></p>
22+
<p>[<a href="http://a.b/c$">http://a.b/c$</a></p>
23+
<p>[<a href="http://a.b/c%25">http://a.b/c%</a></p>
24+
<p>[<a href="http://a.b/c">http://a.b/c</a>&amp;</p>
25+
<p>[<a href="http://a.b/c">http://a.b/c</a>'</p>
26+
<p>[<a href="http://a.b/c(">http://a.b/c(</a></p>
27+
<p>[<a href="http://a.b/c">http://a.b/c</a>)</p>
28+
<p>[<a href="http://a.b/c*">http://a.b/c*</a></p>
29+
<p>[<a href="http://a.b/c+">http://a.b/c+</a></p>
30+
<p>[<a href="http://a.b/c">http://a.b/c</a>,</p>
31+
<p>[<a href="http://a.b/c-">http://a.b/c-</a></p>
32+
<p>[<a href="http://a.b/c">http://a.b/c</a></p>
33+
<p>[<a href="http://a.b/c">http://a.b/c</a>.</p>
34+
<p>[<a href="http://a.b/c/">http://a.b/c/</a></p>
35+
<p>[<a href="http://a.b/c">http://a.b/c</a>:</p>
36+
<p>[<a href="http://a.b/c">http://a.b/c</a>;</p>
37+
<p>[<a href="http://a.b/c">http://a.b/c</a>&lt;</p>
38+
<p>[<a href="http://a.b/c=">http://a.b/c=</a></p>
39+
<p>[<a href="http://a.b/c">http://a.b/c</a>></p>
40+
<p>[<a href="http://a.b/c">http://a.b/c</a>?</p>
41+
<p>[<a href="http://a.b/c@">http://a.b/c@</a></p>
42+
<p>[<a href="http://a.b/c%5B">http://a.b/c[</a></p>
43+
<p>[<a href="http://a.b/c%5C">http://a.b/c\</a></p>
44+
<p>[<a href="http://a.b/c">http://a.b/c</a>]</p>
45+
<p>[<a href="http://a.b/c%5E">http://a.b/c^</a></p>
46+
<p>[<a href="http://a.b/c_">http://a.b/c_</a></p>
47+
<p>[<a href="http://a.b/c%60">http://a.b/c`</a></p>
48+
<p>[<a href="http://a.b/c%7B">http://a.b/c{</a></p>
49+
<p>[<a href="http://a.b/c%7C">http://a.b/c|</a></p>
50+
<p>[<a href="http://a.b/c">http://a.b/c</a>}</p>
51+
<p>[<a href="http://a.b/c~">http://a.b/c~</a></p>
52+
<hr>
53+
<p>[<a href="http://www">www</a>.</p>
54+
<p>[<a href="http://www.a">www.a</a></p>
55+
<p>[<a href="http://www">www</a>..</p>
56+
<p>[<a href="http://www.a">www.a</a>.</p>
57+
<p>[<a href="http://www.a">www.a</a>..</p>
58+
<p>[<a href="http://www.a..b">www.a..b</a></p>
59+
<p>[<a href="http://www.a.b">www.a.b</a></p>
60+
<p>[<a href="http://www.a.b">www.a.b</a>.</p>
61+
<p>[<a href="http://www.a.b">www.a.b</a>..</p>
62+
<p>[<a href="http://www.a.b.c">www.a.b.c</a></p>
63+
<p>[<a href="http://www.a.b..c">www.a.b..c</a></p>
64+
<p>[www.a.b_.c</p>
65+
<p>[<a href="http://www.a_.b.c">www.a_.b.c</a></p>
66+
<p>[www.a_.b_.c</p>
67+
<p>[<a href="http://www.a.b%C2%A9">www.a.b©</a></p>
68+
<p>[<a href="http://www.%E9%BB%9E%E7%9C%8B.com">www.點看.com</a></p>
69+
<hr>
70+
<p>[<a href="mailto:[email protected]">[email protected]</a></p>
71+
<p>[<a href="mailto:[email protected]">[email protected]</a></p>
72+
<p>[<a href="mailto:[email protected]">[email protected]</a>.</p>
73+
<p>[<a href="mailto:[email protected]">[email protected]</a>.</p>
74+
<p>[<a href="mailto:[email protected]">[email protected]</a>..</p>
75+
<p>[<a href="mailto:[email protected]">[email protected]</a>..b</p>
76+
<p>[<a href="mailto:[email protected]">[email protected]</a></p>
77+
<p>[<a href="mailto:[email protected]">[email protected]</a>.</p>
78+
<p>[<a href="mailto:[email protected]">[email protected]</a>..</p>
79+
<p>[<a href="mailto:[email protected]">[email protected]</a></p>
80+
<p>[<a href="mailto:[email protected]">[email protected]</a>..c</p>
81+
<p>[<a href="mailto:[email protected]_.c">[email protected]_.c</a></p>
82+
<p>[<a href="mailto:[email protected]_.b.c">[email protected]_.b.c</a></p>
83+
<p>[<a href="mailto:[email protected]_.b_.c">[email protected]_.b_.c</a></p>
84+
<p>[<a href="mailto:[email protected]">[email protected]</a>©</p>
85+
<p>[a@b點看.com</p>
86+
<p>[點看@b.com</p>

0 commit comments

Comments
 (0)