| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 |
- '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 C_LT = '<';
- var C_GT = '>';
- var C_AT_SIGN = '@';
- var C_SLASH = '/';
- var MAILTO = 'mailto:';
- var MAILTO_LENGTH = MAILTO.length;
- /* Tokenise a link. */
- function autoLink(eat, value, silent) {
- var self;
- var subvalue;
- var length;
- var index;
- var queue;
- var character;
- var hasAtCharacter;
- var link;
- var now;
- var content;
- var tokenizers;
- var exit;
- if (value.charAt(0) !== C_LT) {
- return;
- }
- self = this;
- subvalue = '';
- length = value.length;
- index = 0;
- queue = '';
- hasAtCharacter = false;
- link = '';
- index++;
- subvalue = C_LT;
- while (index < length) {
- character = value.charAt(index);
- if (
- whitespace(character) ||
- character === C_GT ||
- character === C_AT_SIGN ||
- (character === ':' && value.charAt(index + 1) === C_SLASH)
- ) {
- break;
- }
- queue += character;
- index++;
- }
- if (!queue) {
- return;
- }
- link += queue;
- queue = '';
- character = value.charAt(index);
- link += character;
- index++;
- if (character === C_AT_SIGN) {
- hasAtCharacter = true;
- } else {
- if (
- character !== ':' ||
- value.charAt(index + 1) !== C_SLASH
- ) {
- return;
- }
- link += C_SLASH;
- index++;
- }
- while (index < length) {
- character = value.charAt(index);
- if (whitespace(character) || character === C_GT) {
- break;
- }
- queue += character;
- index++;
- }
- character = value.charAt(index);
- if (!queue || character !== C_GT) {
- 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, MAILTO_LENGTH).toLowerCase() === MAILTO) {
- content = content.substr(MAILTO_LENGTH);
- now.column += MAILTO_LENGTH;
- now.offset += MAILTO_LENGTH;
- } 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
- });
- }
|