Files
coopgo/node_modules/mdast-util-gfm-autolink-literal/from-markdown.js
sgauthier 6e64e138e2
All checks were successful
Publish To Prod / deploy_and_publish (push) Successful in 35s
planning
2024-10-14 09:15:30 +02:00

158 lines
3.8 KiB
JavaScript

var ccount = require('ccount')
var findAndReplace = require('mdast-util-find-and-replace')
var unicodePunctuation = require('micromark/dist/character/unicode-punctuation')
var unicodeWhitespace = require('micromark/dist/character/unicode-whitespace')
exports.transforms = [transformGfmAutolinkLiterals]
exports.enter = {
literalAutolink: enterLiteralAutolink,
literalAutolinkEmail: enterLiteralAutolinkValue,
literalAutolinkHttp: enterLiteralAutolinkValue,
literalAutolinkWww: enterLiteralAutolinkValue
}
exports.exit = {
literalAutolink: exitLiteralAutolink,
literalAutolinkEmail: exitLiteralAutolinkEmail,
literalAutolinkHttp: exitLiteralAutolinkHttp,
literalAutolinkWww: exitLiteralAutolinkWww
}
function enterLiteralAutolink(token) {
this.enter({type: 'link', title: null, url: '', children: []}, token)
}
function enterLiteralAutolinkValue(token) {
this.config.enter.autolinkProtocol.call(this, token)
}
function exitLiteralAutolinkHttp(token) {
this.config.exit.autolinkProtocol.call(this, token)
}
function exitLiteralAutolinkWww(token) {
this.config.exit.data.call(this, token)
this.stack[this.stack.length - 1].url = 'http://' + this.sliceSerialize(token)
}
function exitLiteralAutolinkEmail(token) {
this.config.exit.autolinkEmail.call(this, token)
}
function exitLiteralAutolink(token) {
this.exit(token)
}
function transformGfmAutolinkLiterals(tree) {
findAndReplace(
tree,
[
[/(https?:\/\/|www(?=\.))([-.\w]+)([^ \t\r\n]*)/i, findUrl],
[/([-.\w+]+)@([-\w]+(?:\.[-\w]+)+)/, findEmail]
],
{ignore: ['link', 'linkReference']}
)
}
function findUrl($0, protocol, domain, path, match) {
var prefix = ''
var parts
var result
// Not an expected previous character.
if (!previous(match)) {
return false
}
// Treat `www` as part of the domain.
if (/^w/i.test(protocol)) {
domain = protocol + domain
protocol = ''
prefix = 'http://'
}
if (!isCorrectDomain(domain)) {
return false
}
parts = splitUrl(domain + path)
if (!parts[0]) return false
result = {
type: 'link',
title: null,
url: prefix + protocol + parts[0],
children: [{type: 'text', value: protocol + parts[0]}]
}
if (parts[1]) {
result = [result, {type: 'text', value: parts[1]}]
}
return result
}
function findEmail($0, atext, label, match) {
// Not an expected previous character.
if (!previous(match, true) || /[_-]$/.test(label)) {
return false
}
return {
type: 'link',
title: null,
url: 'mailto:' + atext + '@' + label,
children: [{type: 'text', value: atext + '@' + label}]
}
}
function isCorrectDomain(domain) {
var parts = domain.split('.')
if (
parts.length < 2 ||
(parts[parts.length - 1] &&
(/_/.test(parts[parts.length - 1]) ||
!/[a-zA-Z\d]/.test(parts[parts.length - 1]))) ||
(parts[parts.length - 2] &&
(/_/.test(parts[parts.length - 2]) ||
!/[a-zA-Z\d]/.test(parts[parts.length - 2])))
) {
return false
}
return true
}
function splitUrl(url) {
var trail = /[!"&'),.:;<>?\]}]+$/.exec(url)
var closingParenIndex
var openingParens
var closingParens
if (trail) {
url = url.slice(0, trail.index)
trail = trail[0]
closingParenIndex = trail.indexOf(')')
openingParens = ccount(url, '(')
closingParens = ccount(url, ')')
while (closingParenIndex !== -1 && openingParens > closingParens) {
url += trail.slice(0, closingParenIndex + 1)
trail = trail.slice(closingParenIndex + 1)
closingParenIndex = trail.indexOf(')')
closingParens++
}
}
return [url, trail]
}
function previous(match, email) {
var code = match.input.charCodeAt(match.index - 1)
return (
(code !== code || unicodeWhitespace(code) || unicodePunctuation(code)) &&
(!email || code !== 47)
)
}