123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- '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.slice(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
- })
- }
|