blob: c73480f411c430ec0dc04e200b3d5d6018eeee2b [file] [log] [blame]
'use strict'
var whitespace = require('is-whitespace-character')
var decode = require('parse-entities')
var locate = require('../locate/tag')
module.exports = autoLink
autoLink.locator = locate
autoLink.notInLink = true
var lessThan = '<'
var greaterThan = '>'
var atSign = '@'
var slash = '/'
var mailto = 'mailto:'
var mailtoLength = mailto.length
function autoLink(eat, value, silent) {
var self = this
var subvalue = ''
var length = value.length
var index = 0
var queue = ''
var hasAtCharacter = false
var link = ''
var character
var now
var content
var tokenizers
var exit
if (value.charAt(0) !== lessThan) {
return
}
index++
subvalue = lessThan
while (index < length) {
character = value.charAt(index)
if (
whitespace(character) ||
character === greaterThan ||
character === atSign ||
(character === ':' && value.charAt(index + 1) === slash)
) {
break
}
queue += character
index++
}
if (!queue) {
return
}
link += queue
queue = ''
character = value.charAt(index)
link += character
index++
if (character === atSign) {
hasAtCharacter = true
} else {
if (character !== ':' || value.charAt(index + 1) !== slash) {
return
}
link += slash
index++
}
while (index < length) {
character = value.charAt(index)
if (whitespace(character) || character === greaterThan) {
break
}
queue += character
index++
}
character = value.charAt(index)
if (!queue || character !== greaterThan) {
return
}
/* istanbul ignore if - never used (yet) */
if (silent) {
return true
}
link += queue
content = link
subvalue += link + character
now = eat.now()
now.column++
now.offset++
if (hasAtCharacter) {
if (link.slice(0, mailtoLength).toLowerCase() === mailto) {
content = content.substr(mailtoLength)
now.column += mailtoLength
now.offset += mailtoLength
} else {
link = mailto + link
}
}
// Temporarily remove all tokenizers except text in autolinks.
tokenizers = self.inlineTokenizers
self.inlineTokenizers = {text: tokenizers.text}
exit = self.enterLink()
content = self.tokenizeInline(content, now)
self.inlineTokenizers = tokenizers
exit()
return eat(subvalue)({
type: 'link',
title: null,
url: decode(link, {nonTerminated: false}),
children: content
})
}