+++ /dev/null
-'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;
-
-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;
-}
-
-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;
- }
-}