function startsWithEntity(value) { var prefix; if (value.charAt(0) !== AMPERSAND) { return false; } prefix = value.split(AMPERSAND, 2).join(AMPERSAND); return decode(prefix).length !== prefix.length; }
// Returns the length of HTML entity that is a prefix of the given string // (excluding the ampersand), 0 if it does not start with an entity. function length(value) { var prefix /* istanbul ignore if - Currently also tested for at implemention, but we * keep it here because that’s proper. */ if (value.charAt(0) !== ampersand) { return 0 } prefix = value.split(ampersand, 2).join(ampersand) return prefix.length - decode(prefix).length }
/** * Returns the length of HTML entity that is a prefix of * the given string (excluding the ampersand), 0 if it * does not start with an entity. * * @example * entityPrefixLength('©cat') // 4 * entityPrefixLength('&foo & &bar') // 0 * * @param {string} value - Input string. * @return {number} - Length of an entity. */ function length(value) { var prefix; /* istanbul ignore if - Currently also tested for at * implemention, but we keep it here because that’s * proper. */ if (value.charAt(0) !== '&') { return 0; } prefix = value.split('&', 2).join('&'); return prefix.length - decode(prefix).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 tokenize; 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 ( 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 (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 support for escapes in autolinks. */ tokenize = self.inlineTokenizers.escape; self.inlineTokenizers.escape = null; exit = self.enterLink(); content = self.tokenizeInline(content, now); self.inlineTokenizers.escape = tokenize; exit(); return eat(subvalue)({ type: 'link', title: null, url: decode(link), children: content }); }
function url(eat, value, silent) { var self = this var subvalue var content var character var index var position var protocol var match var length var queue var parenCount var nextCharacter var tokenizers var exit if (!self.options.gfm) { return } subvalue = '' index = -1 while (++index < protocolsLength) { protocol = protocols[index] match = value.slice(0, protocol.length) if (match.toLowerCase() === protocol) { subvalue = match break } } if (!subvalue) { return } index = subvalue.length length = value.length queue = '' parenCount = 0 while (index < length) { character = value.charAt(index) if (whitespace(character) || character === lessThan) { break } if ( character === dot || character === comma || character === colon || character === semicolon || character === quotationMark || character === apostrophe || character === rightParenthesis || character === rightSquareBracket ) { nextCharacter = value.charAt(index + 1) if (!nextCharacter || whitespace(nextCharacter)) { break } } if (character === leftParenthesis || character === leftSquareBracket) { parenCount++ } if (character === rightParenthesis || character === rightSquareBracket) { parenCount-- if (parenCount < 0) { break } } queue += character index++ } if (!queue) { return } subvalue += queue content = subvalue if (protocol === mailto) { position = queue.indexOf(atSign) if (position === -1 || position === length - 1) { return } content = content.substr(mailto.length) } /* istanbul ignore if - never used (yet) */ if (silent) { return true } exit = self.enterLink() // Temporarily remove all tokenizers except text in url. tokenizers = self.inlineTokenizers self.inlineTokenizers = {text: tokenizers.text} content = self.tokenizeInline(content, eat.now()) self.inlineTokenizers = tokenizers exit() return eat(subvalue)({ type: 'link', title: null, url: decode(subvalue, {nonTerminated: false}), children: content }) }
/* Tokenise a URL. */ function url(eat, value, silent) { var self = this; var subvalue; var content; var character; var index; var position; var protocol; var match; var length; var queue; var parenCount; var nextCharacter; var exit; if (!self.options.gfm) { return; } subvalue = ''; index = -1; length = PROTOCOLS_LENGTH; while (++index < length) { protocol = PROTOCOLS[index]; match = value.slice(0, protocol.length); if (match.toLowerCase() === protocol) { subvalue = match; break; } } if (!subvalue) { return; } index = subvalue.length; length = value.length; queue = ''; parenCount = 0; while (index < length) { character = value.charAt(index); if (whitespace(character) || character === C_LT) { break; } if ( character === '.' || character === ',' || character === ':' || character === ';' || character === '"' || character === '\'' || character === ')' || character === ']' ) { nextCharacter = value.charAt(index + 1); if (!nextCharacter || whitespace(nextCharacter)) { break; } } if (character === C_PAREN_OPEN || character === C_BRACKET_OPEN) { parenCount++; } if (character === C_PAREN_CLOSE || character === C_BRACKET_CLOSE) { parenCount--; if (parenCount < 0) { break; } } queue += character; index++; } if (!queue) { return; } subvalue += queue; content = subvalue; if (protocol === MAILTO_PROTOCOL) { position = queue.indexOf(C_AT_SIGN); if (position === -1 || position === length - 1) { return; } content = content.substr(MAILTO_PROTOCOL.length); } /* istanbul ignore if - never used (yet) */ if (silent) { return true; } exit = self.enterLink(); content = self.tokenizeInline(content, eat.now()); exit(); return eat(subvalue)({ type: 'link', title: null, url: decode(subvalue), children: content }); }