summaryrefslogtreecommitdiff
path: root/tools/node_modules/eslint/node_modules/remark-parse/lib/tokenize/link.js
diff options
context:
space:
mode:
Diffstat (limited to 'tools/node_modules/eslint/node_modules/remark-parse/lib/tokenize/link.js')
-rw-r--r--tools/node_modules/eslint/node_modules/remark-parse/lib/tokenize/link.js399
1 files changed, 399 insertions, 0 deletions
diff --git a/tools/node_modules/eslint/node_modules/remark-parse/lib/tokenize/link.js b/tools/node_modules/eslint/node_modules/remark-parse/lib/tokenize/link.js
new file mode 100644
index 0000000000..fb11c50990
--- /dev/null
+++ b/tools/node_modules/eslint/node_modules/remark-parse/lib/tokenize/link.js
@@ -0,0 +1,399 @@
+/**
+ * @author Titus Wormer
+ * @copyright 2015 Titus Wormer
+ * @license MIT
+ * @module remark:parse:tokenize:link
+ * @fileoverview Tokenise a link.
+ */
+
+'use strict';
+
+var has = require('has');
+var whitespace = require('is-whitespace-character');
+var locate = require('../locate/link');
+
+module.exports = link;
+link.locator = locate;
+
+var C_BACKSLASH = '\\';
+var C_BRACKET_OPEN = '[';
+var C_BRACKET_CLOSE = ']';
+var C_PAREN_OPEN = '(';
+var C_PAREN_CLOSE = ')';
+var C_LT = '<';
+var C_GT = '>';
+var C_TICK = '`';
+var C_DOUBLE_QUOTE = '"';
+var C_SINGLE_QUOTE = '\'';
+
+/* Map of characters, which can be used to mark link
+ * and image titles. */
+var LINK_MARKERS = {};
+
+LINK_MARKERS[C_DOUBLE_QUOTE] = C_DOUBLE_QUOTE;
+LINK_MARKERS[C_SINGLE_QUOTE] = C_SINGLE_QUOTE;
+
+/* Map of characters, which can be used to mark link
+ * and image titles in commonmark-mode. */
+var COMMONMARK_LINK_MARKERS = {};
+
+COMMONMARK_LINK_MARKERS[C_DOUBLE_QUOTE] = C_DOUBLE_QUOTE;
+COMMONMARK_LINK_MARKERS[C_SINGLE_QUOTE] = C_SINGLE_QUOTE;
+COMMONMARK_LINK_MARKERS[C_PAREN_OPEN] = C_PAREN_CLOSE;
+
+/* Tokenise a link. */
+function link(eat, value, silent) {
+ var self = this;
+ var subvalue = '';
+ var index = 0;
+ var character = value.charAt(0);
+ var commonmark = self.options.commonmark;
+ var gfm = self.options.gfm;
+ var closed;
+ var count;
+ var opening;
+ var beforeURL;
+ var beforeTitle;
+ var subqueue;
+ var hasMarker;
+ var markers;
+ var isImage;
+ var content;
+ var marker;
+ var length;
+ var title;
+ var depth;
+ var queue;
+ var url;
+ var now;
+ var exit;
+ var node;
+
+ /* Detect whether this is an image. */
+ if (character === '!') {
+ isImage = true;
+ subvalue = character;
+ character = value.charAt(++index);
+ }
+
+ /* Eat the opening. */
+ if (character !== C_BRACKET_OPEN) {
+ return;
+ }
+
+ /* Exit when this is a link and we’re already inside
+ * a link. */
+ if (!isImage && self.inLink) {
+ return;
+ }
+
+ subvalue += character;
+ queue = '';
+ index++;
+
+ /* Eat the content. */
+ length = value.length;
+ now = eat.now();
+ depth = 0;
+
+ now.column += index;
+ now.offset += index;
+
+ while (index < length) {
+ character = value.charAt(index);
+ subqueue = character;
+
+ if (character === C_TICK) {
+ /* Inline-code in link content. */
+ count = 1;
+
+ while (value.charAt(index + 1) === C_TICK) {
+ subqueue += character;
+ index++;
+ count++;
+ }
+
+ if (!opening) {
+ opening = count;
+ } else if (count >= opening) {
+ opening = 0;
+ }
+ } else if (character === C_BACKSLASH) {
+ /* Allow brackets to be escaped. */
+ index++;
+ subqueue += value.charAt(index);
+ /* In GFM mode, brackets in code still count.
+ * In all other modes, they don’t. This empty
+ * block prevents the next statements are
+ * entered. */
+ } else if ((!opening || gfm) && character === C_BRACKET_OPEN) {
+ depth++;
+ } else if ((!opening || gfm) && character === C_BRACKET_CLOSE) {
+ if (depth) {
+ depth--;
+ } else {
+ /* Allow white-space between content and
+ * url in GFM mode. */
+ if (gfm) {
+ while (index < length) {
+ character = value.charAt(index + 1);
+
+ if (!whitespace(character)) {
+ break;
+ }
+
+ subqueue += character;
+ index++;
+ }
+ }
+
+ if (value.charAt(index + 1) !== C_PAREN_OPEN) {
+ return;
+ }
+
+ subqueue += C_PAREN_OPEN;
+ closed = true;
+ index++;
+
+ break;
+ }
+ }
+
+ queue += subqueue;
+ subqueue = '';
+ index++;
+ }
+
+ /* Eat the content closing. */
+ if (!closed) {
+ return;
+ }
+
+ content = queue;
+ subvalue += queue + subqueue;
+ index++;
+
+ /* Eat white-space. */
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (!whitespace(character)) {
+ break;
+ }
+
+ subvalue += character;
+ index++;
+ }
+
+ /* Eat the URL. */
+ character = value.charAt(index);
+ markers = commonmark ? COMMONMARK_LINK_MARKERS : LINK_MARKERS;
+ queue = '';
+ beforeURL = subvalue;
+
+ if (character === C_LT) {
+ index++;
+ beforeURL += C_LT;
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (character === C_GT) {
+ break;
+ }
+
+ if (commonmark && character === '\n') {
+ return;
+ }
+
+ queue += character;
+ index++;
+ }
+
+ if (value.charAt(index) !== C_GT) {
+ return;
+ }
+
+ subvalue += C_LT + queue + C_GT;
+ url = queue;
+ index++;
+ } else {
+ character = null;
+ subqueue = '';
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (subqueue && has(markers, character)) {
+ break;
+ }
+
+ if (whitespace(character)) {
+ if (commonmark) {
+ break;
+ }
+
+ subqueue += character;
+ } else {
+ if (character === C_PAREN_OPEN) {
+ depth++;
+ } else if (character === C_PAREN_CLOSE) {
+ if (depth === 0) {
+ break;
+ }
+
+ depth--;
+ }
+
+ queue += subqueue;
+ subqueue = '';
+
+ if (character === C_BACKSLASH) {
+ queue += C_BACKSLASH;
+ character = value.charAt(++index);
+ }
+
+ queue += character;
+ }
+
+ index++;
+ }
+
+ subvalue += queue;
+ url = queue;
+ index = subvalue.length;
+ }
+
+ /* Eat white-space. */
+ queue = '';
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (!whitespace(character)) {
+ break;
+ }
+
+ queue += character;
+ index++;
+ }
+
+ character = value.charAt(index);
+ subvalue += queue;
+
+ /* Eat the title. */
+ if (queue && has(markers, character)) {
+ index++;
+ subvalue += character;
+ queue = '';
+ marker = markers[character];
+ beforeTitle = subvalue;
+
+ /* In commonmark-mode, things are pretty easy: the
+ * marker cannot occur inside the title.
+ *
+ * Non-commonmark does, however, support nested
+ * delimiters. */
+ if (commonmark) {
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (character === marker) {
+ break;
+ }
+
+ if (character === C_BACKSLASH) {
+ queue += C_BACKSLASH;
+ character = value.charAt(++index);
+ }
+
+ index++;
+ queue += character;
+ }
+
+ character = value.charAt(index);
+
+ if (character !== marker) {
+ return;
+ }
+
+ title = queue;
+ subvalue += queue + character;
+ index++;
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (!whitespace(character)) {
+ break;
+ }
+
+ subvalue += character;
+ index++;
+ }
+ } else {
+ subqueue = '';
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (character === marker) {
+ if (hasMarker) {
+ queue += marker + subqueue;
+ subqueue = '';
+ }
+
+ hasMarker = true;
+ } else if (!hasMarker) {
+ queue += character;
+ } else if (character === C_PAREN_CLOSE) {
+ subvalue += queue + marker + subqueue;
+ title = queue;
+ break;
+ } else if (whitespace(character)) {
+ subqueue += character;
+ } else {
+ queue += marker + subqueue + character;
+ subqueue = '';
+ hasMarker = false;
+ }
+
+ index++;
+ }
+ }
+ }
+
+ if (value.charAt(index) !== C_PAREN_CLOSE) {
+ return;
+ }
+
+ /* istanbul ignore if - never used (yet) */
+ if (silent) {
+ return true;
+ }
+
+ subvalue += C_PAREN_CLOSE;
+
+ url = self.decode.raw(self.unescape(url), eat(beforeURL).test().end);
+
+ if (title) {
+ beforeTitle = eat(beforeTitle).test().end;
+ title = self.decode.raw(self.unescape(title), beforeTitle);
+ }
+
+ node = {
+ type: isImage ? 'image' : 'link',
+ title: title || null,
+ url: url
+ };
+
+ if (isImage) {
+ node.alt = self.decode.raw(self.unescape(content), now) || null;
+ } else {
+ exit = self.enterLink();
+ node.children = self.tokenizeInline(content, now);
+ exit();
+ }
+
+ return eat(subvalue)(node);
+}