Skip to content

Commit 3d14647

Browse files
committed
Use ESM
1 parent cff7385 commit 3d14647

File tree

8 files changed

+244
-251
lines changed

8 files changed

+244
-251
lines changed

.gitignore

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
.DS_Store
2-
*.log
3-
.nyc_output/
41
coverage/
52
node_modules/
3+
.DS_Store
4+
*.log
65
yarn.lock

.prettierignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
coverage/
22
*.html
3-
*.json
43
*.md

from-markdown.js

Lines changed: 0 additions & 157 deletions
This file was deleted.

index.js

Lines changed: 182 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,182 @@
1-
exports.fromMarkdown = require('./from-markdown')
2-
exports.toMarkdown = require('./to-markdown')
1+
import {ccount} from 'ccount'
2+
import {findAndReplace} from 'mdast-util-find-and-replace'
3+
import unicodePunctuation from 'micromark/dist/character/unicode-punctuation.js'
4+
import unicodeWhitespace from 'micromark/dist/character/unicode-whitespace.js'
5+
6+
var inConstruct = 'phrasing'
7+
var notInConstruct = ['autolink', 'link', 'image', 'label']
8+
9+
export const gfmAutolinkLiteralFromMarkdown = {
10+
transforms: [transformGfmAutolinkLiterals],
11+
enter: {
12+
literalAutolink: enterLiteralAutolink,
13+
literalAutolinkEmail: enterLiteralAutolinkValue,
14+
literalAutolinkHttp: enterLiteralAutolinkValue,
15+
literalAutolinkWww: enterLiteralAutolinkValue
16+
},
17+
exit: {
18+
literalAutolink: exitLiteralAutolink,
19+
literalAutolinkEmail: exitLiteralAutolinkEmail,
20+
literalAutolinkHttp: exitLiteralAutolinkHttp,
21+
literalAutolinkWww: exitLiteralAutolinkWww
22+
}
23+
}
24+
25+
export const gfmAutolinkLiteralToMarkdown = {
26+
unsafe: [
27+
{
28+
character: '@',
29+
before: '[+\\-.\\w]',
30+
after: '[\\-.\\w]',
31+
inConstruct,
32+
notInConstruct
33+
},
34+
{
35+
character: '.',
36+
before: '[Ww]',
37+
after: '[\\-.\\w]',
38+
inConstruct,
39+
notInConstruct
40+
},
41+
{character: ':', before: '[ps]', after: '\\/', inConstruct, notInConstruct}
42+
]
43+
}
44+
45+
function enterLiteralAutolink(token) {
46+
this.enter({type: 'link', title: null, url: '', children: []}, token)
47+
}
48+
49+
function enterLiteralAutolinkValue(token) {
50+
this.config.enter.autolinkProtocol.call(this, token)
51+
}
52+
53+
function exitLiteralAutolinkHttp(token) {
54+
this.config.exit.autolinkProtocol.call(this, token)
55+
}
56+
57+
function exitLiteralAutolinkWww(token) {
58+
this.config.exit.data.call(this, token)
59+
this.stack[this.stack.length - 1].url = 'http://' + this.sliceSerialize(token)
60+
}
61+
62+
function exitLiteralAutolinkEmail(token) {
63+
this.config.exit.autolinkEmail.call(this, token)
64+
}
65+
66+
function exitLiteralAutolink(token) {
67+
this.exit(token)
68+
}
69+
70+
function transformGfmAutolinkLiterals(tree) {
71+
findAndReplace(
72+
tree,
73+
[
74+
[/(https?:\/\/|www(?=\.))([-.\w]+)([^ \t\r\n]*)/i, findUrl],
75+
[/([-.\w+]+)@([-\w]+(?:\.[-\w]+)+)/, findEmail]
76+
],
77+
{ignore: ['link', 'linkReference']}
78+
)
79+
}
80+
81+
function findUrl($0, protocol, domain, path, match) {
82+
var prefix = ''
83+
var parts
84+
var result
85+
86+
// Not an expected previous character.
87+
if (!previous(match)) {
88+
return false
89+
}
90+
91+
// Treat `www` as part of the domain.
92+
if (/^w/i.test(protocol)) {
93+
domain = protocol + domain
94+
protocol = ''
95+
prefix = 'http://'
96+
}
97+
98+
if (!isCorrectDomain(domain)) {
99+
return false
100+
}
101+
102+
parts = splitUrl(domain + path)
103+
104+
if (!parts[0]) return false
105+
106+
result = {
107+
type: 'link',
108+
title: null,
109+
url: prefix + protocol + parts[0],
110+
children: [{type: 'text', value: protocol + parts[0]}]
111+
}
112+
113+
if (parts[1]) {
114+
result = [result, {type: 'text', value: parts[1]}]
115+
}
116+
117+
return result
118+
}
119+
120+
function findEmail($0, atext, label, match) {
121+
// Not an expected previous character.
122+
if (!previous(match, true) || /[_-]$/.test(label)) {
123+
return false
124+
}
125+
126+
return {
127+
type: 'link',
128+
title: null,
129+
url: 'mailto:' + atext + '@' + label,
130+
children: [{type: 'text', value: atext + '@' + label}]
131+
}
132+
}
133+
134+
function isCorrectDomain(domain) {
135+
var parts = domain.split('.')
136+
137+
if (
138+
parts.length < 2 ||
139+
(parts[parts.length - 1] &&
140+
(/_/.test(parts[parts.length - 1]) ||
141+
!/[a-zA-Z\d]/.test(parts[parts.length - 1]))) ||
142+
(parts[parts.length - 2] &&
143+
(/_/.test(parts[parts.length - 2]) ||
144+
!/[a-zA-Z\d]/.test(parts[parts.length - 2])))
145+
) {
146+
return false
147+
}
148+
149+
return true
150+
}
151+
152+
function splitUrl(url) {
153+
var trail = /[!"&'),.:;<>?\]}]+$/.exec(url)
154+
var closingParenIndex
155+
var openingParens
156+
var closingParens
157+
158+
if (trail) {
159+
url = url.slice(0, trail.index)
160+
trail = trail[0]
161+
closingParenIndex = trail.indexOf(')')
162+
openingParens = ccount(url, '(')
163+
closingParens = ccount(url, ')')
164+
165+
while (closingParenIndex !== -1 && openingParens > closingParens) {
166+
url += trail.slice(0, closingParenIndex + 1)
167+
trail = trail.slice(closingParenIndex + 1)
168+
closingParenIndex = trail.indexOf(')')
169+
closingParens++
170+
}
171+
}
172+
173+
return [url, trail]
174+
}
175+
176+
function previous(match, email) {
177+
var code = match.input.charCodeAt(match.index - 1)
178+
return (
179+
(code !== code || unicodeWhitespace(code) || unicodePunctuation(code)) &&
180+
(!email || code !== 47)
181+
)
182+
}

0 commit comments

Comments
 (0)