summaryrefslogtreecommitdiff
path: root/tools/eslint/node_modules/remark-parse
diff options
context:
space:
mode:
Diffstat (limited to 'tools/eslint/node_modules/remark-parse')
-rw-r--r--tools/eslint/node_modules/remark-parse/index.js30
-rw-r--r--tools/eslint/node_modules/remark-parse/lib/block-elements.json116
-rw-r--r--tools/eslint/node_modules/remark-parse/lib/decode.js71
-rw-r--r--tools/eslint/node_modules/remark-parse/lib/defaults.js20
-rw-r--r--tools/eslint/node_modules/remark-parse/lib/escapes.json75
-rw-r--r--tools/eslint/node_modules/remark-parse/lib/locate/break.js25
-rw-r--r--tools/eslint/node_modules/remark-parse/lib/locate/code-inline.js15
-rw-r--r--tools/eslint/node_modules/remark-parse/lib/locate/delete.js15
-rw-r--r--tools/eslint/node_modules/remark-parse/lib/locate/emphasis.js26
-rw-r--r--tools/eslint/node_modules/remark-parse/lib/locate/escape.js15
-rw-r--r--tools/eslint/node_modules/remark-parse/lib/locate/link.js24
-rw-r--r--tools/eslint/node_modules/remark-parse/lib/locate/strong.js26
-rw-r--r--tools/eslint/node_modules/remark-parse/lib/locate/tag.js15
-rw-r--r--tools/eslint/node_modules/remark-parse/lib/locate/url.js34
-rw-r--r--tools/eslint/node_modules/remark-parse/lib/parse.js53
-rw-r--r--tools/eslint/node_modules/remark-parse/lib/parser.js6428
-rw-r--r--tools/eslint/node_modules/remark-parse/lib/set-options.js59
-rw-r--r--tools/eslint/node_modules/remark-parse/lib/tokenize/auto-link.js151
-rw-r--r--tools/eslint/node_modules/remark-parse/lib/tokenize/blockquote.js137
-rw-r--r--tools/eslint/node_modules/remark-parse/lib/tokenize/break.js51
-rw-r--r--tools/eslint/node_modules/remark-parse/lib/tokenize/code-fenced.js245
-rw-r--r--tools/eslint/node_modules/remark-parse/lib/tokenize/code-indented.js106
-rw-r--r--tools/eslint/node_modules/remark-parse/lib/tokenize/code-inline.js120
-rw-r--r--tools/eslint/node_modules/remark-parse/lib/tokenize/definition.js287
-rw-r--r--tools/eslint/node_modules/remark-parse/lib/tokenize/delete.js69
-rw-r--r--tools/eslint/node_modules/remark-parse/lib/tokenize/emphasis.js94
-rw-r--r--tools/eslint/node_modules/remark-parse/lib/tokenize/escape.js43
-rw-r--r--tools/eslint/node_modules/remark-parse/lib/tokenize/footnote-definition.js194
-rw-r--r--tools/eslint/node_modules/remark-parse/lib/tokenize/heading-atx.js150
-rw-r--r--tools/eslint/node_modules/remark-parse/lib/tokenize/heading-setext.js116
-rw-r--r--tools/eslint/node_modules/remark-parse/lib/tokenize/html-block.js103
-rw-r--r--tools/eslint/node_modules/remark-parse/lib/tokenize/html-inline.js63
-rw-r--r--tools/eslint/node_modules/remark-parse/lib/tokenize/link.js399
-rw-r--r--tools/eslint/node_modules/remark-parse/lib/tokenize/list.js494
-rw-r--r--tools/eslint/node_modules/remark-parse/lib/tokenize/newline.js55
-rw-r--r--tools/eslint/node_modules/remark-parse/lib/tokenize/paragraph.js130
-rw-r--r--tools/eslint/node_modules/remark-parse/lib/tokenize/reference.js219
-rw-r--r--tools/eslint/node_modules/remark-parse/lib/tokenize/strong.js93
-rw-r--r--tools/eslint/node_modules/remark-parse/lib/tokenize/table.js276
-rw-r--r--tools/eslint/node_modules/remark-parse/lib/tokenize/text.js67
-rw-r--r--tools/eslint/node_modules/remark-parse/lib/tokenize/thematic-break.js79
-rw-r--r--tools/eslint/node_modules/remark-parse/lib/tokenize/url.js153
-rw-r--r--tools/eslint/node_modules/remark-parse/lib/tokenize/yaml.js74
-rw-r--r--tools/eslint/node_modules/remark-parse/lib/tokenizer.js451
-rw-r--r--tools/eslint/node_modules/remark-parse/lib/unescape.js46
-rw-r--r--tools/eslint/node_modules/remark-parse/lib/util/get-indentation.js46
-rw-r--r--tools/eslint/node_modules/remark-parse/lib/util/html.js33
-rw-r--r--tools/eslint/node_modules/remark-parse/lib/util/interrupt.js51
-rw-r--r--tools/eslint/node_modules/remark-parse/lib/util/normalize.js29
-rw-r--r--tools/eslint/node_modules/remark-parse/lib/util/remove-indentation.js102
-rw-r--r--tools/eslint/node_modules/remark-parse/package.json15
-rw-r--r--tools/eslint/node_modules/remark-parse/readme.md178
52 files changed, 6537 insertions, 5429 deletions
diff --git a/tools/eslint/node_modules/remark-parse/index.js b/tools/eslint/node_modules/remark-parse/index.js
index 1579e35518..a7590bad77 100644
--- a/tools/eslint/node_modules/remark-parse/index.js
+++ b/tools/eslint/node_modules/remark-parse/index.js
@@ -1,14 +1,30 @@
+/**
+ * @author Titus Wormer
+ * @copyright 2015-2016 Titus Wormer
+ * @license MIT
+ * @module remark:parse
+ * @fileoverview Markdown parser.
+ */
+
'use strict';
+/* eslint-env commonjs */
+
+/* Dependencies. */
var unherit = require('unherit');
-var xtend = require('xtend');
var Parser = require('./lib/parser.js');
-module.exports = parse;
+/**
+ * Attacher.
+ *
+ * @param {unified} processor - Unified processor.
+ */
+function parse(processor) {
+ processor.Parser = unherit(Parser);
+}
+
+/* Patch `Parser`. */
parse.Parser = Parser;
-function parse(options) {
- var Local = unherit(Parser);
- Local.prototype.options = xtend(Local.prototype.options, this.data('settings'), options);
- this.Parser = Local;
-}
+/* Expose */
+module.exports = parse;
diff --git a/tools/eslint/node_modules/remark-parse/lib/block-elements.json b/tools/eslint/node_modules/remark-parse/lib/block-elements.json
index 2d13b56179..af5e657cbe 100644
--- a/tools/eslint/node_modules/remark-parse/lib/block-elements.json
+++ b/tools/eslint/node_modules/remark-parse/lib/block-elements.json
@@ -1,68 +1,52 @@
[
- "address",
- "article",
- "aside",
- "base",
- "basefont",
- "blockquote",
- "body",
- "caption",
- "center",
- "col",
- "colgroup",
- "dd",
- "details",
- "dialog",
- "dir",
- "div",
- "dl",
- "dt",
- "fieldset",
- "figcaption",
- "figure",
- "footer",
- "form",
- "frame",
- "frameset",
- "h1",
- "h2",
- "h3",
- "h4",
- "h5",
- "h6",
- "head",
- "header",
- "hgroup",
- "hr",
- "html",
- "iframe",
- "legend",
- "li",
- "link",
- "main",
- "menu",
- "menuitem",
- "meta",
- "nav",
- "noframes",
- "ol",
- "optgroup",
- "option",
- "p",
- "param",
- "pre",
- "section",
- "source",
- "title",
- "summary",
- "table",
- "tbody",
- "td",
- "tfoot",
- "th",
- "thead",
- "title",
- "tr",
- "track",
- "ul"
+ "article",
+ "header",
+ "aside",
+ "hgroup",
+ "blockquote",
+ "hr",
+ "iframe",
+ "body",
+ "li",
+ "map",
+ "button",
+ "object",
+ "canvas",
+ "ol",
+ "caption",
+ "output",
+ "col",
+ "p",
+ "colgroup",
+ "pre",
+ "dd",
+ "progress",
+ "div",
+ "section",
+ "dl",
+ "table",
+ "td",
+ "dt",
+ "tbody",
+ "embed",
+ "textarea",
+ "fieldset",
+ "tfoot",
+ "figcaption",
+ "th",
+ "figure",
+ "thead",
+ "footer",
+ "tr",
+ "form",
+ "ul",
+ "h1",
+ "h2",
+ "h3",
+ "h4",
+ "h5",
+ "h6",
+ "video",
+ "script",
+ "style"
]
diff --git a/tools/eslint/node_modules/remark-parse/lib/decode.js b/tools/eslint/node_modules/remark-parse/lib/decode.js
deleted file mode 100644
index 75116385ee..0000000000
--- a/tools/eslint/node_modules/remark-parse/lib/decode.js
+++ /dev/null
@@ -1,71 +0,0 @@
-/**
- * @author Titus Wormer
- * @copyright 2015 Titus Wormer
- * @license MIT
- * @module remark:parse:decode
- * @fileoverview Decode entities.
- */
-
-'use strict';
-
-var entities = require('parse-entities');
-
-module.exports = factory;
-
-/* Factory to create an entity decoder. */
-function factory(ctx) {
- decoder.raw = decodeRaw;
-
- return decoder;
-
- /* Normalize `position` to add an `indent`. */
- function normalize(position) {
- var offsets = ctx.offset;
- var line = position.line;
- var result = [];
-
- while (++line) {
- if (!(line in offsets)) {
- break;
- }
-
- result.push((offsets[line] || 0) + 1);
- }
-
- return {
- start: position,
- indent: result
- };
- }
-
- /* Handle a warning.
- * See https://github.com/wooorm/parse-entities
- * for the warnings. */
- function handleWarning(reason, position, code) {
- if (code === 3) {
- return;
- }
-
- ctx.file.message(reason, position);
- }
-
- /* Decode `value` (at `position`) into text-nodes. */
- function decoder(value, position, handler) {
- entities(value, {
- position: normalize(position),
- warning: handleWarning,
- text: handler,
- reference: handler,
- textContext: ctx,
- referenceContext: ctx
- });
- }
-
- /* Decode `value` (at `position`) into a string. */
- function decodeRaw(value, position) {
- return entities(value, {
- position: normalize(position),
- warning: handleWarning
- });
- }
-}
diff --git a/tools/eslint/node_modules/remark-parse/lib/defaults.js b/tools/eslint/node_modules/remark-parse/lib/defaults.js
index ccb3fabd48..79f26f2a34 100644
--- a/tools/eslint/node_modules/remark-parse/lib/defaults.js
+++ b/tools/eslint/node_modules/remark-parse/lib/defaults.js
@@ -1,6 +1,6 @@
/**
* @author Titus Wormer
- * @copyright 2015 Titus Wormer
+ * @copyright 2015-2016 Titus Wormer
* @license MIT
* @module remark:parse:defaults
* @fileoverview Default options for `parse`.
@@ -8,14 +8,14 @@
'use strict';
-/* Expose. */
+/* eslint-env commonjs */
+
module.exports = {
- position: true,
- gfm: true,
- yaml: true,
- commonmark: false,
- footnotes: false,
- pedantic: false,
- blocks: require('./block-elements'),
- breaks: false
+ 'position': true,
+ 'gfm': true,
+ 'yaml': true,
+ 'commonmark': false,
+ 'footnotes': false,
+ 'pedantic': false,
+ 'breaks': false
};
diff --git a/tools/eslint/node_modules/remark-parse/lib/escapes.json b/tools/eslint/node_modules/remark-parse/lib/escapes.json
new file mode 100644
index 0000000000..f74e70cfda
--- /dev/null
+++ b/tools/eslint/node_modules/remark-parse/lib/escapes.json
@@ -0,0 +1,75 @@
+{
+ "default": [
+ "\\",
+ "`",
+ "*",
+ "{",
+ "}",
+ "[",
+ "]",
+ "(",
+ ")",
+ "#",
+ "+",
+ "-",
+ ".",
+ "!",
+ "_",
+ ">"
+ ],
+ "gfm": [
+ "\\",
+ "`",
+ "*",
+ "{",
+ "}",
+ "[",
+ "]",
+ "(",
+ ")",
+ "#",
+ "+",
+ "-",
+ ".",
+ "!",
+ "_",
+ ">",
+ "~",
+ "|"
+ ],
+ "commonmark": [
+ "\\",
+ "`",
+ "*",
+ "{",
+ "}",
+ "[",
+ "]",
+ "(",
+ ")",
+ "#",
+ "+",
+ "-",
+ ".",
+ "!",
+ "_",
+ ">",
+ "~",
+ "|",
+ "\n",
+ "\"",
+ "$",
+ "%",
+ "&",
+ "'",
+ ",",
+ "/",
+ ":",
+ ";",
+ "<",
+ "=",
+ "?",
+ "@",
+ "^"
+ ]
+}
diff --git a/tools/eslint/node_modules/remark-parse/lib/locate/break.js b/tools/eslint/node_modules/remark-parse/lib/locate/break.js
deleted file mode 100644
index b5550e1007..0000000000
--- a/tools/eslint/node_modules/remark-parse/lib/locate/break.js
+++ /dev/null
@@ -1,25 +0,0 @@
-/**
- * @author Titus Wormer
- * @copyright 2015 Titus Wormer
- * @license MIT
- * @module remark:parse:locate:break
- * @fileoverview Locate a break.
- */
-
-'use strict';
-
-module.exports = locate;
-
-function locate(value, fromIndex) {
- var index = value.indexOf('\n', fromIndex);
-
- while (index > fromIndex) {
- if (value.charAt(index - 1) !== ' ') {
- break;
- }
-
- index--;
- }
-
- return index;
-}
diff --git a/tools/eslint/node_modules/remark-parse/lib/locate/code-inline.js b/tools/eslint/node_modules/remark-parse/lib/locate/code-inline.js
deleted file mode 100644
index 010e74dcec..0000000000
--- a/tools/eslint/node_modules/remark-parse/lib/locate/code-inline.js
+++ /dev/null
@@ -1,15 +0,0 @@
-/**
- * @author Titus Wormer
- * @copyright 2015 Titus Wormer
- * @license MIT
- * @module remark:parse:locate:code-inline
- * @fileoverview Locate inline code.
- */
-
-'use strict';
-
-module.exports = locate;
-
-function locate(value, fromIndex) {
- return value.indexOf('`', fromIndex);
-}
diff --git a/tools/eslint/node_modules/remark-parse/lib/locate/delete.js b/tools/eslint/node_modules/remark-parse/lib/locate/delete.js
deleted file mode 100644
index 1a892e1be7..0000000000
--- a/tools/eslint/node_modules/remark-parse/lib/locate/delete.js
+++ /dev/null
@@ -1,15 +0,0 @@
-/**
- * @author Titus Wormer
- * @copyright 2015 Titus Wormer
- * @license MIT
- * @module remark:parse:locate:delete
- * @fileoverview Locate strikethrough.
- */
-
-'use strict';
-
-module.exports = locate;
-
-function locate(value, fromIndex) {
- return value.indexOf('~~', fromIndex);
-}
diff --git a/tools/eslint/node_modules/remark-parse/lib/locate/emphasis.js b/tools/eslint/node_modules/remark-parse/lib/locate/emphasis.js
deleted file mode 100644
index 270daad0f9..0000000000
--- a/tools/eslint/node_modules/remark-parse/lib/locate/emphasis.js
+++ /dev/null
@@ -1,26 +0,0 @@
-/**
- * @author Titus Wormer
- * @copyright 2015 Titus Wormer
- * @license MIT
- * @module remark:parse:locate:emphasis
- * @fileoverview Locate italics / emphasis.
- */
-
-'use strict';
-
-module.exports = locate;
-
-function locate(value, fromIndex) {
- var asterisk = value.indexOf('*', fromIndex);
- var underscore = value.indexOf('_', fromIndex);
-
- if (underscore === -1) {
- return asterisk;
- }
-
- if (asterisk === -1) {
- return underscore;
- }
-
- return underscore < asterisk ? underscore : asterisk;
-}
diff --git a/tools/eslint/node_modules/remark-parse/lib/locate/escape.js b/tools/eslint/node_modules/remark-parse/lib/locate/escape.js
deleted file mode 100644
index 45f9b449a7..0000000000
--- a/tools/eslint/node_modules/remark-parse/lib/locate/escape.js
+++ /dev/null
@@ -1,15 +0,0 @@
-/**
- * @author Titus Wormer
- * @copyright 2015 Titus Wormer
- * @license MIT
- * @module remark:parse:locate:escape
- * @fileoverview Locate an escape.
- */
-
-'use strict';
-
-module.exports = locate;
-
-function locate(value, fromIndex) {
- return value.indexOf('\\', fromIndex);
-}
diff --git a/tools/eslint/node_modules/remark-parse/lib/locate/link.js b/tools/eslint/node_modules/remark-parse/lib/locate/link.js
deleted file mode 100644
index dab2a3c54f..0000000000
--- a/tools/eslint/node_modules/remark-parse/lib/locate/link.js
+++ /dev/null
@@ -1,24 +0,0 @@
-/**
- * @author Titus Wormer
- * @copyright 2015 Titus Wormer
- * @license MIT
- * @module remark:parse:locate:link
- * @fileoverview Locate a link.
- */
-
-'use strict';
-
-module.exports = locate;
-
-function locate(value, fromIndex) {
- var link = value.indexOf('[', fromIndex);
- var image = value.indexOf('![', fromIndex);
-
- if (image === -1) {
- return link;
- }
-
- /* Link can never be `-1` if an image is found, so we don’t need
- * to check for that :) */
- return link < image ? link : image;
-}
diff --git a/tools/eslint/node_modules/remark-parse/lib/locate/strong.js b/tools/eslint/node_modules/remark-parse/lib/locate/strong.js
deleted file mode 100644
index 717259f36e..0000000000
--- a/tools/eslint/node_modules/remark-parse/lib/locate/strong.js
+++ /dev/null
@@ -1,26 +0,0 @@
-/**
- * @author Titus Wormer
- * @copyright 2015 Titus Wormer
- * @license MIT
- * @module remark:parse:locate:strong
- * @fileoverview Locate bold / strong / importance.
- */
-
-'use strict';
-
-module.exports = locate;
-
-function locate(value, fromIndex) {
- var asterisk = value.indexOf('**', fromIndex);
- var underscore = value.indexOf('__', fromIndex);
-
- if (underscore === -1) {
- return asterisk;
- }
-
- if (asterisk === -1) {
- return underscore;
- }
-
- return underscore < asterisk ? underscore : asterisk;
-}
diff --git a/tools/eslint/node_modules/remark-parse/lib/locate/tag.js b/tools/eslint/node_modules/remark-parse/lib/locate/tag.js
deleted file mode 100644
index 56e2d49e56..0000000000
--- a/tools/eslint/node_modules/remark-parse/lib/locate/tag.js
+++ /dev/null
@@ -1,15 +0,0 @@
-/**
- * @author Titus Wormer
- * @copyright 2015 Titus Wormer
- * @license MIT
- * @module remark:parse:locate:tag
- * @fileoverview Locate a tag.
- */
-
-'use strict';
-
-module.exports = locate;
-
-function locate(value, fromIndex) {
- return value.indexOf('<', fromIndex);
-}
diff --git a/tools/eslint/node_modules/remark-parse/lib/locate/url.js b/tools/eslint/node_modules/remark-parse/lib/locate/url.js
deleted file mode 100644
index 53b239241c..0000000000
--- a/tools/eslint/node_modules/remark-parse/lib/locate/url.js
+++ /dev/null
@@ -1,34 +0,0 @@
-/**
- * @author Titus Wormer
- * @copyright 2015 Titus Wormer
- * @license MIT
- * @module remark:parse:locate:url
- * @fileoverview Locate a URL.
- */
-
-'use strict';
-
-module.exports = locate;
-
-var PROTOCOLS = ['https://', 'http://', 'mailto:'];
-
-function locate(value, fromIndex) {
- var length = PROTOCOLS.length;
- var index = -1;
- var min = -1;
- var position;
-
- if (!this.options.gfm) {
- return -1;
- }
-
- while (++index < length) {
- position = value.indexOf(PROTOCOLS[index], fromIndex);
-
- if (position !== -1 && (position < min || min === -1)) {
- min = position;
- }
- }
-
- return min;
-}
diff --git a/tools/eslint/node_modules/remark-parse/lib/parse.js b/tools/eslint/node_modules/remark-parse/lib/parse.js
deleted file mode 100644
index 53a50b181e..0000000000
--- a/tools/eslint/node_modules/remark-parse/lib/parse.js
+++ /dev/null
@@ -1,53 +0,0 @@
-/**
- * @author Titus Wormer
- * @copyright 2015 Titus Wormer
- * @license MIT
- * @module remark:parse:parse
- * @fileoverview Parse the document
- */
-
-'use strict';
-
-var xtend = require('xtend');
-var removePosition = require('unist-util-remove-position');
-
-module.exports = parse;
-
-var C_NEWLINE = '\n';
-var EXPRESSION_LINE_BREAKS = /\r\n|\r/g;
-
-/* Parse the bound file. */
-function parse() {
- var self = this;
- var value = String(self.file);
- var start = {line: 1, column: 1, offset: 0};
- var content = xtend(start);
- var node;
-
- /* Clean non-unix newlines: `\r\n` and `\r` are all
- * changed to `\n`. This should not affect positional
- * information. */
- value = value.replace(EXPRESSION_LINE_BREAKS, C_NEWLINE);
-
- if (value.charCodeAt(0) === 0xFEFF) {
- value = value.slice(1);
-
- content.column++;
- content.offset++;
- }
-
- node = {
- type: 'root',
- children: self.tokenizeBlock(value, content),
- position: {
- start: start,
- end: self.eof || xtend(start)
- }
- };
-
- if (!self.options.position) {
- removePosition(node, true);
- }
-
- return node;
-}
diff --git a/tools/eslint/node_modules/remark-parse/lib/parser.js b/tools/eslint/node_modules/remark-parse/lib/parser.js
index 8fe982b661..f55f41c95e 100644
--- a/tools/eslint/node_modules/remark-parse/lib/parser.js
+++ b/tools/eslint/node_modules/remark-parse/lib/parser.js
@@ -1,162 +1,6318 @@
/**
* @author Titus Wormer
- * @copyright 2015 Titus Wormer
+ * @copyright 2015-2016 Titus Wormer
* @license MIT
- * @module remark:parse
+ * @module remark:parser
* @fileoverview Markdown parser.
*/
'use strict';
-var xtend = require('xtend');
-var toggle = require('state-toggle');
+/* eslint-env commonjs */
+
+/*
+ * Dependencies.
+ */
+
+var decode = require('parse-entities');
+var repeat = require('repeat-string');
+var trim = require('trim');
+var trimTrailingLines = require('trim-trailing-lines');
+var extend = require('extend');
var vfileLocation = require('vfile-location');
-var unescape = require('./unescape');
-var decode = require('./decode');
-var tokenizer = require('./tokenizer');
+var removePosition = require('unist-util-remove-position');
+var collapseWhiteSpace = require('collapse-white-space');
+var defaultOptions = require('./defaults.js');
+var escapes = require('./escapes.json');
+var blockElements = require('./block-elements.json');
-module.exports = Parser;
+/*
+ * Methods.
+ */
+
+var has = {}.hasOwnProperty;
+
+/*
+ * Numeric constants.
+ */
+
+var SPACE_SIZE = 1;
+var TAB_SIZE = 4;
+var CODE_INDENT_LENGTH = 4;
+var MIN_FENCE_COUNT = 3;
+var MAX_ATX_COUNT = 6;
+var MAX_LINE_HEADING_INDENT = 3;
+var THEMATIC_BREAK_MARKER_COUNT = 3;
+var MIN_CLOSING_HTML_NEWLINE_COUNT = 2;
+var MIN_BREAK_LENGTH = 2;
+var MIN_TABLE_COLUMNS = 2;
+var MIN_TABLE_ROWS = 2;
+
+/*
+ * Error messages.
+ */
+
+var ERR_INFINITE_LOOP = 'Infinite loop';
+var ERR_MISSING_LOCATOR = 'Missing locator: ';
+var ERR_INCORRECTLY_EATEN = 'Incorrectly eaten value: please report this ' +
+ 'warning on http://git.io/vg5Ft';
+
+/*
+ * Expressions.
+ */
+
+var EXPRESSION_BULLET = /^([ \t]*)([*+-]|\d+[.)])( {1,4}(?! )| |\t|$|(?=\n))([^\n]*)/;
+var EXPRESSION_PEDANTIC_BULLET = /^([ \t]*)([*+-]|\d+[.)])([ \t]+)/;
+var EXPRESSION_INITIAL_INDENT = /^( {1,4}|\t)?/gm;
+var EXPRESSION_INITIAL_TAB = /^( {4}|\t)?/gm;
+var EXPRESSION_HTML_LINK_OPEN = /^<a /i;
+var EXPRESSION_HTML_LINK_CLOSE = /^<\/a>/i;
+var EXPRESSION_LOOSE_LIST_ITEM = /\n\n(?!\s*$)/;
+var EXPRESSION_TASK_ITEM = /^\[([\ \t]|x|X)\][\ \t]/;
+var EXPRESSION_LINE_BREAKS = /\r\n|\r/g;
+
+/*
+ * Characters.
+ */
+
+var C_BACKSLASH = '\\';
+var C_UNDERSCORE = '_';
+var C_ASTERISK = '*';
+var C_TICK = '`';
+var C_AT_SIGN = '@';
+var C_HASH = '#';
+var C_PLUS = '+';
+var C_DASH = '-';
+var C_DOT = '.';
+var C_PIPE = '|';
+var C_DOUBLE_QUOTE = '"';
+var C_SINGLE_QUOTE = '\'';
+var C_COMMA = ',';
+var C_SLASH = '/';
+var C_COLON = ':';
+var C_SEMI_COLON = ';';
+var C_QUESTION_MARK = '?';
+var C_CARET = '^';
+var C_EQUALS = '=';
+var C_EXCLAMATION_MARK = '!';
+var C_TILDE = '~';
+var C_LT = '<';
+var C_GT = '>';
+var C_BRACKET_OPEN = '[';
+var C_BRACKET_CLOSE = ']';
+var C_PAREN_OPEN = '(';
+var C_PAREN_CLOSE = ')';
+var C_SPACE = ' ';
+var C_FORM_FEED = '\f';
+var C_NEWLINE = '\n';
+var C_CARRIAGE_RETURN = '\r';
+var C_TAB = '\t';
+var C_VERTICAL_TAB = '\v';
+var C_NO_BREAK_SPACE = '\u00a0';
+var C_OGHAM_SPACE = '\u1680';
+var C_MONGOLIAN_VOWEL_SEPARATOR = '\u180e';
+var C_EN_QUAD = '\u2000';
+var C_EM_QUAD = '\u2001';
+var C_EN_SPACE = '\u2002';
+var C_EM_SPACE = '\u2003';
+var C_THREE_PER_EM_SPACE = '\u2004';
+var C_FOUR_PER_EM_SPACE = '\u2005';
+var C_SIX_PER_EM_SPACE = '\u2006';
+var C_FIGURE_SPACE = '\u2007';
+var C_PUNCTUATION_SPACE = '\u2008';
+var C_THIN_SPACE = '\u2009';
+var C_HAIR_SPACE = '\u200a';
+var C_LINE_SEPARATOR = '​\u2028';
+var C_PARAGRAPH_SEPARATOR = '​\u2029';
+var C_NARROW_NO_BREAK_SPACE = '\u202f';
+var C_IDEOGRAPHIC_SPACE = '\u3000';
+var C_ZERO_WIDTH_NO_BREAK_SPACE = '\ufeff';
+var C_X_LOWER = 'x';
+
+/*
+ * Character codes.
+ */
+
+var CC_A_LOWER = 'a'.charCodeAt(0);
+var CC_A_UPPER = 'A'.charCodeAt(0);
+var CC_Z_LOWER = 'z'.charCodeAt(0);
+var CC_Z_UPPER = 'Z'.charCodeAt(0);
+var CC_0 = '0'.charCodeAt(0);
+var CC_9 = '9'.charCodeAt(0);
+
+/*
+ * Protocols.
+ */
+
+var HTTP_PROTOCOL = 'http://';
+var HTTPS_PROTOCOL = 'https://';
+var MAILTO_PROTOCOL = 'mailto:';
-/* Construct a new parser. */
-function Parser(doc, file) {
- this.file = file;
- this.offset = {};
- this.options = xtend(this.options);
- this.setOptions({});
-
- this.inList = false;
- this.inBlock = false;
- this.inLink = false;
- this.atStart = true;
-
- this.toOffset = vfileLocation(file).toOffset;
- this.unescape = unescape(this, 'escape');
- this.decode = decode(this);
-}
-
-/* Prototype. */
-var proto = Parser.prototype;
-
-/* Expose core. */
-proto.setOptions = require('./set-options');
-proto.parse = require('./parse');
-
-/* Expose `defaults`. */
-proto.options = require('./defaults');
-
-/* Enter and exit helpers. */
-proto.exitStart = toggle('atStart', true);
-proto.enterList = toggle('inList', false);
-proto.enterLink = toggle('inLink', false);
-proto.enterBlock = toggle('inBlock', false);
-
-/* Nodes that can interupt a paragraph:
- *
- * ```markdown
- * A paragraph, followed by a thematic break.
- * ___
- * ```
- *
- * In the above example, the thematic break “interupts”
- * the paragraph. */
-proto.interruptParagraph = [
- ['thematicBreak'],
- ['atxHeading'],
- ['fencedCode'],
- ['blockquote'],
- ['html'],
- ['setextHeading', {commonmark: false}],
- ['definition', {commonmark: false}],
- ['footnote', {commonmark: false}]
+var PROTOCOLS = [
+ HTTP_PROTOCOL,
+ HTTPS_PROTOCOL,
+ MAILTO_PROTOCOL
];
-/* Nodes that can interupt a list:
+var PROTOCOLS_LENGTH = PROTOCOLS.length;
+
+/*
+ * Textual constants.
+ */
+
+var YAML_FENCE = repeat(C_DASH, 3);
+var CODE_INDENT = repeat(C_SPACE, CODE_INDENT_LENGTH);
+var EMPTY = '';
+var BLOCK = 'block';
+var INLINE = 'inline';
+var COMMENT_START = '<!--';
+var COMMENT_END = '-->';
+var CDATA_START = '<![CDATA[';
+var CDATA_END = ']]>';
+var COMMENT_END_CHAR = COMMENT_END.charAt(0);
+var CDATA_END_CHAR = CDATA_END.charAt(0);
+var COMMENT_START_LENGTH = COMMENT_START.length;
+var COMMENT_END_LENGTH = COMMENT_END.length;
+var CDATA_START_LENGTH = CDATA_START.length;
+var CDATA_END_LENGTH = CDATA_END.length;
+
+/*
+ * Node types.
+ */
+
+var T_THEMATIC_BREAK = 'thematicBreak';
+var T_HTML = 'html';
+var T_YAML = 'yaml';
+var T_TABLE = 'table';
+var T_TABLE_CELL = 'tableCell';
+var T_TABLE_HEADER = 'tableRow';
+var T_TABLE_ROW = 'tableRow';
+var T_PARAGRAPH = 'paragraph';
+var T_TEXT = 'text';
+var T_CODE = 'code';
+var T_LIST = 'list';
+var T_LIST_ITEM = 'listItem';
+var T_DEFINITION = 'definition';
+var T_FOOTNOTE_DEFINITION = 'footnoteDefinition';
+var T_HEADING = 'heading';
+var T_BLOCKQUOTE = 'blockquote';
+var T_LINK = 'link';
+var T_IMAGE = 'image';
+var T_FOOTNOTE = 'footnote';
+var T_STRONG = 'strong';
+var T_EMPHASIS = 'emphasis';
+var T_DELETE = 'delete';
+var T_INLINE_CODE = 'inlineCode';
+var T_BREAK = 'break';
+var T_ROOT = 'root';
+
+/*
+ * Available table alignments.
+ */
+
+var TABLE_ALIGN_LEFT = 'left';
+var TABLE_ALIGN_CENTER = 'center';
+var TABLE_ALIGN_RIGHT = 'right';
+var TABLE_ALIGN_NONE = null;
+
+/*
+ * Available reference types.
+ */
+
+var REFERENCE_TYPE_SHORTCUT = 'shortcut';
+var REFERENCE_TYPE_COLLAPSED = 'collapsed';
+var REFERENCE_TYPE_FULL = 'full';
+
+/*
+ * A map of characters, and their column length,
+ * which can be used as indentation.
+ */
+
+var INDENTATION_CHARACTERS = {};
+
+INDENTATION_CHARACTERS[C_SPACE] = SPACE_SIZE;
+INDENTATION_CHARACTERS[C_TAB] = TAB_SIZE;
+
+/*
+ * A map of characters, which can be used to mark emphasis.
+ */
+
+var EMPHASIS_MARKERS = {};
+
+EMPHASIS_MARKERS[C_ASTERISK] = true;
+EMPHASIS_MARKERS[C_UNDERSCORE] = true;
+
+/*
+ * A map of characters, which can be used to mark rules.
+ */
+
+var RULE_MARKERS = {};
+
+RULE_MARKERS[C_ASTERISK] = true;
+RULE_MARKERS[C_UNDERSCORE] = true;
+RULE_MARKERS[C_DASH] = true;
+
+/*
+ * A map of characters which can be used to mark
+ * list-items.
+ */
+
+var LIST_UNORDERED_MARKERS = {};
+
+LIST_UNORDERED_MARKERS[C_ASTERISK] = true;
+LIST_UNORDERED_MARKERS[C_PLUS] = true;
+LIST_UNORDERED_MARKERS[C_DASH] = true;
+
+/*
+ * A map of characters which can be used to mark
+ * list-items after a digit.
+ */
+
+var LIST_ORDERED_MARKERS = {};
+
+LIST_ORDERED_MARKERS[C_DOT] = true;
+
+/*
+ * A map of characters which can be used to mark
+ * list-items after a digit.
+ */
+
+var LIST_ORDERED_COMMONMARK_MARKERS = {};
+
+LIST_ORDERED_COMMONMARK_MARKERS[C_DOT] = true;
+LIST_ORDERED_COMMONMARK_MARKERS[C_PAREN_CLOSE] = true;
+
+/*
+ * A 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;
+
+/*
+ * A 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;
+
+/*
+ * A map of characters which can be used to mark setext
+ * headers, mapping to their corresponding depth.
+ */
+
+var SETEXT_MARKERS = {};
+
+SETEXT_MARKERS[C_EQUALS] = 1;
+SETEXT_MARKERS[C_DASH] = 2;
+
+/*
+ * A map of two functions which can create list items.
+ */
+
+var LIST_ITEM_MAP = {};
+
+LIST_ITEM_MAP.true = renderPedanticListItem;
+LIST_ITEM_MAP.false = renderNormalListItem;
+
+/**
+ * Check whether `character` is alphabetic.
*
- * ```markdown
- * - One
- * ___
- * ```
+ * @param {string} character - Single character to check.
+ * @return {boolean} - Whether `character` is alphabetic.
+ */
+function isAlphabetic(character) {
+ var code = character.charCodeAt(0);
+
+ return (code >= CC_A_LOWER && code <= CC_Z_LOWER) ||
+ (code >= CC_A_UPPER && code <= CC_Z_UPPER);
+}
+
+/**
+ * Check whether `character` is numeric.
*
- * In the above example, the thematic break “interupts”
- * the list. */
-proto.interruptList = [
- ['fencedCode', {pedantic: false}],
- ['thematicBreak', {pedantic: false}],
- ['definition', {commonmark: false}],
- ['footnote', {commonmark: false}]
-];
+ * @param {string} character - Single character to check.
+ * @return {boolean} - Whether `character` is numeric.
+ */
+function isNumeric(character) {
+ var code = character.charCodeAt(0);
-/* Nodes that can interupt a blockquote:
- *
- * ```markdown
- * > A paragraph.
- * ___
- * ```
- *
- * In the above example, the thematic break “interupts”
- * the blockquote. */
-proto.interruptBlockquote = [
- ['indentedCode', {commonmark: true}],
- ['fencedCode', {commonmark: true}],
- ['atxHeading', {commonmark: true}],
- ['setextHeading', {commonmark: true}],
- ['thematicBreak', {commonmark: true}],
- ['html', {commonmark: true}],
- ['list', {commonmark: true}],
- ['definition', {commonmark: false}],
- ['footnote', {commonmark: false}]
-];
+ return code >= CC_0 && code <= CC_9;
+}
+
+/**
+ * Check whether `character` is a word character.
+ *
+ * @param {string} character - Single character to check.
+ * @return {boolean} - Whether `character` is a word
+ * character.
+ */
+function isWordCharacter(character) {
+ return character === C_UNDERSCORE ||
+ isAlphabetic(character) ||
+ isNumeric(character);
+}
+
+/**
+ * Check whether `character` is white-space.
+ *
+ * @param {string} character - Single character to check.
+ * @return {boolean} - Whether `character` is white-space.
+ */
+function isWhiteSpace(character) {
+ return character === C_SPACE ||
+ character === C_FORM_FEED ||
+ character === C_NEWLINE ||
+ character === C_CARRIAGE_RETURN ||
+ character === C_TAB ||
+ character === C_VERTICAL_TAB ||
+ character === C_NO_BREAK_SPACE ||
+ character === C_OGHAM_SPACE ||
+ character === C_MONGOLIAN_VOWEL_SEPARATOR ||
+ character === C_EN_QUAD ||
+ character === C_EM_QUAD ||
+ character === C_EN_SPACE ||
+ character === C_EM_SPACE ||
+ character === C_THREE_PER_EM_SPACE ||
+ character === C_FOUR_PER_EM_SPACE ||
+ character === C_SIX_PER_EM_SPACE ||
+ character === C_FIGURE_SPACE ||
+ character === C_PUNCTUATION_SPACE ||
+ character === C_THIN_SPACE ||
+ character === C_HAIR_SPACE ||
+ character === C_LINE_SEPARATOR ||
+ character === C_PARAGRAPH_SEPARATOR ||
+ character === C_NARROW_NO_BREAK_SPACE ||
+ character === C_IDEOGRAPHIC_SPACE ||
+ character === C_ZERO_WIDTH_NO_BREAK_SPACE;
+}
+
+/**
+ * Check whether `character` can be inside an unquoted
+ * attribute value.
+ *
+ * @param {string} character - Single character to check.
+ * @return {boolean} - Whether `character` can be inside
+ * an unquoted attribute value.
+ */
+function isUnquotedAttributeCharacter(character) {
+ return character !== C_DOUBLE_QUOTE &&
+ character !== C_SINGLE_QUOTE &&
+ character !== C_EQUALS &&
+ character !== C_LT &&
+ character !== C_GT &&
+ character !== C_TICK;
+}
+
+/**
+ * Check whether `character` can be inside a double-quoted
+ * attribute value.
+ *
+ * @property {string} delimiter - Closing delimiter.
+ * @param {string} character - Single character to check.
+ * @return {boolean} - Whether `character` can be inside
+ * a double-quoted attribute value.
+ */
+function isDoubleQuotedAttributeCharacter(character) {
+ return character !== C_DOUBLE_QUOTE;
+}
+
+isDoubleQuotedAttributeCharacter.delimiter = C_DOUBLE_QUOTE;
+
+/**
+ * Check whether `character` can be inside a single-quoted
+ * attribute value.
+ *
+ * @property {string} delimiter - Closing delimiter.
+ * @param {string} character - Single character to check.
+ * @return {boolean} - Whether `character` can be inside
+ * a single-quoted attribute value.
+ */
+function isSingleQuotedAttributeCharacter(character) {
+ return character !== C_SINGLE_QUOTE;
+}
+
+isSingleQuotedAttributeCharacter.delimiter = C_SINGLE_QUOTE;
+
+/**
+ * Check whether `character` can be inside an enclosed
+ * URI.
+ *
+ * @property {string} delimiter - Closing delimiter.
+ * @param {string} character - Character to test.
+ * @return {boolean} - Whether `character` can be inside
+ * an enclosed URI.
+ */
+function isEnclosedURLCharacter(character) {
+ return character !== C_GT &&
+ character !== C_BRACKET_OPEN &&
+ character !== C_BRACKET_CLOSE;
+}
+
+isEnclosedURLCharacter.delimiter = C_GT;
+
+/**
+ * Check whether `character` can be inside an unclosed
+ * URI.
+ *
+ * @param {string} character - Character to test.
+ * @return {boolean} - Whether `character` can be inside
+ * an unclosed URI.
+ */
+function isUnclosedURLCharacter(character) {
+ return character !== C_BRACKET_OPEN &&
+ character !== C_BRACKET_CLOSE &&
+ !isWhiteSpace(character);
+}
+
+/**
+ * Normalize an identifier. Collapses multiple white space
+ * characters into a single space, and removes casing.
+ *
+ * @example
+ * normalizeIdentifier('FOO\t bar'); // 'foo bar'
+ *
+ * @param {string} value - Content to normalize.
+ * @return {string} - Normalized content.
+ */
+function normalize(value) {
+ return collapseWhiteSpace(value).toLowerCase();
+}
+
+/**
+ * Construct a state `toggler`: a function which inverses
+ * `property` in context based on its current value.
+ * The by `toggler` returned function restores that value.
+ *
+ * @example
+ * var context = {};
+ * var key = 'foo';
+ * var val = true;
+ * context[key] = val;
+ * context.enter = toggle(key, val);
+ * context[key]; // true
+ * var exit = context.enter();
+ * context[key]; // false
+ * var nested = context.enter();
+ * context[key]; // false
+ * nested();
+ * context[key]; // false
+ * exit();
+ * context[key]; // true
+ *
+ * @param {string} key - Property to toggle.
+ * @param {boolean} state - It's default state.
+ * @return {function(): function()} - Enter.
+ */
+function toggle(key, state) {
+ /**
+ * Construct a toggler for the bound `key`.
+ *
+ * @return {Function} - Exit state.
+ */
+ function enter() {
+ var self = this;
+ var current = self[key];
+
+ self[key] = !state;
+
+ /**
+ * State canceler, cancels the state, if allowed.
+ */
+ function exit() {
+ self[key] = current;
+ }
+
+ return exit;
+ }
+
+ return enter;
+}
+
+/*
+ * Define nodes of a type which can be merged.
+ */
+
+var MERGEABLE_NODES = {};
+
+/**
+ * Check whether a node is mergeable with adjacent nodes.
+ *
+ * @param {Object} node - Node to check.
+ * @return {boolean} - Whether `node` is mergable.
+ */
+function mergeable(node) {
+ var start;
+ var end;
+
+ if (node.type !== 'text' || !node.position) {
+ return true;
+ }
+
+ start = node.position.start;
+ end = node.position.end;
+
+ /*
+ * Only merge nodes which occupy the same size as their
+ * `value`.
+ */
+
+ return start.line !== end.line ||
+ end.column - start.column === node.value.length;
+}
+
+/**
+ * Merge two text nodes: `node` into `prev`.
+ *
+ * @param {Object} prev - Preceding sibling.
+ * @param {Object} node - Following sibling.
+ * @return {Object} - `prev`.
+ */
+MERGEABLE_NODES.text = function (prev, node) {
+ prev.value += node.value;
+
+ return prev;
+};
+
+/**
+ * Merge two blockquotes: `node` into `prev`, unless in
+ * CommonMark mode.
+ *
+ * @param {Object} prev - Preceding sibling.
+ * @param {Object} node - Following sibling.
+ * @return {Object} - `prev`, or `node` in CommonMark mode.
+ */
+MERGEABLE_NODES.blockquote = function (prev, node) {
+ if (this.options.commonmark) {
+ return node;
+ }
+
+ prev.children = prev.children.concat(node.children);
+
+ return prev;
+};
+
+/**
+ * Factory to create an entity decoder.
+ *
+ * @param {Object} context - Context to attach to, e.g.,
+ * a parser.
+ * @return {Function} - See `decode`.
+ */
+function decodeFactory(context) {
+ /**
+ * Normalize `position` to add an `indent`.
+ *
+ * @param {Position} position - Reference
+ * @return {Position} - Augmented with `indent`.
+ */
+ function normalize(position) {
+ return {
+ 'start': position,
+ 'indent': context.getIndent(position.line)
+ };
+ }
+
+ /**
+ * Handle a warning.
+ *
+ * @this {VFile} - Virtual file.
+ * @param {string} reason - Reason for warning.
+ * @param {Position} position - Place of warning.
+ * @param {number} code - Code for warning.
+ */
+ function handleWarning(reason, position, code) {
+ if (code === 3) {
+ return;
+ }
+
+ context.file.warn(reason, position);
+ }
+
+ /**
+ * Decode `value` (at `position`) into text-nodes.
+ *
+ * @param {string} value - Value to parse.
+ * @param {Position} position - Position to start parsing at.
+ * @param {Function} handler - Node handler.
+ */
+ function decoder(value, position, handler) {
+ decode(value, {
+ 'position': normalize(position),
+ 'warning': handleWarning,
+ 'text': handler,
+ 'reference': handler,
+ 'textContext': context,
+ 'referenceContext': context
+ });
+ }
+
+ /**
+ * Decode `value` (at `position`) into a string.
+ *
+ * @param {string} value - Value to parse.
+ * @param {Position} position - Position to start
+ * parsing at.
+ * @return {string} - Plain-text.
+ */
+ function decodeRaw(value, position) {
+ return decode(value, {
+ 'position': normalize(position),
+ 'warning': handleWarning
+ });
+ }
+
+ decoder.raw = decodeRaw;
+
+ return decoder;
+}
+
+/**
+ * Factory to de-escape a value, based on a list at `key`
+ * in `scope`.
+ *
+ * @example
+ * var scope = {escape: ['a']}
+ * var descape = descapeFactory(scope, 'escape');
+ *
+ * @param {Object} scope - List of escapable characters.
+ * @param {string} key - Key in `map` at which the list
+ * exists.
+ * @return {function(string): string} - Function which
+ * takes a value and returns its unescaped version.
+ */
+function descapeFactory(scope, key) {
+ /**
+ * De-escape a string using the expression at `key`
+ * in `scope`.
+ *
+ * @example
+ * var scope = {escape: ['a']}
+ * var descape = descapeFactory(scope, 'escape');
+ * descape('\a \b'); // 'a \b'
+ *
+ * @param {string} value - Escaped string.
+ * @return {string} - Unescaped string.
+ */
+ function descape(value) {
+ var prev = 0;
+ var index = value.indexOf(C_BACKSLASH);
+ var escape = scope[key];
+ var queue = [];
+ var character;
+
+ while (index !== -1) {
+ queue.push(value.slice(prev, index));
+ prev = index + 1;
+ character = value.charAt(prev);
+
+ /*
+ * If the following character is not a valid escape,
+ * add the slash.
+ */
+
+ if (!character || escape.indexOf(character) === -1) {
+ queue.push(C_BACKSLASH);
+ }
+
+ index = value.indexOf(C_BACKSLASH, prev);
+ }
+
+ queue.push(value.slice(prev));
+
+ return queue.join(EMPTY);
+ }
+
+ return descape;
+}
+
+/**
+ * Gets indentation information for a line.
+ *
+ * @example
+ * getIndent(' foo');
+ * // {indent: 2, stops: {1: 0, 2: 1}}
+ *
+ * getIndent('\tfoo');
+ * // {indent: 4, stops: {4: 0}}
+ *
+ * getIndent(' \tfoo');
+ * // {indent: 4, stops: {1: 0, 2: 1, 4: 2}}
+ *
+ * getIndent('\t foo')
+ * // {indent: 6, stops: {4: 0, 5: 1, 6: 2}}
+ *
+ * @param {string} value - Indented line.
+ * @return {Object} - Indetation information.
+ */
+function getIndent(value) {
+ var index = 0;
+ var indent = 0;
+ var character = value.charAt(index);
+ var stops = {};
+ var size;
+
+ while (character in INDENTATION_CHARACTERS) {
+ size = INDENTATION_CHARACTERS[character];
+
+ indent += size;
+
+ if (size > 1) {
+ indent = Math.floor(indent / size) * size;
+ }
+
+ stops[indent] = index;
+
+ character = value.charAt(++index);
+ }
+
+ return {
+ 'indent': indent,
+ 'stops': stops
+ };
+}
+
+/**
+ * Remove the minimum indent from every line in `value`.
+ * Supports both tab, spaced, and mixed indentation (as
+ * well as possible).
+ *
+ * @example
+ * removeIndentation(' foo'); // 'foo'
+ * removeIndentation(' foo', 2); // ' foo'
+ * removeIndentation('\tfoo', 2); // ' foo'
+ * removeIndentation(' foo\n bar'); // ' foo\n bar'
+ *
+ * @param {string} value - Value to trim.
+ * @param {number?} [maximum] - Maximum indentation
+ * to remove.
+ * @return {string} - Unindented `value`.
+ */
+function removeIndentation(value, maximum) {
+ var values = value.split(C_NEWLINE);
+ var position = values.length + 1;
+ var minIndent = Infinity;
+ var matrix = [];
+ var index;
+ var indentation;
+ var stops;
+ var padding;
+
+ values.unshift(repeat(C_SPACE, maximum) + C_EXCLAMATION_MARK);
+
+ while (position--) {
+ indentation = getIndent(values[position]);
+
+ matrix[position] = indentation.stops;
+
+ if (trim(values[position]).length === 0) {
+ continue;
+ }
+
+ if (indentation.indent) {
+ if (indentation.indent > 0 && indentation.indent < minIndent) {
+ minIndent = indentation.indent;
+ }
+ } else {
+ minIndent = Infinity;
+
+ break;
+ }
+ }
+
+ if (minIndent !== Infinity) {
+ position = values.length;
+
+ while (position--) {
+ stops = matrix[position];
+ index = minIndent;
+
+ while (index && !(index in stops)) {
+ index--;
+ }
+
+ if (
+ trim(values[position]).length !== 0 &&
+ minIndent &&
+ index !== minIndent
+ ) {
+ padding = C_TAB;
+ } else {
+ padding = EMPTY;
+ }
+
+ values[position] = padding + values[position].slice(
+ index in stops ? stops[index] + 1 : 0
+ );
+ }
+ }
+
+ values.shift();
+
+ return values.join(C_NEWLINE);
+}
+
+/**
+ * Tokenise a line.
+ *
+ * @example
+ * tokenizeNewline(eat, '\n\n');
+ *
+ * @param {function(string)} eat - Eater.
+ * @param {string} value - Rest of content.
+ * @param {boolean?} [silent] - Whether this is a dry run.
+ * @return {boolean?} - `true` when matching.
+ */
+function tokenizeNewline(eat, value, silent) {
+ var character = value.charAt(0);
+ var length;
+ var subvalue;
+ var queue;
+ var index;
+
+ if (character !== C_NEWLINE) {
+ return;
+ }
+
+ /* istanbul ignore if - never used (yet) */
+ if (silent) {
+ return true;
+ }
+
+ index = 1;
+ length = value.length;
+ subvalue = C_NEWLINE;
+ queue = EMPTY;
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (!isWhiteSpace(character)) {
+ break;
+ }
+
+ queue += character;
+
+ if (character === C_NEWLINE) {
+ subvalue += queue;
+ queue = EMPTY;
+ }
+
+ index++;
+ }
+
+ eat(subvalue);
+}
+
+/**
+ * Tokenise an indented code block.
+ *
+ * @example
+ * tokenizeIndentedCode(eat, '\tfoo');
+ *
+ * @param {function(string)} eat - Eater.
+ * @param {string} value - Rest of content.
+ * @param {boolean?} [silent] - Whether this is a dry run.
+ * @return {Node?|boolean} - `code` node.
+ */
+function tokenizeIndentedCode(eat, value, silent) {
+ var self = this;
+ var index = -1;
+ var length = value.length;
+ var character;
+ var subvalue = EMPTY;
+ var content = EMPTY;
+ var subvalueQueue = EMPTY;
+ var contentQueue = EMPTY;
+ var blankQueue;
+ var indent;
+
+ while (++index < length) {
+ character = value.charAt(index);
+
+ if (indent) {
+ indent = false;
+
+ subvalue += subvalueQueue;
+ content += contentQueue;
+ subvalueQueue = contentQueue = EMPTY;
+
+ if (character === C_NEWLINE) {
+ subvalueQueue = contentQueue = character;
+ } else {
+ subvalue += character;
+ content += character;
+
+ while (++index < length) {
+ character = value.charAt(index);
+
+ if (!character || character === C_NEWLINE) {
+ contentQueue = subvalueQueue = character;
+ break;
+ }
+
+ subvalue += character;
+ content += character;
+ }
+ }
+ } else if (
+ character === C_SPACE &&
+ value.charAt(index + 1) === C_SPACE &&
+ value.charAt(index + 2) === C_SPACE &&
+ value.charAt(index + 3) === C_SPACE
+ ) {
+ subvalueQueue += CODE_INDENT;
+ index += 3;
+ indent = true;
+ } else if (character === C_TAB) {
+ subvalueQueue += character;
+ indent = true;
+ } else {
+ blankQueue = EMPTY;
+
+ while (character === C_TAB || character === C_SPACE) {
+ blankQueue += character;
+ character = value.charAt(++index);
+ }
+
+ if (character !== C_NEWLINE) {
+ break;
+ }
+
+ subvalueQueue += blankQueue + character;
+ contentQueue += character;
+ }
+ }
+
+ if (content) {
+ if (silent) {
+ return true;
+ }
+
+ return eat(subvalue)(self.renderCodeBlock(content));
+ }
+}
+
+/**
+ * Tokenise a fenced code block.
+ *
+ * @example
+ * tokenizeFencedCode(eat, '```js\nfoo()\n```');
+ *
+ * @param {function(string)} eat - Eater.
+ * @param {string} value - Rest of content.
+ * @param {boolean?} [silent] - Whether this is a dry run.
+ * @return {Node?|boolean} - `code` node.
+ */
+function tokenizeFencedCode(eat, value, silent) {
+ var self = this;
+ var settings = self.options;
+ var length = value.length + 1;
+ var index = 0;
+ var subvalue = EMPTY;
+ var fenceCount;
+ var marker;
+ var character;
+ var flag;
+ var queue;
+ var content;
+ var exdentedContent;
+ var closing;
+ var exdentedClosing;
+ var indent;
+ var now;
+
+ if (!settings.gfm) {
+ return;
+ }
+
+ /*
+ * Eat initial spacing.
+ */
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (character !== C_SPACE && character !== C_TAB) {
+ break;
+ }
+
+ subvalue += character;
+ index++;
+ }
+
+ indent = index; // TODO: CHECK.
+
+ /*
+ * Eat the fence.
+ */
+
+ character = value.charAt(index);
+
+ if (character !== C_TILDE && character !== C_TICK) {
+ return;
+ }
+
+ index++;
+ marker = character;
+ fenceCount = 1;
+ subvalue += character;
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (character !== marker) {
+ break;
+ }
+
+ subvalue += character;
+ fenceCount++;
+ index++;
+ }
+
+ if (fenceCount < MIN_FENCE_COUNT) {
+ return;
+ }
+
+ /*
+ * Eat spacing before flag.
+ */
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (character !== C_SPACE && character !== C_TAB) {
+ break;
+ }
+
+ subvalue += character;
+ index++;
+ }
+
+ /*
+ * Eat flag.
+ */
+
+ flag = queue = EMPTY;
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (
+ character === C_NEWLINE ||
+ character === C_TILDE ||
+ character === C_TICK
+ ) {
+ break;
+ }
+
+ if (character === C_SPACE || character === C_TAB) {
+ queue += character;
+ } else {
+ flag += queue + character;
+ queue = EMPTY;
+ }
+
+ index++;
+ }
+
+ character = value.charAt(index);
+
+ if (character && character !== C_NEWLINE) {
+ return;
+ }
+
+ if (silent) {
+ return true;
+ }
+
+ now = eat.now();
+ now.column += subvalue.length;
+ now.offset += subvalue.length;
+
+ subvalue += flag;
+ flag = self.decode.raw(self.descape(flag), now);
+
+ if (queue) {
+ subvalue += queue;
+ }
+
+ queue = closing = exdentedClosing = content = exdentedContent = EMPTY;
+
+ /*
+ * Eat content.
+ */
+
+ while (index < length) {
+ character = value.charAt(index);
+ content += closing;
+ exdentedContent += exdentedClosing;
+ closing = exdentedClosing = EMPTY;
+
+ if (character !== C_NEWLINE) {
+ content += character;
+ exdentedClosing += character;
+ index++;
+ continue;
+ }
+
+ /*
+ * Add the newline to `subvalue` if its the first
+ * character. Otherwise, add it to the `closing`
+ * queue.
+ */
+
+ if (!content) {
+ subvalue += character;
+ } else {
+ closing += character;
+ exdentedClosing += character;
+ }
+
+ queue = EMPTY;
+ index++;
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (character !== C_SPACE) {
+ break;
+ }
+
+ queue += character;
+ index++;
+ }
+
+ closing += queue;
+ exdentedClosing += queue.slice(indent);
+
+ if (queue.length >= CODE_INDENT_LENGTH) {
+ continue;
+ }
+
+ queue = EMPTY;
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (character !== marker) {
+ break;
+ }
+
+ queue += character;
+ index++;
+ }
+
+ closing += queue;
+ exdentedClosing += queue;
+
+ if (queue.length < fenceCount) {
+ continue;
+ }
+
+ queue = EMPTY;
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (character !== C_SPACE && character !== C_TAB) {
+ break;
+ }
+
+ closing += character;
+ exdentedClosing += character;
+ index++;
+ }
+
+ if (!character || character === C_NEWLINE) {
+ break;
+ }
+ }
+
+ subvalue += content + closing;
+
+ return eat(subvalue)(self.renderCodeBlock(exdentedContent, flag));
+}
+
+/**
+ * Tokenise an ATX-style heading.
+ *
+ * @example
+ * tokenizeATXHeading(eat, ' # foo');
+ *
+ * @param {function(string)} eat - Eater.
+ * @param {string} value - Rest of content.
+ * @param {boolean?} [silent] - Whether this is a dry run.
+ * @return {Node?|boolean} - `heading` node.
+ */
+function tokenizeATXHeading(eat, value, silent) {
+ var self = this;
+ var settings = self.options;
+ var length = value.length + 1;
+ var index = -1;
+ var now = eat.now();
+ var subvalue = EMPTY;
+ var content = EMPTY;
+ var character;
+ var queue;
+ var depth;
+
+ /*
+ * Eat initial spacing.
+ */
+
+ while (++index < length) {
+ character = value.charAt(index);
+
+ if (character !== C_SPACE && character !== C_TAB) {
+ index--;
+ break;
+ }
+
+ subvalue += character;
+ }
+
+ /*
+ * Eat hashes.
+ */
+
+ depth = 0;
+ length = index + MAX_ATX_COUNT + 1;
+
+ while (++index <= length) {
+ character = value.charAt(index);
+
+ if (character !== C_HASH) {
+ index--;
+ break;
+ }
+
+ subvalue += character;
+ depth++;
+ }
+
+ if (
+ !depth ||
+ (!settings.pedantic && value.charAt(index + 1) === C_HASH)
+ ) {
+ return;
+ }
+
+ length = value.length + 1;
+
+ /*
+ * Eat intermediate white-space.
+ */
+
+ queue = EMPTY;
+
+ while (++index < length) {
+ character = value.charAt(index);
+
+ if (character !== C_SPACE && character !== C_TAB) {
+ index--;
+ break;
+ }
+
+ queue += character;
+ }
+
+ /*
+ * Exit when not in pedantic mode without spacing.
+ */
+
+ if (
+ !settings.pedantic &&
+ !queue.length &&
+ character &&
+ character !== C_NEWLINE
+ ) {
+ return;
+ }
+
+ if (silent) {
+ return true;
+ }
+
+ /*
+ * Eat content.
+ */
+
+ subvalue += queue;
+ queue = content = EMPTY;
+
+ while (++index < length) {
+ character = value.charAt(index);
+
+ if (!character || character === C_NEWLINE) {
+ break;
+ }
+
+ if (
+ character !== C_SPACE &&
+ character !== C_TAB &&
+ character !== C_HASH
+ ) {
+ content += queue + character;
+ queue = EMPTY;
+ continue;
+ }
+
+ while (character === C_SPACE || character === C_TAB) {
+ queue += character;
+ character = value.charAt(++index);
+ }
+
+ while (character === C_HASH) {
+ queue += character;
+ character = value.charAt(++index);
+ }
+
+ while (character === C_SPACE || character === C_TAB) {
+ queue += character;
+ character = value.charAt(++index);
+ }
+
+ index--;
+ }
+
+ now.column += subvalue.length;
+ now.offset += subvalue.length;
+ subvalue += content + queue;
+
+ return eat(subvalue)(self.renderHeading(content, depth, now));
+}
+
+/**
+ * Tokenise a Setext-style heading.
+ *
+ * @example
+ * tokenizeSetextHeading(eat, 'foo\n===');
+ *
+ * @param {function(string)} eat - Eater.
+ * @param {string} value - Rest of content.
+ * @param {boolean?} [silent] - Whether this is a dry run.
+ * @return {Node?|boolean} - `heading` node.
+ */
+function tokenizeSetextHeading(eat, value, silent) {
+ var self = this;
+ var now = eat.now();
+ var length = value.length;
+ var index = -1;
+ var subvalue = EMPTY;
+ var content;
+ var queue;
+ var character;
+ var marker;
+ var depth;
+
+ /*
+ * Eat initial indentation.
+ */
+
+ while (++index < length) {
+ character = value.charAt(index);
+
+ if (character !== C_SPACE || index >= MAX_LINE_HEADING_INDENT) {
+ index--;
+ break;
+ }
+
+ subvalue += character;
+ }
+
+ /*
+ * Eat content.
+ */
+
+ content = queue = EMPTY;
+
+ while (++index < length) {
+ character = value.charAt(index);
+
+ if (character === C_NEWLINE) {
+ index--;
+ break;
+ }
+
+ if (character === C_SPACE || character === C_TAB) {
+ queue += character;
+ } else {
+ content += queue + character;
+ queue = EMPTY;
+ }
+ }
+
+ now.column += subvalue.length;
+ now.offset += subvalue.length;
+ subvalue += content + queue;
+
+ /*
+ * Ensure the content is followed by a newline and a
+ * valid marker.
+ */
+
+ character = value.charAt(++index);
+ marker = value.charAt(++index);
+
+ if (character !== C_NEWLINE || !SETEXT_MARKERS[marker]) {
+ return;
+ }
+
+ subvalue += character;
+
+ /*
+ * Eat Setext-line.
+ */
+
+ queue = marker;
+ depth = SETEXT_MARKERS[marker];
+
+ while (++index < length) {
+ character = value.charAt(index);
+
+ if (character !== marker) {
+ if (character !== C_NEWLINE) {
+ return;
+ }
+
+ index--;
+ break;
+ }
+
+ queue += character;
+ }
+
+ if (silent) {
+ return true;
+ }
+
+ return eat(subvalue + queue)(self.renderHeading(content, depth, now));
+}
+
+/**
+ * Tokenise a horizontal rule.
+ *
+ * @example
+ * tokenizeThematicBreak(eat, '***');
+ *
+ * @param {function(string)} eat - Eater.
+ * @param {string} value - Rest of content.
+ * @param {boolean?} [silent] - Whether this is a dry run.
+ * @return {Node?|boolean} - `thematicBreak` node.
+ */
+function tokenizeThematicBreak(eat, value, silent) {
+ var self = this;
+ var index = -1;
+ var length = value.length + 1;
+ var subvalue = EMPTY;
+ var character;
+ var marker;
+ var markerCount;
+ var queue;
+
+ while (++index < length) {
+ character = value.charAt(index);
+
+ if (character !== C_TAB && character !== C_SPACE) {
+ break;
+ }
+
+ subvalue += character;
+ }
+
+ if (RULE_MARKERS[character] !== true) {
+ return;
+ }
+
+ marker = character;
+ subvalue += character;
+ markerCount = 1;
+ queue = EMPTY;
+
+ while (++index < length) {
+ character = value.charAt(index);
+
+ if (character === marker) {
+ markerCount++;
+ subvalue += queue + marker;
+ queue = EMPTY;
+ } else if (character === C_SPACE) {
+ queue += character;
+ } else if (
+ markerCount >= THEMATIC_BREAK_MARKER_COUNT &&
+ (!character || character === C_NEWLINE)
+ ) {
+ subvalue += queue;
+
+ if (silent) {
+ return true;
+ }
+
+ return eat(subvalue)(self.renderVoid(T_THEMATIC_BREAK));
+ } else {
+ return;
+ }
+ }
+}
+
+/**
+ * Tokenise a blockquote.
+ *
+ * @example
+ * tokenizeBlockquote(eat, '> Foo');
+ *
+ * @param {function(string)} eat - Eater.
+ * @param {string} value - Rest of content.
+ * @param {boolean?} [silent] - Whether this is a dry run.
+ * @return {Node?|boolean} - `blockquote` node.
+ */
+function tokenizeBlockquote(eat, value, silent) {
+ var self = this;
+ var commonmark = self.options.commonmark;
+ var now = eat.now();
+ var indent = self.indent(now.line);
+ var length = value.length;
+ var values = [];
+ var contents = [];
+ var indents = [];
+ var add;
+ var tokenizers;
+ var index = 0;
+ var character;
+ var rest;
+ var nextIndex;
+ var content;
+ var line;
+ var startIndex;
+ var prefixed;
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (character !== C_SPACE && character !== C_TAB) {
+ break;
+ }
+
+ index++;
+ }
+
+ if (value.charAt(index) !== C_GT) {
+ return;
+ }
+
+ if (silent) {
+ return true;
+ }
+
+ tokenizers = self.blockTokenizers;
+ index = 0;
+
+ while (index < length) {
+ nextIndex = value.indexOf(C_NEWLINE, index);
+ startIndex = index;
+ prefixed = false;
+
+ if (nextIndex === -1) {
+ nextIndex = length;
+ }
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (character !== C_SPACE && character !== C_TAB) {
+ break;
+ }
+
+ index++;
+ }
+
+ if (value.charAt(index) === C_GT) {
+ index++;
+ prefixed = true;
+
+ if (value.charAt(index) === C_SPACE) {
+ index++;
+ }
+ } else {
+ index = startIndex;
+ }
+
+ content = value.slice(index, nextIndex);
+
+ if (!prefixed && !trim(content)) {
+ index = startIndex;
+ break;
+ }
+
+ if (!prefixed) {
+ rest = value.slice(index);
+
+ if (
+ commonmark &&
+ (
+ tokenizers.indentedCode.call(self, eat, rest, true) ||
+ tokenizers.fencedCode.call(self, eat, rest, true) ||
+ tokenizers.atxHeading.call(self, eat, rest, true) ||
+ tokenizers.setextHeading.call(self, eat, rest, true) ||
+ tokenizers.thematicBreak.call(self, eat, rest, true) ||
+ tokenizers.html.call(self, eat, rest, true) ||
+ tokenizers.list.call(self, eat, rest, true)
+ )
+ ) {
+ break;
+ }
+
+ if (
+ !commonmark &&
+ (
+ tokenizers.definition.call(self, eat, rest, true) ||
+ tokenizers.footnote.call(self, eat, rest, true)
+ )
+ ) {
+ break;
+ }
+ }
+
+ line = startIndex === index ?
+ content :
+ value.slice(startIndex, nextIndex);
+
+ indents.push(index - startIndex);
+ values.push(line);
+ contents.push(content);
+
+ index = nextIndex + 1;
+ }
+
+ index = -1;
+ length = indents.length;
+ add = eat(values.join(C_NEWLINE));
+
+ while (++index < length) {
+ indent(indents[index]);
+ }
+
+ return add(self.renderBlockquote(contents.join(C_NEWLINE), now));
+}
+
+/**
+ * Tokenise a list.
+ *
+ * @example
+ * tokenizeList(eat, '- Foo');
+ *
+ * @param {function(string)} eat - Eater.
+ * @param {string} value - Rest of content.
+ * @param {boolean?} [silent] - Whether this is a dry run.
+ * @return {Node?|boolean} - `list` node.
+ */
+function tokenizeList(eat, value, silent) {
+ var self = this;
+ var commonmark = self.options.commonmark;
+ var pedantic = self.options.pedantic;
+ var tokenizers = self.blockTokenizers;
+ var markers;
+ var index = 0;
+ var length = value.length;
+ var start = null;
+ var queue;
+ var ordered;
+ var character;
+ var marker;
+ var nextIndex;
+ var startIndex;
+ var prefixed;
+ var currentMarker;
+ var content;
+ var line;
+ var prevEmpty;
+ var empty;
+ var items;
+ var allLines;
+ var emptyLines;
+ var item;
+ var enterTop;
+ var exitBlockquote;
+ var isLoose;
+ var node;
+ var now;
+ var end;
+ var indented;
+ var size;
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (character !== C_SPACE && character !== C_TAB) {
+ break;
+ }
+
+ index++;
+ }
+
+ character = value.charAt(index);
+
+ markers = commonmark ?
+ LIST_ORDERED_COMMONMARK_MARKERS :
+ LIST_ORDERED_MARKERS;
+
+ if (LIST_UNORDERED_MARKERS[character] === true) {
+ marker = character;
+ ordered = false;
+ } else {
+ ordered = true;
+ queue = EMPTY;
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (!isNumeric(character)) {
+ break;
+ }
+
+ queue += character;
+ index++;
+ }
+
+ character = value.charAt(index);
+
+ if (!queue || markers[character] !== true) {
+ return;
+ }
+
+ start = parseInt(queue, 10);
+ marker = character;
+ }
+
+ character = value.charAt(++index);
+
+ if (character !== C_SPACE && character !== C_TAB) {
+ return;
+ }
+
+ if (silent) {
+ return true;
+ }
+
+ index = 0;
+ items = [];
+ allLines = [];
+ emptyLines = [];
+
+ while (index < length) {
+ nextIndex = value.indexOf(C_NEWLINE, index);
+ startIndex = index;
+ prefixed = false;
+ indented = false;
+
+ if (nextIndex === -1) {
+ nextIndex = length;
+ }
+
+ end = index + TAB_SIZE;
+ size = 0;
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (character === C_TAB) {
+ size += TAB_SIZE - size % TAB_SIZE;
+ } else if (character === C_SPACE) {
+ size++;
+ } else {
+ break;
+ }
+
+ index++;
+ }
+
+ if (size >= TAB_SIZE) {
+ indented = true;
+ }
+
+ if (item && size >= item.indent) {
+ indented = true;
+ }
+
+ character = value.charAt(index);
+ currentMarker = null;
+
+ if (!indented) {
+ if (LIST_UNORDERED_MARKERS[character] === true) {
+ currentMarker = character;
+ index++;
+ size++;
+ } else {
+ queue = EMPTY;
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (!isNumeric(character)) {
+ break;
+ }
+
+ queue += character;
+ index++;
+ }
+
+ character = value.charAt(index);
+ index++;
+
+ if (queue && markers[character] === true) {
+ currentMarker = character;
+ size += queue.length + 1;
+ }
+ }
+
+ if (currentMarker) {
+ character = value.charAt(index);
+
+ if (character === C_TAB) {
+ size += TAB_SIZE - size % TAB_SIZE;
+ index++;
+ } else if (character === C_SPACE) {
+ end = index + TAB_SIZE;
+
+ while (index < end) {
+ if (value.charAt(index) !== C_SPACE) {
+ break;
+ }
+
+ index++;
+ size++;
+ }
+
+ if (index === end && value.charAt(index) === C_SPACE) {
+ index -= TAB_SIZE - 1;
+ size -= TAB_SIZE - 1;
+ }
+ } else if (
+ character !== C_NEWLINE &&
+ character !== EMPTY
+ ) {
+ currentMarker = null;
+ }
+ }
+ }
+
+ if (currentMarker) {
+ if (commonmark && marker !== currentMarker) {
+ break;
+ }
+
+ prefixed = true;
+ } else {
+ if (
+ !commonmark &&
+ !indented &&
+ value.charAt(startIndex) === C_SPACE
+ ) {
+ indented = true;
+ } else if (
+ commonmark &&
+ item
+ ) {
+ indented = size >= item.indent || size > TAB_SIZE;
+ }
+
+ prefixed = false;
+ index = startIndex;
+ }
+
+ line = value.slice(startIndex, nextIndex);
+ content = startIndex === index ? line : value.slice(index, nextIndex);
+
+ if (currentMarker && RULE_MARKERS[currentMarker] === true) {
+ if (
+ tokenizers.thematicBreak.call(self, eat, line, true)
+ ) {
+ break;
+ }
+ }
+
+ prevEmpty = empty;
+ empty = !trim(content).length;
+
+ if (indented && item) {
+ item.value = item.value.concat(emptyLines, line);
+ allLines = allLines.concat(emptyLines, line);
+ emptyLines = [];
+ } else if (prefixed) {
+ if (emptyLines.length) {
+ item.value.push(EMPTY);
+ item.trail = emptyLines.concat();
+ }
+
+ item = {
+ // 'bullet': value.slice(startIndex, index),
+ 'value': [line],
+ 'indent': size,
+ 'trail': []
+ };
+
+ items.push(item);
+ allLines = allLines.concat(emptyLines, line);
+ emptyLines = [];
+ } else if (empty) {
+ // TODO: disable when in pedantic-mode.
+ if (prevEmpty) {
+ break;
+ }
+
+ emptyLines.push(line);
+ } else {
+ if (prevEmpty) {
+ break;
+ }
+
+ if (
+ !pedantic &&
+ (
+ tokenizers.fencedCode.call(self, eat, line, true) ||
+ tokenizers.thematicBreak.call(self, eat, line, true)
+ )
+ ) {
+ break;
+ }
+
+ if (!commonmark) {
+ if (
+ tokenizers.definition.call(self, eat, line, true) ||
+ tokenizers.footnote.call(self, eat, line, true)
+ ) {
+ break;
+ }
+ }
+
+ item.value = item.value.concat(emptyLines, line);
+ allLines = allLines.concat(emptyLines, line);
+ emptyLines = [];
+ }
+
+ index = nextIndex + 1;
+ }
+
+ node = eat(allLines.join(C_NEWLINE)).reset({
+ 'type': T_LIST,
+ 'ordered': ordered,
+ 'start': start,
+ 'loose': null,
+ 'children': []
+ });
+
+ enterTop = self.enterList();
+ exitBlockquote = self.enterBlock();
+ isLoose = false;
+ index = -1;
+ length = items.length;
+
+ while (++index < length) {
+ item = items[index].value.join(C_NEWLINE);
+ now = eat.now();
+
+ item = eat(item)(self.renderListItem(item, now), node);
+
+ if (item.loose) {
+ isLoose = true;
+ }
+
+ item = items[index].trail.join(C_NEWLINE);
+
+ if (index !== length - 1) {
+ item += C_NEWLINE;
+ }
+
+ eat(item);
+ }
+
+ enterTop();
+ exitBlockquote();
+
+ node.loose = isLoose;
+
+ return node;
+}
+
+/**
+ * Try to match comment.
+ *
+ * @param {string} value - Value to parse.
+ * @param {Object} settings - Configuration as available on
+ * a parser.
+ * @return {string?} - When applicable, the comment at the
+ * start of `value`.
+ */
+function eatHTMLComment(value, settings) {
+ var index = COMMENT_START_LENGTH;
+ var queue = COMMENT_START;
+ var length = value.length;
+ var commonmark = settings.commonmark;
+ var character;
+ var hasNonDash;
+
+ if (value.slice(0, index) === queue) {
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (
+ character === COMMENT_END_CHAR &&
+ value.slice(index, index + COMMENT_END_LENGTH) === COMMENT_END
+ ) {
+ return queue + COMMENT_END;
+ }
+
+ if (commonmark) {
+ if (character === C_GT && !hasNonDash) {
+ return;
+ }
+
+ if (character === C_DASH) {
+ if (value.charAt(index + 1) === C_DASH) {
+ return;
+ }
+ } else {
+ hasNonDash = true;
+ }
+ }
+
+ queue += character;
+ index++;
+ }
+ }
+}
+
+/**
+ * Try to match CDATA.
+ *
+ * @param {string} value - Value to parse.
+ * @return {string?} - When applicable, the CDATA at the
+ * start of `value`.
+ */
+function eatHTMLCDATA(value) {
+ var index = CDATA_START_LENGTH;
+ var queue = value.slice(0, index);
+ var length = value.length;
+ var character;
+
+ if (queue.toUpperCase() === CDATA_START) {
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (
+ character === CDATA_END_CHAR &&
+ value.slice(index, index + CDATA_END_LENGTH) === CDATA_END
+ ) {
+ return queue + CDATA_END;
+ }
+
+ queue += character;
+ index++;
+ }
+ }
+}
+
+/**
+ * Try to match a processing instruction.
+ *
+ * @param {string} value - Value to parse.
+ * @return {string?} - When applicable, the processing
+ * instruction at the start of `value`.
+ */
+function eatHTMLProcessingInstruction(value) {
+ var index = 0;
+ var queue = EMPTY;
+ var length = value.length;
+ var character;
+
+ if (
+ value.charAt(index) === C_LT &&
+ value.charAt(++index) === C_QUESTION_MARK
+ ) {
+ queue = C_LT + C_QUESTION_MARK;
+ index++;
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (
+ character === C_QUESTION_MARK &&
+ value.charAt(index + 1) === C_GT
+ ) {
+ return queue + character + C_GT;
+ }
+
+ queue += character;
+ index++;
+ }
+ }
+}
+
+/**
+ * Try to match a declaration.
+ *
+ * @param {string} value - Value to parse.
+ * @return {string?} - When applicable, the declaration at
+ * the start of `value`.
+ */
+function eatHTMLDeclaration(value) {
+ var index = 0;
+ var length = value.length;
+ var queue = EMPTY;
+ var subqueue = EMPTY;
+ var character;
+
+ if (
+ value.charAt(index) === C_LT &&
+ value.charAt(++index) === C_EXCLAMATION_MARK
+ ) {
+ queue = C_LT + C_EXCLAMATION_MARK;
+ index++;
+
+ /*
+ * Eat as many alphabetic characters as
+ * possible.
+ */
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (!isAlphabetic(character)) {
+ break;
+ }
+
+ subqueue += character;
+ index++;
+ }
+
+ character = value.charAt(index);
+
+ if (!subqueue || !isWhiteSpace(character)) {
+ return;
+ }
+
+ queue += subqueue + character;
+ index++;
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (character === C_GT) {
+ return queue;
+ }
+
+ queue += character;
+ index++;
+ }
+ }
+}
+
+/**
+ * Try to match a closing tag.
+ *
+ * @param {string} value - Value to parse.
+ * @param {boolean?} [isBlock] - Whether the tag-name
+ * must be a known block-level node to match.
+ * @return {string?} - When applicable, the closing tag at
+ * the start of `value`.
+ */
+function eatHTMLClosingTag(value, isBlock) {
+ var index = 0;
+ var length = value.length;
+ var queue = EMPTY;
+ var subqueue = EMPTY;
+ var character;
+
+ if (
+ value.charAt(index) === C_LT &&
+ value.charAt(++index) === C_SLASH
+ ) {
+ queue = C_LT + C_SLASH;
+ subqueue = character = value.charAt(++index);
+
+ if (!isAlphabetic(character)) {
+ return;
+ }
+
+ index++;
+
+ /*
+ * Eat as many alphabetic characters as
+ * possible.
+ */
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (!isAlphabetic(character) && !isNumeric(character)) {
+ break;
+ }
+
+ subqueue += character;
+ index++;
+ }
+
+ if (isBlock && blockElements.indexOf(subqueue.toLowerCase()) === -1) {
+ return;
+ }
+
+ queue += subqueue;
+
+ /*
+ * Eat white-space.
+ */
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (!isWhiteSpace(character)) {
+ break;
+ }
+
+ queue += character;
+ index++;
+ }
+
+ if (value.charAt(index) === C_GT) {
+ return queue + C_GT;
+ }
+ }
+}
+
+/**
+ * Try to match an opening tag.
+ *
+ * @param {string} value - Value to parse.
+ * @param {boolean?} [isBlock] - Whether the tag-name
+ * must be a known block-level node to match.
+ * @return {string?} - When applicable, the opening tag at
+ * the start of `value`.
+ */
+function eatHTMLOpeningTag(value, isBlock) {
+ var index = 0;
+ var length = value.length;
+ var queue = EMPTY;
+ var subqueue = EMPTY;
+ var character = value.charAt(index);
+ var hasEquals;
+ var test;
+
+ if (character === C_LT) {
+ queue = character;
+ subqueue = character = value.charAt(++index);
+
+ if (!isAlphabetic(character)) {
+ return;
+ }
+
+ index++;
+
+ /*
+ * Eat as many alphabetic characters as
+ * possible.
+ */
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (!isAlphabetic(character) && !isNumeric(character)) {
+ break;
+ }
+
+ subqueue += character;
+ index++;
+ }
+
+ if (isBlock && blockElements.indexOf(subqueue.toLowerCase()) === -1) {
+ return;
+ }
+
+ queue += subqueue;
+ subqueue = EMPTY;
+
+ /*
+ * Find attributes.
+ */
+
+ while (index < length) {
+ /*
+ * Eat white-space.
+ */
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (!isWhiteSpace(character)) {
+ break;
+ }
+
+ subqueue += character;
+ index++;
+ }
+
+ if (!subqueue) {
+ break;
+ }
+
+ /*
+ * Eat an attribute name.
+ */
+
+ queue += subqueue;
+ subqueue = EMPTY;
+ character = value.charAt(index);
+
+ if (
+ isAlphabetic(character) ||
+ character === C_UNDERSCORE ||
+ character === C_COLON
+ ) {
+ subqueue = character;
+ index++;
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (
+ !isAlphabetic(character) &&
+ !isNumeric(character) &&
+ character !== C_UNDERSCORE &&
+ character !== C_COLON &&
+ character !== C_DOT &&
+ character !== C_DASH
+ ) {
+ break;
+ }
+
+ subqueue += character;
+ index++;
+ }
+ }
+
+ if (!subqueue) {
+ break;
+ }
+
+ queue += subqueue;
+ subqueue = EMPTY;
+ hasEquals = false;
+
+ /*
+ * Eat zero or more white-space and one
+ * equals sign.
+ */
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (!isWhiteSpace(character)) {
+ if (!hasEquals && character === C_EQUALS) {
+ hasEquals = true;
+ } else {
+ break;
+ }
+ }
+
+ subqueue += character;
+ index++;
+ }
+
+ queue += subqueue;
+ subqueue = EMPTY;
+
+ if (!hasEquals) {
+ queue += subqueue;
+ } else {
+ character = value.charAt(index);
+ queue += subqueue;
+
+ if (character === C_DOUBLE_QUOTE) {
+ test = isDoubleQuotedAttributeCharacter;
+ subqueue = character;
+ index++;
+ } else if (character === C_SINGLE_QUOTE) {
+ test = isSingleQuotedAttributeCharacter;
+ subqueue = character;
+ index++;
+ } else {
+ test = isUnquotedAttributeCharacter;
+ subqueue = EMPTY;
+ }
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (!test(character)) {
+ break;
+ }
+
+ subqueue += character;
+ index++;
+ }
+
+ character = value.charAt(index);
+ index++;
+
+ if (!test.delimiter) {
+ if (!subqueue.length) {
+ return;
+ }
+
+ index--;
+ } else if (character === test.delimiter) {
+ subqueue += character;
+ } else {
+ return;
+ }
+
+ queue += subqueue;
+ subqueue = EMPTY;
+ }
+ }
+
+ /*
+ * More white-space is already eaten by the
+ * attributes subroutine.
+ */
+
+ character = value.charAt(index);
+
+ /*
+ * Eat an optional backslash (for self-closing
+ * tags).
+ */
+
+ if (character === C_SLASH) {
+ queue += character;
+ character = value.charAt(++index);
+ }
+
+ return character === C_GT ? queue + character : null;
+ }
+}
+
+/**
+ * Tokenise HTML.
+ *
+ * @example
+ * tokenizeBlockHTML(eat, '<span>foo</span>');
+ *
+ * @param {function(string)} eat - Eater.
+ * @param {string} value - Rest of content.
+ * @param {boolean?} [silent] - Whether this is a dry run.
+ * @return {Node?|boolean} - `html` node.
+ */
+function tokenizeBlockHTML(eat, value, silent) {
+ var self = this;
+ var index = 0;
+ var length = value.length;
+ var subvalue = EMPTY;
+ var offset;
+ var lineCount;
+ var character;
+ var queue;
+
+ /*
+ * Eat initial spacing.
+ */
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (character !== C_TAB && character !== C_SPACE) {
+ break;
+ }
+
+ subvalue += character;
+ index++;
+ }
+
+ offset = index;
+ value = value.slice(offset);
+
+ /*
+ * Try to eat an HTML thing.
+ */
+
+ queue = eatHTMLComment(value, self.options) ||
+ eatHTMLCDATA(value) ||
+ eatHTMLProcessingInstruction(value) ||
+ eatHTMLDeclaration(value) ||
+ eatHTMLClosingTag(value, true) ||
+ eatHTMLOpeningTag(value, true);
+
+ if (!queue) {
+ return;
+ }
+
+ if (silent) {
+ return true;
+ }
+
+ subvalue += queue;
+ index = subvalue.length - offset;
+ queue = EMPTY;
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (character === C_NEWLINE) {
+ queue += character;
+ lineCount++;
+ } else if (queue.length < MIN_CLOSING_HTML_NEWLINE_COUNT) {
+ subvalue += queue + character;
+ queue = EMPTY;
+ } else {
+ break;
+ }
+
+ index++;
+ }
+
+ return eat(subvalue)(self.renderRaw(T_HTML, subvalue));
+}
+
+/**
+ * Tokenise a definition.
+ *
+ * @example
+ * var value = '[foo]: http://example.com "Example Domain"';
+ * tokenizeDefinition(eat, value);
+ *
+ * @property {boolean} notInList
+ * @property {boolean} notInBlock
+ * @param {function(string)} eat - Eater.
+ * @param {string} value - Rest of content.
+ * @param {boolean?} [silent] - Whether this is a dry run.
+ * @return {Node?|boolean} - `definition` node.
+ */
+function tokenizeDefinition(eat, value, silent) {
+ var self = this;
+ var commonmark = self.options.commonmark;
+ var index = 0;
+ var length = value.length;
+ var subvalue = EMPTY;
+ var beforeURL;
+ var beforeTitle;
+ var queue;
+ var character;
+ var test;
+ var identifier;
+ var url;
+ var title;
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (character !== C_SPACE && character !== C_TAB) {
+ break;
+ }
+
+ subvalue += character;
+ index++;
+ }
+
+ character = value.charAt(index);
+
+ if (character !== C_BRACKET_OPEN) {
+ return;
+ }
+
+ index++;
+ subvalue += character;
+ queue = EMPTY;
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (character === C_BRACKET_CLOSE) {
+ break;
+ } else if (character === C_BACKSLASH) {
+ queue += character;
+ index++;
+ character = value.charAt(index);
+ }
+
+ queue += character;
+ index++;
+ }
+
+ if (
+ !queue ||
+ value.charAt(index) !== C_BRACKET_CLOSE ||
+ value.charAt(index + 1) !== C_COLON
+ ) {
+ return;
+ }
+
+ identifier = queue;
+ subvalue += queue + C_BRACKET_CLOSE + C_COLON;
+ index = subvalue.length;
+ queue = EMPTY;
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (
+ character !== C_TAB &&
+ character !== C_SPACE &&
+ character !== C_NEWLINE
+ ) {
+ break;
+ }
+
+ subvalue += character;
+ index++;
+ }
+
+ character = value.charAt(index);
+ queue = EMPTY;
+ beforeURL = subvalue;
+
+ if (character === C_LT) {
+ index++;
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (!isEnclosedURLCharacter(character)) {
+ break;
+ }
+
+ queue += character;
+ index++;
+ }
+
+ character = value.charAt(index);
+
+ if (character !== isEnclosedURLCharacter.delimiter) {
+ if (commonmark) {
+ return;
+ }
+
+ index -= queue.length + 1;
+ queue = EMPTY;
+ } else {
+ subvalue += C_LT + queue + character;
+ index++;
+ }
+ }
+
+ if (!queue) {
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (!isUnclosedURLCharacter(character)) {
+ break;
+ }
+
+ queue += character;
+ index++;
+ }
+
+ subvalue += queue;
+ }
+
+ if (!queue) {
+ return;
+ }
+
+ url = queue;
+ queue = EMPTY;
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (
+ character !== C_TAB &&
+ character !== C_SPACE &&
+ character !== C_NEWLINE
+ ) {
+ break;
+ }
+
+ queue += character;
+ index++;
+ }
+
+ character = value.charAt(index);
+ test = null;
+
+ if (character === C_DOUBLE_QUOTE) {
+ test = C_DOUBLE_QUOTE;
+ } else if (character === C_SINGLE_QUOTE) {
+ test = C_SINGLE_QUOTE;
+ } else if (character === C_PAREN_OPEN) {
+ test = C_PAREN_CLOSE;
+ }
+
+ if (!test) {
+ queue = EMPTY;
+ index = subvalue.length;
+ } else if (!queue) {
+ return;
+ } else {
+ subvalue += queue + character;
+ index = subvalue.length;
+ queue = EMPTY;
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (character === test) {
+ break;
+ }
+
+ if (character === C_NEWLINE) {
+ index++;
+ character = value.charAt(index);
+
+ if (character === C_NEWLINE || character === test) {
+ return;
+ }
+
+ queue += C_NEWLINE;
+ }
+
+ queue += character;
+ index++;
+ }
+
+ character = value.charAt(index);
+
+ if (character !== test) {
+ return;
+ }
+
+ beforeTitle = subvalue;
+ subvalue += queue + character;
+ index++;
+ title = queue;
+ queue = EMPTY;
+ }
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (character !== C_TAB && character !== C_SPACE) {
+ break;
+ }
+
+ subvalue += character;
+ index++;
+ }
+
+ character = value.charAt(index);
+
+ if (!character || character === C_NEWLINE) {
+ if (silent) {
+ return true;
+ }
+
+ beforeURL = eat(beforeURL).test().end;
+ url = self.decode.raw(self.descape(url), beforeURL);
+
+ if (title) {
+ beforeTitle = eat(beforeTitle).test().end;
+ title = self.decode.raw(self.descape(title), beforeTitle);
+ }
+
+ return eat(subvalue)({
+ 'type': T_DEFINITION,
+ 'identifier': normalize(identifier),
+ 'title': title || null,
+ 'url': url
+ });
+ }
+}
+
+tokenizeDefinition.notInList = true;
+tokenizeDefinition.notInBlock = true;
+
+/**
+ * Tokenise YAML front matter.
+ *
+ * @example
+ * tokenizeYAMLFrontMatter(eat, '---\nfoo: bar\n---');
+ *
+ * @property {boolean} onlyAtStart
+ * @param {function(string)} eat - Eater.
+ * @param {string} value - Rest of content.
+ * @param {boolean?} [silent] - Whether this is a dry run.
+ * @return {Node?|boolean} - `yaml` node.
+ */
+function tokenizeYAMLFrontMatter(eat, value, silent) {
+ var self = this;
+ var subvalue;
+ var content;
+ var index;
+ var length;
+ var character;
+ var queue;
+
+ if (
+ !self.options.yaml ||
+ value.charAt(0) !== C_DASH ||
+ value.charAt(1) !== C_DASH ||
+ value.charAt(2) !== C_DASH ||
+ value.charAt(3) !== C_NEWLINE
+ ) {
+ return;
+ }
+
+ subvalue = YAML_FENCE + C_NEWLINE;
+ content = queue = EMPTY;
+ index = 3;
+ length = value.length;
+
+ while (++index < length) {
+ character = value.charAt(index);
+
+ if (
+ character === C_DASH &&
+ (queue || !content) &&
+ value.charAt(index + 1) === C_DASH &&
+ value.charAt(index + 2) === C_DASH
+ ) {
+ /* istanbul ignore if - never used (yet) */
+ if (silent) {
+ return true;
+ }
+
+ subvalue += queue + YAML_FENCE;
+
+ return eat(subvalue)(self.renderRaw(T_YAML, content));
+ }
+
+ if (character === C_NEWLINE) {
+ queue += character;
+ } else {
+ subvalue += queue + character;
+ content += queue + character;
+ queue = EMPTY;
+ }
+ }
+}
+
+tokenizeYAMLFrontMatter.onlyAtStart = true;
+
+/**
+ * Tokenise a footnote definition.
+ *
+ * @example
+ * tokenizeFootnoteDefinition(eat, '[^foo]: Bar.');
+ *
+ * @property {boolean} notInList
+ * @property {boolean} notInBlock
+ * @param {function(string)} eat - Eater.
+ * @param {string} value - Rest of content.
+ * @param {boolean?} [silent] - Whether this is a dry run.
+ * @return {Node?|boolean} - `footnoteDefinition` node.
+ */
+function tokenizeFootnoteDefinition(eat, value, silent) {
+ var self = this;
+ var index;
+ var length;
+ var subvalue;
+ var now;
+ var indent;
+ var content;
+ var queue;
+ var subqueue;
+ var character;
+ var identifier;
+
+ if (!self.options.footnotes) {
+ return;
+ }
+
+ index = 0;
+ length = value.length;
+ subvalue = EMPTY;
+ now = eat.now();
+ indent = self.indent(now.line);
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (!isWhiteSpace(character)) {
+ break;
+ }
+
+ subvalue += character;
+ index++;
+ }
+
+ if (
+ value.charAt(index) !== C_BRACKET_OPEN ||
+ value.charAt(index + 1) !== C_CARET
+ ) {
+ return;
+ }
+
+ subvalue += C_BRACKET_OPEN + C_CARET;
+ index = subvalue.length;
+ queue = EMPTY;
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (character === C_BRACKET_CLOSE) {
+ break;
+ } else if (character === C_BACKSLASH) {
+ queue += character;
+ index++;
+ character = value.charAt(index);
+ }
+
+ queue += character;
+ index++;
+ }
+
+ if (
+ !queue ||
+ value.charAt(index) !== C_BRACKET_CLOSE ||
+ value.charAt(index + 1) !== C_COLON
+ ) {
+ return;
+ }
+
+ if (silent) {
+ return true;
+ }
+
+ identifier = normalize(queue);
+ subvalue += queue + C_BRACKET_CLOSE + C_COLON;
+ index = subvalue.length;
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (
+ character !== C_TAB &&
+ character !== C_SPACE
+ ) {
+ break;
+ }
+
+ subvalue += character;
+ index++;
+ }
+
+ now.column += subvalue.length;
+ now.offset += subvalue.length;
+ queue = content = subqueue = EMPTY;
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (character === C_NEWLINE) {
+ subqueue = character;
+ index++;
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (character !== C_NEWLINE) {
+ break;
+ }
+
+ subqueue += character;
+ index++;
+ }
+
+ queue += subqueue;
+ subqueue = EMPTY;
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (character !== C_SPACE) {
+ break;
+ }
+
+ subqueue += character;
+ index++;
+ }
+
+ if (!subqueue.length) {
+ break;
+ }
+
+ queue += subqueue;
+ }
+
+ if (queue) {
+ content += queue;
+ queue = EMPTY;
+ }
+
+ content += character;
+ index++;
+ }
+
+ subvalue += content;
+
+ content = content.replace(EXPRESSION_INITIAL_TAB, function (line) {
+ indent(line.length);
+
+ return EMPTY;
+ });
+
+ return eat(subvalue)(
+ self.renderFootnoteDefinition(identifier, content, now)
+ );
+}
+
+tokenizeFootnoteDefinition.notInList = true;
+tokenizeFootnoteDefinition.notInBlock = true;
+
+/**
+ * Tokenise a table.
+ *
+ * @example
+ * tokenizeTable(eat, ' | foo |\n | --- |\n | bar |');
+ *
+ * @property {boolean} notInList
+ * @param {function(string)} eat - Eater.
+ * @param {string} value - Rest of content.
+ * @param {boolean?} [silent] - Whether this is a dry run.
+ * @return {Node?|boolean} - `table` node.
+ */
+function tokenizeTable(eat, value, silent) {
+ var self = this;
+ var index;
+ var alignments;
+ var alignment;
+ var subvalue;
+ var row;
+ var length;
+ var lines;
+ var queue;
+ var character;
+ var hasDash;
+ var align;
+ var cell;
+ var preamble;
+ var count;
+ var opening;
+ var now;
+ var position;
+ var lineCount;
+ var line;
+ var rows;
+ var table;
+ var lineIndex;
+ var pipeIndex;
+ var first;
+
+ /*
+ * Exit when not in gfm-mode.
+ */
+
+ if (!self.options.gfm) {
+ return;
+ }
+
+ /*
+ * Get the rows.
+ * Detecting tables soon is hard, so there are some
+ * checks for performance here, such as the minimum
+ * number of rows, and allowed characters in the
+ * alignment row.
+ */
+
+ index = lineCount = 0;
+ length = value.length + 1;
+ lines = [];
+
+ while (index < length) {
+ lineIndex = value.indexOf(C_NEWLINE, index);
+ pipeIndex = value.indexOf(C_PIPE, index + 1);
+
+ if (lineIndex === -1) {
+ lineIndex = value.length;
+ }
+
+ if (
+ pipeIndex === -1 ||
+ pipeIndex > lineIndex
+ ) {
+ if (lineCount < MIN_TABLE_ROWS) {
+ return;
+ }
+
+ break;
+ }
+
+ lines.push(value.slice(index, lineIndex));
+ lineCount++;
+ index = lineIndex + 1;
+ }
-/* Handlers. */
-proto.blockTokenizers = {
- yamlFrontMatter: require('./tokenize/yaml'),
- newline: require('./tokenize/newline'),
- indentedCode: require('./tokenize/code-indented'),
- fencedCode: require('./tokenize/code-fenced'),
- blockquote: require('./tokenize/blockquote'),
- atxHeading: require('./tokenize/heading-atx'),
- thematicBreak: require('./tokenize/thematic-break'),
- list: require('./tokenize/list'),
- setextHeading: require('./tokenize/heading-setext'),
- html: require('./tokenize/html-block'),
- footnote: require('./tokenize/footnote-definition'),
- definition: require('./tokenize/definition'),
- table: require('./tokenize/table'),
- paragraph: require('./tokenize/paragraph')
+ /*
+ * Parse the alignment row.
+ */
+
+ subvalue = lines.join(C_NEWLINE);
+ alignments = lines.splice(1, 1)[0] || [];
+ index = 0;
+ length = alignments.length;
+ lineCount--;
+ alignment = false;
+ align = [];
+
+ while (index < length) {
+ character = alignments.charAt(index);
+
+ if (character === C_PIPE) {
+ hasDash = null;
+
+ if (alignment === false) {
+ if (first === false) {
+ return;
+ }
+ } else {
+ align.push(alignment);
+ alignment = false;
+ }
+
+ first = false;
+ } else if (character === C_DASH) {
+ hasDash = true;
+ alignment = alignment || TABLE_ALIGN_NONE;
+ } else if (character === C_COLON) {
+ if (alignment === TABLE_ALIGN_LEFT) {
+ alignment = TABLE_ALIGN_CENTER;
+ } else if (hasDash && alignment === TABLE_ALIGN_NONE) {
+ alignment = TABLE_ALIGN_RIGHT;
+ } else {
+ alignment = TABLE_ALIGN_LEFT;
+ }
+ } else if (!isWhiteSpace(character)) {
+ return;
+ }
+
+ index++;
+ }
+
+ if (alignment !== false) {
+ align.push(alignment);
+ }
+
+ /*
+ * Exit when without enough columns.
+ */
+
+ if (align.length < MIN_TABLE_COLUMNS) {
+ return;
+ }
+
+ /* istanbul ignore if - never used (yet) */
+ if (silent) {
+ return true;
+ }
+
+ /*
+ * Parse the rows.
+ */
+
+ position = -1;
+ rows = [];
+
+ table = eat(subvalue).reset({
+ 'type': T_TABLE,
+ 'align': align,
+ 'children': rows
+ });
+
+ while (++position < lineCount) {
+ line = lines[position];
+ row = self.renderParent(position ? T_TABLE_ROW : T_TABLE_HEADER, []);
+
+ /*
+ * Eat a newline character when this is not the
+ * first row.
+ */
+
+ if (position) {
+ eat(C_NEWLINE);
+ }
+
+ /*
+ * Eat the row.
+ */
+
+ eat(line).reset(row, table);
+
+ length = line.length + 1;
+ index = 0;
+ queue = EMPTY;
+ cell = EMPTY;
+ preamble = true;
+ count = opening = null;
+
+ while (index < length) {
+ character = line.charAt(index);
+
+ if (character === C_TAB || character === C_SPACE) {
+ if (cell) {
+ queue += character;
+ } else {
+ eat(character);
+ }
+
+ index++;
+ continue;
+ }
+
+ if (character === EMPTY || character === C_PIPE) {
+ if (preamble) {
+ eat(character);
+ } else {
+ if (character && opening) {
+ queue += character;
+ index++;
+ continue;
+ }
+
+ if ((cell || character) && !preamble) {
+ subvalue = cell;
+
+ if (queue.length > 1) {
+ if (character) {
+ subvalue += queue.slice(0, queue.length - 1);
+ queue = queue.charAt(queue.length - 1);
+ } else {
+ subvalue += queue;
+ queue = EMPTY;
+ }
+ }
+
+ now = eat.now();
+
+ eat(subvalue)(
+ self.renderInline(T_TABLE_CELL, cell, now), row
+ );
+ }
+
+ eat(queue + character);
+
+ queue = EMPTY;
+ cell = EMPTY;
+ }
+ } else {
+ if (queue) {
+ cell += queue;
+ queue = EMPTY;
+ }
+
+ cell += character;
+
+ if (character === C_BACKSLASH && index !== length - 2) {
+ cell += line.charAt(index + 1);
+ index++;
+ }
+
+ if (character === C_TICK) {
+ count = 1;
+
+ while (line.charAt(index + 1) === character) {
+ cell += character;
+ index++;
+ count++;
+ }
+
+ if (!opening) {
+ opening = count;
+ } else if (count >= opening) {
+ opening = 0;
+ }
+ }
+ }
+
+ preamble = false;
+ index++;
+ }
+
+ /*
+ * Eat the alignment row.
+ */
+
+ if (!position) {
+ eat(C_NEWLINE + alignments);
+ }
+ }
+
+ return table;
+}
+
+tokenizeTable.notInList = true;
+
+/**
+ * Tokenise a paragraph node.
+ *
+ * @example
+ * tokenizeParagraph(eat, 'Foo.');
+ *
+ * @param {function(string)} eat - Eater.
+ * @param {string} value - Rest of content.
+ * @param {boolean?} [silent] - Whether this is a dry run.
+ * @return {Node?|boolean} - `paragraph` node.
+ */
+function tokenizeParagraph(eat, value, silent) {
+ var self = this;
+ var settings = self.options;
+ var commonmark = settings.commonmark;
+ var gfm = settings.gfm;
+ var tokenizers = self.blockTokenizers;
+ var index = value.indexOf(C_NEWLINE);
+ var length = value.length;
+ var position;
+ var subvalue;
+ var character;
+ var size;
+ var now;
+
+ while (index < length) {
+ /*
+ * Eat everything if there’s no following newline.
+ */
+
+ if (index === -1) {
+ index = length;
+ break;
+ }
+
+ /*
+ * Stop if the next character is NEWLINE.
+ */
+
+ if (value.charAt(index + 1) === C_NEWLINE) {
+ break;
+ }
+
+ /*
+ * In commonmark-mode, following indented lines
+ * are part of the paragraph.
+ */
+
+ if (commonmark) {
+ size = 0;
+ position = index + 1;
+
+ while (position < length) {
+ character = value.charAt(position);
+
+ if (character === C_TAB) {
+ size = TAB_SIZE;
+ break;
+ } else if (character === C_SPACE) {
+ size++;
+ } else {
+ break;
+ }
+
+ position++;
+ }
+
+ if (size >= TAB_SIZE) {
+ index = value.indexOf(C_NEWLINE, index + 1);
+ continue;
+ }
+ }
+
+ /*
+ * Check if the following code contains a possible
+ * block.
+ */
+
+ subvalue = value.slice(index + 1);
+
+ if (
+ tokenizers.thematicBreak.call(self, eat, subvalue, true) ||
+ tokenizers.atxHeading.call(self, eat, subvalue, true) ||
+ tokenizers.fencedCode.call(self, eat, subvalue, true) ||
+ tokenizers.blockquote.call(self, eat, subvalue, true) ||
+ tokenizers.html.call(self, eat, subvalue, true)
+ ) {
+ break;
+ }
+
+ /*
+ * Break if the following line starts a list, when
+ * already in a list, or when in commonmark, or when
+ * in gfm mode and the bullet is *not* numeric.
+ */
+
+ if (
+ tokenizers.list.call(self, eat, subvalue, true) &&
+ (
+ self.inList ||
+ commonmark ||
+ (gfm && !isNumeric(trim.left(subvalue).charAt(0)))
+ )
+ ) {
+ break;
+ }
+
+ if (
+ !commonmark &&
+ (
+ tokenizers.setextHeading.call(self, eat, subvalue, true) ||
+ tokenizers.definition.call(self, eat, subvalue, true) ||
+ tokenizers.footnote.call(self, eat, subvalue, true)
+ )
+ ) {
+ break;
+ }
+
+ position = index;
+ index = value.indexOf(C_NEWLINE, index + 1);
+
+ if (index !== -1 && trim(value.slice(position, index)) === EMPTY) {
+ index = position;
+ break;
+ }
+ }
+
+ subvalue = value.slice(0, index);
+
+ if (trim(subvalue) === EMPTY) {
+ eat(subvalue);
+
+ return null;
+ }
+
+ /* istanbul ignore if - never used (yet) */
+ if (silent) {
+ return true;
+ }
+
+ now = eat.now();
+ subvalue = trimTrailingLines(subvalue);
+
+ return eat(subvalue)(self.renderInline(T_PARAGRAPH, subvalue, now));
+}
+
+/**
+ * Tokenise a text node.
+ *
+ * @example
+ * tokenizeText(eat, 'foo');
+ *
+ * @param {function(string)} eat - Eater.
+ * @param {string} value - Rest of content.
+ * @param {boolean?} [silent] - Whether this is a dry run.
+ * @return {Node?|boolean} - `text` node.
+ */
+function tokenizeText(eat, value, silent) {
+ var self = this;
+ var methods;
+ var tokenizers;
+ var index;
+ var length;
+ var subvalue;
+ var position;
+ var tokenizer;
+ var name;
+ var min;
+ var now;
+
+ /* istanbul ignore if - never used (yet) */
+ if (silent) {
+ return true;
+ }
+
+ methods = self.inlineMethods;
+ length = methods.length;
+ tokenizers = self.inlineTokenizers;
+ index = -1;
+ min = value.length;
+
+ while (++index < length) {
+ name = methods[index];
+
+ if (name === 'text' || !tokenizers[name]) {
+ continue;
+ }
+
+ tokenizer = tokenizers[name].locator;
+
+ if (!tokenizer) {
+ eat.file.fail(ERR_MISSING_LOCATOR + C_TICK + name + C_TICK);
+ continue;
+ }
+
+ position = tokenizer.call(self, value, 1);
+
+ if (position !== -1 && position < min) {
+ min = position;
+ }
+ }
+
+ subvalue = value.slice(0, min);
+ now = eat.now();
+
+ self.decode(subvalue, now, function (content, position, source) {
+ eat(source || content)(self.renderRaw(T_TEXT, content));
+ });
+}
+
+/**
+ * Create a code-block node.
+ *
+ * @example
+ * renderCodeBlock('foo()', 'js', now());
+ *
+ * @param {string?} [value] - Code.
+ * @param {string?} [language] - Optional language flag.
+ * @param {Function} eat - Eater.
+ * @return {Object} - `code` node.
+ */
+function renderCodeBlock(value, language) {
+ return {
+ 'type': T_CODE,
+ 'lang': language || null,
+ 'value': trimTrailingLines(value || EMPTY)
+ };
+}
+
+/**
+ * Create a list-item using overly simple mechanics.
+ *
+ * @example
+ * renderPedanticListItem('- _foo_', now());
+ *
+ * @param {string} value - List-item.
+ * @param {Object} position - List-item location.
+ * @return {string} - Cleaned `value`.
+ */
+function renderPedanticListItem(value, position) {
+ var self = this;
+ var indent = self.indent(position.line);
+
+ /**
+ * A simple replacer which removed all matches,
+ * and adds their length to `offset`.
+ *
+ * @param {string} $0 - Indentation to subtract.
+ * @return {string} - An empty string.
+ */
+ function replacer($0) {
+ indent($0.length);
+
+ return EMPTY;
+ }
+
+ /*
+ * Remove the list-item’s bullet.
+ */
+
+ value = value.replace(EXPRESSION_PEDANTIC_BULLET, replacer);
+
+ /*
+ * The initial line was also matched by the below, so
+ * we reset the `line`.
+ */
+
+ indent = self.indent(position.line);
+
+ return value.replace(EXPRESSION_INITIAL_INDENT, replacer);
+}
+
+/**
+ * Create a list-item using sane mechanics.
+ *
+ * @example
+ * renderNormalListItem('- _foo_', now());
+ *
+ * @param {string} value - List-item.
+ * @param {Object} position - List-item location.
+ * @return {string} - Cleaned `value`.
+ */
+function renderNormalListItem(value, position) {
+ var self = this;
+ var indent = self.indent(position.line);
+ var max;
+ var bullet;
+ var rest;
+ var lines;
+ var trimmedLines;
+ var index;
+ var length;
+
+ /*
+ * Remove the list-item’s bullet.
+ */
+
+ value = value.replace(EXPRESSION_BULLET, function ($0, $1, $2, $3, $4) {
+ bullet = $1 + $2 + $3;
+ rest = $4;
+
+ /*
+ * Make sure that the first nine numbered list items
+ * can indent with an extra space. That is, when
+ * the bullet did not receive an extra final space.
+ */
+
+ if (Number($2) < 10 && bullet.length % 2 === 1) {
+ $2 = C_SPACE + $2;
+ }
+
+ max = $1 + repeat(C_SPACE, $2.length) + $3;
+
+ return max + rest;
+ });
+
+ lines = value.split(C_NEWLINE);
+
+ trimmedLines = removeIndentation(
+ value, getIndent(max).indent
+ ).split(C_NEWLINE);
+
+ /*
+ * We replaced the initial bullet with something
+ * else above, which was used to trick
+ * `removeIndentation` into removing some more
+ * characters when possible. However, that could
+ * result in the initial line to be stripped more
+ * than it should be.
+ */
+
+ trimmedLines[0] = rest;
+
+ indent(bullet.length);
+
+ index = 0;
+ length = lines.length;
+
+ while (++index < length) {
+ indent(lines[index].length - trimmedLines[index].length);
+ }
+
+ return trimmedLines.join(C_NEWLINE);
+}
+
+/**
+ * Create a list-item node.
+ *
+ * @example
+ * renderListItem('- _foo_', now());
+ *
+ * @param {Object} value - List-item.
+ * @param {Object} position - List-item location.
+ * @return {Object} - `listItem` node.
+ */
+function renderListItem(value, position) {
+ var self = this;
+ var checked = null;
+ var node;
+ var task;
+ var indent;
+
+ value = LIST_ITEM_MAP[self.options.pedantic].apply(self, arguments);
+
+ if (self.options.gfm) {
+ task = value.match(EXPRESSION_TASK_ITEM);
+
+ if (task) {
+ indent = task[0].length;
+ checked = task[1].toLowerCase() === C_X_LOWER;
+
+ self.indent(position.line)(indent);
+ value = value.slice(indent);
+ }
+ }
+
+ node = {
+ 'type': T_LIST_ITEM,
+ 'loose': EXPRESSION_LOOSE_LIST_ITEM.test(value) ||
+ value.charAt(value.length - 1) === C_NEWLINE,
+ 'checked': checked
+ };
+
+ node.children = self.tokenizeBlock(value, position);
+
+ return node;
+}
+
+/**
+ * Create a footnote-definition node.
+ *
+ * @example
+ * renderFootnoteDefinition('1', '_foo_', now());
+ *
+ * @param {string} identifier - Unique reference.
+ * @param {string} value - Contents
+ * @param {Object} position - Definition location.
+ * @return {Object} - `footnoteDefinition` node.
+ */
+function renderFootnoteDefinition(identifier, value, position) {
+ var self = this;
+ var exitBlockquote = self.enterBlock();
+ var node;
+
+ node = {
+ 'type': T_FOOTNOTE_DEFINITION,
+ 'identifier': identifier,
+ 'children': self.tokenizeBlock(value, position)
+ };
+
+ exitBlockquote();
+
+ return node;
+}
+
+/**
+ * Create a heading node.
+ *
+ * @example
+ * renderHeading('_foo_', 1, now());
+ *
+ * @param {string} value - Content.
+ * @param {number} depth - Heading depth.
+ * @param {Object} position - Heading content location.
+ * @return {Object} - `heading` node
+ */
+function renderHeading(value, depth, position) {
+ return {
+ 'type': T_HEADING,
+ 'depth': depth,
+ 'children': this.tokenizeInline(value, position)
+ };
+}
+
+/**
+ * Create a blockquote node.
+ *
+ * @example
+ * renderBlockquote('_foo_', eat);
+ *
+ * @param {string} value - Content.
+ * @param {Object} now - Position.
+ * @return {Object} - `blockquote` node.
+ */
+function renderBlockquote(value, now) {
+ var self = this;
+ var exitBlockquote = self.enterBlock();
+ var node = {
+ 'type': T_BLOCKQUOTE,
+ 'children': self.tokenizeBlock(value, now)
+ };
+
+ exitBlockquote();
+
+ return node;
+}
+
+/**
+ * Create a void node.
+ *
+ * @example
+ * renderVoid('thematicBreak');
+ *
+ * @param {string} type - Node type.
+ * @return {Object} - Node of type `type`.
+ */
+function renderVoid(type) {
+ return {
+ 'type': type
+ };
+}
+
+/**
+ * Create a parent.
+ *
+ * @example
+ * renderParent('paragraph', '_foo_');
+ *
+ * @param {string} type - Node type.
+ * @param {Array.<Object>} children - Child nodes.
+ * @return {Object} - Node of type `type`.
+ */
+function renderParent(type, children) {
+ return {
+ 'type': type,
+ 'children': children
+ };
+}
+
+/**
+ * Create a raw node.
+ *
+ * @example
+ * renderRaw('inlineCode', 'foo()');
+ *
+ * @param {string} type - Node type.
+ * @param {string} value - Contents.
+ * @return {Object} - Node of type `type`.
+ */
+function renderRaw(type, value) {
+ return {
+ 'type': type,
+ 'value': value
+ };
+}
+
+/**
+ * Create a link node.
+ *
+ * @example
+ * renderLink(true, 'example.com', 'example', 'Example Domain', now(), eat);
+ * renderLink(false, 'fav.ico', 'example', 'Example Domain', now(), eat);
+ *
+ * @param {boolean} isLink - Whether linking to a document
+ * or an image.
+ * @param {string} url - URI reference.
+ * @param {string} content - Content.
+ * @param {string?} title - Title.
+ * @param {Object} position - Location of link.
+ * @return {Object} - `link` or `image` node.
+ */
+function renderLink(isLink, url, content, title, position) {
+ var self = this;
+ var exitLink = self.enterLink();
+ var node;
+
+ node = {
+ 'type': isLink ? T_LINK : T_IMAGE,
+ 'title': title || null
+ };
+
+ if (isLink) {
+ node.url = url;
+ node.children = self.tokenizeInline(content, position);
+ } else {
+ node.url = url;
+ node.alt = content ?
+ self.decode.raw(self.descape(content), position) :
+ null;
+ }
+
+ exitLink();
+
+ return node;
+}
+
+/**
+ * Create a footnote node.
+ *
+ * @example
+ * renderFootnote('_foo_', now());
+ *
+ * @param {string} value - Contents.
+ * @param {Object} position - Location of footnote.
+ * @return {Object} - `footnote` node.
+ */
+function renderFootnote(value, position) {
+ return this.renderInline(T_FOOTNOTE, value, position);
+}
+
+/**
+ * Add a node with inline content.
+ *
+ * @example
+ * renderInline('strong', '_foo_', now());
+ *
+ * @param {string} type - Node type.
+ * @param {string} value - Contents.
+ * @param {Object} position - Location of node.
+ * @return {Object} - Node of type `type`.
+ */
+function renderInline(type, value, position) {
+ return this.renderParent(type, this.tokenizeInline(value, position));
+}
+
+/**
+ * Add a node with block content.
+ *
+ * @example
+ * renderBlock('blockquote', 'Foo.', now());
+ *
+ * @param {string} type - Node type.
+ * @param {string} value - Contents.
+ * @param {Object} position - Location of node.
+ * @return {Object} - Node of type `type`.
+ */
+function renderBlock(type, value, position) {
+ return this.renderParent(type, this.tokenizeBlock(value, position));
+}
+
+/**
+ * Find a possible escape sequence.
+ *
+ * @example
+ * locateEscape('foo \- bar'); // 4
+ *
+ * @param {string} value - Value to search.
+ * @param {number} fromIndex - Index to start searching at.
+ * @return {number} - Location of possible escape sequence.
+ */
+function locateEscape(value, fromIndex) {
+ return value.indexOf(C_BACKSLASH, fromIndex);
+}
+
+/**
+ * Tokenise an escape sequence.
+ *
+ * @example
+ * tokenizeEscape(eat, '\\a');
+ *
+ * @property {Function} locator - Escape locator.
+ * @param {function(string)} eat - Eater.
+ * @param {string} value - Rest of content.
+ * @param {boolean?} [silent] - Whether this is a dry run.
+ * @return {Node?|boolean} - `text` or `break` node.
+ */
+function tokenizeEscape(eat, value, silent) {
+ var self = this;
+ var character;
+
+ if (value.charAt(0) === C_BACKSLASH) {
+ character = value.charAt(1);
+
+ if (self.escape.indexOf(character) !== -1) {
+ /* istanbul ignore if - never used (yet) */
+ if (silent) {
+ return true;
+ }
+
+ return eat(C_BACKSLASH + character)(
+ character === C_NEWLINE ?
+ self.renderVoid(T_BREAK) :
+ self.renderRaw(T_TEXT, character)
+ );
+ }
+ }
+}
+
+tokenizeEscape.locator = locateEscape;
+
+/**
+ * Find a possible auto-link.
+ *
+ * @example
+ * locateAutoLink('foo <bar'); // 4
+ *
+ * @param {string} value - Value to search.
+ * @param {number} fromIndex - Index to start searching at.
+ * @return {number} - Location of possible auto-link.
+ */
+function locateAutoLink(value, fromIndex) {
+ return value.indexOf(C_LT, fromIndex);
+}
+
+/**
+ * Tokenise a URL in carets.
+ *
+ * @example
+ * tokenizeAutoLink(eat, '<http://foo.bar>');
+ *
+ * @property {boolean} notInLink
+ * @property {Function} locator - Auto-link locator.
+ * @param {function(string)} eat - Eater.
+ * @param {string} value - Rest of content.
+ * @param {boolean?} [silent] - Whether this is a dry run.
+ * @return {Node?|boolean} - `link` node.
+ */
+function tokenizeAutoLink(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 node;
+
+ if (value.charAt(0) !== C_LT) {
+ return;
+ }
+
+ self = this;
+ subvalue = EMPTY;
+ length = value.length;
+ index = 0;
+ queue = EMPTY;
+ hasAtCharacter = false;
+ link = EMPTY;
+
+ index++;
+ subvalue = C_LT;
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (
+ character === C_SPACE ||
+ character === C_GT ||
+ character === C_AT_SIGN ||
+ (character === C_COLON && value.charAt(index + 1) === C_SLASH)
+ ) {
+ break;
+ }
+
+ queue += character;
+ index++;
+ }
+
+ if (!queue) {
+ return;
+ }
+
+ link += queue;
+ queue = EMPTY;
+
+ character = value.charAt(index);
+ link += character;
+ index++;
+
+ if (character === C_AT_SIGN) {
+ hasAtCharacter = true;
+ } else {
+ if (
+ character !== C_COLON ||
+ value.charAt(index + 1) !== C_SLASH
+ ) {
+ return;
+ }
+
+ link += C_SLASH;
+ index++;
+ }
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (character === C_SPACE || 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.substr(0, MAILTO_PROTOCOL.length).toLowerCase() !==
+ MAILTO_PROTOCOL
+ ) {
+ link = MAILTO_PROTOCOL + link;
+ } else {
+ content = content.substr(MAILTO_PROTOCOL.length);
+ now.column += MAILTO_PROTOCOL.length;
+ now.offset += MAILTO_PROTOCOL.length;
+ }
+ }
+
+ /*
+ * Temporarily remove support for escapes in autolinks.
+ */
+
+ tokenize = self.inlineTokenizers.escape;
+ self.inlineTokenizers.escape = null;
+
+ node = eat(subvalue)(
+ self.renderLink(true, decode(link), content, null, now, eat)
+ );
+
+ self.inlineTokenizers.escape = tokenize;
+
+ return node;
+}
+
+tokenizeAutoLink.notInLink = true;
+tokenizeAutoLink.locator = locateAutoLink;
+
+/**
+ * Find a possible URL.
+ *
+ * @example
+ * locateURL('foo http://bar'); // 4
+ *
+ * @param {string} value - Value to search.
+ * @param {number} fromIndex - Index to start searching at.
+ * @return {number} - Location of possible URL.
+ */
+function locateURL(value, fromIndex) {
+ var index = -1;
+ var min = -1;
+ var position;
+
+ if (!this.options.gfm) {
+ return -1;
+ }
+
+ while (++index < PROTOCOLS_LENGTH) {
+ position = value.indexOf(PROTOCOLS[index], fromIndex);
+
+ if (position !== -1 && (position < min || min === -1)) {
+ min = position;
+ }
+ }
+
+ return min;
+}
+
+/**
+ * Tokenise a URL in text.
+ *
+ * @example
+ * tokenizeURL(eat, 'http://foo.bar');
+ *
+ * @property {boolean} notInLink
+ * @property {Function} locator - URL locator.
+ * @param {function(string)} eat - Eater.
+ * @param {string} value - Rest of content.
+ * @param {boolean?} [silent] - Whether this is a dry run.
+ * @return {Node?|boolean} - `link` node.
+ */
+function tokenizeURL(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 now;
+
+ if (!self.options.gfm) {
+ return;
+ }
+
+ subvalue = EMPTY;
+ 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 = EMPTY;
+ parenCount = 0;
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (isWhiteSpace(character) || character === C_LT) {
+ break;
+ }
+
+ if (
+ character === C_DOT ||
+ character === C_COMMA ||
+ character === C_COLON ||
+ character === C_SEMI_COLON ||
+ character === C_DOUBLE_QUOTE ||
+ character === C_SINGLE_QUOTE ||
+ character === C_PAREN_CLOSE ||
+ character === C_BRACKET_CLOSE
+ ) {
+ nextCharacter = value.charAt(index + 1);
+
+ if (
+ !nextCharacter ||
+ isWhiteSpace(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;
+ }
+
+ now = eat.now();
+
+ return eat(subvalue)(
+ self.renderLink(true, decode(subvalue), content, null, now, eat)
+ );
+}
+
+tokenizeURL.notInLink = true;
+tokenizeURL.locator = locateURL;
+
+/**
+ * Find a possible tag.
+ *
+ * @example
+ * locateTag('foo <bar'); // 4
+ *
+ * @param {string} value - Value to search.
+ * @param {number} fromIndex - Index to start searching at.
+ * @return {number} - Location of possible tag.
+ */
+function locateTag(value, fromIndex) {
+ return value.indexOf(C_LT, fromIndex);
+}
+
+/**
+ * Tokenise an HTML tag.
+ *
+ * @example
+ * tokenizeInlineHTML(eat, '<span foo="bar">');
+ *
+ * @property {Function} locator - Tag locator.
+ * @param {function(string)} eat - Eater.
+ * @param {string} value - Rest of content.
+ * @param {boolean?} [silent] - Whether this is a dry run.
+ * @return {Node?|boolean} - `html` node.
+ */
+function tokenizeInlineHTML(eat, value, silent) {
+ var self = this;
+ var subvalue = eatHTMLComment(value, self.options) ||
+ eatHTMLCDATA(value) ||
+ eatHTMLProcessingInstruction(value) ||
+ eatHTMLDeclaration(value) ||
+ eatHTMLClosingTag(value) ||
+ eatHTMLOpeningTag(value);
+
+ if (!subvalue) {
+ return;
+ }
+
+ /* istanbul ignore if - never used (yet) */
+ if (silent) {
+ return true;
+ }
+
+ if (!self.inLink && EXPRESSION_HTML_LINK_OPEN.test(subvalue)) {
+ self.inLink = true;
+ } else if (self.inLink && EXPRESSION_HTML_LINK_CLOSE.test(subvalue)) {
+ self.inLink = false;
+ }
+
+ return eat(subvalue)(self.renderRaw(T_HTML, subvalue));
+}
+
+tokenizeInlineHTML.locator = locateTag;
+
+/**
+ * Find a possible link.
+ *
+ * @example
+ * locateLink('foo ![bar'); // 4
+ *
+ * @param {string} value - Value to search.
+ * @param {number} fromIndex - Index to start searching at.
+ * @return {number} - Location of possible link.
+ */
+function locateLink(value, fromIndex) {
+ var link = value.indexOf(C_BRACKET_OPEN, fromIndex);
+ var image = value.indexOf(C_EXCLAMATION_MARK + C_BRACKET_OPEN, fromIndex);
+
+ if (image === -1) {
+ return link;
+ }
+
+ /*
+ * Link can never be `-1` if an image is found, so we don’t need to
+ * check for that :)
+ */
+
+ return link < image ? link : image;
+}
+
+/**
+ * Tokenise a link.
+ *
+ * @example
+ * tokenizeLink(eat, '![foo](fav.ico "Favicon"));
+ *
+ * @property {Function} locator - Link locator.
+ * @param {function(string)} eat - Eater.
+ * @param {string} value - Rest of content.
+ * @param {boolean?} [silent] - Whether this is a dry run.
+ * @return {Node?|boolean} - `link` or `image` node.
+ */
+function tokenizeLink(eat, value, silent) {
+ var self = this;
+ var subvalue = EMPTY;
+ 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 openCount;
+ var hasMarker;
+ var markers;
+ var isImage;
+ var content;
+ var marker;
+ var length;
+ var title;
+ var depth;
+ var queue;
+ var url;
+ var now;
+
+ /*
+ * Detect whether this is an image.
+ */
+
+ if (character === C_EXCLAMATION_MARK) {
+ 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 = EMPTY;
+ index++;
+
+ /*
+ * Eat the content.
+ */
+
+ length = value.length;
+ now = eat.now();
+ depth = 0;
+
+ now.column += index;
+ now.offset += index;
+
+ while (index < length) {
+ subqueue = character = value.charAt(index);
+
+ 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 (!isWhiteSpace(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 = EMPTY;
+ 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 (!isWhiteSpace(character)) {
+ break;
+ }
+
+ subvalue += character;
+ index++;
+ }
+
+ /*
+ * Eat the URL.
+ */
+
+ character = value.charAt(index);
+ markers = commonmark ? COMMONMARK_LINK_MARKERS : LINK_MARKERS;
+ openCount = 0;
+ queue = EMPTY;
+ 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 === C_NEWLINE) {
+ return;
+ }
+
+ queue += character;
+ index++;
+ }
+
+ if (value.charAt(index) !== C_GT) {
+ return;
+ }
+
+ subvalue += C_LT + queue + C_GT;
+ url = queue;
+ index++;
+ } else {
+ character = null;
+ subqueue = EMPTY;
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (subqueue && has.call(markers, character)) {
+ break;
+ }
+
+ if (isWhiteSpace(character)) {
+ if (commonmark) {
+ break;
+ }
+
+ subqueue += character;
+ } else {
+ if (character === C_PAREN_OPEN) {
+ depth++;
+ openCount++;
+ } else if (character === C_PAREN_CLOSE) {
+ if (depth === 0) {
+ break;
+ }
+
+ depth--;
+ }
+
+ queue += subqueue;
+ subqueue = EMPTY;
+
+ 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 = EMPTY;
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (!isWhiteSpace(character)) {
+ break;
+ }
+
+ queue += character;
+ index++;
+ }
+
+ character = value.charAt(index);
+ subvalue += queue;
+
+ /*
+ * Eat the title.
+ */
+
+ if (queue && has.call(markers, character)) {
+ index++;
+ subvalue += character;
+ queue = EMPTY;
+ 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 (!isWhiteSpace(character)) {
+ break;
+ }
+
+ subvalue += character;
+ index++;
+ }
+ } else {
+ subqueue = EMPTY;
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (character === marker) {
+ if (hasMarker) {
+ queue += marker + subqueue;
+ subqueue = EMPTY;
+ }
+
+ hasMarker = true;
+ } else if (!hasMarker) {
+ queue += character;
+ } else if (character === C_PAREN_CLOSE) {
+ subvalue += queue + marker + subqueue;
+ title = queue;
+ break;
+ } else if (isWhiteSpace(character)) {
+ subqueue += character;
+ } else {
+ queue += marker + subqueue + character;
+ subqueue = EMPTY;
+ 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.descape(url), eat(beforeURL).test().end);
+
+ if (title) {
+ beforeTitle = eat(beforeTitle).test().end;
+ title = self.decode.raw(self.descape(title), beforeTitle);
+ }
+
+ return eat(subvalue)(
+ self.renderLink(!isImage, url, content, title, now, eat)
+ );
+}
+
+tokenizeLink.locator = locateLink;
+
+/**
+ * Tokenise a reference link, image, or footnote;
+ * shortcut reference link, or footnote.
+ *
+ * @example
+ * tokenizeReference(eat, '[foo]');
+ * tokenizeReference(eat, '[foo][]');
+ * tokenizeReference(eat, '[foo][bar]');
+ *
+ * @property {Function} locator - Reference locator.
+ * @param {function(string)} eat - Eater.
+ * @param {string} value - Rest of content.
+ * @param {boolean?} [silent] - Whether this is a dry run.
+ * @return {Node?|boolean} - Reference node.
+ */
+function tokenizeReference(eat, value, silent) {
+ var self = this;
+ var character = value.charAt(0);
+ var index = 0;
+ var length = value.length;
+ var subvalue = EMPTY;
+ var intro = EMPTY;
+ var type = T_LINK;
+ var referenceType = REFERENCE_TYPE_SHORTCUT;
+ var content;
+ var identifier;
+ var now;
+ var node;
+ var exitLink;
+ var queue;
+ var bracketed;
+ var depth;
+
+ /*
+ * Check whether we’re eating an image.
+ */
+
+ if (character === C_EXCLAMATION_MARK) {
+ type = T_IMAGE;
+ intro = character;
+ character = value.charAt(++index);
+ }
+
+ if (character !== C_BRACKET_OPEN) {
+ return;
+ }
+
+ index++;
+ intro += character;
+ queue = EMPTY;
+
+ /*
+ * Check whether we’re eating a footnote.
+ */
+
+ if (
+ self.options.footnotes &&
+ type === T_LINK &&
+ value.charAt(index) === C_CARET
+ ) {
+ intro += C_CARET;
+ index++;
+ type = T_FOOTNOTE;
+ }
+
+ /*
+ * Eat the text.
+ */
+
+ depth = 0;
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (character === C_BRACKET_OPEN) {
+ bracketed = true;
+ depth++;
+ } else if (character === C_BRACKET_CLOSE) {
+ if (!depth) {
+ break;
+ }
+
+ depth--;
+ }
+
+ if (character === C_BACKSLASH) {
+ queue += C_BACKSLASH;
+ character = value.charAt(++index);
+ }
+
+ queue += character;
+ index++;
+ }
+
+ subvalue = content = queue;
+ character = value.charAt(index);
+
+ if (character !== C_BRACKET_CLOSE) {
+ return;
+ }
+
+ index++;
+ subvalue += character;
+ queue = EMPTY;
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (!isWhiteSpace(character)) {
+ break;
+ }
+
+ queue += character;
+ index++;
+ }
+
+ character = value.charAt(index);
+
+ if (character !== C_BRACKET_OPEN) {
+ if (!content) {
+ return;
+ }
+
+ identifier = content;
+ } else {
+ identifier = EMPTY;
+ queue += character;
+ index++;
+
+ while (index < length) {
+ character = value.charAt(index);
+
+ if (
+ character === C_BRACKET_OPEN ||
+ character === C_BRACKET_CLOSE
+ ) {
+ break;
+ }
+
+ if (character === C_BACKSLASH) {
+ identifier += C_BACKSLASH;
+ character = value.charAt(++index);
+ }
+
+ identifier += character;
+ index++;
+ }
+
+ character = value.charAt(index);
+
+ if (character === C_BRACKET_CLOSE) {
+ queue += identifier + character;
+ index++;
+
+ referenceType = identifier ?
+ REFERENCE_TYPE_FULL :
+ REFERENCE_TYPE_COLLAPSED;
+ } else {
+ identifier = EMPTY;
+ }
+
+ subvalue += queue;
+ queue = EMPTY;
+ }
+
+ /*
+ * Brackets cannot be inside the identifier.
+ */
+
+ if (referenceType !== REFERENCE_TYPE_FULL && bracketed) {
+ return;
+ }
+
+ /*
+ * Inline footnotes cannot have an identifier.
+ */
+
+ if (type === T_FOOTNOTE && referenceType !== REFERENCE_TYPE_SHORTCUT) {
+ type = T_LINK;
+ intro = C_BRACKET_OPEN + C_CARET;
+ content = C_CARET + content;
+ }
+
+ subvalue = intro + subvalue;
+
+ if (type === T_LINK && self.inLink) {
+ return null;
+ }
+
+ /* istanbul ignore if - never used (yet) */
+ if (silent) {
+ return true;
+ }
+
+ if (type === T_FOOTNOTE && content.indexOf(C_SPACE) !== -1) {
+ return eat(subvalue)(self.renderFootnote(content, eat.now()));
+ }
+
+ now = eat.now();
+ now.column += intro.length;
+ now.offset += intro.length;
+ identifier = referenceType === REFERENCE_TYPE_FULL ? identifier : content;
+
+ node = {
+ 'type': type + 'Reference',
+ 'identifier': normalize(identifier)
+ };
+
+ if (type === T_LINK || type === T_IMAGE) {
+ node.referenceType = referenceType;
+ }
+
+ if (type === T_LINK) {
+ exitLink = self.enterLink();
+ node.children = self.tokenizeInline(content, now);
+ exitLink();
+ } else if (type === T_IMAGE) {
+ node.alt = self.decode.raw(self.descape(content), now) || null;
+ }
+
+ return eat(subvalue)(node);
+}
+
+tokenizeReference.locator = locateLink;
+
+/**
+ * Find a possible strong emphasis.
+ *
+ * @example
+ * locateStrong('foo **bar'); // 4
+ *
+ * @param {string} value - Value to search.
+ * @param {number} fromIndex - Index to start searching at.
+ * @return {number} - Location of possible strong emphasis.
+ */
+function locateStrong(value, fromIndex) {
+ var asterisk = value.indexOf(C_ASTERISK + C_ASTERISK, fromIndex);
+ var underscore = value.indexOf(C_UNDERSCORE + C_UNDERSCORE, fromIndex);
+
+ if (underscore === -1) {
+ return asterisk;
+ }
+
+ if (asterisk === -1) {
+ return underscore;
+ }
+
+ return underscore < asterisk ? underscore : asterisk;
+}
+
+/**
+ * Tokenise strong emphasis.
+ *
+ * @example
+ * tokenizeStrong(eat, '**foo**');
+ * tokenizeStrong(eat, '__foo__');
+ *
+ * @property {Function} locator - Strong emphasis locator.
+ * @param {function(string)} eat - Eater.
+ * @param {string} value - Rest of content.
+ * @param {boolean?} [silent] - Whether this is a dry run.
+ * @return {Node?|boolean} - `strong` node.
+ */
+function tokenizeStrong(eat, value, silent) {
+ var self = this;
+ var index = 0;
+ var character = value.charAt(index);
+ var now;
+ var pedantic;
+ var marker;
+ var queue;
+ var subvalue;
+ var length;
+ var prev;
+
+ if (
+ EMPHASIS_MARKERS[character] !== true ||
+ value.charAt(++index) !== character
+ ) {
+ return;
+ }
+
+ pedantic = self.options.pedantic;
+ marker = character;
+ subvalue = marker + marker;
+ length = value.length;
+ index++;
+ queue = character = EMPTY;
+
+ if (pedantic && isWhiteSpace(value.charAt(index))) {
+ return;
+ }
+
+ while (index < length) {
+ prev = character;
+ character = value.charAt(index);
+
+ if (
+ character === marker &&
+ value.charAt(index + 1) === marker &&
+ (!pedantic || !isWhiteSpace(prev))
+ ) {
+ character = value.charAt(index + 2);
+
+ if (character !== marker) {
+ if (!trim(queue)) {
+ return;
+ }
+
+ /* istanbul ignore if - never used (yet) */
+ if (silent) {
+ return true;
+ }
+
+ now = eat.now();
+ now.column += 2;
+ now.offset += 2;
+
+ return eat(subvalue + queue + subvalue)(
+ self.renderInline(T_STRONG, queue, now)
+ );
+ }
+ }
+
+ if (!pedantic && character === C_BACKSLASH) {
+ queue += character;
+ character = value.charAt(++index);
+ }
+
+ queue += character;
+ index++;
+ }
+}
+
+tokenizeStrong.locator = locateStrong;
+
+/**
+ * Find possible slight emphasis.
+ *
+ * @example
+ * locateEmphasis('foo *bar'); // 4
+ *
+ * @param {string} value - Value to search.
+ * @param {number} fromIndex - Index to start searching at.
+ * @return {number} - Location of possible slight emphasis.
+ */
+function locateEmphasis(value, fromIndex) {
+ var asterisk = value.indexOf(C_ASTERISK, fromIndex);
+ var underscore = value.indexOf(C_UNDERSCORE, fromIndex);
+
+ if (underscore === -1) {
+ return asterisk;
+ }
+
+ if (asterisk === -1) {
+ return underscore;
+ }
+
+ return underscore < asterisk ? underscore : asterisk;
+}
+
+/**
+ * Tokenise slight emphasis.
+ *
+ * @example
+ * tokenizeEmphasis(eat, '*foo*');
+ * tokenizeEmphasis(eat, '_foo_');
+ *
+ * @property {Function} locator - Slight emphasis locator.
+ * @param {function(string)} eat - Eater.
+ * @param {string} value - Rest of content.
+ * @param {boolean?} [silent] - Whether this is a dry run.
+ * @return {Node?|boolean} - `emphasis` node.
+ */
+function tokenizeEmphasis(eat, value, silent) {
+ var self = this;
+ var index = 0;
+ var character = value.charAt(index);
+ var now;
+ var pedantic;
+ var marker;
+ var queue;
+ var subvalue;
+ var length;
+ var prev;
+
+ if (EMPHASIS_MARKERS[character] !== true) {
+ return;
+ }
+
+ pedantic = self.options.pedantic;
+ subvalue = marker = character;
+ length = value.length;
+ index++;
+ queue = character = EMPTY;
+
+ if (pedantic && isWhiteSpace(value.charAt(index))) {
+ return;
+ }
+
+ while (index < length) {
+ prev = character;
+ character = value.charAt(index);
+
+ if (
+ character === marker &&
+ (!pedantic || !isWhiteSpace(prev))
+ ) {
+ character = value.charAt(++index);
+
+ if (character !== marker) {
+ if (!trim(queue) || prev === marker) {
+ return;
+ }
+
+ if (
+ pedantic ||
+ marker !== C_UNDERSCORE ||
+ !isWordCharacter(character)
+ ) {
+ /* istanbul ignore if - never used (yet) */
+ if (silent) {
+ return true;
+ }
+
+ now = eat.now();
+ now.column++;
+ now.offset++;
+
+ return eat(subvalue + queue + marker)(
+ self.renderInline(T_EMPHASIS, queue, now)
+ );
+ }
+ }
+
+ queue += marker;
+ }
+
+ if (!pedantic && character === C_BACKSLASH) {
+ queue += character;
+ character = value.charAt(++index);
+ }
+
+ queue += character;
+ index++;
+ }
+}
+
+tokenizeEmphasis.locator = locateEmphasis;
+
+/**
+ * Find a possible deletion.
+ *
+ * @example
+ * locateDeletion('foo ~~bar'); // 4
+ *
+ * @param {string} value - Value to search.
+ * @param {number} fromIndex - Index to start searching at.
+ * @return {number} - Location of possible deletion.
+ */
+function locateDeletion(value, fromIndex) {
+ return value.indexOf(C_TILDE + C_TILDE, fromIndex);
+}
+
+/**
+ * Tokenise a deletion.
+ *
+ * @example
+ * tokenizeDeletion(eat, '~~foo~~');
+ *
+ * @property {Function} locator - Deletion locator.
+ * @param {function(string)} eat - Eater.
+ * @param {string} value - Rest of content.
+ * @param {boolean?} [silent] - Whether this is a dry run.
+ * @return {Node?|boolean} - `delete` node.
+ */
+function tokenizeDeletion(eat, value, silent) {
+ var self = this;
+ var character = EMPTY;
+ var previous = EMPTY;
+ var preceding = EMPTY;
+ var subvalue = EMPTY;
+ var index;
+ var length;
+ var now;
+
+ if (
+ !self.options.gfm ||
+ value.charAt(0) !== C_TILDE ||
+ value.charAt(1) !== C_TILDE ||
+ isWhiteSpace(value.charAt(2))
+ ) {
+ return;
+ }
+
+ index = 1;
+ length = value.length;
+ now = eat.now();
+ now.column += 2;
+ now.offset += 2;
+
+ while (++index < length) {
+ character = value.charAt(index);
+
+ if (
+ character === C_TILDE &&
+ previous === C_TILDE &&
+ (!preceding || !isWhiteSpace(preceding))
+ ) {
+ /* istanbul ignore if - never used (yet) */
+ if (silent) {
+ return true;
+ }
+
+ return eat(C_TILDE + C_TILDE + subvalue + C_TILDE + C_TILDE)(
+ self.renderInline(T_DELETE, subvalue, now)
+ );
+ }
+
+ subvalue += previous;
+ preceding = previous;
+ previous = character;
+ }
+}
+
+tokenizeDeletion.locator = locateDeletion;
+
+/**
+ * Find possible inline code.
+ *
+ * @example
+ * locateInlineCode('foo `bar'); // 4
+ *
+ * @param {string} value - Value to search.
+ * @param {number} fromIndex - Index to start searching at.
+ * @return {number} - Location of possible inline code.
+ */
+function locateInlineCode(value, fromIndex) {
+ return value.indexOf(C_TICK, fromIndex);
+}
+
+/**
+ * Tokenise inline code.
+ *
+ * @example
+ * tokenizeInlineCode(eat, '`foo()`');
+ *
+ * @property {Function} locator - Inline code locator.
+ * @param {function(string)} eat - Eater.
+ * @param {string} value - Rest of content.
+ * @param {boolean?} [silent] - Whether this is a dry run.
+ * @return {Node?|boolean} - `inlineCode` node.
+ */
+function tokenizeInlineCode(eat, value, silent) {
+ var self = this;
+ var length = value.length;
+ var index = 0;
+ var queue = EMPTY;
+ var tickQueue = EMPTY;
+ var contentQueue;
+ var subqueue;
+ var count;
+ var openingCount;
+ var subvalue;
+ var character;
+ var found;
+ var next;
+
+ while (index < length) {
+ if (value.charAt(index) !== C_TICK) {
+ break;
+ }
+
+ queue += C_TICK;
+ index++;
+ }
+
+ if (!queue) {
+ return;
+ }
+
+ subvalue = queue;
+ openingCount = index;
+ queue = EMPTY;
+ next = value.charAt(index);
+ count = 0;
+
+ while (index < length) {
+ character = next;
+ next = value.charAt(index + 1);
+
+ if (character === C_TICK) {
+ count++;
+ tickQueue += character;
+ } else {
+ count = 0;
+ queue += character;
+ }
+
+ if (count && next !== C_TICK) {
+ if (count === openingCount) {
+ subvalue += queue + tickQueue;
+ found = true;
+ break;
+ }
+
+ queue += tickQueue;
+ tickQueue = EMPTY;
+ }
+
+ index++;
+ }
+
+ if (!found) {
+ if (openingCount % 2 !== 0) {
+ return;
+ }
+
+ queue = EMPTY;
+ }
+
+ /* istanbul ignore if - never used (yet) */
+ if (silent) {
+ return true;
+ }
+
+ contentQueue = subqueue = EMPTY;
+ length = queue.length;
+ index = -1;
+
+ while (++index < length) {
+ character = queue.charAt(index);
+
+ if (isWhiteSpace(character)) {
+ subqueue += character;
+ continue;
+ }
+
+ if (subqueue) {
+ if (contentQueue) {
+ contentQueue += subqueue;
+ }
+
+ subqueue = EMPTY;
+ }
+
+ contentQueue += character;
+ }
+
+ return eat(subvalue)(self.renderRaw(T_INLINE_CODE, contentQueue));
+}
+
+tokenizeInlineCode.locator = locateInlineCode;
+
+/**
+ * Find a possible break.
+ *
+ * @example
+ * locateBreak('foo \nbar'); // 3
+ *
+ * @param {string} value - Value to search.
+ * @param {number} fromIndex - Index to start searching at.
+ * @return {number} - Location of possible break.
+ */
+function locateBreak(value, fromIndex) {
+ var index = value.indexOf(C_NEWLINE, fromIndex);
+
+ while (index > fromIndex) {
+ if (value.charAt(index - 1) !== C_SPACE) {
+ break;
+ }
+
+ index--;
+ }
+
+ return index;
+}
+
+/**
+ * Tokenise a break.
+ *
+ * @example
+ * tokenizeBreak(eat, ' \n');
+ *
+ * @property {Function} locator - Break locator.
+ * @param {function(string)} eat - Eater.
+ * @param {string} value - Rest of content.
+ * @param {boolean?} [silent] - Whether this is a dry run.
+ * @return {Node?|boolean} - `break` node.
+ */
+function tokenizeBreak(eat, value, silent) {
+ var self = this;
+ var breaks = self.options.breaks;
+ var length = value.length;
+ var index = -1;
+ var queue = EMPTY;
+ var character;
+
+ while (++index < length) {
+ character = value.charAt(index);
+
+ if (character === C_NEWLINE) {
+ if (!breaks && index < MIN_BREAK_LENGTH) {
+ return;
+ }
+
+ /* istanbul ignore if - never used (yet) */
+ if (silent) {
+ return true;
+ }
+
+ queue += character;
+ return eat(queue)(self.renderVoid(T_BREAK));
+ }
+
+ if (character !== C_SPACE) {
+ return;
+ }
+
+ queue += character;
+ }
+}
+
+tokenizeBreak.locator = locateBreak;
+
+/**
+ * Construct a new parser.
+ *
+ * @example
+ * var parser = new Parser(new VFile('Foo'));
+ *
+ * @constructor
+ * @class {Parser}
+ * @param {VFile} file - File to parse.
+ * @param {Object?} [options] - Passed to
+ * `Parser#setOptions()`.
+ */
+function Parser(file, options) {
+ var self = this;
+
+ self.file = file;
+ self.inLink = false;
+ self.inBlock = false;
+ self.inList = false;
+ self.atStart = true;
+ self.toOffset = vfileLocation(file).toOffset;
+
+ self.descape = descapeFactory(self, 'escape');
+ self.decode = decodeFactory(self);
+
+ self.options = extend({}, self.options);
+
+ self.setOptions(options);
+}
+
+/**
+ * Set options. Does not overwrite previously set
+ * options.
+ *
+ * @example
+ * var parser = new Parser();
+ * parser.setOptions({gfm: true});
+ *
+ * @this {Parser}
+ * @throws {Error} - When an option is invalid.
+ * @param {Object?} [options] - Parse settings.
+ * @return {Parser} - `self`.
+ */
+Parser.prototype.setOptions = function (options) {
+ var self = this;
+ var current = self.options;
+ var key;
+
+ if (options === null || options === undefined) {
+ options = {};
+ } else if (typeof options === 'object') {
+ options = extend({}, options);
+ } else {
+ throw new Error(
+ 'Invalid value `' + options + '` ' +
+ 'for setting `options`'
+ );
+ }
+
+ for (key in defaultOptions) {
+ var value = options[key];
+
+ if (value === null || value === undefined) {
+ value = current[key];
+ }
+
+ if (typeof value !== 'boolean') {
+ throw new Error(
+ 'Invalid value `' + value + '` ' +
+ 'for setting `options.' + key + '`'
+ );
+ }
+
+ options[key] = value;
+ }
+
+ self.options = options;
+
+ if (options.commonmark) {
+ self.escape = escapes.commonmark;
+ } else if (options.gfm) {
+ self.escape = escapes.gfm;
+ } else {
+ self.escape = escapes.default;
+ }
+
+ return self;
+};
+
+/*
+ * Expose `defaults`.
+ */
+
+Parser.prototype.options = defaultOptions;
+
+/**
+ * Factory to track indentation for each line corresponding
+ * to the given `start` and the number of invocations.
+ *
+ * @param {number} start - Starting line.
+ * @return {function(offset)} - Indenter.
+ */
+Parser.prototype.indent = function (start) {
+ var self = this;
+ var line = start;
+
+ /**
+ * Intender which increments the global offset,
+ * starting at the bound line, and further incrementing
+ * each line for each invocation.
+ *
+ * @example
+ * indenter(2);
+ *
+ * @param {number} offset - Number to increment the
+ * offset.
+ */
+ function indenter(offset) {
+ self.offset[line] = (self.offset[line] || 0) + offset;
+
+ line++;
+ }
+
+ return indenter;
};
-proto.inlineTokenizers = {
- escape: require('./tokenize/escape'),
- autoLink: require('./tokenize/auto-link'),
- url: require('./tokenize/url'),
- html: require('./tokenize/html-inline'),
- link: require('./tokenize/link'),
- reference: require('./tokenize/reference'),
- strong: require('./tokenize/strong'),
- emphasis: require('./tokenize/emphasis'),
- deletion: require('./tokenize/delete'),
- code: require('./tokenize/code-inline'),
- break: require('./tokenize/break'),
- text: require('./tokenize/text')
+/**
+ * Get found offsets starting at `start`.
+ *
+ * @param {number} start - Starting line.
+ * @return {Array.<number>} - Offsets starting at `start`.
+ */
+Parser.prototype.getIndent = function (start) {
+ var offset = this.offset;
+ var result = [];
+
+ while (++start) {
+ if (!(start in offset)) {
+ break;
+ }
+
+ result.push((offset[start] || 0) + 1);
+ }
+
+ return result;
};
-/* Expose precedence. */
-proto.blockMethods = keys(proto.blockTokenizers);
-proto.inlineMethods = keys(proto.inlineTokenizers);
+/**
+ * Parse the bound file.
+ *
+ * @example
+ * new Parser(new File('_Foo_.')).parse();
+ *
+ * @this {Parser}
+ * @return {Object} - `root` node.
+ */
+Parser.prototype.parse = function () {
+ var self = this;
+ var value = String(self.file);
+ var column = 1;
+ var node;
+
+ /*
+ * Clean non-unix newlines: `\r\n` and `\r` are all
+ * changed to `\n`. This should not affect positional
+ * information.
+ */
+
+ value = value.replace(EXPRESSION_LINE_BREAKS, C_NEWLINE);
+
+ if (value.charCodeAt(0) === 0xFEFF) {
+ value = value.slice(1);
+ column++;
+ self.offset++;
+ }
+
+ /*
+ * Add an `offset` matrix, used to keep track of
+ * syntax and white space indentation per line.
+ */
+
+ self.offset = {};
+
+ node = self.renderBlock(T_ROOT, value, {
+ 'line': 1,
+ 'column': column
+ });
+
+ node.position = {
+ 'start': {
+ 'line': 1,
+ 'column': 1,
+ 'offset': 0
+ }
+ };
+
+ node.position.end = self.eof || extend({}, node.position.start);
+
+ if (!self.options.position) {
+ removePosition(node);
+ }
+
+ return node;
+};
+
+/*
+ * Enter and exit helpers.
+ */
+
+Parser.prototype.exitStart = toggle('atStart', true);
+Parser.prototype.enterList = toggle('inList', false);
+Parser.prototype.enterLink = toggle('inLink', false);
+Parser.prototype.enterBlock = toggle('inBlock', false);
+
+/*
+ * Expose helpers
+ */
+
+Parser.prototype.renderRaw = renderRaw;
+Parser.prototype.renderVoid = renderVoid;
+Parser.prototype.renderParent = renderParent;
+Parser.prototype.renderInline = renderInline;
+Parser.prototype.renderBlock = renderBlock;
+
+Parser.prototype.renderLink = renderLink;
+Parser.prototype.renderCodeBlock = renderCodeBlock;
+Parser.prototype.renderBlockquote = renderBlockquote;
+Parser.prototype.renderListItem = renderListItem;
+Parser.prototype.renderFootnoteDefinition = renderFootnoteDefinition;
+Parser.prototype.renderHeading = renderHeading;
+Parser.prototype.renderFootnote = renderFootnote;
+
+/**
+ * Construct a tokenizer. This creates both
+ * `tokenizeInline` and `tokenizeBlock`.
+ *
+ * @example
+ * Parser.prototype.tokenizeInline = tokenizeFactory('inline');
+ *
+ * @param {string} type - Name of parser, used to find
+ * its expressions (`%sMethods`) and tokenizers
+ * (`%Tokenizers`).
+ * @return {Function} - Tokenizer.
+ */
+function tokenizeFactory(type) {
+ /**
+ * Tokenizer for a bound `type`
+ *
+ * @example
+ * parser = new Parser();
+ * parser.tokenizeInline('_foo_');
+ *
+ * @param {string} value - Content.
+ * @param {Object} location - Offset at which `value`
+ * starts.
+ * @return {Array.<Object>} - Nodes.
+ */
+ function tokenize(value, location) {
+ var self = this;
+ var offset = self.offset;
+ var tokens = [];
+ var methods = self[type + 'Methods'];
+ var tokenizers = self[type + 'Tokenizers'];
+ var line = location.line;
+ var column = location.column;
+ var add;
+ var index;
+ var length;
+ var method;
+ var name;
+ var matched;
+ var valueLength;
+
+ /*
+ * Trim white space only lines.
+ */
+
+ if (!value) {
+ return tokens;
+ }
+
+ /**
+ * Update line, column, and offset based on
+ * `value`.
+ *
+ * @example
+ * updatePosition('foo');
+ *
+ * @param {string} subvalue - Subvalue to eat.
+ */
+ function updatePosition(subvalue) {
+ var lastIndex = -1;
+ var index = subvalue.indexOf(C_NEWLINE);
+
+ while (index !== -1) {
+ line++;
+ lastIndex = index;
+ index = subvalue.indexOf(C_NEWLINE, index + 1);
+ }
+
+ if (lastIndex === -1) {
+ column += subvalue.length;
+ } else {
+ column = subvalue.length - lastIndex;
+ }
+
+ if (line in offset) {
+ if (lastIndex !== -1) {
+ column += offset[line];
+ } else if (column <= offset[line]) {
+ column = offset[line] + 1;
+ }
+ }
+ }
-/* Tokenizers. */
-proto.tokenizeBlock = tokenizer('block');
-proto.tokenizeInline = tokenizer('inline');
-proto.tokenizeFactory = tokenizer;
+ /**
+ * Get offset. Called before the first character is
+ * eaten to retrieve the range's offsets.
+ *
+ * @return {Function} - `done`, to be called when
+ * the last character is eaten.
+ */
+ function getOffset() {
+ var indentation = [];
+ var pos = line + 1;
-/* Get all keys in `value`. */
-function keys(value) {
- var result = [];
- var key;
+ /**
+ * Done. Called when the last character is
+ * eaten to retrieve the range’s offsets.
+ *
+ * @return {Array.<number>} - Offset.
+ */
+ function done() {
+ var last = line + 1;
- for (key in value) {
- result.push(key);
- }
+ while (pos < last) {
+ indentation.push((offset[pos] || 0) + 1);
- return result;
+ pos++;
+ }
+
+ return indentation;
+ }
+
+ return done;
+ }
+
+ /**
+ * Get the current position.
+ *
+ * @example
+ * position = now(); // {line: 1, column: 1, offset: 0}
+ *
+ * @return {Object} - Current Position.
+ */
+ function now() {
+ var pos = {
+ 'line': line,
+ 'column': column
+ };
+
+ pos.offset = self.toOffset(pos);
+
+ return pos;
+ }
+
+ /**
+ * Store position information for a node.
+ *
+ * @example
+ * start = now();
+ * updatePosition('foo');
+ * location = new Position(start);
+ * // {
+ * // start: {line: 1, column: 1, offset: 0},
+ * // end: {line: 1, column: 3, offset: 2}
+ * // }
+ *
+ * @param {Object} start - Starting position.
+ */
+ function Position(start) {
+ this.start = start;
+ this.end = now();
+ }
+
+ /**
+ * Throw when a value is incorrectly eaten.
+ * This shouldn’t happen but will throw on new,
+ * incorrect rules.
+ *
+ * @example
+ * // When the current value is set to `foo bar`.
+ * validateEat('foo');
+ * eat('foo');
+ *
+ * validateEat('bar');
+ * // throws, because the space is not eaten.
+ *
+ * @param {string} subvalue - Value to be eaten.
+ * @throws {Error} - When `subvalue` cannot be eaten.
+ */
+ function validateEat(subvalue) {
+ /* istanbul ignore if */
+ if (value.substring(0, subvalue.length) !== subvalue) {
+ self.file.fail(ERR_INCORRECTLY_EATEN, now());
+ }
+ }
+
+ /**
+ * Mark position and patch `node.position`.
+ *
+ * @example
+ * var update = position();
+ * updatePosition('foo');
+ * update({});
+ * // {
+ * // position: {
+ * // start: {line: 1, column: 1, offset: 0},
+ * // end: {line: 1, column: 3, offset: 2}
+ * // }
+ * // }
+ *
+ * @returns {Function} - Updater.
+ */
+ function position() {
+ var before = now();
+
+ /**
+ * Add the position to a node.
+ *
+ * @example
+ * update({type: 'text', value: 'foo'});
+ *
+ * @param {Node} node - Node to attach position
+ * on.
+ * @param {Array} [indent] - Indentation for
+ * `node`.
+ * @return {Node} - `node`.
+ */
+ function update(node, indent) {
+ var prev = node.position;
+ var start = prev ? prev.start : before;
+ var combined = [];
+ var n = prev && prev.end.line;
+ var l = before.line;
+
+ node.position = new Position(start);
+
+ /*
+ * If there was already a `position`, this
+ * node was merged. Fixing `start` wasn’t
+ * hard, but the indent is different.
+ * Especially because some information, the
+ * indent between `n` and `l` wasn’t
+ * tracked. Luckily, that space is
+ * (should be?) empty, so we can safely
+ * check for it now.
+ */
+
+ if (prev && indent && prev.indent) {
+ combined = prev.indent;
+
+ if (n < l) {
+ while (++n < l) {
+ combined.push((offset[n] || 0) + 1);
+ }
+
+ combined.push(before.column);
+ }
+
+ indent = combined.concat(indent);
+ }
+
+ node.position.indent = indent || [];
+
+ return node;
+ }
+
+ return update;
+ }
+
+ /**
+ * Add `node` to `parent`s children or to `tokens`.
+ * Performs merges where possible.
+ *
+ * @example
+ * add({});
+ *
+ * add({}, {children: []});
+ *
+ * @param {Object} node - Node to add.
+ * @param {Object} [parent] - Parent to insert into.
+ * @return {Object} - Added or merged into node.
+ */
+ add = function (node, parent) {
+ var prev;
+ var children;
+
+ if (!parent) {
+ children = tokens;
+ } else {
+ children = parent.children;
+ }
+
+ prev = children[children.length - 1];
+
+ if (
+ prev &&
+ node.type === prev.type &&
+ node.type in MERGEABLE_NODES &&
+ mergeable(prev) &&
+ mergeable(node)
+ ) {
+ node = MERGEABLE_NODES[node.type].call(
+ self, prev, node
+ );
+ }
+
+ if (node !== prev) {
+ children.push(node);
+ }
+
+ if (self.atStart && tokens.length) {
+ self.exitStart();
+ }
+
+ return node;
+ };
+
+ /**
+ * Remove `subvalue` from `value`.
+ * `subvalue` must be at the start of `value`.
+ *
+ * @example
+ * eat('foo')({type: 'text', value: 'foo'});
+ *
+ * @param {string} subvalue - Removed from `value`,
+ * and passed to `updatePosition`.
+ * @return {Function} - Wrapper around `add`, which
+ * also adds `position` to node.
+ */
+ function eat(subvalue) {
+ var indent = getOffset();
+ var pos = position();
+ var current = now();
+
+ validateEat(subvalue);
+
+ /**
+ * Add the given arguments, add `position` to
+ * the returned node, and return the node.
+ *
+ * @param {Object} node - Node to add.
+ * @param {Object} [parent] - Node to insert into.
+ * @return {Node} - Added node.
+ */
+ function apply(node, parent) {
+ return pos(add(pos(node), parent), indent);
+ }
+
+ /**
+ * Functions just like apply, but resets the
+ * content: the line and column are reversed,
+ * and the eaten value is re-added.
+ *
+ * This is useful for nodes with a single
+ * type of content, such as lists and tables.
+ *
+ * See `apply` above for what parameters are
+ * expected.
+ *
+ * @return {Node} - Added node.
+ */
+ function reset() {
+ var node = apply.apply(null, arguments);
+
+ line = current.line;
+ column = current.column;
+ value = subvalue + value;
+
+ return node;
+ }
+
+ /**
+ * Test the position, after eating, and reverse
+ * to a not-eaten state.
+ *
+ * @return {Position} - Position after eating `subvalue`.
+ */
+ function test() {
+ var result = pos({});
+
+ line = current.line;
+ column = current.column;
+ value = subvalue + value;
+
+ return result.position;
+ }
+
+ apply.reset = reset;
+ apply.test = reset.test = test;
+
+ value = value.substring(subvalue.length);
+
+ updatePosition(subvalue);
+
+ indent = indent();
+
+ return apply;
+ }
+
+ /*
+ * Expose `now` on `eat`.
+ */
+
+ eat.now = now;
+
+ /*
+ * Expose `file` on `eat`.
+ */
+
+ eat.file = self.file;
+
+ /*
+ * Sync initial offset.
+ */
+
+ updatePosition(EMPTY);
+
+ /*
+ * Iterate over `value`, and iterate over all
+ * tokenizers. When one eats something, re-iterate
+ * with the remaining value. If no tokenizer eats,
+ * something failed (should not happen) and an
+ * exception is thrown.
+ */
+
+ while (value) {
+ index = -1;
+ length = methods.length;
+ matched = false;
+
+ while (++index < length) {
+ name = methods[index];
+ method = tokenizers[name];
+
+ if (
+ method &&
+ (!method.onlyAtStart || self.atStart) &&
+ (!method.notInList || !self.inList) &&
+ (!method.notInBlock || !self.inBlock) &&
+ (!method.notInLink || !self.inLink)
+ ) {
+ valueLength = value.length;
+
+ method.apply(self, [eat, value]);
+
+ matched = valueLength !== value.length;
+
+ if (matched) {
+ break;
+ }
+ }
+ }
+
+ /* istanbul ignore if */
+ if (!matched) {
+ self.file.fail(ERR_INFINITE_LOOP, eat.now());
+
+ /*
+ * Errors are not thrown on `File#fail`
+ * when `quiet: true`.
+ */
+
+ break;
+ }
+ }
+
+ self.eof = now();
+
+ return tokens;
+ }
+
+ return tokenize;
}
+
+/*
+ * Expose tokenizers for block-level nodes.
+ */
+
+Parser.prototype.blockTokenizers = {
+ 'yamlFrontMatter': tokenizeYAMLFrontMatter,
+ 'newline': tokenizeNewline,
+ 'indentedCode': tokenizeIndentedCode,
+ 'fencedCode': tokenizeFencedCode,
+ 'blockquote': tokenizeBlockquote,
+ 'atxHeading': tokenizeATXHeading,
+ 'thematicBreak': tokenizeThematicBreak,
+ 'list': tokenizeList,
+ 'setextHeading': tokenizeSetextHeading,
+ 'html': tokenizeBlockHTML,
+ 'footnote': tokenizeFootnoteDefinition,
+ 'definition': tokenizeDefinition,
+ 'table': tokenizeTable,
+ 'paragraph': tokenizeParagraph
+};
+
+/*
+ * Expose order in which to parse block-level nodes.
+ */
+
+Parser.prototype.blockMethods = [
+ 'yamlFrontMatter',
+ 'newline',
+ 'indentedCode',
+ 'fencedCode',
+ 'blockquote',
+ 'atxHeading',
+ 'thematicBreak',
+ 'list',
+ 'setextHeading',
+ 'html',
+ 'footnote',
+ 'definition',
+ 'table',
+ 'paragraph'
+];
+
+/**
+ * Block tokenizer.
+ *
+ * @example
+ * var parser = new Parser();
+ * parser.tokenizeBlock('> foo.');
+ *
+ * @param {string} value - Content.
+ * @return {Array.<Object>} - Nodes.
+ */
+
+Parser.prototype.tokenizeBlock = tokenizeFactory(BLOCK);
+
+/*
+ * Expose tokenizers for inline-level nodes.
+ */
+
+Parser.prototype.inlineTokenizers = {
+ 'escape': tokenizeEscape,
+ 'autoLink': tokenizeAutoLink,
+ 'url': tokenizeURL,
+ 'html': tokenizeInlineHTML,
+ 'link': tokenizeLink,
+ 'reference': tokenizeReference,
+ 'strong': tokenizeStrong,
+ 'emphasis': tokenizeEmphasis,
+ 'deletion': tokenizeDeletion,
+ 'code': tokenizeInlineCode,
+ 'break': tokenizeBreak,
+ 'text': tokenizeText
+};
+
+/*
+ * Expose order in which to parse inline-level nodes.
+ */
+
+Parser.prototype.inlineMethods = [
+ 'escape',
+ 'autoLink',
+ 'url',
+ 'html',
+ 'link',
+ 'reference',
+ 'strong',
+ 'emphasis',
+ 'deletion',
+ 'code',
+ 'break',
+ 'text'
+];
+
+/**
+ * Inline tokenizer.
+ *
+ * @example
+ * var parser = new Parser();
+ * parser.tokenizeInline('_foo_');
+ *
+ * @param {string} value - Content.
+ * @return {Array.<Object>} - Nodes.
+ */
+
+Parser.prototype.tokenizeInline = tokenizeFactory(INLINE);
+
+/*
+ * Expose `tokenizeFactory` so dependencies could create
+ * their own tokenizers.
+ */
+
+Parser.prototype.tokenizeFactory = tokenizeFactory;
+
+/*
+ * Expose `attacher`.
+ */
+
+module.exports = Parser;
diff --git a/tools/eslint/node_modules/remark-parse/lib/set-options.js b/tools/eslint/node_modules/remark-parse/lib/set-options.js
deleted file mode 100644
index 3f9abad7c4..0000000000
--- a/tools/eslint/node_modules/remark-parse/lib/set-options.js
+++ /dev/null
@@ -1,59 +0,0 @@
-/**
- * @author Titus Wormer
- * @copyright 2015 Titus Wormer
- * @license MIT
- * @module remark:parse
- * @fileoverview Markdown parser.
- */
-
-'use strict';
-
-var xtend = require('xtend');
-var escapes = require('markdown-escapes');
-var defaults = require('./defaults');
-
-module.exports = setOptions;
-
-/* Set options. */
-function setOptions(options) {
- var self = this;
- var current = self.options;
- var key;
- var value;
-
- if (options == null) {
- options = {};
- } else if (typeof options === 'object') {
- options = xtend(options);
- } else {
- throw new Error(
- 'Invalid value `' + options + '` ' +
- 'for setting `options`'
- );
- }
-
- for (key in defaults) {
- value = options[key];
-
- if (value == null) {
- value = current[key];
- }
-
- if (
- (key !== 'blocks' && typeof value !== 'boolean') ||
- (key === 'blocks' && typeof value !== 'object')
- ) {
- throw new Error(
- 'Invalid value `' + value + '` ' +
- 'for setting `options.' + key + '`'
- );
- }
-
- options[key] = value;
- }
-
- self.options = options;
- self.escape = escapes(options);
-
- return self;
-}
diff --git a/tools/eslint/node_modules/remark-parse/lib/tokenize/auto-link.js b/tools/eslint/node_modules/remark-parse/lib/tokenize/auto-link.js
deleted file mode 100644
index 3861b48a14..0000000000
--- a/tools/eslint/node_modules/remark-parse/lib/tokenize/auto-link.js
+++ /dev/null
@@ -1,151 +0,0 @@
-/**
- * @author Titus Wormer
- * @copyright 2015 Titus Wormer
- * @license MIT
- * @module remark:parse:tokenize:auto-link
- * @fileoverview Tokenise an auto-link.
- */
-
-'use strict';
-
-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 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
- });
-}
diff --git a/tools/eslint/node_modules/remark-parse/lib/tokenize/blockquote.js b/tools/eslint/node_modules/remark-parse/lib/tokenize/blockquote.js
deleted file mode 100644
index 764e0aa010..0000000000
--- a/tools/eslint/node_modules/remark-parse/lib/tokenize/blockquote.js
+++ /dev/null
@@ -1,137 +0,0 @@
-/**
- * @author Titus Wormer
- * @copyright 2015 Titus Wormer
- * @license MIT
- * @module remark:parse:tokenize:blockquote
- * @fileoverview Tokenise blockquote.
- */
-
-'use strict';
-
-var trim = require('trim');
-var interrupt = require('../util/interrupt');
-
-module.exports = blockquote;
-
-var C_NEWLINE = '\n';
-var C_TAB = '\t';
-var C_SPACE = ' ';
-var C_GT = '>';
-
-/* Tokenise a blockquote. */
-function blockquote(eat, value, silent) {
- var self = this;
- var offsets = self.offset;
- var tokenizers = self.blockTokenizers;
- var interruptors = self.interruptBlockquote;
- var now = eat.now();
- var currentLine = now.line;
- var length = value.length;
- var values = [];
- var contents = [];
- var indents = [];
- var add;
- var index = 0;
- var character;
- var rest;
- var nextIndex;
- var content;
- var line;
- var startIndex;
- var prefixed;
- var exit;
-
- while (index < length) {
- character = value.charAt(index);
-
- if (character !== C_SPACE && character !== C_TAB) {
- break;
- }
-
- index++;
- }
-
- if (value.charAt(index) !== C_GT) {
- return;
- }
-
- if (silent) {
- return true;
- }
-
- index = 0;
-
- while (index < length) {
- nextIndex = value.indexOf(C_NEWLINE, index);
- startIndex = index;
- prefixed = false;
-
- if (nextIndex === -1) {
- nextIndex = length;
- }
-
- while (index < length) {
- character = value.charAt(index);
-
- if (character !== C_SPACE && character !== C_TAB) {
- break;
- }
-
- index++;
- }
-
- if (value.charAt(index) === C_GT) {
- index++;
- prefixed = true;
-
- if (value.charAt(index) === C_SPACE) {
- index++;
- }
- } else {
- index = startIndex;
- }
-
- content = value.slice(index, nextIndex);
-
- if (!prefixed && !trim(content)) {
- index = startIndex;
- break;
- }
-
- if (!prefixed) {
- rest = value.slice(index);
-
- /* Check if the following code contains a possible
- * block. */
- if (interrupt(interruptors, tokenizers, self, [eat, rest, true])) {
- break;
- }
- }
-
- line = startIndex === index ? content : value.slice(startIndex, nextIndex);
-
- indents.push(index - startIndex);
- values.push(line);
- contents.push(content);
-
- index = nextIndex + 1;
- }
-
- index = -1;
- length = indents.length;
- add = eat(values.join(C_NEWLINE));
-
- while (++index < length) {
- offsets[currentLine] = (offsets[currentLine] || 0) + indents[index];
- currentLine++;
- }
-
- exit = self.enterBlock();
- contents = self.tokenizeBlock(contents.join(C_NEWLINE), now);
- exit();
-
- return add({
- type: 'blockquote',
- children: contents
- });
-}
diff --git a/tools/eslint/node_modules/remark-parse/lib/tokenize/break.js b/tools/eslint/node_modules/remark-parse/lib/tokenize/break.js
deleted file mode 100644
index 6d2d0dcff9..0000000000
--- a/tools/eslint/node_modules/remark-parse/lib/tokenize/break.js
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
- * @author Titus Wormer
- * @copyright 2015 Titus Wormer
- * @license MIT
- * @module remark:parse:tokenize:break
- * @fileoverview Tokenise a break.
- */
-
-'use strict';
-
-var locate = require('../locate/break');
-
-module.exports = hardBreak;
-hardBreak.locator = locate;
-
-var MIN_BREAK_LENGTH = 2;
-
-/* Tokenise a break. */
-function hardBreak(eat, value, silent) {
- var self = this;
- var breaks = self.options.breaks;
- var length = value.length;
- var index = -1;
- var queue = '';
- var character;
-
- while (++index < length) {
- character = value.charAt(index);
-
- if (character === '\n') {
- if (!breaks && index < MIN_BREAK_LENGTH) {
- return;
- }
-
- /* istanbul ignore if - never used (yet) */
- if (silent) {
- return true;
- }
-
- queue += character;
-
- return eat(queue)({type: 'break'});
- }
-
- if (character !== ' ') {
- return;
- }
-
- queue += character;
- }
-}
diff --git a/tools/eslint/node_modules/remark-parse/lib/tokenize/code-fenced.js b/tools/eslint/node_modules/remark-parse/lib/tokenize/code-fenced.js
deleted file mode 100644
index f2577405b2..0000000000
--- a/tools/eslint/node_modules/remark-parse/lib/tokenize/code-fenced.js
+++ /dev/null
@@ -1,245 +0,0 @@
-/**
- * @author Titus Wormer
- * @copyright 2015 Titus Wormer
- * @license MIT
- * @module remark:parse:tokenize:code-fenced
- * @fileoverview Tokenise fenced code.
- */
-
-'use strict';
-
-var trim = require('trim-trailing-lines');
-
-module.exports = fencedCode;
-
-var C_NEWLINE = '\n';
-var C_TAB = '\t';
-var C_SPACE = ' ';
-var C_TILDE = '~';
-var C_TICK = '`';
-
-var MIN_FENCE_COUNT = 3;
-var CODE_INDENT_COUNT = 4;
-
-/* Tokenise fenced code. */
-function fencedCode(eat, value, silent) {
- var self = this;
- var settings = self.options;
- var length = value.length + 1;
- var index = 0;
- var subvalue = '';
- var fenceCount;
- var marker;
- var character;
- var flag;
- var queue;
- var content;
- var exdentedContent;
- var closing;
- var exdentedClosing;
- var indent;
- var now;
-
- if (!settings.gfm) {
- return;
- }
-
- /* Eat initial spacing. */
- while (index < length) {
- character = value.charAt(index);
-
- if (character !== C_SPACE && character !== C_TAB) {
- break;
- }
-
- subvalue += character;
- index++;
- }
-
- indent = index;
-
- /* Eat the fence. */
- character = value.charAt(index);
-
- if (character !== C_TILDE && character !== C_TICK) {
- return;
- }
-
- index++;
- marker = character;
- fenceCount = 1;
- subvalue += character;
-
- while (index < length) {
- character = value.charAt(index);
-
- if (character !== marker) {
- break;
- }
-
- subvalue += character;
- fenceCount++;
- index++;
- }
-
- if (fenceCount < MIN_FENCE_COUNT) {
- return;
- }
-
- /* Eat spacing before flag. */
- while (index < length) {
- character = value.charAt(index);
-
- if (character !== C_SPACE && character !== C_TAB) {
- break;
- }
-
- subvalue += character;
- index++;
- }
-
- /* Eat flag. */
- flag = '';
- queue = '';
-
- while (index < length) {
- character = value.charAt(index);
-
- if (
- character === C_NEWLINE ||
- character === C_TILDE ||
- character === C_TICK
- ) {
- break;
- }
-
- if (character === C_SPACE || character === C_TAB) {
- queue += character;
- } else {
- flag += queue + character;
- queue = '';
- }
-
- index++;
- }
-
- character = value.charAt(index);
-
- if (character && character !== C_NEWLINE) {
- return;
- }
-
- if (silent) {
- return true;
- }
-
- now = eat.now();
- now.column += subvalue.length;
- now.offset += subvalue.length;
-
- subvalue += flag;
- flag = self.decode.raw(self.unescape(flag), now);
-
- if (queue) {
- subvalue += queue;
- }
-
- queue = '';
- closing = '';
- exdentedClosing = '';
- content = '';
- exdentedContent = '';
-
- /* Eat content. */
- while (index < length) {
- character = value.charAt(index);
- content += closing;
- exdentedContent += exdentedClosing;
- closing = '';
- exdentedClosing = '';
-
- if (character !== C_NEWLINE) {
- content += character;
- exdentedClosing += character;
- index++;
- continue;
- }
-
- /* Add the newline to `subvalue` if its the first
- * character. Otherwise, add it to the `closing`
- * queue. */
- if (content) {
- closing += character;
- exdentedClosing += character;
- } else {
- subvalue += character;
- }
-
- queue = '';
- index++;
-
- while (index < length) {
- character = value.charAt(index);
-
- if (character !== C_SPACE) {
- break;
- }
-
- queue += character;
- index++;
- }
-
- closing += queue;
- exdentedClosing += queue.slice(indent);
-
- if (queue.length >= CODE_INDENT_COUNT) {
- continue;
- }
-
- queue = '';
-
- while (index < length) {
- character = value.charAt(index);
-
- if (character !== marker) {
- break;
- }
-
- queue += character;
- index++;
- }
-
- closing += queue;
- exdentedClosing += queue;
-
- if (queue.length < fenceCount) {
- continue;
- }
-
- queue = '';
-
- while (index < length) {
- character = value.charAt(index);
-
- if (character !== C_SPACE && character !== C_TAB) {
- break;
- }
-
- closing += character;
- exdentedClosing += character;
- index++;
- }
-
- if (!character || character === C_NEWLINE) {
- break;
- }
- }
-
- subvalue += content + closing;
-
- return eat(subvalue)({
- type: 'code',
- lang: flag || null,
- value: trim(exdentedContent)
- });
-}
diff --git a/tools/eslint/node_modules/remark-parse/lib/tokenize/code-indented.js b/tools/eslint/node_modules/remark-parse/lib/tokenize/code-indented.js
deleted file mode 100644
index 50c581fe26..0000000000
--- a/tools/eslint/node_modules/remark-parse/lib/tokenize/code-indented.js
+++ /dev/null
@@ -1,106 +0,0 @@
-/**
- * @author Titus Wormer
- * @copyright 2015 Titus Wormer
- * @license MIT
- * @module remark:parse:tokenize:code-indented
- * @fileoverview Tokenise indented code.
- */
-
-'use strict';
-
-var repeat = require('repeat-string');
-var trim = require('trim-trailing-lines');
-
-module.exports = indentedCode;
-
-var C_NEWLINE = '\n';
-var C_TAB = '\t';
-var C_SPACE = ' ';
-
-var CODE_INDENT_COUNT = 4;
-var CODE_INDENT = repeat(C_SPACE, CODE_INDENT_COUNT);
-
-/* Tokenise indented code. */
-function indentedCode(eat, value, silent) {
- var index = -1;
- var length = value.length;
- var subvalue = '';
- var content = '';
- var subvalueQueue = '';
- var contentQueue = '';
- var character;
- var blankQueue;
- var indent;
-
- while (++index < length) {
- character = value.charAt(index);
-
- if (indent) {
- indent = false;
-
- subvalue += subvalueQueue;
- content += contentQueue;
- subvalueQueue = '';
- contentQueue = '';
-
- if (character === C_NEWLINE) {
- subvalueQueue = character;
- contentQueue = character;
- } else {
- subvalue += character;
- content += character;
-
- while (++index < length) {
- character = value.charAt(index);
-
- if (!character || character === C_NEWLINE) {
- contentQueue = character;
- subvalueQueue = character;
- break;
- }
-
- subvalue += character;
- content += character;
- }
- }
- } else if (
- character === C_SPACE &&
- value.charAt(index + 1) === character &&
- value.charAt(index + 2) === character &&
- value.charAt(index + 3) === character
- ) {
- subvalueQueue += CODE_INDENT;
- index += 3;
- indent = true;
- } else if (character === C_TAB) {
- subvalueQueue += character;
- indent = true;
- } else {
- blankQueue = '';
-
- while (character === C_TAB || character === C_SPACE) {
- blankQueue += character;
- character = value.charAt(++index);
- }
-
- if (character !== C_NEWLINE) {
- break;
- }
-
- subvalueQueue += blankQueue + character;
- contentQueue += character;
- }
- }
-
- if (content) {
- if (silent) {
- return true;
- }
-
- return eat(subvalue)({
- type: 'code',
- lang: null,
- value: trim(content)
- });
- }
-}
diff --git a/tools/eslint/node_modules/remark-parse/lib/tokenize/code-inline.js b/tools/eslint/node_modules/remark-parse/lib/tokenize/code-inline.js
deleted file mode 100644
index 9157412753..0000000000
--- a/tools/eslint/node_modules/remark-parse/lib/tokenize/code-inline.js
+++ /dev/null
@@ -1,120 +0,0 @@
-/**
- * @author Titus Wormer
- * @copyright 2015 Titus Wormer
- * @license MIT
- * @module remark:parse:tokenize:code-inline
- * @fileoverview Tokenise inline code.
- */
-
-'use strict';
-
-var whitespace = require('is-whitespace-character');
-var locate = require('../locate/code-inline');
-
-module.exports = inlineCode;
-inlineCode.locator = locate;
-
-var C_TICK = '`';
-
-/* Tokenise inline code. */
-function inlineCode(eat, value, silent) {
- var length = value.length;
- var index = 0;
- var queue = '';
- var tickQueue = '';
- var contentQueue;
- var subqueue;
- var count;
- var openingCount;
- var subvalue;
- var character;
- var found;
- var next;
-
- while (index < length) {
- if (value.charAt(index) !== C_TICK) {
- break;
- }
-
- queue += C_TICK;
- index++;
- }
-
- if (!queue) {
- return;
- }
-
- subvalue = queue;
- openingCount = index;
- queue = '';
- next = value.charAt(index);
- count = 0;
-
- while (index < length) {
- character = next;
- next = value.charAt(index + 1);
-
- if (character === C_TICK) {
- count++;
- tickQueue += character;
- } else {
- count = 0;
- queue += character;
- }
-
- if (count && next !== C_TICK) {
- if (count === openingCount) {
- subvalue += queue + tickQueue;
- found = true;
- break;
- }
-
- queue += tickQueue;
- tickQueue = '';
- }
-
- index++;
- }
-
- if (!found) {
- if (openingCount % 2 !== 0) {
- return;
- }
-
- queue = '';
- }
-
- /* istanbul ignore if - never used (yet) */
- if (silent) {
- return true;
- }
-
- contentQueue = '';
- subqueue = '';
- length = queue.length;
- index = -1;
-
- while (++index < length) {
- character = queue.charAt(index);
-
- if (whitespace(character)) {
- subqueue += character;
- continue;
- }
-
- if (subqueue) {
- if (contentQueue) {
- contentQueue += subqueue;
- }
-
- subqueue = '';
- }
-
- contentQueue += character;
- }
-
- return eat(subvalue)({
- type: 'inlineCode',
- value: contentQueue
- });
-}
diff --git a/tools/eslint/node_modules/remark-parse/lib/tokenize/definition.js b/tools/eslint/node_modules/remark-parse/lib/tokenize/definition.js
deleted file mode 100644
index 3f7345a2c9..0000000000
--- a/tools/eslint/node_modules/remark-parse/lib/tokenize/definition.js
+++ /dev/null
@@ -1,287 +0,0 @@
-/**
- * @author Titus Wormer
- * @copyright 2015 Titus Wormer
- * @license MIT
- * @module remark:parse:tokenize:definition
- * @fileoverview Tokenise a definition.
- */
-
-'use strict';
-
-var whitespace = require('is-whitespace-character');
-var normalize = require('../util/normalize');
-
-module.exports = definition;
-definition.notInList = true;
-definition.notInBlock = true;
-
-var C_DOUBLE_QUOTE = '"';
-var C_SINGLE_QUOTE = '\'';
-var C_BACKSLASH = '\\';
-var C_NEWLINE = '\n';
-var C_TAB = '\t';
-var C_SPACE = ' ';
-var C_BRACKET_OPEN = '[';
-var C_BRACKET_CLOSE = ']';
-var C_PAREN_OPEN = '(';
-var C_PAREN_CLOSE = ')';
-var C_COLON = ':';
-var C_LT = '<';
-var C_GT = '>';
-
-/* Tokenise a definition. */
-function definition(eat, value, silent) {
- var self = this;
- var commonmark = self.options.commonmark;
- var index = 0;
- var length = value.length;
- var subvalue = '';
- var beforeURL;
- var beforeTitle;
- var queue;
- var character;
- var test;
- var identifier;
- var url;
- var title;
-
- while (index < length) {
- character = value.charAt(index);
-
- if (character !== C_SPACE && character !== C_TAB) {
- break;
- }
-
- subvalue += character;
- index++;
- }
-
- character = value.charAt(index);
-
- if (character !== C_BRACKET_OPEN) {
- return;
- }
-
- index++;
- subvalue += character;
- queue = '';
-
- while (index < length) {
- character = value.charAt(index);
-
- if (character === C_BRACKET_CLOSE) {
- break;
- } else if (character === C_BACKSLASH) {
- queue += character;
- index++;
- character = value.charAt(index);
- }
-
- queue += character;
- index++;
- }
-
- if (
- !queue ||
- value.charAt(index) !== C_BRACKET_CLOSE ||
- value.charAt(index + 1) !== C_COLON
- ) {
- return;
- }
-
- identifier = queue;
- subvalue += queue + C_BRACKET_CLOSE + C_COLON;
- index = subvalue.length;
- queue = '';
-
- while (index < length) {
- character = value.charAt(index);
-
- if (
- character !== C_TAB &&
- character !== C_SPACE &&
- character !== C_NEWLINE
- ) {
- break;
- }
-
- subvalue += character;
- index++;
- }
-
- character = value.charAt(index);
- queue = '';
- beforeURL = subvalue;
-
- if (character === C_LT) {
- index++;
-
- while (index < length) {
- character = value.charAt(index);
-
- if (!isEnclosedURLCharacter(character)) {
- break;
- }
-
- queue += character;
- index++;
- }
-
- character = value.charAt(index);
-
- if (character === isEnclosedURLCharacter.delimiter) {
- subvalue += C_LT + queue + character;
- index++;
- } else {
- if (commonmark) {
- return;
- }
-
- index -= queue.length + 1;
- queue = '';
- }
- }
-
- if (!queue) {
- while (index < length) {
- character = value.charAt(index);
-
- if (!isUnclosedURLCharacter(character)) {
- break;
- }
-
- queue += character;
- index++;
- }
-
- subvalue += queue;
- }
-
- if (!queue) {
- return;
- }
-
- url = queue;
- queue = '';
-
- while (index < length) {
- character = value.charAt(index);
-
- if (
- character !== C_TAB &&
- character !== C_SPACE &&
- character !== C_NEWLINE
- ) {
- break;
- }
-
- queue += character;
- index++;
- }
-
- character = value.charAt(index);
- test = null;
-
- if (character === C_DOUBLE_QUOTE) {
- test = C_DOUBLE_QUOTE;
- } else if (character === C_SINGLE_QUOTE) {
- test = C_SINGLE_QUOTE;
- } else if (character === C_PAREN_OPEN) {
- test = C_PAREN_CLOSE;
- }
-
- if (!test) {
- queue = '';
- index = subvalue.length;
- } else if (queue) {
- subvalue += queue + character;
- index = subvalue.length;
- queue = '';
-
- while (index < length) {
- character = value.charAt(index);
-
- if (character === test) {
- break;
- }
-
- if (character === C_NEWLINE) {
- index++;
- character = value.charAt(index);
-
- if (character === C_NEWLINE || character === test) {
- return;
- }
-
- queue += C_NEWLINE;
- }
-
- queue += character;
- index++;
- }
-
- character = value.charAt(index);
-
- if (character !== test) {
- return;
- }
-
- beforeTitle = subvalue;
- subvalue += queue + character;
- index++;
- title = queue;
- queue = '';
- } else {
- return;
- }
-
- while (index < length) {
- character = value.charAt(index);
-
- if (character !== C_TAB && character !== C_SPACE) {
- break;
- }
-
- subvalue += character;
- index++;
- }
-
- character = value.charAt(index);
-
- if (!character || character === C_NEWLINE) {
- if (silent) {
- return true;
- }
-
- beforeURL = eat(beforeURL).test().end;
- url = self.decode.raw(self.unescape(url), beforeURL);
-
- if (title) {
- beforeTitle = eat(beforeTitle).test().end;
- title = self.decode.raw(self.unescape(title), beforeTitle);
- }
-
- return eat(subvalue)({
- type: 'definition',
- identifier: normalize(identifier),
- title: title || null,
- url: url
- });
- }
-}
-
-/* Check if `character` can be inside an enclosed URI. */
-function isEnclosedURLCharacter(character) {
- return character !== C_GT &&
- character !== C_BRACKET_OPEN &&
- character !== C_BRACKET_CLOSE;
-}
-
-isEnclosedURLCharacter.delimiter = C_GT;
-
-/* Check if `character` can be inside an unclosed URI. */
-function isUnclosedURLCharacter(character) {
- return character !== C_BRACKET_OPEN &&
- character !== C_BRACKET_CLOSE &&
- !whitespace(character);
-}
diff --git a/tools/eslint/node_modules/remark-parse/lib/tokenize/delete.js b/tools/eslint/node_modules/remark-parse/lib/tokenize/delete.js
deleted file mode 100644
index 60ae9c4936..0000000000
--- a/tools/eslint/node_modules/remark-parse/lib/tokenize/delete.js
+++ /dev/null
@@ -1,69 +0,0 @@
-/**
- * @author Titus Wormer
- * @copyright 2015 Titus Wormer
- * @license MIT
- * @module remark:parse:tokenize:delete
- * @fileoverview Tokenise strikethrough.
- */
-
-'use strict';
-
-var whitespace = require('is-whitespace-character');
-var locate = require('../locate/delete');
-
-module.exports = strikethrough;
-strikethrough.locator = locate;
-
-var C_TILDE = '~';
-var DOUBLE = '~~';
-
-/* Tokenise strikethrough. */
-function strikethrough(eat, value, silent) {
- var self = this;
- var character = '';
- var previous = '';
- var preceding = '';
- var subvalue = '';
- var index;
- var length;
- var now;
-
- if (
- !self.options.gfm ||
- value.charAt(0) !== C_TILDE ||
- value.charAt(1) !== C_TILDE ||
- whitespace(value.charAt(2))
- ) {
- return;
- }
-
- index = 1;
- length = value.length;
- now = eat.now();
- now.column += 2;
- now.offset += 2;
-
- while (++index < length) {
- character = value.charAt(index);
-
- if (
- character === C_TILDE &&
- previous === C_TILDE &&
- (!preceding || !whitespace(preceding))
- ) {
- /* istanbul ignore if - never used (yet) */
- if (silent) {
- return true;
- }
-
- return eat(DOUBLE + subvalue + DOUBLE)({
- type: 'delete',
- children: self.tokenizeInline(subvalue, now)
- });
- }
-
- subvalue += previous;
- preceding = previous;
- previous = character;
- }
-}
diff --git a/tools/eslint/node_modules/remark-parse/lib/tokenize/emphasis.js b/tools/eslint/node_modules/remark-parse/lib/tokenize/emphasis.js
deleted file mode 100644
index 4624936922..0000000000
--- a/tools/eslint/node_modules/remark-parse/lib/tokenize/emphasis.js
+++ /dev/null
@@ -1,94 +0,0 @@
-/**
- * @author Titus Wormer
- * @copyright 2015 Titus Wormer
- * @license MIT
- * @module remark:parse:tokenize:emphasis
- * @fileoverview Tokenise emphasis.
- */
-
-'use strict';
-
-var trim = require('trim');
-var word = require('is-word-character');
-var whitespace = require('is-whitespace-character');
-var locate = require('../locate/emphasis');
-
-module.exports = emphasis;
-emphasis.locator = locate;
-
-var C_ASTERISK = '*';
-var C_UNDERSCORE = '_';
-
-/* Tokenise emphasis. */
-function emphasis(eat, value, silent) {
- var self = this;
- var index = 0;
- var character = value.charAt(index);
- var now;
- var pedantic;
- var marker;
- var queue;
- var subvalue;
- var length;
- var prev;
-
- if (character !== C_ASTERISK && character !== C_UNDERSCORE) {
- return;
- }
-
- pedantic = self.options.pedantic;
- subvalue = character;
- marker = character;
- length = value.length;
- index++;
- queue = '';
- character = '';
-
- if (pedantic && whitespace(value.charAt(index))) {
- return;
- }
-
- while (index < length) {
- prev = character;
- character = value.charAt(index);
-
- if (character === marker && (!pedantic || !whitespace(prev))) {
- character = value.charAt(++index);
-
- if (character !== marker) {
- if (!trim(queue) || prev === marker) {
- return;
- }
-
- if (!pedantic && marker === C_UNDERSCORE && word(character)) {
- queue += marker;
- continue;
- }
-
- /* istanbul ignore if - never used (yet) */
- if (silent) {
- return true;
- }
-
- now = eat.now();
- now.column++;
- now.offset++;
-
- return eat(subvalue + queue + marker)({
- type: 'emphasis',
- children: self.tokenizeInline(queue, now)
- });
- }
-
- queue += marker;
- }
-
- if (!pedantic && character === '\\') {
- queue += character;
- character = value.charAt(++index);
- }
-
- queue += character;
- index++;
- }
-}
diff --git a/tools/eslint/node_modules/remark-parse/lib/tokenize/escape.js b/tools/eslint/node_modules/remark-parse/lib/tokenize/escape.js
deleted file mode 100644
index 3e41a4cec5..0000000000
--- a/tools/eslint/node_modules/remark-parse/lib/tokenize/escape.js
+++ /dev/null
@@ -1,43 +0,0 @@
-/**
- * @author Titus Wormer
- * @copyright 2015 Titus Wormer
- * @license MIT
- * @module remark:parse:tokenize:escape
- * @fileoverview Tokenise an escape.
- */
-
-'use strict';
-
-var locate = require('../locate/escape');
-
-module.exports = escape;
-escape.locator = locate;
-
-/* Tokenise an escape. */
-function escape(eat, value, silent) {
- var self = this;
- var character;
- var node;
-
- if (value.charAt(0) === '\\') {
- character = value.charAt(1);
-
- if (self.escape.indexOf(character) !== -1) {
- /* istanbul ignore if - never used (yet) */
- if (silent) {
- return true;
- }
-
- if (character === '\n') {
- node = {type: 'break'};
- } else {
- node = {
- type: 'text',
- value: character
- };
- }
-
- return eat('\\' + character)(node);
- }
- }
-}
diff --git a/tools/eslint/node_modules/remark-parse/lib/tokenize/footnote-definition.js b/tools/eslint/node_modules/remark-parse/lib/tokenize/footnote-definition.js
deleted file mode 100644
index 3537ccb611..0000000000
--- a/tools/eslint/node_modules/remark-parse/lib/tokenize/footnote-definition.js
+++ /dev/null
@@ -1,194 +0,0 @@
-/**
- * @author Titus Wormer
- * @copyright 2015 Titus Wormer
- * @license MIT
- * @module remark:parse:tokenize:footnote-definition
- * @fileoverview Tokenise footnote definition.
- */
-
-'use strict';
-
-var whitespace = require('is-whitespace-character');
-var normalize = require('../util/normalize');
-
-module.exports = footnoteDefinition;
-footnoteDefinition.notInList = true;
-footnoteDefinition.notInBlock = true;
-
-var C_BACKSLASH = '\\';
-var C_NEWLINE = '\n';
-var C_TAB = '\t';
-var C_SPACE = ' ';
-var C_BRACKET_OPEN = '[';
-var C_BRACKET_CLOSE = ']';
-var C_CARET = '^';
-var C_COLON = ':';
-
-var EXPRESSION_INITIAL_TAB = /^( {4}|\t)?/gm;
-
-/* Tokenise a footnote definition. */
-function footnoteDefinition(eat, value, silent) {
- var self = this;
- var offsets = self.offset;
- var index;
- var length;
- var subvalue;
- var now;
- var currentLine;
- var content;
- var queue;
- var subqueue;
- var character;
- var identifier;
- var add;
- var exit;
-
- if (!self.options.footnotes) {
- return;
- }
-
- index = 0;
- length = value.length;
- subvalue = '';
- now = eat.now();
- currentLine = now.line;
-
- while (index < length) {
- character = value.charAt(index);
-
- if (!whitespace(character)) {
- break;
- }
-
- subvalue += character;
- index++;
- }
-
- if (
- value.charAt(index) !== C_BRACKET_OPEN ||
- value.charAt(index + 1) !== C_CARET
- ) {
- return;
- }
-
- subvalue += C_BRACKET_OPEN + C_CARET;
- index = subvalue.length;
- queue = '';
-
- while (index < length) {
- character = value.charAt(index);
-
- if (character === C_BRACKET_CLOSE) {
- break;
- } else if (character === C_BACKSLASH) {
- queue += character;
- index++;
- character = value.charAt(index);
- }
-
- queue += character;
- index++;
- }
-
- if (
- !queue ||
- value.charAt(index) !== C_BRACKET_CLOSE ||
- value.charAt(index + 1) !== C_COLON
- ) {
- return;
- }
-
- if (silent) {
- return true;
- }
-
- identifier = normalize(queue);
- subvalue += queue + C_BRACKET_CLOSE + C_COLON;
- index = subvalue.length;
-
- while (index < length) {
- character = value.charAt(index);
-
- if (character !== C_TAB && character !== C_SPACE) {
- break;
- }
-
- subvalue += character;
- index++;
- }
-
- now.column += subvalue.length;
- now.offset += subvalue.length;
- queue = '';
- content = '';
- subqueue = '';
-
- while (index < length) {
- character = value.charAt(index);
-
- if (character === C_NEWLINE) {
- subqueue = character;
- index++;
-
- while (index < length) {
- character = value.charAt(index);
-
- if (character !== C_NEWLINE) {
- break;
- }
-
- subqueue += character;
- index++;
- }
-
- queue += subqueue;
- subqueue = '';
-
- while (index < length) {
- character = value.charAt(index);
-
- if (character !== C_SPACE) {
- break;
- }
-
- subqueue += character;
- index++;
- }
-
- if (subqueue.length === 0) {
- break;
- }
-
- queue += subqueue;
- }
-
- if (queue) {
- content += queue;
- queue = '';
- }
-
- content += character;
- index++;
- }
-
- subvalue += content;
-
- content = content.replace(EXPRESSION_INITIAL_TAB, function (line) {
- offsets[currentLine] = (offsets[currentLine] || 0) + line.length;
- currentLine++;
-
- return '';
- });
-
- add = eat(subvalue);
-
- exit = self.enterBlock();
- content = self.tokenizeBlock(content, now);
- exit();
-
- return add({
- type: 'footnoteDefinition',
- identifier: identifier,
- children: content
- });
-}
diff --git a/tools/eslint/node_modules/remark-parse/lib/tokenize/heading-atx.js b/tools/eslint/node_modules/remark-parse/lib/tokenize/heading-atx.js
deleted file mode 100644
index e5fdedc537..0000000000
--- a/tools/eslint/node_modules/remark-parse/lib/tokenize/heading-atx.js
+++ /dev/null
@@ -1,150 +0,0 @@
-/**
- * @author Titus Wormer
- * @copyright 2015 Titus Wormer
- * @license MIT
- * @module remark:parse:tokenize:heading-atx
- * @fileoverview Tokenise an ATX-style heading.
- */
-
-'use strict';
-
-module.exports = atxHeading;
-
-var C_NEWLINE = '\n';
-var C_TAB = '\t';
-var C_SPACE = ' ';
-var C_HASH = '#';
-
-var MAX_ATX_COUNT = 6;
-
-/* Tokenise an ATX-style heading. */
-function atxHeading(eat, value, silent) {
- var self = this;
- var settings = self.options;
- var length = value.length + 1;
- var index = -1;
- var now = eat.now();
- var subvalue = '';
- var content = '';
- var character;
- var queue;
- var depth;
-
- /* Eat initial spacing. */
- while (++index < length) {
- character = value.charAt(index);
-
- if (character !== C_SPACE && character !== C_TAB) {
- index--;
- break;
- }
-
- subvalue += character;
- }
-
- /* Eat hashes. */
- depth = 0;
-
- while (++index <= length) {
- character = value.charAt(index);
-
- if (character !== C_HASH) {
- index--;
- break;
- }
-
- subvalue += character;
- depth++;
- }
-
- if (depth > MAX_ATX_COUNT) {
- return;
- }
-
- if (
- !depth ||
- (!settings.pedantic && value.charAt(index + 1) === C_HASH)
- ) {
- return;
- }
-
- length = value.length + 1;
-
- /* Eat intermediate white-space. */
- queue = '';
-
- while (++index < length) {
- character = value.charAt(index);
-
- if (character !== C_SPACE && character !== C_TAB) {
- index--;
- break;
- }
-
- queue += character;
- }
-
- /* Exit when not in pedantic mode without spacing. */
- if (
- !settings.pedantic &&
- queue.length === 0 &&
- character &&
- character !== C_NEWLINE
- ) {
- return;
- }
-
- if (silent) {
- return true;
- }
-
- /* Eat content. */
- subvalue += queue;
- queue = '';
- content = '';
-
- while (++index < length) {
- character = value.charAt(index);
-
- if (!character || character === C_NEWLINE) {
- break;
- }
-
- if (
- character !== C_SPACE &&
- character !== C_TAB &&
- character !== C_HASH
- ) {
- content += queue + character;
- queue = '';
- continue;
- }
-
- while (character === C_SPACE || character === C_TAB) {
- queue += character;
- character = value.charAt(++index);
- }
-
- while (character === C_HASH) {
- queue += character;
- character = value.charAt(++index);
- }
-
- while (character === C_SPACE || character === C_TAB) {
- queue += character;
- character = value.charAt(++index);
- }
-
- index--;
- }
-
- now.column += subvalue.length;
- now.offset += subvalue.length;
- subvalue += content + queue;
-
- return eat(subvalue)({
- type: 'heading',
- depth: depth,
- children: self.tokenizeInline(content, now)
- });
-}
diff --git a/tools/eslint/node_modules/remark-parse/lib/tokenize/heading-setext.js b/tools/eslint/node_modules/remark-parse/lib/tokenize/heading-setext.js
deleted file mode 100644
index db8bbcfb73..0000000000
--- a/tools/eslint/node_modules/remark-parse/lib/tokenize/heading-setext.js
+++ /dev/null
@@ -1,116 +0,0 @@
-/**
- * @author Titus Wormer
- * @copyright 2015 Titus Wormer
- * @license MIT
- * @module remark:parse:tokenize:heading-setext
- * @fileoverview Tokenise an setext-style heading.
- */
-
-'use strict';
-
-module.exports = setextHeading;
-
-var C_NEWLINE = '\n';
-var C_TAB = '\t';
-var C_SPACE = ' ';
-var C_EQUALS = '=';
-var C_DASH = '-';
-
-var MAX_HEADING_INDENT = 3;
-
-/* Map of characters which can be used to mark setext
- * headers, mapping to their corresponding depth. */
-var SETEXT_MARKERS = {};
-
-SETEXT_MARKERS[C_EQUALS] = 1;
-SETEXT_MARKERS[C_DASH] = 2;
-
-/* Tokenise an setext-style heading. */
-function setextHeading(eat, value, silent) {
- var self = this;
- var now = eat.now();
- var length = value.length;
- var index = -1;
- var subvalue = '';
- var content;
- var queue;
- var character;
- var marker;
- var depth;
-
- /* Eat initial indentation. */
- while (++index < length) {
- character = value.charAt(index);
-
- if (character !== C_SPACE || index >= MAX_HEADING_INDENT) {
- index--;
- break;
- }
-
- subvalue += character;
- }
-
- /* Eat content. */
- content = '';
- queue = '';
-
- while (++index < length) {
- character = value.charAt(index);
-
- if (character === C_NEWLINE) {
- index--;
- break;
- }
-
- if (character === C_SPACE || character === C_TAB) {
- queue += character;
- } else {
- content += queue + character;
- queue = '';
- }
- }
-
- now.column += subvalue.length;
- now.offset += subvalue.length;
- subvalue += content + queue;
-
- /* Ensure the content is followed by a newline and a
- * valid marker. */
- character = value.charAt(++index);
- marker = value.charAt(++index);
-
- if (character !== C_NEWLINE || !SETEXT_MARKERS[marker]) {
- return;
- }
-
- subvalue += character;
-
- /* Eat Setext-line. */
- queue = marker;
- depth = SETEXT_MARKERS[marker];
-
- while (++index < length) {
- character = value.charAt(index);
-
- if (character !== marker) {
- if (character !== C_NEWLINE) {
- return;
- }
-
- index--;
- break;
- }
-
- queue += character;
- }
-
- if (silent) {
- return true;
- }
-
- return eat(subvalue + queue)({
- type: 'heading',
- depth: depth,
- children: self.tokenizeInline(content, now)
- });
-}
diff --git a/tools/eslint/node_modules/remark-parse/lib/tokenize/html-block.js b/tools/eslint/node_modules/remark-parse/lib/tokenize/html-block.js
deleted file mode 100644
index dc861b53c3..0000000000
--- a/tools/eslint/node_modules/remark-parse/lib/tokenize/html-block.js
+++ /dev/null
@@ -1,103 +0,0 @@
-/**
- * @author Titus Wormer
- * @copyright 2015 Titus Wormer
- * @license MIT
- * @module remark:parse:tokenize:html-block
- * @fileoverview Tokenise block HTML.
- */
-
-'use strict';
-
-var openCloseTag = require('../util/html').openCloseTag;
-
-module.exports = blockHTML;
-
-var C_TAB = '\t';
-var C_SPACE = ' ';
-var C_NEWLINE = '\n';
-var C_LT = '<';
-
-/* Tokenise block HTML. */
-function blockHTML(eat, value, silent) {
- var self = this;
- var blocks = self.options.blocks;
- var length = value.length;
- var index = 0;
- var next;
- var line;
- var offset;
- var character;
- var count;
- var sequence;
- var subvalue;
-
- var sequences = [
- [/^<(script|pre|style)(?=(\s|>|$))/i, /<\/(script|pre|style)>/i, true],
- [/^<!--/, /-->/, true],
- [/^<\?/, /\?>/, true],
- [/^<![A-Za-z]/, />/, true],
- [/^<!\[CDATA\[/, /\]\]>/, true],
- [new RegExp('^</?(' + blocks.join('|') + ')(?=(\\s|/?>|$))', 'i'), /^$/, true],
- [new RegExp(openCloseTag.source + '\\s*$'), /^$/, false]
- ];
-
- /* Eat initial spacing. */
- while (index < length) {
- character = value.charAt(index);
-
- if (character !== C_TAB && character !== C_SPACE) {
- break;
- }
-
- index++;
- }
-
- if (value.charAt(index) !== C_LT) {
- return;
- }
-
- next = value.indexOf(C_NEWLINE, index + 1);
- next = next === -1 ? length : next;
- line = value.slice(index, next);
- offset = -1;
- count = sequences.length;
-
- while (++offset < count) {
- if (sequences[offset][0].test(line)) {
- sequence = sequences[offset];
- break;
- }
- }
-
- if (!sequence) {
- return;
- }
-
- if (silent) {
- return sequence[2];
- }
-
- index = next;
-
- if (!sequence[1].test(line)) {
- while (index < length) {
- next = value.indexOf(C_NEWLINE, index + 1);
- next = next === -1 ? length : next;
- line = value.slice(index + 1, next);
-
- if (sequence[1].test(line)) {
- if (line) {
- index = next;
- }
-
- break;
- }
-
- index = next;
- }
- }
-
- subvalue = value.slice(0, index);
-
- return eat(subvalue)({type: 'html', value: subvalue});
-}
diff --git a/tools/eslint/node_modules/remark-parse/lib/tokenize/html-inline.js b/tools/eslint/node_modules/remark-parse/lib/tokenize/html-inline.js
deleted file mode 100644
index d8c0b9ab21..0000000000
--- a/tools/eslint/node_modules/remark-parse/lib/tokenize/html-inline.js
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * @author Titus Wormer
- * @copyright 2015 Titus Wormer
- * @license MIT
- * @module remark:parse:tokenize:html-inline
- * @fileoverview Tokenise inline HTML.
- */
-
-'use strict';
-
-var alphabetical = require('is-alphabetical');
-var locate = require('../locate/tag');
-var tag = require('../util/html').tag;
-
-module.exports = inlineHTML;
-inlineHTML.locator = locate;
-
-var EXPRESSION_HTML_LINK_OPEN = /^<a /i;
-var EXPRESSION_HTML_LINK_CLOSE = /^<\/a>/i;
-
-/* Tokenise inline HTML. */
-function inlineHTML(eat, value, silent) {
- var self = this;
- var length = value.length;
- var character;
- var subvalue;
-
- if (value.charAt(0) !== '<' || length < 3) {
- return;
- }
-
- character = value.charAt(1);
-
- if (
- !alphabetical(character) &&
- character !== '?' &&
- character !== '!' &&
- character !== '/'
- ) {
- return;
- }
-
- subvalue = value.match(tag);
-
- if (!subvalue) {
- return;
- }
-
- /* istanbul ignore if - not used yet. */
- if (silent) {
- return true;
- }
-
- subvalue = subvalue[0];
-
- if (!self.inLink && EXPRESSION_HTML_LINK_OPEN.test(subvalue)) {
- self.inLink = true;
- } else if (self.inLink && EXPRESSION_HTML_LINK_CLOSE.test(subvalue)) {
- self.inLink = false;
- }
-
- return eat(subvalue)({type: 'html', value: subvalue});
-}
diff --git a/tools/eslint/node_modules/remark-parse/lib/tokenize/link.js b/tools/eslint/node_modules/remark-parse/lib/tokenize/link.js
deleted file mode 100644
index fb11c50990..0000000000
--- a/tools/eslint/node_modules/remark-parse/lib/tokenize/link.js
+++ /dev/null
@@ -1,399 +0,0 @@
-/**
- * @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);
-}
diff --git a/tools/eslint/node_modules/remark-parse/lib/tokenize/list.js b/tools/eslint/node_modules/remark-parse/lib/tokenize/list.js
deleted file mode 100644
index da8002e574..0000000000
--- a/tools/eslint/node_modules/remark-parse/lib/tokenize/list.js
+++ /dev/null
@@ -1,494 +0,0 @@
-/**
- * @author Titus Wormer
- * @copyright 2015 Titus Wormer
- * @license MIT
- * @module remark:parse:tokenize:list
- * @fileoverview Tokenise a list.
- */
-
-'use strict';
-
-/* eslint-disable max-params */
-
-var trim = require('trim');
-var repeat = require('repeat-string');
-var decimal = require('is-decimal');
-var getIndent = require('../util/get-indentation');
-var removeIndent = require('../util/remove-indentation');
-var interrupt = require('../util/interrupt');
-
-module.exports = list;
-
-var C_ASTERISK = '*';
-var C_UNDERSCORE = '_';
-var C_PLUS = '+';
-var C_DASH = '-';
-var C_DOT = '.';
-var C_SPACE = ' ';
-var C_NEWLINE = '\n';
-var C_TAB = '\t';
-var C_PAREN_CLOSE = ')';
-var C_X_LOWER = 'x';
-
-var TAB_SIZE = 4;
-var EXPRESSION_LOOSE_LIST_ITEM = /\n\n(?!\s*$)/;
-var EXPRESSION_TASK_ITEM = /^\[([ \t]|x|X)][ \t]/;
-var EXPRESSION_BULLET = /^([ \t]*)([*+-]|\d+[.)])( {1,4}(?! )| |\t|$|(?=\n))([^\n]*)/;
-var EXPRESSION_PEDANTIC_BULLET = /^([ \t]*)([*+-]|\d+[.)])([ \t]+)/;
-var EXPRESSION_INITIAL_INDENT = /^( {1,4}|\t)?/gm;
-
-/* Map of characters which can be used to mark
- * list-items. */
-var LIST_UNORDERED_MARKERS = {};
-
-LIST_UNORDERED_MARKERS[C_ASTERISK] = true;
-LIST_UNORDERED_MARKERS[C_PLUS] = true;
-LIST_UNORDERED_MARKERS[C_DASH] = true;
-
-/* Map of characters which can be used to mark
- * list-items after a digit. */
-var LIST_ORDERED_MARKERS = {};
-
-LIST_ORDERED_MARKERS[C_DOT] = true;
-
-/* Map of characters which can be used to mark
- * list-items after a digit. */
-var LIST_ORDERED_COMMONMARK_MARKERS = {};
-
-LIST_ORDERED_COMMONMARK_MARKERS[C_DOT] = true;
-LIST_ORDERED_COMMONMARK_MARKERS[C_PAREN_CLOSE] = true;
-
-/* Tokenise a list. */
-function list(eat, value, silent) {
- var self = this;
- var commonmark = self.options.commonmark;
- var pedantic = self.options.pedantic;
- var tokenizers = self.blockTokenizers;
- var interuptors = self.interruptList;
- var markers;
- var index = 0;
- var length = value.length;
- var start = null;
- var size = 0;
- var queue;
- var ordered;
- var character;
- var marker;
- var nextIndex;
- var startIndex;
- var prefixed;
- var currentMarker;
- var content;
- var line;
- var prevEmpty;
- var empty;
- var items;
- var allLines;
- var emptyLines;
- var item;
- var enterTop;
- var exitBlockquote;
- var isLoose;
- var node;
- var now;
- var end;
- var indented;
-
- while (index < length) {
- character = value.charAt(index);
-
- if (character === C_TAB) {
- size += TAB_SIZE - (size % TAB_SIZE);
- } else if (character === C_SPACE) {
- size++;
- } else {
- break;
- }
-
- index++;
- }
-
- if (size >= TAB_SIZE) {
- return;
- }
-
- character = value.charAt(index);
-
- markers = commonmark ?
- LIST_ORDERED_COMMONMARK_MARKERS :
- LIST_ORDERED_MARKERS;
-
- if (LIST_UNORDERED_MARKERS[character] === true) {
- marker = character;
- ordered = false;
- } else {
- ordered = true;
- queue = '';
-
- while (index < length) {
- character = value.charAt(index);
-
- if (!decimal(character)) {
- break;
- }
-
- queue += character;
- index++;
- }
-
- character = value.charAt(index);
-
- if (!queue || markers[character] !== true) {
- return;
- }
-
- start = parseInt(queue, 10);
- marker = character;
- }
-
- character = value.charAt(++index);
-
- if (character !== C_SPACE && character !== C_TAB) {
- return;
- }
-
- if (silent) {
- return true;
- }
-
- index = 0;
- items = [];
- allLines = [];
- emptyLines = [];
-
- while (index < length) {
- nextIndex = value.indexOf(C_NEWLINE, index);
- startIndex = index;
- prefixed = false;
- indented = false;
-
- if (nextIndex === -1) {
- nextIndex = length;
- }
-
- end = index + TAB_SIZE;
- size = 0;
-
- while (index < length) {
- character = value.charAt(index);
-
- if (character === C_TAB) {
- size += TAB_SIZE - (size % TAB_SIZE);
- } else if (character === C_SPACE) {
- size++;
- } else {
- break;
- }
-
- index++;
- }
-
- if (size >= TAB_SIZE) {
- indented = true;
- }
-
- if (item && size >= item.indent) {
- indented = true;
- }
-
- character = value.charAt(index);
- currentMarker = null;
-
- if (!indented) {
- if (LIST_UNORDERED_MARKERS[character] === true) {
- currentMarker = character;
- index++;
- size++;
- } else {
- queue = '';
-
- while (index < length) {
- character = value.charAt(index);
-
- if (!decimal(character)) {
- break;
- }
-
- queue += character;
- index++;
- }
-
- character = value.charAt(index);
- index++;
-
- if (queue && markers[character] === true) {
- currentMarker = character;
- size += queue.length + 1;
- }
- }
-
- if (currentMarker) {
- character = value.charAt(index);
-
- if (character === C_TAB) {
- size += TAB_SIZE - (size % TAB_SIZE);
- index++;
- } else if (character === C_SPACE) {
- end = index + TAB_SIZE;
-
- while (index < end) {
- if (value.charAt(index) !== C_SPACE) {
- break;
- }
-
- index++;
- size++;
- }
-
- if (index === end && value.charAt(index) === C_SPACE) {
- index -= TAB_SIZE - 1;
- size -= TAB_SIZE - 1;
- }
- } else if (character !== C_NEWLINE && character !== '') {
- currentMarker = null;
- }
- }
- }
-
- if (currentMarker) {
- if (!pedantic && marker !== currentMarker) {
- break;
- }
-
- prefixed = true;
- } else {
- if (!commonmark && !indented && value.charAt(startIndex) === C_SPACE) {
- indented = true;
- } else if (commonmark && item) {
- indented = size >= item.indent || size > TAB_SIZE;
- }
-
- prefixed = false;
- index = startIndex;
- }
-
- line = value.slice(startIndex, nextIndex);
- content = startIndex === index ? line : value.slice(index, nextIndex);
-
- if (
- currentMarker === C_ASTERISK ||
- currentMarker === C_UNDERSCORE ||
- currentMarker === C_DASH
- ) {
- if (tokenizers.thematicBreak.call(self, eat, line, true)) {
- break;
- }
- }
-
- prevEmpty = empty;
- empty = !trim(content).length;
-
- if (indented && item) {
- item.value = item.value.concat(emptyLines, line);
- allLines = allLines.concat(emptyLines, line);
- emptyLines = [];
- } else if (prefixed) {
- if (emptyLines.length !== 0) {
- item.value.push('');
- item.trail = emptyLines.concat();
- }
-
- item = {
- value: [line],
- indent: size,
- trail: []
- };
-
- items.push(item);
- allLines = allLines.concat(emptyLines, line);
- emptyLines = [];
- } else if (empty) {
- if (prevEmpty) {
- break;
- }
-
- emptyLines.push(line);
- } else {
- if (prevEmpty) {
- break;
- }
-
- if (interrupt(interuptors, tokenizers, self, [eat, line, true])) {
- break;
- }
-
- item.value = item.value.concat(emptyLines, line);
- allLines = allLines.concat(emptyLines, line);
- emptyLines = [];
- }
-
- index = nextIndex + 1;
- }
-
- node = eat(allLines.join(C_NEWLINE)).reset({
- type: 'list',
- ordered: ordered,
- start: start,
- loose: null,
- children: []
- });
-
- enterTop = self.enterList();
- exitBlockquote = self.enterBlock();
- isLoose = false;
- index = -1;
- length = items.length;
-
- while (++index < length) {
- item = items[index].value.join(C_NEWLINE);
- now = eat.now();
-
- item = eat(item)(listItem(self, item, now), node);
-
- if (item.loose) {
- isLoose = true;
- }
-
- item = items[index].trail.join(C_NEWLINE);
-
- if (index !== length - 1) {
- item += C_NEWLINE;
- }
-
- eat(item);
- }
-
- enterTop();
- exitBlockquote();
-
- node.loose = isLoose;
-
- return node;
-}
-
-/**
- * Create a list-item node.
- *
- * @example
- * listItem('- _foo_', now());
- *
- * @param {Object} ctx - Parser.
- * @param {Object} value - List-item.
- * @param {Object} position - List-item location.
- * @return {Object} - `listItem` node.
- */
-function listItem(ctx, value, position) {
- var offsets = ctx.offset;
- var fn = ctx.options.pedantic ? pedanticListItem : normalListItem;
- var checked = null;
- var task;
- var indent;
-
- value = fn.apply(null, arguments);
-
- if (ctx.options.gfm) {
- task = value.match(EXPRESSION_TASK_ITEM);
-
- if (task) {
- indent = task[0].length;
- checked = task[1].toLowerCase() === C_X_LOWER;
- offsets[position.line] += indent;
- value = value.slice(indent);
- }
- }
-
- return {
- type: 'listItem',
- loose: EXPRESSION_LOOSE_LIST_ITEM.test(value) ||
- value.charAt(value.length - 1) === C_NEWLINE,
- checked: checked,
- children: ctx.tokenizeBlock(value, position)
- };
-}
-
-/* Create a list-item using overly simple mechanics. */
-function pedanticListItem(ctx, value, position) {
- var offsets = ctx.offset;
- var line = position.line;
-
- /* Remove the list-item’s bullet. */
- value = value.replace(EXPRESSION_PEDANTIC_BULLET, replacer);
-
- /* The initial line was also matched by the below, so
- * we reset the `line`. */
- line = position.line;
-
- return value.replace(EXPRESSION_INITIAL_INDENT, replacer);
-
- /* A simple replacer which removed all matches,
- * and adds their length to `offset`. */
- function replacer($0) {
- offsets[line] = (offsets[line] || 0) + $0.length;
- line++;
-
- return '';
- }
-}
-
-/* Create a list-item using sane mechanics. */
-function normalListItem(ctx, value, position) {
- var offsets = ctx.offset;
- var line = position.line;
- var max;
- var bullet;
- var rest;
- var lines;
- var trimmedLines;
- var index;
- var length;
-
- /* Remove the list-item’s bullet. */
- value = value.replace(EXPRESSION_BULLET, replacer);
-
- lines = value.split(C_NEWLINE);
-
- trimmedLines = removeIndent(value, getIndent(max).indent).split(C_NEWLINE);
-
- /* We replaced the initial bullet with something
- * else above, which was used to trick
- * `removeIndentation` into removing some more
- * characters when possible. However, that could
- * result in the initial line to be stripped more
- * than it should be. */
- trimmedLines[0] = rest;
-
- offsets[line] = (offsets[line] || 0) + bullet.length;
- line++;
-
- index = 0;
- length = lines.length;
-
- while (++index < length) {
- offsets[line] = (offsets[line] || 0) +
- lines[index].length - trimmedLines[index].length;
- line++;
- }
-
- return trimmedLines.join(C_NEWLINE);
-
- function replacer($0, $1, $2, $3, $4) {
- bullet = $1 + $2 + $3;
- rest = $4;
-
- /* Make sure that the first nine numbered list items
- * can indent with an extra space. That is, when
- * the bullet did not receive an extra final space. */
- if (Number($2) < 10 && bullet.length % 2 === 1) {
- $2 = C_SPACE + $2;
- }
-
- max = $1 + repeat(C_SPACE, $2.length) + $3;
-
- return max + rest;
- }
-}
diff --git a/tools/eslint/node_modules/remark-parse/lib/tokenize/newline.js b/tools/eslint/node_modules/remark-parse/lib/tokenize/newline.js
deleted file mode 100644
index f710e0ef97..0000000000
--- a/tools/eslint/node_modules/remark-parse/lib/tokenize/newline.js
+++ /dev/null
@@ -1,55 +0,0 @@
-/**
- * @author Titus Wormer
- * @copyright 2015 Titus Wormer
- * @license MIT
- * @module remark:parse:tokenize:newline
- * @fileoverview Tokenise a newline.
- */
-
-'use strict';
-
-var whitespace = require('is-whitespace-character');
-
-module.exports = newline;
-
-/* Tokenise newline. */
-function newline(eat, value, silent) {
- var character = value.charAt(0);
- var length;
- var subvalue;
- var queue;
- var index;
-
- if (character !== '\n') {
- return;
- }
-
- /* istanbul ignore if - never used (yet) */
- if (silent) {
- return true;
- }
-
- index = 1;
- length = value.length;
- subvalue = character;
- queue = '';
-
- while (index < length) {
- character = value.charAt(index);
-
- if (!whitespace(character)) {
- break;
- }
-
- queue += character;
-
- if (character === '\n') {
- subvalue += queue;
- queue = '';
- }
-
- index++;
- }
-
- eat(subvalue);
-}
diff --git a/tools/eslint/node_modules/remark-parse/lib/tokenize/paragraph.js b/tools/eslint/node_modules/remark-parse/lib/tokenize/paragraph.js
deleted file mode 100644
index 7d064522ff..0000000000
--- a/tools/eslint/node_modules/remark-parse/lib/tokenize/paragraph.js
+++ /dev/null
@@ -1,130 +0,0 @@
-/**
- * @author Titus Wormer
- * @copyright 2015 Titus Wormer
- * @license MIT
- * @module remark:parse:tokenize:paragraph
- * @fileoverview Tokenise a paragraph.
- */
-
-'use strict';
-
-var trim = require('trim');
-var decimal = require('is-decimal');
-var trimTrailingLines = require('trim-trailing-lines');
-var interrupt = require('../util/interrupt');
-
-module.exports = paragraph;
-
-var C_NEWLINE = '\n';
-var C_TAB = '\t';
-var C_SPACE = ' ';
-
-var TAB_SIZE = 4;
-
-/* Tokenise paragraph. */
-function paragraph(eat, value, silent) {
- var self = this;
- var settings = self.options;
- var commonmark = settings.commonmark;
- var gfm = settings.gfm;
- var tokenizers = self.blockTokenizers;
- var interruptors = self.interruptParagraph;
- var index = value.indexOf(C_NEWLINE);
- var length = value.length;
- var position;
- var subvalue;
- var character;
- var size;
- var now;
-
- while (index < length) {
- /* Eat everything if there’s no following newline. */
- if (index === -1) {
- index = length;
- break;
- }
-
- /* Stop if the next character is NEWLINE. */
- if (value.charAt(index + 1) === C_NEWLINE) {
- break;
- }
-
- /* In commonmark-mode, following indented lines
- * are part of the paragraph. */
- if (commonmark) {
- size = 0;
- position = index + 1;
-
- while (position < length) {
- character = value.charAt(position);
-
- if (character === C_TAB) {
- size = TAB_SIZE;
- break;
- } else if (character === C_SPACE) {
- size++;
- } else {
- break;
- }
-
- position++;
- }
-
- if (size >= TAB_SIZE) {
- index = value.indexOf(C_NEWLINE, index + 1);
- continue;
- }
- }
-
- subvalue = value.slice(index + 1);
-
- /* Check if the following code contains a possible
- * block. */
- if (interrupt(interruptors, tokenizers, self, [eat, subvalue, true])) {
- break;
- }
-
- /* Break if the following line starts a list, when
- * already in a list, or when in commonmark, or when
- * in gfm mode and the bullet is *not* numeric. */
- if (
- tokenizers.list.call(self, eat, subvalue, true) &&
- (
- self.inList ||
- commonmark ||
- (gfm && !decimal(trim.left(subvalue).charAt(0)))
- )
- ) {
- break;
- }
-
- position = index;
- index = value.indexOf(C_NEWLINE, index + 1);
-
- if (index !== -1 && trim(value.slice(position, index)) === '') {
- index = position;
- break;
- }
- }
-
- subvalue = value.slice(0, index);
-
- if (trim(subvalue) === '') {
- eat(subvalue);
-
- return null;
- }
-
- /* istanbul ignore if - never used (yet) */
- if (silent) {
- return true;
- }
-
- now = eat.now();
- subvalue = trimTrailingLines(subvalue);
-
- return eat(subvalue)({
- type: 'paragraph',
- children: self.tokenizeInline(subvalue, now)
- });
-}
diff --git a/tools/eslint/node_modules/remark-parse/lib/tokenize/reference.js b/tools/eslint/node_modules/remark-parse/lib/tokenize/reference.js
deleted file mode 100644
index 1fa150d9e6..0000000000
--- a/tools/eslint/node_modules/remark-parse/lib/tokenize/reference.js
+++ /dev/null
@@ -1,219 +0,0 @@
-/**
- * @author Titus Wormer
- * @copyright 2015 Titus Wormer
- * @license MIT
- * @module remark:parse:tokenize:reference
- * @fileoverview Tokenise a reference.
- */
-
-'use strict';
-
-var whitespace = require('is-whitespace-character');
-var locate = require('../locate/link');
-var normalize = require('../util/normalize');
-
-module.exports = reference;
-reference.locator = locate;
-
-var T_LINK = 'link';
-var T_IMAGE = 'image';
-var T_FOOTNOTE = 'footnote';
-var REFERENCE_TYPE_SHORTCUT = 'shortcut';
-var REFERENCE_TYPE_COLLAPSED = 'collapsed';
-var REFERENCE_TYPE_FULL = 'full';
-var C_CARET = '^';
-var C_BACKSLASH = '\\';
-var C_BRACKET_OPEN = '[';
-var C_BRACKET_CLOSE = ']';
-
-/* Tokenise a reference. */
-function reference(eat, value, silent) {
- var self = this;
- var character = value.charAt(0);
- var index = 0;
- var length = value.length;
- var subvalue = '';
- var intro = '';
- var type = T_LINK;
- var referenceType = REFERENCE_TYPE_SHORTCUT;
- var content;
- var identifier;
- var now;
- var node;
- var exit;
- var queue;
- var bracketed;
- var depth;
-
- /* Check whether we’re eating an image. */
- if (character === '!') {
- type = T_IMAGE;
- intro = character;
- character = value.charAt(++index);
- }
-
- if (character !== C_BRACKET_OPEN) {
- return;
- }
-
- index++;
- intro += character;
- queue = '';
-
- /* Check whether we’re eating a footnote. */
- if (
- self.options.footnotes &&
- type === T_LINK &&
- value.charAt(index) === C_CARET
- ) {
- intro += C_CARET;
- index++;
- type = T_FOOTNOTE;
- }
-
- /* Eat the text. */
- depth = 0;
-
- while (index < length) {
- character = value.charAt(index);
-
- if (character === C_BRACKET_OPEN) {
- bracketed = true;
- depth++;
- } else if (character === C_BRACKET_CLOSE) {
- if (!depth) {
- break;
- }
-
- depth--;
- }
-
- if (character === C_BACKSLASH) {
- queue += C_BACKSLASH;
- character = value.charAt(++index);
- }
-
- queue += character;
- index++;
- }
-
- subvalue = queue;
- content = queue;
- character = value.charAt(index);
-
- if (character !== C_BRACKET_CLOSE) {
- return;
- }
-
- index++;
- subvalue += character;
- queue = '';
-
- while (index < length) {
- character = value.charAt(index);
-
- if (!whitespace(character)) {
- break;
- }
-
- queue += character;
- index++;
- }
-
- character = value.charAt(index);
-
- if (character === C_BRACKET_OPEN) {
- identifier = '';
- queue += character;
- index++;
-
- while (index < length) {
- character = value.charAt(index);
-
- if (character === C_BRACKET_OPEN || character === C_BRACKET_CLOSE) {
- break;
- }
-
- if (character === C_BACKSLASH) {
- identifier += C_BACKSLASH;
- character = value.charAt(++index);
- }
-
- identifier += character;
- index++;
- }
-
- character = value.charAt(index);
-
- if (character === C_BRACKET_CLOSE) {
- referenceType = identifier ? REFERENCE_TYPE_FULL : REFERENCE_TYPE_COLLAPSED;
- queue += identifier + character;
- index++;
- } else {
- identifier = '';
- }
-
- subvalue += queue;
- queue = '';
- } else {
- if (!content) {
- return;
- }
-
- identifier = content;
- }
-
- /* Brackets cannot be inside the identifier. */
- if (referenceType !== REFERENCE_TYPE_FULL && bracketed) {
- return;
- }
-
- /* Inline footnotes cannot have an identifier. */
- if (type === T_FOOTNOTE && referenceType !== REFERENCE_TYPE_SHORTCUT) {
- type = T_LINK;
- intro = C_BRACKET_OPEN + C_CARET;
- content = C_CARET + content;
- }
-
- subvalue = intro + subvalue;
-
- if (type === T_LINK && self.inLink) {
- return null;
- }
-
- /* istanbul ignore if - never used (yet) */
- if (silent) {
- return true;
- }
-
- if (type === T_FOOTNOTE && content.indexOf(' ') !== -1) {
- return eat(subvalue)({
- type: 'footnote',
- children: this.tokenizeInline(content, eat.now())
- });
- }
-
- now = eat.now();
- now.column += intro.length;
- now.offset += intro.length;
- identifier = referenceType === REFERENCE_TYPE_FULL ? identifier : content;
-
- node = {
- type: type + 'Reference',
- identifier: normalize(identifier)
- };
-
- if (type === T_LINK || type === T_IMAGE) {
- node.referenceType = referenceType;
- }
-
- if (type === T_LINK) {
- exit = self.enterLink();
- node.children = self.tokenizeInline(content, now);
- exit();
- } else if (type === T_IMAGE) {
- node.alt = self.decode.raw(self.unescape(content), now) || null;
- }
-
- return eat(subvalue)(node);
-}
diff --git a/tools/eslint/node_modules/remark-parse/lib/tokenize/strong.js b/tools/eslint/node_modules/remark-parse/lib/tokenize/strong.js
deleted file mode 100644
index 765993fa0b..0000000000
--- a/tools/eslint/node_modules/remark-parse/lib/tokenize/strong.js
+++ /dev/null
@@ -1,93 +0,0 @@
-/**
- * @author Titus Wormer
- * @copyright 2015 Titus Wormer
- * @license MIT
- * @module remark:parse:tokenize:strong
- * @fileoverview Tokenise strong.
- */
-
-'use strict';
-
-var trim = require('trim');
-var whitespace = require('is-whitespace-character');
-var locate = require('../locate/strong');
-
-module.exports = strong;
-strong.locator = locate;
-
-var C_ASTERISK = '*';
-var C_UNDERSCORE = '_';
-
-/* Tokenise strong. */
-function strong(eat, value, silent) {
- var self = this;
- var index = 0;
- var character = value.charAt(index);
- var now;
- var pedantic;
- var marker;
- var queue;
- var subvalue;
- var length;
- var prev;
-
- if (
- (character !== C_ASTERISK && character !== C_UNDERSCORE) ||
- value.charAt(++index) !== character
- ) {
- return;
- }
-
- pedantic = self.options.pedantic;
- marker = character;
- subvalue = marker + marker;
- length = value.length;
- index++;
- queue = '';
- character = '';
-
- if (pedantic && whitespace(value.charAt(index))) {
- return;
- }
-
- while (index < length) {
- prev = character;
- character = value.charAt(index);
-
- if (
- character === marker &&
- value.charAt(index + 1) === marker &&
- (!pedantic || !whitespace(prev))
- ) {
- character = value.charAt(index + 2);
-
- if (character !== marker) {
- if (!trim(queue)) {
- return;
- }
-
- /* istanbul ignore if - never used (yet) */
- if (silent) {
- return true;
- }
-
- now = eat.now();
- now.column += 2;
- now.offset += 2;
-
- return eat(subvalue + queue + subvalue)({
- type: 'strong',
- children: self.tokenizeInline(queue, now)
- });
- }
- }
-
- if (!pedantic && character === '\\') {
- queue += character;
- character = value.charAt(++index);
- }
-
- queue += character;
- index++;
- }
-}
diff --git a/tools/eslint/node_modules/remark-parse/lib/tokenize/table.js b/tools/eslint/node_modules/remark-parse/lib/tokenize/table.js
deleted file mode 100644
index c440067e10..0000000000
--- a/tools/eslint/node_modules/remark-parse/lib/tokenize/table.js
+++ /dev/null
@@ -1,276 +0,0 @@
-/**
- * @author Titus Wormer
- * @copyright 2015 Titus Wormer
- * @license MIT
- * @module remark:parse:tokenize:table
- * @fileoverview Tokenise a table.
- */
-
-'use strict';
-
-var whitespace = require('is-whitespace-character');
-
-module.exports = table;
-table.notInList = true;
-
-var C_BACKSLASH = '\\';
-var C_TICK = '`';
-var C_DASH = '-';
-var C_PIPE = '|';
-var C_COLON = ':';
-var C_SPACE = ' ';
-var C_NEWLINE = '\n';
-var C_TAB = '\t';
-
-var MIN_TABLE_COLUMNS = 1;
-var MIN_TABLE_ROWS = 2;
-
-var TABLE_ALIGN_LEFT = 'left';
-var TABLE_ALIGN_CENTER = 'center';
-var TABLE_ALIGN_RIGHT = 'right';
-var TABLE_ALIGN_NONE = null;
-
-/* Tokenise a table. */
-function table(eat, value, silent) {
- var self = this;
- var index;
- var alignments;
- var alignment;
- var subvalue;
- var row;
- var length;
- var lines;
- var queue;
- var character;
- var hasDash;
- var align;
- var cell;
- var preamble;
- var count;
- var opening;
- var now;
- var position;
- var lineCount;
- var line;
- var rows;
- var table;
- var lineIndex;
- var pipeIndex;
- var first;
-
- /* Exit when not in gfm-mode. */
- if (!self.options.gfm) {
- return;
- }
-
- /* Get the rows.
- * Detecting tables soon is hard, so there are some
- * checks for performance here, such as the minimum
- * number of rows, and allowed characters in the
- * alignment row. */
- index = 0;
- lineCount = 0;
- length = value.length + 1;
- lines = [];
-
- while (index < length) {
- lineIndex = value.indexOf(C_NEWLINE, index);
- pipeIndex = value.indexOf(C_PIPE, index + 1);
-
- if (lineIndex === -1) {
- lineIndex = value.length;
- }
-
- if (pipeIndex === -1 || pipeIndex > lineIndex) {
- if (lineCount < MIN_TABLE_ROWS) {
- return;
- }
-
- break;
- }
-
- lines.push(value.slice(index, lineIndex));
- lineCount++;
- index = lineIndex + 1;
- }
-
- /* Parse the alignment row. */
- subvalue = lines.join(C_NEWLINE);
- alignments = lines.splice(1, 1)[0] || [];
- index = 0;
- length = alignments.length;
- lineCount--;
- alignment = false;
- align = [];
-
- while (index < length) {
- character = alignments.charAt(index);
-
- if (character === C_PIPE) {
- hasDash = null;
-
- if (alignment === false) {
- if (first === false) {
- return;
- }
- } else {
- align.push(alignment);
- alignment = false;
- }
-
- first = false;
- } else if (character === C_DASH) {
- hasDash = true;
- alignment = alignment || TABLE_ALIGN_NONE;
- } else if (character === C_COLON) {
- if (alignment === TABLE_ALIGN_LEFT) {
- alignment = TABLE_ALIGN_CENTER;
- } else if (hasDash && alignment === TABLE_ALIGN_NONE) {
- alignment = TABLE_ALIGN_RIGHT;
- } else {
- alignment = TABLE_ALIGN_LEFT;
- }
- } else if (!whitespace(character)) {
- return;
- }
-
- index++;
- }
-
- if (alignment !== false) {
- align.push(alignment);
- }
-
- /* Exit when without enough columns. */
- if (align.length < MIN_TABLE_COLUMNS) {
- return;
- }
-
- /* istanbul ignore if - never used (yet) */
- if (silent) {
- return true;
- }
-
- /* Parse the rows. */
- position = -1;
- rows = [];
-
- table = eat(subvalue).reset({
- type: 'table',
- align: align,
- children: rows
- });
-
- while (++position < lineCount) {
- line = lines[position];
- row = {type: 'tableRow', children: []};
-
- /* Eat a newline character when this is not the
- * first row. */
- if (position) {
- eat(C_NEWLINE);
- }
-
- /* Eat the row. */
- eat(line).reset(row, table);
-
- length = line.length + 1;
- index = 0;
- queue = '';
- cell = '';
- preamble = true;
- count = null;
- opening = null;
-
- while (index < length) {
- character = line.charAt(index);
-
- if (character === C_TAB || character === C_SPACE) {
- if (cell) {
- queue += character;
- } else {
- eat(character);
- }
-
- index++;
- continue;
- }
-
- if (character === '' || character === C_PIPE) {
- if (preamble) {
- eat(character);
- } else {
- if (character && opening) {
- queue += character;
- index++;
- continue;
- }
-
- if ((cell || character) && !preamble) {
- subvalue = cell;
-
- if (queue.length > 1) {
- if (character) {
- subvalue += queue.slice(0, queue.length - 1);
- queue = queue.charAt(queue.length - 1);
- } else {
- subvalue += queue;
- queue = '';
- }
- }
-
- now = eat.now();
-
- eat(subvalue)({
- type: 'tableCell',
- children: self.tokenizeInline(cell, now)
- }, row);
- }
-
- eat(queue + character);
-
- queue = '';
- cell = '';
- }
- } else {
- if (queue) {
- cell += queue;
- queue = '';
- }
-
- cell += character;
-
- if (character === C_BACKSLASH && index !== length - 2) {
- cell += line.charAt(index + 1);
- index++;
- }
-
- if (character === C_TICK) {
- count = 1;
-
- while (line.charAt(index + 1) === character) {
- cell += character;
- index++;
- count++;
- }
-
- if (!opening) {
- opening = count;
- } else if (count >= opening) {
- opening = 0;
- }
- }
- }
-
- preamble = false;
- index++;
- }
-
- /* Eat the alignment row. */
- if (!position) {
- eat(C_NEWLINE + alignments);
- }
- }
-
- return table;
-}
diff --git a/tools/eslint/node_modules/remark-parse/lib/tokenize/text.js b/tools/eslint/node_modules/remark-parse/lib/tokenize/text.js
deleted file mode 100644
index ef6d3f2879..0000000000
--- a/tools/eslint/node_modules/remark-parse/lib/tokenize/text.js
+++ /dev/null
@@ -1,67 +0,0 @@
-/**
- * @author Titus Wormer
- * @copyright 2015 Titus Wormer
- * @license MIT
- * @module remark:parse:tokenize:text
- * @fileoverview Tokenise text.
- */
-
-'use strict';
-
-module.exports = text;
-
-/* Tokenise text. */
-function text(eat, value, silent) {
- var self = this;
- var methods;
- var tokenizers;
- var index;
- var length;
- var subvalue;
- var position;
- var tokenizer;
- var name;
- var min;
- var now;
-
- /* istanbul ignore if - never used (yet) */
- if (silent) {
- return true;
- }
-
- methods = self.inlineMethods;
- length = methods.length;
- tokenizers = self.inlineTokenizers;
- index = -1;
- min = value.length;
-
- while (++index < length) {
- name = methods[index];
-
- if (name === 'text' || !tokenizers[name]) {
- continue;
- }
-
- tokenizer = tokenizers[name].locator;
-
- if (!tokenizer) {
- eat.file.fail('Missing locator: `' + name + '`');
- }
-
- position = tokenizer.call(self, value, 1);
-
- if (position !== -1 && position < min) {
- min = position;
- }
- }
-
- subvalue = value.slice(0, min);
- now = eat.now();
-
- self.decode(subvalue, now, function (content, position, source) {
- eat(source || content)({
- type: 'text',
- value: content
- });
- });
-}
diff --git a/tools/eslint/node_modules/remark-parse/lib/tokenize/thematic-break.js b/tools/eslint/node_modules/remark-parse/lib/tokenize/thematic-break.js
deleted file mode 100644
index a580d09fe0..0000000000
--- a/tools/eslint/node_modules/remark-parse/lib/tokenize/thematic-break.js
+++ /dev/null
@@ -1,79 +0,0 @@
-/**
- * @author Titus Wormer
- * @copyright 2015 Titus Wormer
- * @license MIT
- * @module remark:parse:tokenize:thematic-break
- * @fileoverview Tokenise a thematic break.
- */
-
-'use strict';
-
-module.exports = thematicBreak;
-
-var C_NEWLINE = '\n';
-var C_TAB = '\t';
-var C_SPACE = ' ';
-var C_ASTERISK = '*';
-var C_UNDERSCORE = '_';
-var C_DASH = '-';
-
-var THEMATIC_BREAK_MARKER_COUNT = 3;
-
-/* Tokenise a thematic break. */
-function thematicBreak(eat, value, silent) {
- var index = -1;
- var length = value.length + 1;
- var subvalue = '';
- var character;
- var marker;
- var markerCount;
- var queue;
-
- while (++index < length) {
- character = value.charAt(index);
-
- if (character !== C_TAB && character !== C_SPACE) {
- break;
- }
-
- subvalue += character;
- }
-
- if (
- character !== C_ASTERISK &&
- character !== C_DASH &&
- character !== C_UNDERSCORE
- ) {
- return;
- }
-
- marker = character;
- subvalue += character;
- markerCount = 1;
- queue = '';
-
- while (++index < length) {
- character = value.charAt(index);
-
- if (character === marker) {
- markerCount++;
- subvalue += queue + marker;
- queue = '';
- } else if (character === C_SPACE) {
- queue += character;
- } else if (
- markerCount >= THEMATIC_BREAK_MARKER_COUNT &&
- (!character || character === C_NEWLINE)
- ) {
- subvalue += queue;
-
- if (silent) {
- return true;
- }
-
- return eat(subvalue)({type: 'thematicBreak'});
- } else {
- return;
- }
- }
-}
diff --git a/tools/eslint/node_modules/remark-parse/lib/tokenize/url.js b/tools/eslint/node_modules/remark-parse/lib/tokenize/url.js
deleted file mode 100644
index fd2debd32f..0000000000
--- a/tools/eslint/node_modules/remark-parse/lib/tokenize/url.js
+++ /dev/null
@@ -1,153 +0,0 @@
-/**
- * @author Titus Wormer
- * @copyright 2015 Titus Wormer
- * @license MIT
- * @module remark:parse:tokenize:url
- * @fileoverview Tokenise a URL.
- */
-
-'use strict';
-
-var decode = require('parse-entities');
-var whitespace = require('is-whitespace-character');
-var locate = require('../locate/url');
-
-module.exports = url;
-url.locator = locate;
-url.notInLink = true;
-
-var C_BRACKET_OPEN = '[';
-var C_BRACKET_CLOSE = ']';
-var C_PAREN_OPEN = '(';
-var C_PAREN_CLOSE = ')';
-var C_LT = '<';
-var C_AT_SIGN = '@';
-
-var HTTP_PROTOCOL = 'http://';
-var HTTPS_PROTOCOL = 'https://';
-var MAILTO_PROTOCOL = 'mailto:';
-
-var PROTOCOLS = [
- HTTP_PROTOCOL,
- HTTPS_PROTOCOL,
- MAILTO_PROTOCOL
-];
-
-var PROTOCOLS_LENGTH = PROTOCOLS.length;
-
-/* 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
- });
-}
diff --git a/tools/eslint/node_modules/remark-parse/lib/tokenize/yaml.js b/tools/eslint/node_modules/remark-parse/lib/tokenize/yaml.js
deleted file mode 100644
index 78dec31a0f..0000000000
--- a/tools/eslint/node_modules/remark-parse/lib/tokenize/yaml.js
+++ /dev/null
@@ -1,74 +0,0 @@
-/**
- * @author Titus Wormer
- * @copyright 2015 Titus Wormer
- * @license MIT
- * @module remark:parse:tokenize:yaml
- * @fileoverview Tokenise YAML.
- */
-
-'use strict';
-
-module.exports = yaml;
-yaml.onlyAtStart = true;
-
-var FENCE = '---';
-var C_DASH = '-';
-var C_NEWLINE = '\n';
-
-/* Tokenise YAML. */
-function yaml(eat, value, silent) {
- var self = this;
- var subvalue;
- var content;
- var index;
- var length;
- var character;
- var queue;
-
- if (
- !self.options.yaml ||
- value.charAt(0) !== C_DASH ||
- value.charAt(1) !== C_DASH ||
- value.charAt(2) !== C_DASH ||
- value.charAt(3) !== C_NEWLINE
- ) {
- return;
- }
-
- subvalue = FENCE + C_NEWLINE;
- content = '';
- queue = '';
- index = 3;
- length = value.length;
-
- while (++index < length) {
- character = value.charAt(index);
-
- if (
- character === C_DASH &&
- (queue || !content) &&
- value.charAt(index + 1) === C_DASH &&
- value.charAt(index + 2) === C_DASH
- ) {
- /* istanbul ignore if - never used (yet) */
- if (silent) {
- return true;
- }
-
- subvalue += queue + FENCE;
-
- return eat(subvalue)({
- type: 'yaml',
- value: content
- });
- }
-
- if (character === C_NEWLINE) {
- queue += character;
- } else {
- subvalue += queue + character;
- content += queue + character;
- queue = '';
- }
- }
-}
diff --git a/tools/eslint/node_modules/remark-parse/lib/tokenizer.js b/tools/eslint/node_modules/remark-parse/lib/tokenizer.js
deleted file mode 100644
index aefe551fc3..0000000000
--- a/tools/eslint/node_modules/remark-parse/lib/tokenizer.js
+++ /dev/null
@@ -1,451 +0,0 @@
-/**
- * @author Titus Wormer
- * @copyright 2015 Titus Wormer
- * @license MIT
- * @module remark:parse:tokenizer
- * @fileoverview Markdown tokenizer.
- */
-
-'use strict';
-
-module.exports = factory;
-
-var MERGEABLE_NODES = {
- text: mergeText,
- blockquote: mergeBlockquote
-};
-
-/* Check whether a node is mergeable with adjacent nodes. */
-function mergeable(node) {
- var start;
- var end;
-
- if (node.type !== 'text' || !node.position) {
- return true;
- }
-
- start = node.position.start;
- end = node.position.end;
-
- /* Only merge nodes which occupy the same size as their
- * `value`. */
- return start.line !== end.line ||
- end.column - start.column === node.value.length;
-}
-
-/* Merge two text nodes: `node` into `prev`. */
-function mergeText(prev, node) {
- prev.value += node.value;
-
- return prev;
-}
-
-/* Merge two blockquotes: `node` into `prev`, unless in
- * CommonMark mode. */
-function mergeBlockquote(prev, node) {
- if (this.options.commonmark) {
- return node;
- }
-
- prev.children = prev.children.concat(node.children);
-
- return prev;
-}
-
-/* Construct a tokenizer. This creates both
- * `tokenizeInline` and `tokenizeBlock`. */
-function factory(type) {
- return tokenize;
-
- /* Tokenizer for a bound `type`. */
- function tokenize(value, location) {
- var self = this;
- var offset = self.offset;
- var tokens = [];
- var methods = self[type + 'Methods'];
- var tokenizers = self[type + 'Tokenizers'];
- var line = location.line;
- var column = location.column;
- var index;
- var length;
- var method;
- var name;
- var matched;
- var valueLength;
-
- /* Trim white space only lines. */
- if (!value) {
- return tokens;
- }
-
- /* Expose on `eat`. */
- eat.now = now;
- eat.file = self.file;
-
- /* Sync initial offset. */
- updatePosition('');
-
- /* Iterate over `value`, and iterate over all
- * tokenizers. When one eats something, re-iterate
- * with the remaining value. If no tokenizer eats,
- * something failed (should not happen) and an
- * exception is thrown. */
- while (value) {
- index = -1;
- length = methods.length;
- matched = false;
-
- while (++index < length) {
- name = methods[index];
- method = tokenizers[name];
-
- if (
- method &&
- (!method.onlyAtStart || self.atStart) &&
- (!method.notInList || !self.inList) &&
- (!method.notInBlock || !self.inBlock) &&
- (!method.notInLink || !self.inLink)
- ) {
- valueLength = value.length;
-
- method.apply(self, [eat, value]);
-
- matched = valueLength !== value.length;
-
- if (matched) {
- break;
- }
- }
- }
-
- /* istanbul ignore if */
- if (!matched) {
- self.file.fail(new Error('Infinite loop'), eat.now());
- }
- }
-
- self.eof = now();
-
- return tokens;
-
- /**
- * Update line, column, and offset based on
- * `value`.
- *
- * @example
- * updatePosition('foo');
- *
- * @param {string} subvalue - Subvalue to eat.
- */
- function updatePosition(subvalue) {
- var lastIndex = -1;
- var index = subvalue.indexOf('\n');
-
- while (index !== -1) {
- line++;
- lastIndex = index;
- index = subvalue.indexOf('\n', index + 1);
- }
-
- if (lastIndex === -1) {
- column += subvalue.length;
- } else {
- column = subvalue.length - lastIndex;
- }
-
- if (line in offset) {
- if (lastIndex !== -1) {
- column += offset[line];
- } else if (column <= offset[line]) {
- column = offset[line] + 1;
- }
- }
- }
-
- /**
- * Get offset. Called before the first character is
- * eaten to retrieve the range's offsets.
- *
- * @return {Function} - `done`, to be called when
- * the last character is eaten.
- */
- function getOffset() {
- var indentation = [];
- var pos = line + 1;
-
- /**
- * Done. Called when the last character is
- * eaten to retrieve the range’s offsets.
- *
- * @return {Array.<number>} - Offset.
- */
- return function () {
- var last = line + 1;
-
- while (pos < last) {
- indentation.push((offset[pos] || 0) + 1);
-
- pos++;
- }
-
- return indentation;
- };
- }
-
- /**
- * Get the current position.
- *
- * @example
- * position = now(); // {line: 1, column: 1, offset: 0}
- *
- * @return {Object} - Current Position.
- */
- function now() {
- var pos = {line: line, column: column};
-
- pos.offset = self.toOffset(pos);
-
- return pos;
- }
-
- /**
- * Store position information for a node.
- *
- * @example
- * start = now();
- * updatePosition('foo');
- * location = new Position(start);
- * // {
- * // start: {line: 1, column: 1, offset: 0},
- * // end: {line: 1, column: 3, offset: 2}
- * // }
- *
- * @param {Object} start - Starting position.
- */
- function Position(start) {
- this.start = start;
- this.end = now();
- }
-
- /**
- * Throw when a value is incorrectly eaten.
- * This shouldn’t happen but will throw on new,
- * incorrect rules.
- *
- * @example
- * // When the current value is set to `foo bar`.
- * validateEat('foo');
- * eat('foo');
- *
- * validateEat('bar');
- * // throws, because the space is not eaten.
- *
- * @param {string} subvalue - Value to be eaten.
- * @throws {Error} - When `subvalue` cannot be eaten.
- */
- function validateEat(subvalue) {
- /* istanbul ignore if */
- if (value.substring(0, subvalue.length) !== subvalue) {
- /* Capture stack-trace. */
- self.file.fail(
- new Error(
- 'Incorrectly eaten value: please report this ' +
- 'warning on http://git.io/vg5Ft'
- ),
- now()
- );
- }
- }
-
- /**
- * Mark position and patch `node.position`.
- *
- * @example
- * var update = position();
- * updatePosition('foo');
- * update({});
- * // {
- * // position: {
- * // start: {line: 1, column: 1, offset: 0},
- * // end: {line: 1, column: 3, offset: 2}
- * // }
- * // }
- *
- * @returns {Function} - Updater.
- */
- function position() {
- var before = now();
-
- return update;
-
- /**
- * Add the position to a node.
- *
- * @example
- * update({type: 'text', value: 'foo'});
- *
- * @param {Node} node - Node to attach position
- * on.
- * @param {Array} [indent] - Indentation for
- * `node`.
- * @return {Node} - `node`.
- */
- function update(node, indent) {
- var prev = node.position;
- var start = prev ? prev.start : before;
- var combined = [];
- var n = prev && prev.end.line;
- var l = before.line;
-
- node.position = new Position(start);
-
- /* If there was already a `position`, this
- * node was merged. Fixing `start` wasn’t
- * hard, but the indent is different.
- * Especially because some information, the
- * indent between `n` and `l` wasn’t
- * tracked. Luckily, that space is
- * (should be?) empty, so we can safely
- * check for it now. */
- if (prev && indent && prev.indent) {
- combined = prev.indent;
-
- if (n < l) {
- while (++n < l) {
- combined.push((offset[n] || 0) + 1);
- }
-
- combined.push(before.column);
- }
-
- indent = combined.concat(indent);
- }
-
- node.position.indent = indent || [];
-
- return node;
- }
- }
-
- /**
- * Add `node` to `parent`s children or to `tokens`.
- * Performs merges where possible.
- *
- * @example
- * add({});
- *
- * add({}, {children: []});
- *
- * @param {Object} node - Node to add.
- * @param {Object} [parent] - Parent to insert into.
- * @return {Object} - Added or merged into node.
- */
- function add(node, parent) {
- var children = parent ? parent.children : tokens;
- var prev = children[children.length - 1];
-
- if (
- prev &&
- node.type === prev.type &&
- node.type in MERGEABLE_NODES &&
- mergeable(prev) &&
- mergeable(node)
- ) {
- node = MERGEABLE_NODES[node.type].call(self, prev, node);
- }
-
- if (node !== prev) {
- children.push(node);
- }
-
- if (self.atStart && tokens.length !== 0) {
- self.exitStart();
- }
-
- return node;
- }
-
- /**
- * Remove `subvalue` from `value`.
- * `subvalue` must be at the start of `value`.
- *
- * @example
- * eat('foo')({type: 'text', value: 'foo'});
- *
- * @param {string} subvalue - Removed from `value`,
- * and passed to `updatePosition`.
- * @return {Function} - Wrapper around `add`, which
- * also adds `position` to node.
- */
- function eat(subvalue) {
- var indent = getOffset();
- var pos = position();
- var current = now();
-
- validateEat(subvalue);
-
- apply.reset = reset;
- reset.test = test;
- apply.test = test;
-
- value = value.substring(subvalue.length);
-
- updatePosition(subvalue);
-
- indent = indent();
-
- return apply;
-
- /**
- * Add the given arguments, add `position` to
- * the returned node, and return the node.
- *
- * @param {Object} node - Node to add.
- * @param {Object} [parent] - Node to insert into.
- * @return {Node} - Added node.
- */
- function apply(node, parent) {
- return pos(add(pos(node), parent), indent);
- }
-
- /**
- * Functions just like apply, but resets the
- * content: the line and column are reversed,
- * and the eaten value is re-added.
- *
- * This is useful for nodes with a single
- * type of content, such as lists and tables.
- *
- * See `apply` above for what parameters are
- * expected.
- *
- * @return {Node} - Added node.
- */
- function reset() {
- var node = apply.apply(null, arguments);
-
- line = current.line;
- column = current.column;
- value = subvalue + value;
-
- return node;
- }
-
- /**
- * Test the position, after eating, and reverse
- * to a not-eaten state.
- *
- * @return {Position} - Position after eating `subvalue`.
- */
- function test() {
- var result = pos({});
-
- line = current.line;
- column = current.column;
- value = subvalue + value;
-
- return result.position;
- }
- }
- }
-}
diff --git a/tools/eslint/node_modules/remark-parse/lib/unescape.js b/tools/eslint/node_modules/remark-parse/lib/unescape.js
deleted file mode 100644
index dc83486126..0000000000
--- a/tools/eslint/node_modules/remark-parse/lib/unescape.js
+++ /dev/null
@@ -1,46 +0,0 @@
-/**
- * @author Titus Wormer
- * @copyright 2015 Titus Wormer
- * @license MIT
- * @module remark:parse:unescape
- * @fileoverview Unescape escapes.
- */
-
-'use strict';
-
-/* Expose. */
-module.exports = factory;
-
-/* Factory to de-escape a value, based on a list at `key`
- * in `ctx`. */
-function factory(ctx, key) {
- return unescape;
-
- /* De-escape a string using the expression at `key`
- * in `ctx`. */
- function unescape(value) {
- var prev = 0;
- var index = value.indexOf('\\');
- var escape = ctx[key];
- var queue = [];
- var character;
-
- while (index !== -1) {
- queue.push(value.slice(prev, index));
- prev = index + 1;
- character = value.charAt(prev);
-
- /* If the following character is not a valid escape,
- * add the slash. */
- if (!character || escape.indexOf(character) === -1) {
- queue.push('\\');
- }
-
- index = value.indexOf('\\', prev);
- }
-
- queue.push(value.slice(prev));
-
- return queue.join('');
- }
-}
diff --git a/tools/eslint/node_modules/remark-parse/lib/util/get-indentation.js b/tools/eslint/node_modules/remark-parse/lib/util/get-indentation.js
deleted file mode 100644
index eebd40c94a..0000000000
--- a/tools/eslint/node_modules/remark-parse/lib/util/get-indentation.js
+++ /dev/null
@@ -1,46 +0,0 @@
-/**
- * @author Titus Wormer
- * @copyright 2015 Titus Wormer
- * @license MIT
- * @module remark:parse:util:get-indentation
- * @fileoverview Get indentation.
- */
-
-'use strict';
-
-/* Expose. */
-module.exports = indentation;
-
-/* Map of characters, and their column length,
- * which can be used as indentation. */
-var characters = {' ': 1, '\t': 4};
-
-/**
- * Gets indentation information for a line.
- *
- * @param {string} value - Indented line.
- * @return {Object} - Indetation information.
- */
-function indentation(value) {
- var index = 0;
- var indent = 0;
- var character = value.charAt(index);
- var stops = {};
- var size;
-
- while (character in characters) {
- size = characters[character];
-
- indent += size;
-
- if (size > 1) {
- indent = Math.floor(indent / size) * size;
- }
-
- stops[indent] = index;
-
- character = value.charAt(++index);
- }
-
- return {indent: indent, stops: stops};
-}
diff --git a/tools/eslint/node_modules/remark-parse/lib/util/html.js b/tools/eslint/node_modules/remark-parse/lib/util/html.js
deleted file mode 100644
index 234ba342e1..0000000000
--- a/tools/eslint/node_modules/remark-parse/lib/util/html.js
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- * @author Titus Wormer
- * @copyright 2015 Titus Wormer
- * @license MIT
- * @module remark:parse:util:html
- * @fileoverview HTML regexes.
- */
-
-'use strict';
-
-var attributeName = '[a-zA-Z_:][a-zA-Z0-9:._-]*';
-var unquoted = '[^"\'=<>`\\u0000-\\u0020]+';
-var singleQuoted = '\'[^\']*\'';
-var doubleQuoted = '"[^"]*"';
-var attributeValue = '(?:' + unquoted + '|' + singleQuoted + '|' + doubleQuoted + ')';
-var attribute = '(?:\\s+' + attributeName + '(?:\\s*=\\s*' + attributeValue + ')?)';
-var openTag = '<[A-Za-z][A-Za-z0-9\\-]*' + attribute + '*\\s*\\/?>';
-var closeTag = '<\\/[A-Za-z][A-Za-z0-9\\-]*\\s*>';
-var comment = '<!---->|<!--(?:-?[^>-])(?:-?[^-])*-->';
-var processing = '<[?].*?[?]>';
-var declaration = '<![A-Za-z]+\\s+[^>]*>';
-var cdata = '<!\\[CDATA\\[[\\s\\S]*?\\]\\]>';
-
-exports.openCloseTag = new RegExp('^(?:' + openTag + '|' + closeTag + ')');
-
-exports.tag = new RegExp('^(?:' +
- openTag + '|' +
- closeTag + '|' +
- comment + '|' +
- processing + '|' +
- declaration + '|' +
- cdata +
-')');
diff --git a/tools/eslint/node_modules/remark-parse/lib/util/interrupt.js b/tools/eslint/node_modules/remark-parse/lib/util/interrupt.js
deleted file mode 100644
index b8dc230550..0000000000
--- a/tools/eslint/node_modules/remark-parse/lib/util/interrupt.js
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
- * @author Titus Wormer
- * @copyright 2015 Titus Wormer
- * @license MIT
- * @module remark:parse:util:get-indentation
- * @fileoverview Get indentation.
- */
-
-'use strict';
-
-module.exports = interrupt;
-
-function interrupt(interruptors, tokenizers, ctx, params) {
- var bools = ['pedantic', 'commonmark'];
- var count = bools.length;
- var length = interruptors.length;
- var index = -1;
- var interruptor;
- var config;
- var fn;
- var offset;
- var bool;
- var ignore;
-
- while (++index < length) {
- interruptor = interruptors[index];
- config = interruptor[1] || {};
- fn = interruptor[0];
- offset = -1;
- ignore = false;
-
- while (++offset < count) {
- bool = bools[offset];
-
- if (config[bool] !== undefined && config[bool] !== ctx.options[bool]) {
- ignore = true;
- break;
- }
- }
-
- if (ignore) {
- continue;
- }
-
- if (tokenizers[fn].apply(ctx, params)) {
- return true;
- }
- }
-
- return false;
-}
diff --git a/tools/eslint/node_modules/remark-parse/lib/util/normalize.js b/tools/eslint/node_modules/remark-parse/lib/util/normalize.js
deleted file mode 100644
index 3602a18f78..0000000000
--- a/tools/eslint/node_modules/remark-parse/lib/util/normalize.js
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- * @author Titus Wormer
- * @copyright 2015 Titus Wormer
- * @license MIT
- * @module remark:parse:util:normalize
- * @fileoverview Normalize an identifier.
- */
-
-'use strict';
-
-/* Dependencies. */
-var collapseWhiteSpace = require('collapse-white-space');
-
-/* Expose. */
-module.exports = normalize;
-
-/**
- * Normalize an identifier. Collapses multiple white space
- * characters into a single space, and removes casing.
- *
- * @example
- * normalizeIdentifier('FOO\t bar'); // 'foo bar'
- *
- * @param {string} value - Content to normalize.
- * @return {string} - Normalized content.
- */
-function normalize(value) {
- return collapseWhiteSpace(value).toLowerCase();
-}
diff --git a/tools/eslint/node_modules/remark-parse/lib/util/remove-indentation.js b/tools/eslint/node_modules/remark-parse/lib/util/remove-indentation.js
deleted file mode 100644
index d56db0bad4..0000000000
--- a/tools/eslint/node_modules/remark-parse/lib/util/remove-indentation.js
+++ /dev/null
@@ -1,102 +0,0 @@
-/**
- * @author Titus Wormer
- * @copyright 2015 Titus Wormer
- * @license MIT
- * @module remark:parse:util:remove-indentation
- * @fileoverview Remove indentation.
- */
-
-'use strict';
-
-/* Dependencies. */
-var trim = require('trim');
-var repeat = require('repeat-string');
-var getIndent = require('./get-indentation');
-
-/* Expose. */
-module.exports = indentation;
-
-/* Characters. */
-var C_SPACE = ' ';
-var C_NEWLINE = '\n';
-var C_TAB = '\t';
-
-/**
- * Remove the minimum indent from every line in `value`.
- * Supports both tab, spaced, and mixed indentation (as
- * well as possible).
- *
- * @example
- * removeIndentation(' foo'); // 'foo'
- * removeIndentation(' foo', 2); // ' foo'
- * removeIndentation('\tfoo', 2); // ' foo'
- * removeIndentation(' foo\n bar'); // ' foo\n bar'
- *
- * @param {string} value - Value to trim.
- * @param {number?} [maximum] - Maximum indentation
- * to remove.
- * @return {string} - Unindented `value`.
- */
-function indentation(value, maximum) {
- var values = value.split(C_NEWLINE);
- var position = values.length + 1;
- var minIndent = Infinity;
- var matrix = [];
- var index;
- var indentation;
- var stops;
- var padding;
-
- values.unshift(repeat(C_SPACE, maximum) + '!');
-
- while (position--) {
- indentation = getIndent(values[position]);
-
- matrix[position] = indentation.stops;
-
- if (trim(values[position]).length === 0) {
- continue;
- }
-
- if (indentation.indent) {
- if (indentation.indent > 0 && indentation.indent < minIndent) {
- minIndent = indentation.indent;
- }
- } else {
- minIndent = Infinity;
-
- break;
- }
- }
-
- if (minIndent !== Infinity) {
- position = values.length;
-
- while (position--) {
- stops = matrix[position];
- index = minIndent;
-
- while (index && !(index in stops)) {
- index--;
- }
-
- if (
- trim(values[position]).length !== 0 &&
- minIndent &&
- index !== minIndent
- ) {
- padding = C_TAB;
- } else {
- padding = '';
- }
-
- values[position] = padding + values[position].slice(
- index in stops ? stops[index] + 1 : 0
- );
- }
- }
-
- values.shift();
-
- return values.join(C_NEWLINE);
-}
diff --git a/tools/eslint/node_modules/remark-parse/package.json b/tools/eslint/node_modules/remark-parse/package.json
index 1a88f33a7c..a39fd06ac8 100644
--- a/tools/eslint/node_modules/remark-parse/package.json
+++ b/tools/eslint/node_modules/remark-parse/package.json
@@ -16,7 +16,7 @@
"fetchSpec": "^1.1.0"
},
"_requiredBy": [
- "/eslint-plugin-markdown"
+ "/remark"
],
"_resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-1.1.0.tgz",
"_shasum": "c3ca10f9a8da04615c28f09aa4e304510526ec21",
@@ -43,22 +43,15 @@
}
],
"dependencies": {
- "collapse-white-space": "^1.0.2",
- "has": "^1.0.1",
- "is-alphabetical": "^1.0.0",
- "is-decimal": "^1.0.0",
- "is-whitespace-character": "^1.0.0",
- "is-word-character": "^1.0.0",
- "markdown-escapes": "^1.0.0",
+ "collapse-white-space": "^1.0.0",
+ "extend": "^3.0.0",
"parse-entities": "^1.0.2",
"repeat-string": "^1.5.4",
- "state-toggle": "^1.0.0",
"trim": "0.0.1",
"trim-trailing-lines": "^1.0.0",
"unherit": "^1.0.4",
"unist-util-remove-position": "^1.0.0",
- "vfile-location": "^2.0.0",
- "xtend": "^4.0.1"
+ "vfile-location": "^2.0.0"
},
"deprecated": false,
"description": "Markdown parser for remark",
diff --git a/tools/eslint/node_modules/remark-parse/readme.md b/tools/eslint/node_modules/remark-parse/readme.md
index 53426f41ee..360e53b076 100644
--- a/tools/eslint/node_modules/remark-parse/readme.md
+++ b/tools/eslint/node_modules/remark-parse/readme.md
@@ -1,7 +1,7 @@
# remark-parse [![Build Status][build-badge]][build-status] [![Coverage Status][coverage-badge]][coverage-status] [![Chat][chat-badge]][chat]
[Parser][] for [**unified**][unified]. Parses markdown to an
-[**MDAST**][mdast] syntax tree. Used in the [**remark**
+[**mdast**][mdast] syntax tree. Used in the [**remark**
processor][processor]. Can be [extended][extend] to change how
markdown is parsed.
@@ -9,7 +9,7 @@ markdown is parsed.
[npm][]:
-```sh
+```bash
npm install remark-parse
```
@@ -17,17 +17,16 @@ npm install remark-parse
```js
var unified = require('unified');
-var createStream = require('unified-stream');
var markdown = require('remark-parse');
var html = require('remark-html');
-var processor = unified()
- .use(markdown, {commonmark: true})
- .use(html)
-
process.stdin
- .pipe(createStream(processor))
- .pipe(process.stdout);
+ .pipe(unified())
+ .use(markdown)
+ .use(html)
+ .pipe(process.stdout, {
+ 'commonmark': true
+ });
```
## Table of Contents
@@ -53,7 +52,7 @@ process.stdin
### `processor.use(parse)`
Configure the `processor` to read markdown as input and process an
-[**MDAST**][mdast] syntax tree.
+[**mdast**][mdast] syntax tree.
#### `options`
@@ -61,14 +60,12 @@ Options are passed later through [`processor.parse()`][parse],
[`processor.process()`][process], or [`processor.pipe()`][pipe].
The following settings are supported:
-* [`gfm`][options-gfm] (`boolean`, default: `true`)
-* [`yaml`][options-yaml] (`boolean`, default: `true`)
-* [`commonmark`][options-commonmark] (`boolean`, default: `false`)
-* [`footnotes`][options-footnotes] (`boolean`, default: `false`)
-* [`pedantic`][options-pedantic] (`boolean`, default: `false`)
-* [`breaks`][options-breaks] (`boolean`, default: `false`)
-* [`blocks`][options-blocks] (`Array.<string>`, default: list of block HTML
- elements)
+* [`gfm`][options-gfm] (`boolean`, default: `true`);
+* [`yaml`][options-yaml] (`boolean`, default: `true`);
+* [`commonmark`][options-commonmark] (`boolean`, default: `false`);
+* [`footnotes`][options-footnotes] (`boolean`, default: `false`);
+* [`pedantic`][options-pedantic] (`boolean`, default: `false`);
+* [`breaks`][options-breaks] (`boolean`, default: `false`).
##### `options.gfm`
@@ -78,11 +75,11 @@ hello ~~hi~~ world
GFM mode (default: `true`) turns on:
-* [Fenced code blocks](https://help.github.com/articles/github-flavored-markdown/#fenced-code-blocks)
-* [Autolinking of URLs](https://help.github.com/articles/github-flavored-markdown/#url-autolinking)
-* [Deletions (strikethrough)](https://help.github.com/articles/github-flavored-markdown/#strikethrough)
-* [Task lists](https://help.github.com/articles/writing-on-github/#task-lists)
-* [Tables](https://help.github.com/articles/github-flavored-markdown/#tables)
+* [Fenced code blocks](https://help.github.com/articles/github-flavored-markdown/#fenced-code-blocks);
+* [Autolinking of URLs](https://help.github.com/articles/github-flavored-markdown/#url-autolinking);
+* [Deletions (strikethrough)](https://help.github.com/articles/github-flavored-markdown/#strikethrough);
+* [Task lists](https://help.github.com/articles/writing-on-github/#task-lists);
+* [Tables](https://help.github.com/articles/github-flavored-markdown/#tables).
##### `options.yaml`
@@ -106,23 +103,23 @@ This is a paragraph
CommonMark mode (default: `false`) allows:
-* Empty lines to split blockquotes
-* Parentheses (`(` and `)`) around for link and image titles
-* Any escaped [ASCII-punctuation][escapes] character
-* Closing parenthesis (`)`) as an ordered list marker
-* URL definitions (and footnotes, when enabled) in blockquotes
+* Empty lines to split blockquotes;
+* Parentheses (`(` and `)`) around for link and image titles;
+* Any escaped [ASCII-punctuation][escapes] character;
+* Closing parenthesis (`)`) as an ordered list marker;
+* URL definitions (and footnotes, when enabled) in blockquotes.
CommonMark mode disallows:
-* Code directly following a paragraph
+* Code directly following a paragraph;
* ATX-headings (`# Hash headings`) without spacing after opening hashes
- or and before closing hashes
-* Setext headings (`Underline headings\n---`) when following a paragraph
-* Newlines in link and image titles
+ or and before closing hashes;
+* Setext headings (`Underline headings\n---`) when following a paragraph;
+* Newlines in link and image titles;
* White space in link and image URLs in auto-links (links in brackets,
- `<` and `>`)
+ `<` and `>`);
* Lazy blockquote continuation, lines not preceded by a closing angle
- bracket (`>`), for lists, code, and thematicBreak
+ bracket (`>`), for lists, code, and thematicBreak.
##### `options.footnotes`
@@ -150,16 +147,6 @@ paragraph.
Breaks mode (default: `false`) exposes newline characters inside
paragraphs as breaks.
-##### `options.blocks`
-
-```md
-<block>foo
-</block>
-```
-
-Blocks (default: a list of HTML block elements) exposes
-let’s users define block-level HTML elements.
-
##### `options.pedantic`
```md
@@ -169,12 +156,12 @@ Check out some_file_name.txt
Pedantic mode (default: `false`) turns on:
* Emphasis (`_alpha_`) and importance (`__bravo__`) with underscores
- in words
-* Unordered lists with different markers (`*`, `-`, `+`)
+ in words;
+* Unordered lists with different markers (`*`, `-`, `+`);
* If `commonmark` is also turned on, ordered lists with different
- markers (`.`, `)`)
+ markers (`.`, `)`);
* And pedantic mode removes less spaces in list-items (at most four,
- instead of the whole indent)
+ instead of the whole indent).
### `parse.Parser`
@@ -194,19 +181,19 @@ prototype to change how markdown is parsed.
The below plug-in adds a [tokenizer][] for at-mentions.
```js
-module.exports = mentions;
-
-function mentions() {
- var Parser = this.Parser;
- var tokenizers = Parser.prototype.inlineTokenizers;
- var methods = Parser.prototype.inlineMethods;
+function mentions(processor) {
+ var Parser = processor.Parser;
+ var tokenizers = Parser.prototype.inlineTokenizers;
+ var methods = Parser.prototype.inlineMethods;
- /* Add an inline tokenizer (defined in the following example). */
- tokenizers.mention = tokenizeMention;
+ /* Add an inline tokenizer (defined in the following example). */
+ tokenizers.mention = tokenizeMention;
- /* Run it just before `text`. */
- methods.splice(methods.indexOf('text'), 0, 'mention');
+ /* Run it just before `text`. */
+ methods.splice(methods.indexOf('text'), 0, 'mention');
}
+
+module.exports = mentions;
```
### `Parser#blockTokenizers`
@@ -234,24 +221,27 @@ which they run.
### `function tokenizer(eat, value, silent)`
```js
-tokenizeMention.notInLink = true;
-tokenizeMention.locator = locateMention;
-
function tokenizeMention(eat, value, silent) {
- var match = /^@(\w+)/.exec(value);
-
- if (match) {
- if (silent) {
- return true;
+ var match = /^@(\w+)/.exec(value);
+
+ if (match) {
+ if (silent) {
+ return true;
+ }
+
+ return eat(match[0])({
+ 'type': 'link',
+ 'url': 'https://social-network/' + match[1],
+ 'children': [{
+ 'type': 'text',
+ 'value': match[0]
+ }]
+ });
}
-
- return eat(match[0])({
- type: 'link',
- url: 'https://social-network/' + match[1],
- children: [{type: 'text', value: match[0]}]
- });
- }
}
+
+tokenizeMention.notInLink = true;
+tokenizeMention.locator = locateMention;
```
The parser knows two types of tokenizers: block level and inline level.
@@ -266,39 +256,39 @@ information on where the next entity may occur.
###### Signatures
-* `Node? = tokenizer(eat, value)`
-* `boolean? = tokenizer(eat, value, silent)`
+* `Node? = tokenizer(eat, value)`;
+* `boolean? = tokenizer(eat, value, silent)`.
###### Parameters
-* `eat` ([`Function`][eat]) — Eat, when applicable, an entity
-* `value` (`string`) — Value which may start an entity
-* `silent` (`boolean`, optional) — Whether to detect or consume
+* `eat` ([`Function`][eat]) — Eat, when applicable, an entity;
+* `value` (`string`) — Value which may start an entity;
+* `silent` (`boolean`, optional) — Whether to detect or consume.
###### Properties
* `locator` ([`Function`][locator])
- — Required for inline tokenizers
+ — Required for inline tokenizers;
* `onlyAtStart` (`boolean`)
- — Whether nodes can only be found at the beginning of the document
+ — Whether nodes can only be found at the beginning of the document;
* `notInBlock` (`boolean`)
— Whether nodes cannot be in blockquotes, lists, or footnote
- definitions
-* `notInList` (`boolean`)
- — Whether nodes cannot be in lists
+ definitions;
* `notInLink` (`boolean`)
- — Whether nodes cannot be in links
+ — Whether nodes cannot be in lists.
+* `notInLink` (`boolean`)
+ — Whether nodes cannot be in links.
###### Returns
-* In _silent_ mode, whether a node can be found at the start of `value`
-* In _normal_ mode, a node if it can be found at the start of `value`
+* In _silent_ mode, whether a node can be found at the start of `value`;
+* In _normal_ mode, a node if it can be found at the start of `value`.
### `tokenizer.locator(value, fromIndex)`
```js
function locateMention(value, fromIndex) {
- return value.indexOf('@', fromIndex);
+ return value.indexOf('@', fromIndex);
}
```
@@ -310,8 +300,8 @@ the index they return, but they must skip any nodes.
###### Parameters
-* `value` (`string`) — Value which may contain an entity
-* `fromIndex` (`number`) — Position to start searching at
+* `value` (`string`) — Value which may contain an entity;
+* `fromIndex` (`number`) — Position to start searching at.
###### Returns
@@ -346,9 +336,9 @@ Add [positional information][location] to `node` and add it to `parent`.
###### Parameters
-* `node` ([`Node`][node]) - Node to patch position on and insert
+* `node` ([`Node`][node]) - Node to patch position on and insert;
* `parent` ([`Node`][node], optional) - Place to add `node` to in
- the syntax tree. Defaults to the currently processed node
+ the syntax tree. Defaults to the currently processed node.
###### Returns
@@ -371,9 +361,9 @@ for list items
###### Parameters
-* `node` ([`Node`][node]) - Node to patch position on and insert
+* `node` ([`Node`][node]) - Node to patch position on and insert;
* `parent` ([`Node`][node], optional) - Place to add `node` to in
- the syntax tree. Defaults to the currently processed node
+ the syntax tree. Defaults to the currently processed node.
###### Returns
@@ -433,8 +423,6 @@ The given `node`.
[options-breaks]: #optionsbreaks
-[options-blocks]: #optionsblocks
-
[parser]: https://github.com/wooorm/unified#processorparser
[extend]: #extending-the-parser