tools: update ESLint to 7.26.0

Update ESLint to 7.26.0

PR-URL: https://github.com/nodejs/node/pull/38605
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: Yongsheng Zhang <zyszys98@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
cjihrig 2021-05-08 15:35:55 -04:00 committed by Michaël Zasso
parent 6b409cf664
commit a028805f1b
No known key found for this signature in database
GPG Key ID: 770F7A9A5AE15600
116 changed files with 4919 additions and 4657 deletions

View File

@ -1,14 +1,17 @@
'use strict';
'use strict'
var unherit = require('unherit');
var xtend = require('xtend');
var Parser = require('./lib/parser.js');
var unherit = require('unherit')
var xtend = require('xtend')
var Parser = require('./lib/parser.js')
module.exports = parse;
parse.Parser = Parser;
module.exports = parse
parse.Parser = Parser
function parse(options) {
var Local = unherit(Parser);
Local.prototype.options = xtend(Local.prototype.options, this.data('settings'), options);
this.Parser = Local;
var settings = this.data('settings')
var Local = unherit(Parser)
Local.prototype.options = xtend(Local.prototype.options, settings, options)
this.Parser = Local
}

View File

@ -0,0 +1,70 @@
'use strict'
module.exports = [
'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'
]

View File

@ -1,68 +0,0 @@
[
"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"
]

View File

@ -1,48 +1,34 @@
'use strict';
'use strict'
var xtend = require('xtend');
var entities = require('parse-entities');
var xtend = require('xtend')
var entities = require('parse-entities')
module.exports = factory;
module.exports = factory
/* Factory to create an entity decoder. */
// Factory to create an entity decoder.
function factory(ctx) {
decoder.raw = decodeRaw;
decoder.raw = decodeRaw
return decoder;
return decoder
/* Normalize `position` to add an `indent`. */
// Normalize `position` to add an `indent`.
function normalize(position) {
var offsets = ctx.offset;
var line = position.line;
var result = [];
var offsets = ctx.offset
var line = position.line
var result = []
while (++line) {
if (!(line in offsets)) {
break;
break
}
result.push((offsets[line] || 0) + 1);
result.push((offsets[line] || 0) + 1)
}
return {
start: position,
indent: result
};
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. */
// Decode `value` (at `position`) into text-nodes.
function decoder(value, position, handler) {
entities(value, {
position: normalize(position),
@ -51,14 +37,22 @@ function factory(ctx) {
reference: handler,
textContext: ctx,
referenceContext: ctx
});
})
}
/* Decode `value` (at `position`) into a string. */
// Decode `value` (at `position`) into a string.
function decodeRaw(value, position, options) {
return entities(value, xtend(options, {
position: normalize(position),
warning: handleWarning
}));
return entities(
value,
xtend(options, {position: normalize(position), warning: handleWarning})
)
}
// Handle a warning.
// See <https://github.com/wooorm/parse-entities> for the warnings.
function handleWarning(reason, position, code) {
if (code !== 3) {
ctx.file.message(reason, position)
}
}
}

View File

@ -1,4 +1,4 @@
'use strict';
'use strict'
module.exports = {
position: true,
@ -6,5 +6,5 @@ module.exports = {
commonmark: false,
footnotes: false,
pedantic: false,
blocks: require('./block-elements.json')
};
blocks: require('./block-elements')
}

View File

@ -1,17 +1,17 @@
'use strict';
'use strict'
module.exports = locate;
module.exports = locate
function locate(value, fromIndex) {
var index = value.indexOf('\n', fromIndex);
var index = value.indexOf('\n', fromIndex)
while (index > fromIndex) {
if (value.charAt(index - 1) !== ' ') {
break;
break
}
index--;
index--
}
return index;
return index
}

View File

@ -1,7 +1,7 @@
'use strict';
'use strict'
module.exports = locate;
module.exports = locate
function locate(value, fromIndex) {
return value.indexOf('`', fromIndex);
return value.indexOf('`', fromIndex)
}

View File

@ -1,7 +1,7 @@
'use strict';
'use strict'
module.exports = locate;
module.exports = locate
function locate(value, fromIndex) {
return value.indexOf('~~', fromIndex);
return value.indexOf('~~', fromIndex)
}

View File

@ -1,18 +1,18 @@
'use strict';
'use strict'
module.exports = locate;
module.exports = locate
function locate(value, fromIndex) {
var asterisk = value.indexOf('*', fromIndex);
var underscore = value.indexOf('_', fromIndex);
var asterisk = value.indexOf('*', fromIndex)
var underscore = value.indexOf('_', fromIndex)
if (underscore === -1) {
return asterisk;
return asterisk
}
if (asterisk === -1) {
return underscore;
return underscore
}
return underscore < asterisk ? underscore : asterisk;
return underscore < asterisk ? underscore : asterisk
}

View File

@ -1,7 +1,7 @@
'use strict';
'use strict'
module.exports = locate;
module.exports = locate
function locate(value, fromIndex) {
return value.indexOf('\\', fromIndex);
return value.indexOf('\\', fromIndex)
}

View File

@ -1,16 +1,16 @@
'use strict';
'use strict'
module.exports = locate;
module.exports = locate
function locate(value, fromIndex) {
var link = value.indexOf('[', fromIndex);
var image = value.indexOf('![', fromIndex);
var link = value.indexOf('[', fromIndex)
var image = value.indexOf('![', fromIndex)
if (image === -1) {
return link;
return link
}
/* Link can never be `-1` if an image is found, so we dont need
* to check for that :) */
return link < image ? link : image;
// Link can never be `-1` if an image is found, so we dont need to check
// for that :)
return link < image ? link : image
}

View File

@ -1,18 +1,18 @@
'use strict';
'use strict'
module.exports = locate;
module.exports = locate
function locate(value, fromIndex) {
var asterisk = value.indexOf('**', fromIndex);
var underscore = value.indexOf('__', fromIndex);
var asterisk = value.indexOf('**', fromIndex)
var underscore = value.indexOf('__', fromIndex)
if (underscore === -1) {
return asterisk;
return asterisk
}
if (asterisk === -1) {
return underscore;
return underscore
}
return underscore < asterisk ? underscore : asterisk;
return underscore < asterisk ? underscore : asterisk
}

View File

@ -1,7 +1,7 @@
'use strict';
'use strict'
module.exports = locate;
module.exports = locate
function locate(value, fromIndex) {
return value.indexOf('<', fromIndex);
return value.indexOf('<', fromIndex)
}

View File

@ -1,26 +1,26 @@
'use strict';
'use strict'
module.exports = locate;
module.exports = locate
var PROTOCOLS = ['https://', 'http://', 'mailto:'];
var protocols = ['https://', 'http://', 'mailto:']
function locate(value, fromIndex) {
var length = PROTOCOLS.length;
var index = -1;
var min = -1;
var position;
var length = protocols.length
var index = -1
var min = -1
var position
if (!this.options.gfm) {
return -1;
return -1
}
while (++index < length) {
position = value.indexOf(PROTOCOLS[index], fromIndex);
position = value.indexOf(protocols[index], fromIndex)
if (position !== -1 && (position < min || min === -1)) {
min = position;
min = position
}
}
return min;
return min
}

View File

@ -1,45 +1,42 @@
'use strict';
'use strict'
var xtend = require('xtend');
var removePosition = require('unist-util-remove-position');
var xtend = require('xtend')
var removePosition = require('unist-util-remove-position')
module.exports = parse;
module.exports = parse
var C_NEWLINE = '\n';
var EXPRESSION_LINE_BREAKS = /\r\n|\r/g;
var lineFeed = '\n'
var lineBreaksExpression = /\r\n|\r/g
/* Parse the bound file. */
// 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;
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);
// Clean non-unix newlines: `\r\n` and `\r` are all changed to `\n`.
// This should not affect positional information.
value = value.replace(lineBreaksExpression, lineFeed)
if (value.charCodeAt(0) === 0xFEFF) {
value = value.slice(1);
// BOM.
if (value.charCodeAt(0) === 0xfeff) {
value = value.slice(1)
content.column++;
content.offset++;
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);
position: {start: start, end: self.eof || xtend(start)}
}
return node;
if (!self.options.position) {
removePosition(node, true)
}
return node
}

View File

@ -1,54 +1,53 @@
'use strict';
'use strict'
var xtend = require('xtend');
var toggle = require('state-toggle');
var vfileLocation = require('vfile-location');
var unescape = require('./unescape');
var decode = require('./decode');
var tokenizer = require('./tokenizer');
var xtend = require('xtend')
var toggle = require('state-toggle')
var vfileLocation = require('vfile-location')
var unescape = require('./unescape')
var decode = require('./decode')
var tokenizer = require('./tokenizer')
module.exports = Parser;
module.exports = Parser
function Parser(doc, file) {
this.file = file;
this.offset = {};
this.options = xtend(this.options);
this.setOptions({});
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.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);
this.toOffset = vfileLocation(file).toOffset
this.unescape = unescape(this, 'escape')
this.decode = decode(this)
}
var proto = Parser.prototype;
var proto = Parser.prototype
/* Expose core. */
proto.setOptions = require('./set-options');
proto.parse = require('./parse');
// Expose core.
proto.setOptions = require('./set-options')
proto.parse = require('./parse')
/* Expose `defaults`. */
proto.options = require('./defaults');
// 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);
// 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. */
// 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'],
@ -58,34 +57,32 @@ proto.interruptParagraph = [
['setextHeading', {commonmark: false}],
['definition', {commonmark: false}],
['footnote', {commonmark: false}]
];
]
/* Nodes that can interupt a list:
*
* ```markdown
* - One
* ___
* ```
*
* In the above example, the thematic break interupts
* the list. */
// Nodes that can interupt a list:
//
// ```markdown
// - One
// ___
// ```
//
// In the above example, the thematic break “interupts” the list.
proto.interruptList = [
['atxHeading', {pedantic: false}],
['fencedCode', {pedantic: false}],
['thematicBreak', {pedantic: false}],
['definition', {commonmark: false}],
['footnote', {commonmark: false}]
];
]
/* Nodes that can interupt a blockquote:
*
* ```markdown
* > A paragraph.
* ___
* ```
*
* In the above example, the thematic break interupts
* the blockquote. */
// 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}],
@ -96,9 +93,9 @@ proto.interruptBlockquote = [
['list', {commonmark: true}],
['definition', {commonmark: false}],
['footnote', {commonmark: false}]
];
]
/* Handlers. */
// Handlers.
proto.blockTokenizers = {
newline: require('./tokenize/newline'),
indentedCode: require('./tokenize/code-indented'),
@ -113,7 +110,7 @@ proto.blockTokenizers = {
definition: require('./tokenize/definition'),
table: require('./tokenize/table'),
paragraph: require('./tokenize/paragraph')
};
}
proto.inlineTokenizers = {
escape: require('./tokenize/escape'),
@ -128,25 +125,25 @@ proto.inlineTokenizers = {
code: require('./tokenize/code-inline'),
break: require('./tokenize/break'),
text: require('./tokenize/text')
};
}
/* Expose precedence. */
proto.blockMethods = keys(proto.blockTokenizers);
proto.inlineMethods = keys(proto.inlineTokenizers);
// Expose precedence.
proto.blockMethods = keys(proto.blockTokenizers)
proto.inlineMethods = keys(proto.inlineTokenizers)
/* Tokenizers. */
proto.tokenizeBlock = tokenizer('block');
proto.tokenizeInline = tokenizer('inline');
proto.tokenizeFactory = tokenizer;
// Tokenizers.
proto.tokenizeBlock = tokenizer('block')
proto.tokenizeInline = tokenizer('inline')
proto.tokenizeFactory = tokenizer
/* Get all keys in `value`. */
// Get all keys in `value`.
function keys(value) {
var result = [];
var key;
var result = []
var key
for (key in value) {
result.push(key);
result.push(key)
}
return result;
return result
}

View File

@ -1,47 +1,46 @@
'use strict';
'use strict'
var xtend = require('xtend');
var escapes = require('markdown-escapes');
var defaults = require('./defaults');
var xtend = require('xtend')
var escapes = require('markdown-escapes')
var defaults = require('./defaults')
module.exports = setOptions;
module.exports = setOptions
function setOptions(options) {
var self = this;
var current = self.options;
var key;
var value;
var self = this
var current = self.options
var key
var value
if (options == null) {
options = {};
options = {}
} else if (typeof options === 'object') {
options = xtend(options);
options = xtend(options)
} else {
throw new Error(
'Invalid value `' + options + '` ' +
'for setting `options`'
);
throw new Error('Invalid value `' + options + '` for setting `options`')
}
for (key in defaults) {
value = options[key];
value = options[key]
if (value == null) {
value = current[key];
value = current[key]
}
if (
(key !== 'blocks' && typeof value !== 'boolean') ||
(key === 'blocks' && typeof value !== 'object')
) {
throw new Error('Invalid value `' + value + '` for setting `options.' + key + '`');
throw new Error(
'Invalid value `' + value + '` for setting `options.' + key + '`'
)
}
options[key] = value;
options[key] = value
}
self.options = options;
self.escape = escapes(options);
self.options = options
self.escape = escapes(options)
return self;
return self
}

View File

@ -1,145 +1,133 @@
'use strict';
'use strict'
var whitespace = require('is-whitespace-character');
var decode = require('parse-entities');
var locate = require('../locate/tag');
var whitespace = require('is-whitespace-character')
var decode = require('parse-entities')
var locate = require('../locate/tag')
module.exports = autoLink;
autoLink.locator = locate;
autoLink.notInLink = true;
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;
var lessThan = '<'
var greaterThan = '>'
var atSign = '@'
var slash = '/'
var mailto = 'mailto:'
var mailtoLength = mailto.length
/* Tokenise a link. */
function autoLink(eat, value, silent) {
var self;
var subvalue;
var length;
var index;
var queue;
var character;
var hasAtCharacter;
var link;
var now;
var content;
var tokenizers;
var exit;
var self = this
var subvalue = ''
var length = value.length
var index = 0
var queue = ''
var hasAtCharacter = false
var link = ''
var character
var now
var content
var tokenizers
var exit
if (value.charAt(0) !== C_LT) {
return;
if (value.charAt(0) !== lessThan) {
return
}
self = this;
subvalue = '';
length = value.length;
index = 0;
queue = '';
hasAtCharacter = false;
link = '';
index++;
subvalue = C_LT;
index++
subvalue = lessThan
while (index < length) {
character = value.charAt(index);
character = value.charAt(index)
if (
whitespace(character) ||
character === C_GT ||
character === C_AT_SIGN ||
(character === ':' && value.charAt(index + 1) === C_SLASH)
character === greaterThan ||
character === atSign ||
(character === ':' && value.charAt(index + 1) === slash)
) {
break;
break
}
queue += character;
index++;
queue += character
index++
}
if (!queue) {
return;
return
}
link += queue;
queue = '';
link += queue
queue = ''
character = value.charAt(index);
link += character;
index++;
character = value.charAt(index)
link += character
index++
if (character === C_AT_SIGN) {
hasAtCharacter = true;
if (character === atSign) {
hasAtCharacter = true
} else {
if (
character !== ':' ||
value.charAt(index + 1) !== C_SLASH
) {
return;
if (character !== ':' || value.charAt(index + 1) !== slash) {
return
}
link += C_SLASH;
index++;
link += slash
index++
}
while (index < length) {
character = value.charAt(index);
character = value.charAt(index)
if (whitespace(character) || character === C_GT) {
break;
if (whitespace(character) || character === greaterThan) {
break
}
queue += character;
index++;
queue += character
index++
}
character = value.charAt(index);
character = value.charAt(index)
if (!queue || character !== C_GT) {
return;
if (!queue || character !== greaterThan) {
return
}
/* istanbul ignore if - never used (yet) */
if (silent) {
return true;
return true
}
link += queue;
content = link;
subvalue += link + character;
now = eat.now();
now.column++;
now.offset++;
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;
if (link.slice(0, mailtoLength).toLowerCase() === mailto) {
content = content.slice(mailtoLength)
now.column += mailtoLength
now.offset += mailtoLength
} else {
link = MAILTO + link;
link = mailto + link
}
}
/* Temporarily remove all tokenizers except text in autolinks. */
tokenizers = self.inlineTokenizers;
self.inlineTokenizers = {text: tokenizers.text};
// Temporarily remove all tokenizers except text in autolinks.
tokenizers = self.inlineTokenizers
self.inlineTokenizers = {text: tokenizers.text}
exit = self.enterLink();
exit = self.enterLink()
content = self.tokenizeInline(content, now);
content = self.tokenizeInline(content, now)
self.inlineTokenizers = tokenizers;
exit();
self.inlineTokenizers = tokenizers
exit()
return eat(subvalue)({
type: 'link',
title: null,
url: decode(link, {nonTerminated: false}),
children: content
});
})
}

View File

@ -1,129 +1,124 @@
'use strict';
'use strict'
var trim = require('trim');
var interrupt = require('../util/interrupt');
var trim = require('trim')
var interrupt = require('../util/interrupt')
module.exports = blockquote;
module.exports = blockquote
var C_NEWLINE = '\n';
var C_TAB = '\t';
var C_SPACE = ' ';
var C_GT = '>';
var lineFeed = '\n'
var tab = '\t'
var space = ' '
var greaterThan = '>'
/* 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;
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);
character = value.charAt(index)
if (character !== C_SPACE && character !== C_TAB) {
break;
if (character !== space && character !== tab) {
break
}
index++;
index++
}
if (value.charAt(index) !== C_GT) {
return;
if (value.charAt(index) !== greaterThan) {
return
}
if (silent) {
return true;
return true
}
index = 0;
index = 0
while (index < length) {
nextIndex = value.indexOf(C_NEWLINE, index);
startIndex = index;
prefixed = false;
nextIndex = value.indexOf(lineFeed, index)
startIndex = index
prefixed = false
if (nextIndex === -1) {
nextIndex = length;
nextIndex = length
}
while (index < length) {
character = value.charAt(index);
character = value.charAt(index)
if (character !== C_SPACE && character !== C_TAB) {
break;
if (character !== space && character !== tab) {
break
}
index++;
index++
}
if (value.charAt(index) === C_GT) {
index++;
prefixed = true;
if (value.charAt(index) === greaterThan) {
index++
prefixed = true
if (value.charAt(index) === C_SPACE) {
index++;
if (value.charAt(index) === space) {
index++
}
} else {
index = startIndex;
index = startIndex
}
content = value.slice(index, nextIndex);
content = value.slice(index, nextIndex)
if (!prefixed && !trim(content)) {
index = startIndex;
break;
index = startIndex
break
}
if (!prefixed) {
rest = value.slice(index);
rest = value.slice(index)
/* Check if the following code contains a possible
* block. */
// Check if the following code contains a possible block.
if (interrupt(interruptors, tokenizers, self, [eat, rest, true])) {
break;
break
}
}
line = startIndex === index ? content : value.slice(startIndex, nextIndex);
line = startIndex === index ? content : value.slice(startIndex, nextIndex)
indents.push(index - startIndex);
values.push(line);
contents.push(content);
indents.push(index - startIndex)
values.push(line)
contents.push(content)
index = nextIndex + 1;
index = nextIndex + 1
}
index = -1;
length = indents.length;
add = eat(values.join(C_NEWLINE));
index = -1
length = indents.length
add = eat(values.join(lineFeed))
while (++index < length) {
offsets[currentLine] = (offsets[currentLine] || 0) + indents[index];
currentLine++;
offsets[currentLine] = (offsets[currentLine] || 0) + indents[index]
currentLine++
}
exit = self.enterBlock();
contents = self.tokenizeBlock(contents.join(C_NEWLINE), now);
exit();
exit = self.enterBlock()
contents = self.tokenizeBlock(contents.join(lineFeed), now)
exit()
return add({
type: 'blockquote',
children: contents
});
return add({type: 'blockquote', children: contents})
}

View File

@ -1,40 +1,42 @@
'use strict';
'use strict'
var locate = require('../locate/break');
var locate = require('../locate/break')
module.exports = hardBreak;
hardBreak.locator = locate;
module.exports = hardBreak
hardBreak.locator = locate
var MIN_BREAK_LENGTH = 2;
var space = ' '
var lineFeed = '\n'
var minBreakLength = 2
function hardBreak(eat, value, silent) {
var length = value.length;
var index = -1;
var queue = '';
var character;
var length = value.length
var index = -1
var queue = ''
var character
while (++index < length) {
character = value.charAt(index);
character = value.charAt(index)
if (character === '\n') {
if (index < MIN_BREAK_LENGTH) {
return;
if (character === lineFeed) {
if (index < minBreakLength) {
return
}
/* istanbul ignore if - never used (yet) */
if (silent) {
return true;
return true
}
queue += character;
queue += character
return eat(queue)({type: 'break'});
return eat(queue)({type: 'break'})
}
if (character !== ' ') {
return;
if (character !== space) {
return
}
queue += character;
queue += character
}
}

View File

@ -1,236 +1,253 @@
'use strict';
'use strict'
var trim = require('trim-trailing-lines');
module.exports = fencedCode
module.exports = fencedCode;
var lineFeed = '\n'
var tab = '\t'
var space = ' '
var tilde = '~'
var graveAccent = '`'
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;
var minFenceCount = 3
var tabSize = 4
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;
var self = this
var gfm = self.options.gfm
var length = value.length + 1
var index = 0
var subvalue = ''
var fenceCount
var marker
var character
var flag
var lang
var meta
var queue
var content
var exdentedContent
var closing
var exdentedClosing
var indent
var now
if (!settings.gfm) {
return;
if (!gfm) {
return
}
/* Eat initial spacing. */
// Eat initial spacing.
while (index < length) {
character = value.charAt(index);
character = value.charAt(index)
if (character !== C_SPACE && character !== C_TAB) {
break;
if (character !== space && character !== tab) {
break
}
subvalue += character;
index++;
subvalue += character
index++
}
indent = index;
indent = index
/* Eat the fence. */
character = value.charAt(index);
// Eat the fence.
character = value.charAt(index)
if (character !== C_TILDE && character !== C_TICK) {
return;
if (character !== tilde && character !== graveAccent) {
return
}
index++;
marker = character;
fenceCount = 1;
subvalue += character;
index++
marker = character
fenceCount = 1
subvalue += character
while (index < length) {
character = value.charAt(index);
character = value.charAt(index)
if (character !== marker) {
break;
break
}
subvalue += character;
fenceCount++;
index++;
subvalue += character
fenceCount++
index++
}
if (fenceCount < MIN_FENCE_COUNT) {
return;
if (fenceCount < minFenceCount) {
return
}
/* Eat spacing before flag. */
// Eat spacing before flag.
while (index < length) {
character = value.charAt(index);
character = value.charAt(index)
if (character !== C_SPACE && character !== C_TAB) {
break;
if (character !== space && character !== tab) {
break
}
subvalue += character;
index++;
subvalue += character
index++
}
/* Eat flag. */
flag = '';
queue = '';
// Eat flag.
flag = ''
queue = ''
while (index < length) {
character = value.charAt(index);
character = value.charAt(index)
if (
character === C_NEWLINE ||
character === C_TILDE ||
character === C_TICK
character === lineFeed ||
(marker === graveAccent && character === marker)
) {
break;
break
}
if (character === C_SPACE || character === C_TAB) {
queue += character;
if (character === space || character === tab) {
queue += character
} else {
flag += queue + character;
queue = '';
flag += queue + character
queue = ''
}
index++;
index++
}
character = value.charAt(index);
character = value.charAt(index)
if (character && character !== C_NEWLINE) {
return;
if (character && character !== lineFeed) {
return
}
if (silent) {
return true;
return true
}
now = eat.now();
now.column += subvalue.length;
now.offset += subvalue.length;
now = eat.now()
now.column += subvalue.length
now.offset += subvalue.length
subvalue += flag;
flag = self.decode.raw(self.unescape(flag), now);
subvalue += flag
flag = self.decode.raw(self.unescape(flag), now)
if (queue) {
subvalue += queue;
subvalue += queue
}
queue = '';
closing = '';
exdentedClosing = '';
content = '';
exdentedContent = '';
queue = ''
closing = ''
exdentedClosing = ''
content = ''
exdentedContent = ''
var skip = true
/* Eat content. */
// Eat content.
while (index < length) {
character = value.charAt(index);
content += closing;
exdentedContent += exdentedClosing;
closing = '';
exdentedClosing = '';
character = value.charAt(index)
content += closing
exdentedContent += exdentedClosing
closing = ''
exdentedClosing = ''
if (character !== C_NEWLINE) {
content += character;
exdentedClosing += character;
index++;
continue;
if (character !== lineFeed) {
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;
// The first line feed is ignored. Others arent.
if (skip) {
subvalue += character
skip = false
} else {
subvalue += character;
closing += character
exdentedClosing += character
}
queue = '';
index++;
queue = ''
index++
while (index < length) {
character = value.charAt(index);
character = value.charAt(index)
if (character !== C_SPACE) {
break;
if (character !== space) {
break
}
queue += character;
index++;
queue += character
index++
}
closing += queue;
exdentedClosing += queue.slice(indent);
closing += queue
exdentedClosing += queue.slice(indent)
if (queue.length >= CODE_INDENT_COUNT) {
continue;
if (queue.length >= tabSize) {
continue
}
queue = '';
queue = ''
while (index < length) {
character = value.charAt(index);
character = value.charAt(index)
if (character !== marker) {
break;
break
}
queue += character;
index++;
queue += character
index++
}
closing += queue;
exdentedClosing += queue;
closing += queue
exdentedClosing += queue
if (queue.length < fenceCount) {
continue;
continue
}
queue = '';
queue = ''
while (index < length) {
character = value.charAt(index);
character = value.charAt(index)
if (character !== C_SPACE && character !== C_TAB) {
break;
if (character !== space && character !== tab) {
break
}
closing += character;
exdentedClosing += character;
index++;
closing += character
exdentedClosing += character
index++
}
if (!character || character === C_NEWLINE) {
break;
if (!character || character === lineFeed) {
break
}
}
subvalue += content + closing;
subvalue += content + closing
// Get lang and meta from the flag.
index = -1
length = flag.length
while (++index < length) {
character = flag.charAt(index)
if (character === space || character === tab) {
if (!lang) {
lang = flag.slice(0, index)
}
} else if (lang) {
meta = flag.slice(index)
break
}
}
return eat(subvalue)({
type: 'code',
lang: flag || null,
value: trim(exdentedContent)
});
lang: lang || flag || null,
meta: meta || null,
value: exdentedContent
})
}

View File

@ -1,98 +1,98 @@
'use strict';
'use strict'
var repeat = require('repeat-string');
var trim = require('trim-trailing-lines');
var repeat = require('repeat-string')
var trim = require('trim-trailing-lines')
module.exports = indentedCode;
module.exports = indentedCode
var C_NEWLINE = '\n';
var C_TAB = '\t';
var C_SPACE = ' ';
var lineFeed = '\n'
var tab = '\t'
var space = ' '
var CODE_INDENT_COUNT = 4;
var CODE_INDENT = repeat(C_SPACE, CODE_INDENT_COUNT);
var tabSize = 4
var codeIndent = repeat(space, tabSize)
/* 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;
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);
character = value.charAt(index)
if (indent) {
indent = false;
indent = false
subvalue += subvalueQueue;
content += contentQueue;
subvalueQueue = '';
contentQueue = '';
subvalue += subvalueQueue
content += contentQueue
subvalueQueue = ''
contentQueue = ''
if (character === C_NEWLINE) {
subvalueQueue = character;
contentQueue = character;
if (character === lineFeed) {
subvalueQueue = character
contentQueue = character
} else {
subvalue += character;
content += character;
subvalue += character
content += character
while (++index < length) {
character = value.charAt(index);
character = value.charAt(index)
if (!character || character === C_NEWLINE) {
contentQueue = character;
subvalueQueue = character;
break;
if (!character || character === lineFeed) {
contentQueue = character
subvalueQueue = character
break
}
subvalue += character;
content += character;
subvalue += character
content += character
}
}
} else if (
character === C_SPACE &&
character === 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;
subvalueQueue += codeIndent
index += 3
indent = true
} else if (character === tab) {
subvalueQueue += character
indent = true
} else {
blankQueue = '';
blankQueue = ''
while (character === C_TAB || character === C_SPACE) {
blankQueue += character;
character = value.charAt(++index);
while (character === tab || character === space) {
blankQueue += character
character = value.charAt(++index)
}
if (character !== C_NEWLINE) {
break;
if (character !== lineFeed) {
break
}
subvalueQueue += blankQueue + character;
contentQueue += character;
subvalueQueue += blankQueue + character
contentQueue += character
}
}
if (content) {
if (silent) {
return true;
return true
}
return eat(subvalue)({
type: 'code',
lang: null,
meta: null,
value: trim(content)
});
})
}
}

View File

@ -1,112 +1,109 @@
'use strict';
'use strict'
var whitespace = require('is-whitespace-character');
var locate = require('../locate/code-inline');
var locate = require('../locate/code-inline')
module.exports = inlineCode;
inlineCode.locator = locate;
module.exports = inlineCode
inlineCode.locator = locate
var C_TICK = '`';
var lineFeed = 10 // '\n'
var space = 32 // ' '
var graveAccent = 96 // '`'
/* 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;
var length = value.length
var index = 0
var openingFenceEnd
var closingFenceStart
var closingFenceEnd
var code
var next
var found
while (index < length) {
if (value.charAt(index) !== C_TICK) {
break;
if (value.charCodeAt(index) !== graveAccent) {
break
}
queue += C_TICK;
index++;
index++
}
if (!queue) {
return;
if (index === 0 || index === length) {
return
}
subvalue = queue;
openingCount = index;
queue = '';
next = value.charAt(index);
count = 0;
openingFenceEnd = index
next = value.charCodeAt(index)
while (index < length) {
character = next;
next = value.charAt(index + 1);
code = next
next = value.charCodeAt(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;
if (code === graveAccent) {
if (closingFenceStart === undefined) {
closingFenceStart = index
}
queue += tickQueue;
tickQueue = '';
closingFenceEnd = index + 1
if (
next !== graveAccent &&
closingFenceEnd - closingFenceStart === openingFenceEnd
) {
found = true
break
}
} else if (closingFenceStart !== undefined) {
closingFenceStart = undefined
closingFenceEnd = undefined
}
index++;
index++
}
if (!found) {
if (openingCount % 2 !== 0) {
return;
}
queue = '';
return
}
/* istanbul ignore if - never used (yet) */
if (silent) {
return true;
return true
}
contentQueue = '';
subqueue = '';
length = queue.length;
index = -1;
// Remove the initial and final space (or line feed), iff they exist and there
// are non-space characters in the content.
index = openingFenceEnd
length = closingFenceStart
code = value.charCodeAt(index)
next = value.charCodeAt(length - 1)
found = false
while (++index < length) {
character = queue.charAt(index);
if (
length - index > 2 &&
(code === space || code === lineFeed) &&
(next === space || next === lineFeed)
) {
index++
length--
if (whitespace(character)) {
subqueue += character;
continue;
}
while (index < length) {
code = value.charCodeAt(index)
if (subqueue) {
if (contentQueue) {
contentQueue += subqueue;
if (code !== space && code !== lineFeed) {
found = true
break
}
subqueue = '';
index++
}
contentQueue += character;
if (found === true) {
openingFenceEnd++
closingFenceStart--
}
}
return eat(subvalue)({
return eat(value.slice(0, closingFenceEnd))({
type: 'inlineCode',
value: contentQueue
});
value: value.slice(openingFenceEnd, closingFenceStart)
})
}

View File

@ -1,278 +1,273 @@
'use strict';
'use strict'
var whitespace = require('is-whitespace-character');
var normalize = require('../util/normalize');
var whitespace = require('is-whitespace-character')
var normalize = require('../util/normalize')
module.exports = definition;
definition.notInList = true;
definition.notInBlock = true;
module.exports = definition
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 = '>';
var quotationMark = '"'
var apostrophe = "'"
var backslash = '\\'
var lineFeed = '\n'
var tab = '\t'
var space = ' '
var leftSquareBracket = '['
var rightSquareBracket = ']'
var leftParenthesis = '('
var rightParenthesis = ')'
var colon = ':'
var lessThan = '<'
var greaterThan = '>'
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;
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);
character = value.charAt(index)
if (character !== C_SPACE && character !== C_TAB) {
break;
if (character !== space && character !== tab) {
break
}
subvalue += character;
index++;
subvalue += character
index++
}
character = value.charAt(index);
character = value.charAt(index)
if (character !== C_BRACKET_OPEN) {
return;
if (character !== leftSquareBracket) {
return
}
index++;
subvalue += character;
queue = '';
index++
subvalue += character
queue = ''
while (index < length) {
character = value.charAt(index);
character = value.charAt(index)
if (character === C_BRACKET_CLOSE) {
break;
} else if (character === C_BACKSLASH) {
queue += character;
index++;
character = value.charAt(index);
if (character === rightSquareBracket) {
break
} else if (character === backslash) {
queue += character
index++
character = value.charAt(index)
}
queue += character;
index++;
queue += character
index++
}
if (
!queue ||
value.charAt(index) !== C_BRACKET_CLOSE ||
value.charAt(index + 1) !== C_COLON
value.charAt(index) !== rightSquareBracket ||
value.charAt(index + 1) !== colon
) {
return;
return
}
identifier = queue;
subvalue += queue + C_BRACKET_CLOSE + C_COLON;
index = subvalue.length;
queue = '';
identifier = queue
subvalue += queue + rightSquareBracket + colon
index = subvalue.length
queue = ''
while (index < length) {
character = value.charAt(index);
character = value.charAt(index)
if (
character !== C_TAB &&
character !== C_SPACE &&
character !== C_NEWLINE
) {
break;
if (character !== tab && character !== space && character !== lineFeed) {
break
}
subvalue += character;
index++;
subvalue += character
index++
}
character = value.charAt(index);
queue = '';
beforeURL = subvalue;
character = value.charAt(index)
queue = ''
beforeURL = subvalue
if (character === C_LT) {
index++;
if (character === lessThan) {
index++
while (index < length) {
character = value.charAt(index);
character = value.charAt(index)
if (!isEnclosedURLCharacter(character)) {
break;
break
}
queue += character;
index++;
queue += character
index++
}
character = value.charAt(index);
character = value.charAt(index)
if (character === isEnclosedURLCharacter.delimiter) {
subvalue += C_LT + queue + character;
index++;
subvalue += lessThan + queue + character
index++
} else {
if (commonmark) {
return;
return
}
index -= queue.length + 1;
queue = '';
index -= queue.length + 1
queue = ''
}
}
if (!queue) {
while (index < length) {
character = value.charAt(index);
character = value.charAt(index)
if (!isUnclosedURLCharacter(character)) {
break;
break
}
queue += character;
index++;
queue += character
index++
}
subvalue += queue;
subvalue += queue
}
if (!queue) {
return;
return
}
url = queue;
queue = '';
url = queue
queue = ''
while (index < length) {
character = value.charAt(index);
character = value.charAt(index)
if (
character !== C_TAB &&
character !== C_SPACE &&
character !== C_NEWLINE
) {
break;
if (character !== tab && character !== space && character !== lineFeed) {
break
}
queue += character;
index++;
queue += character
index++
}
character = value.charAt(index);
test = null;
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 (character === quotationMark) {
test = quotationMark
} else if (character === apostrophe) {
test = apostrophe
} else if (character === leftParenthesis) {
test = rightParenthesis
}
if (!test) {
queue = '';
index = subvalue.length;
queue = ''
index = subvalue.length
} else if (queue) {
subvalue += queue + character;
index = subvalue.length;
queue = '';
subvalue += queue + character
index = subvalue.length
queue = ''
while (index < length) {
character = value.charAt(index);
character = value.charAt(index)
if (character === test) {
break;
break
}
if (character === C_NEWLINE) {
index++;
character = value.charAt(index);
if (character === lineFeed) {
index++
character = value.charAt(index)
if (character === C_NEWLINE || character === test) {
return;
if (character === lineFeed || character === test) {
return
}
queue += C_NEWLINE;
queue += lineFeed
}
queue += character;
index++;
queue += character
index++
}
character = value.charAt(index);
character = value.charAt(index)
if (character !== test) {
return;
return
}
beforeTitle = subvalue;
subvalue += queue + character;
index++;
title = queue;
queue = '';
beforeTitle = subvalue
subvalue += queue + character
index++
title = queue
queue = ''
} else {
return;
return
}
while (index < length) {
character = value.charAt(index);
character = value.charAt(index)
if (character !== C_TAB && character !== C_SPACE) {
break;
if (character !== tab && character !== space) {
break
}
subvalue += character;
index++;
subvalue += character
index++
}
character = value.charAt(index);
character = value.charAt(index)
if (!character || character === C_NEWLINE) {
if (!character || character === lineFeed) {
if (silent) {
return true;
return true
}
beforeURL = eat(beforeURL).test().end;
url = self.decode.raw(self.unescape(url), beforeURL, {nonTerminated: false});
beforeURL = eat(beforeURL).test().end
url = self.decode.raw(self.unescape(url), beforeURL, {nonTerminated: false})
if (title) {
beforeTitle = eat(beforeTitle).test().end;
title = self.decode.raw(self.unescape(title), beforeTitle);
beforeTitle = eat(beforeTitle).test().end
title = self.decode.raw(self.unescape(title), beforeTitle)
}
return eat(subvalue)({
type: 'definition',
identifier: normalize(identifier),
label: identifier,
title: title || null,
url: url
});
})
}
}
/* Check if `character` can be inside an enclosed URI. */
// Check if `character` can be inside an enclosed URI.
function isEnclosedURLCharacter(character) {
return character !== C_GT &&
character !== C_BRACKET_OPEN &&
character !== C_BRACKET_CLOSE;
return (
character !== greaterThan &&
character !== leftSquareBracket &&
character !== rightSquareBracket
)
}
isEnclosedURLCharacter.delimiter = C_GT;
isEnclosedURLCharacter.delimiter = greaterThan
/* Check if `character` can be inside an unclosed URI. */
// Check if `character` can be inside an unclosed URI.
function isUnclosedURLCharacter(character) {
return character !== C_BRACKET_OPEN &&
character !== C_BRACKET_CLOSE &&
!whitespace(character);
return (
character !== leftSquareBracket &&
character !== rightSquareBracket &&
!whitespace(character)
)
}

View File

@ -1,60 +1,60 @@
'use strict';
'use strict'
var whitespace = require('is-whitespace-character');
var locate = require('../locate/delete');
var whitespace = require('is-whitespace-character')
var locate = require('../locate/delete')
module.exports = strikethrough;
strikethrough.locator = locate;
module.exports = strikethrough
strikethrough.locator = locate
var C_TILDE = '~';
var DOUBLE = '~~';
var tilde = '~'
var fence = '~~'
function strikethrough(eat, value, silent) {
var self = this;
var character = '';
var previous = '';
var preceding = '';
var subvalue = '';
var index;
var length;
var now;
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 ||
value.charAt(0) !== tilde ||
value.charAt(1) !== tilde ||
whitespace(value.charAt(2))
) {
return;
return
}
index = 1;
length = value.length;
now = eat.now();
now.column += 2;
now.offset += 2;
index = 1
length = value.length
now = eat.now()
now.column += 2
now.offset += 2
while (++index < length) {
character = value.charAt(index);
character = value.charAt(index)
if (
character === C_TILDE &&
previous === C_TILDE &&
character === tilde &&
previous === tilde &&
(!preceding || !whitespace(preceding))
) {
/* istanbul ignore if - never used (yet) */
if (silent) {
return true;
return true
}
return eat(DOUBLE + subvalue + DOUBLE)({
return eat(fence + subvalue + fence)({
type: 'delete',
children: self.tokenizeInline(subvalue, now)
});
})
}
subvalue += previous;
preceding = previous;
previous = character;
subvalue += previous
preceding = previous
previous = character
}
}

View File

@ -1,85 +1,86 @@
'use strict';
'use strict'
var trim = require('trim');
var word = require('is-word-character');
var whitespace = require('is-whitespace-character');
var locate = require('../locate/emphasis');
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;
module.exports = emphasis
emphasis.locator = locate
var C_ASTERISK = '*';
var C_UNDERSCORE = '_';
var asterisk = '*'
var underscore = '_'
var backslash = '\\'
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;
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;
if (character !== asterisk && character !== underscore) {
return
}
pedantic = self.options.pedantic;
subvalue = character;
marker = character;
length = value.length;
index++;
queue = '';
character = '';
pedantic = self.options.pedantic
subvalue = character
marker = character
length = value.length
index++
queue = ''
character = ''
if (pedantic && whitespace(value.charAt(index))) {
return;
return
}
while (index < length) {
prev = character;
character = value.charAt(index);
prev = character
character = value.charAt(index)
if (character === marker && (!pedantic || !whitespace(prev))) {
character = value.charAt(++index);
character = value.charAt(++index)
if (character !== marker) {
if (!trim(queue) || prev === marker) {
return;
return
}
if (!pedantic && marker === C_UNDERSCORE && word(character)) {
queue += marker;
continue;
if (!pedantic && marker === underscore && word(character)) {
queue += marker
continue
}
/* istanbul ignore if - never used (yet) */
if (silent) {
return true;
return true
}
now = eat.now();
now.column++;
now.offset++;
now = eat.now()
now.column++
now.offset++
return eat(subvalue + queue + marker)({
type: 'emphasis',
children: self.tokenizeInline(queue, now)
});
})
}
queue += marker;
queue += marker
}
if (!pedantic && character === '\\') {
queue += character;
character = value.charAt(++index);
if (!pedantic && character === backslash) {
queue += character
character = value.charAt(++index)
}
queue += character;
index++;
queue += character
index++
}
}

View File

@ -1,34 +1,34 @@
'use strict';
'use strict'
var locate = require('../locate/escape');
var locate = require('../locate/escape')
module.exports = escape;
escape.locator = locate;
module.exports = escape
escape.locator = locate
var lineFeed = '\n'
var backslash = '\\'
function escape(eat, value, silent) {
var self = this;
var character;
var node;
var self = this
var character
var node
if (value.charAt(0) === '\\') {
character = value.charAt(1);
if (value.charAt(0) === backslash) {
character = value.charAt(1)
if (self.escape.indexOf(character) !== -1) {
/* istanbul ignore if - never used (yet) */
if (silent) {
return true;
return true
}
if (character === '\n') {
node = {type: 'break'};
if (character === lineFeed) {
node = {type: 'break'}
} else {
node = {
type: 'text',
value: character
};
node = {type: 'text', value: character}
}
return eat('\\' + character)(node);
return eat(backslash + character)(node)
}
}
}

View File

@ -1,185 +1,186 @@
'use strict';
'use strict'
var whitespace = require('is-whitespace-character');
var normalize = require('../util/normalize');
var whitespace = require('is-whitespace-character')
var normalize = require('../util/normalize')
module.exports = footnoteDefinition;
footnoteDefinition.notInList = true;
footnoteDefinition.notInBlock = true;
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 backslash = '\\'
var lineFeed = '\n'
var tab = '\t'
var space = ' '
var leftSquareBracket = '['
var rightSquareBracket = ']'
var caret = '^'
var colon = ':'
var EXPRESSION_INITIAL_TAB = /^( {4}|\t)?/gm;
var EXPRESSION_INITIAL_TAB = /^( {4}|\t)?/gm
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;
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;
return
}
index = 0;
length = value.length;
subvalue = '';
now = eat.now();
currentLine = now.line;
index = 0
length = value.length
subvalue = ''
now = eat.now()
currentLine = now.line
while (index < length) {
character = value.charAt(index);
character = value.charAt(index)
if (!whitespace(character)) {
break;
break
}
subvalue += character;
index++;
subvalue += character
index++
}
if (
value.charAt(index) !== C_BRACKET_OPEN ||
value.charAt(index + 1) !== C_CARET
value.charAt(index) !== leftSquareBracket ||
value.charAt(index + 1) !== caret
) {
return;
return
}
subvalue += C_BRACKET_OPEN + C_CARET;
index = subvalue.length;
queue = '';
subvalue += leftSquareBracket + caret
index = subvalue.length
queue = ''
while (index < length) {
character = value.charAt(index);
character = value.charAt(index)
if (character === C_BRACKET_CLOSE) {
break;
} else if (character === C_BACKSLASH) {
queue += character;
index++;
character = value.charAt(index);
if (character === rightSquareBracket) {
break
} else if (character === backslash) {
queue += character
index++
character = value.charAt(index)
}
queue += character;
index++;
queue += character
index++
}
if (
!queue ||
value.charAt(index) !== C_BRACKET_CLOSE ||
value.charAt(index + 1) !== C_COLON
value.charAt(index) !== rightSquareBracket ||
value.charAt(index + 1) !== colon
) {
return;
return
}
if (silent) {
return true;
return true
}
identifier = normalize(queue);
subvalue += queue + C_BRACKET_CLOSE + C_COLON;
index = subvalue.length;
identifier = queue
subvalue += queue + rightSquareBracket + colon
index = subvalue.length
while (index < length) {
character = value.charAt(index);
character = value.charAt(index)
if (character !== C_TAB && character !== C_SPACE) {
break;
if (character !== tab && character !== space) {
break
}
subvalue += character;
index++;
subvalue += character
index++
}
now.column += subvalue.length;
now.offset += subvalue.length;
queue = '';
content = '';
subqueue = '';
now.column += subvalue.length
now.offset += subvalue.length
queue = ''
content = ''
subqueue = ''
while (index < length) {
character = value.charAt(index);
character = value.charAt(index)
if (character === C_NEWLINE) {
subqueue = character;
index++;
if (character === lineFeed) {
subqueue = character
index++
while (index < length) {
character = value.charAt(index);
character = value.charAt(index)
if (character !== C_NEWLINE) {
break;
if (character !== lineFeed) {
break
}
subqueue += character;
index++;
subqueue += character
index++
}
queue += subqueue;
subqueue = '';
queue += subqueue
subqueue = ''
while (index < length) {
character = value.charAt(index);
character = value.charAt(index)
if (character !== C_SPACE) {
break;
if (character !== space) {
break
}
subqueue += character;
index++;
subqueue += character
index++
}
if (subqueue.length === 0) {
break;
break
}
queue += subqueue;
queue += subqueue
}
if (queue) {
content += queue;
queue = '';
content += queue
queue = ''
}
content += character;
index++;
content += character
index++
}
subvalue += content;
subvalue += content
content = content.replace(EXPRESSION_INITIAL_TAB, function (line) {
offsets[currentLine] = (offsets[currentLine] || 0) + line.length;
currentLine++;
content = content.replace(EXPRESSION_INITIAL_TAB, function(line) {
offsets[currentLine] = (offsets[currentLine] || 0) + line.length
currentLine++
return '';
});
return ''
})
add = eat(subvalue);
add = eat(subvalue)
exit = self.enterBlock();
content = self.tokenizeBlock(content, now);
exit();
exit = self.enterBlock()
content = self.tokenizeBlock(content, now)
exit()
return add({
type: 'footnoteDefinition',
identifier: identifier,
identifier: normalize(identifier),
label: identifier,
children: content
});
})
}

View File

@ -1,141 +1,135 @@
'use strict';
'use strict'
module.exports = atxHeading;
module.exports = atxHeading
var C_NEWLINE = '\n';
var C_TAB = '\t';
var C_SPACE = ' ';
var C_HASH = '#';
var lineFeed = '\n'
var tab = '\t'
var space = ' '
var numberSign = '#'
var MAX_ATX_COUNT = 6;
var maxFenceCount = 6
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;
var self = this
var pedantic = self.options.pedantic
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. */
// Eat initial spacing.
while (++index < length) {
character = value.charAt(index);
character = value.charAt(index)
if (character !== C_SPACE && character !== C_TAB) {
index--;
break;
if (character !== space && character !== tab) {
index--
break
}
subvalue += character;
subvalue += character
}
/* Eat hashes. */
depth = 0;
// Eat hashes.
depth = 0
while (++index <= length) {
character = value.charAt(index);
character = value.charAt(index)
if (character !== C_HASH) {
index--;
break;
if (character !== numberSign) {
index--
break
}
subvalue += character;
depth++;
subvalue += character
depth++
}
if (depth > MAX_ATX_COUNT) {
return;
if (depth > maxFenceCount) {
return
}
if (
!depth ||
(!settings.pedantic && value.charAt(index + 1) === C_HASH)
) {
return;
if (!depth || (!pedantic && value.charAt(index + 1) === numberSign)) {
return
}
length = value.length + 1;
length = value.length + 1
/* Eat intermediate white-space. */
queue = '';
// Eat intermediate white-space.
queue = ''
while (++index < length) {
character = value.charAt(index);
character = value.charAt(index)
if (character !== C_SPACE && character !== C_TAB) {
index--;
break;
if (character !== space && character !== tab) {
index--
break
}
queue += character;
queue += character
}
/* Exit when not in pedantic mode without spacing. */
if (
!settings.pedantic &&
queue.length === 0 &&
character &&
character !== C_NEWLINE
) {
return;
// Exit when not in pedantic mode without spacing.
if (!pedantic && queue.length === 0 && character && character !== lineFeed) {
return
}
if (silent) {
return true;
return true
}
/* Eat content. */
subvalue += queue;
queue = '';
content = '';
// Eat content.
subvalue += queue
queue = ''
content = ''
while (++index < length) {
character = value.charAt(index);
character = value.charAt(index)
if (!character || character === C_NEWLINE) {
break;
if (!character || character === lineFeed) {
break
}
if (
character !== C_SPACE &&
character !== C_TAB &&
character !== C_HASH
) {
content += queue + character;
queue = '';
continue;
if (character !== space && character !== tab && character !== numberSign) {
content += queue + character
queue = ''
continue
}
while (character === C_SPACE || character === C_TAB) {
queue += character;
character = value.charAt(++index);
while (character === space || character === tab) {
queue += character
character = value.charAt(++index)
}
while (character === C_HASH) {
queue += character;
character = value.charAt(++index);
// `#` without a queue is part of the content.
if (!pedantic && content && !queue && character === numberSign) {
content += character
continue
}
while (character === C_SPACE || character === C_TAB) {
queue += character;
character = value.charAt(++index);
while (character === numberSign) {
queue += character
character = value.charAt(++index)
}
index--;
while (character === space || character === tab) {
queue += character
character = value.charAt(++index)
}
index--
}
now.column += subvalue.length;
now.offset += subvalue.length;
subvalue += content + queue;
now.column += subvalue.length
now.offset += subvalue.length
subvalue += content + queue
return eat(subvalue)({
type: 'heading',
depth: depth,
children: self.tokenizeInline(content, now)
});
})
}

View File

@ -1,107 +1,102 @@
'use strict';
'use strict'
module.exports = setextHeading;
module.exports = setextHeading
var C_NEWLINE = '\n';
var C_TAB = '\t';
var C_SPACE = ' ';
var C_EQUALS = '=';
var C_DASH = '-';
var lineFeed = '\n'
var tab = '\t'
var space = ' '
var equalsTo = '='
var dash = '-'
var MAX_HEADING_INDENT = 3;
var maxIndent = 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;
var equalsToDepth = 1
var dashDepth = 2
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;
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. */
// Eat initial indentation.
while (++index < length) {
character = value.charAt(index);
character = value.charAt(index)
if (character !== C_SPACE || index >= MAX_HEADING_INDENT) {
index--;
break;
if (character !== space || index >= maxIndent) {
index--
break
}
subvalue += character;
subvalue += character
}
/* Eat content. */
content = '';
queue = '';
// Eat content.
content = ''
queue = ''
while (++index < length) {
character = value.charAt(index);
character = value.charAt(index)
if (character === C_NEWLINE) {
index--;
break;
if (character === lineFeed) {
index--
break
}
if (character === C_SPACE || character === C_TAB) {
queue += character;
if (character === space || character === tab) {
queue += character
} else {
content += queue + character;
queue = '';
content += queue + character
queue = ''
}
}
now.column += subvalue.length;
now.offset += subvalue.length;
subvalue += content + 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);
// 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;
if (character !== lineFeed || (marker !== equalsTo && marker !== dash)) {
return
}
subvalue += character;
subvalue += character
/* Eat Setext-line. */
queue = marker;
depth = SETEXT_MARKERS[marker];
// Eat Setext-line.
queue = marker
depth = marker === equalsTo ? equalsToDepth : dashDepth
while (++index < length) {
character = value.charAt(index);
character = value.charAt(index)
if (character !== marker) {
if (character !== C_NEWLINE) {
return;
if (character !== lineFeed) {
return
}
index--;
break;
index--
break
}
queue += character;
queue += character
}
if (silent) {
return true;
return true
}
return eat(subvalue + queue)({
type: 'heading',
depth: depth,
children: self.tokenizeInline(content, now)
});
})
}

View File

@ -1,94 +1,111 @@
'use strict';
'use strict'
var openCloseTag = require('../util/html').openCloseTag;
var openCloseTag = require('../util/html').openCloseTag
module.exports = blockHTML;
module.exports = blockHtml
var C_TAB = '\t';
var C_SPACE = ' ';
var C_NEWLINE = '\n';
var C_LT = '<';
var tab = '\t'
var space = ' '
var lineFeed = '\n'
var lessThan = '<'
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 rawOpenExpression = /^<(script|pre|style)(?=(\s|>|$))/i
var rawCloseExpression = /<\/(script|pre|style)>/i
var commentOpenExpression = /^<!--/
var commentCloseExpression = /-->/
var instructionOpenExpression = /^<\?/
var instructionCloseExpression = /\?>/
var directiveOpenExpression = /^<![A-Za-z]/
var directiveCloseExpression = />/
var cdataOpenExpression = /^<!\[CDATA\[/
var cdataCloseExpression = /\]\]>/
var elementCloseExpression = /^$/
var otherElementOpenExpression = new RegExp(openCloseTag.source + '\\s*$')
function blockHtml(eat, value, silent) {
var self = this
var blocks = self.options.blocks.join('|')
var elementOpenExpression = new RegExp(
'^</?(' + blocks + ')(?=(\\s|/?>|$))',
'i'
)
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]
];
[rawOpenExpression, rawCloseExpression, true],
[commentOpenExpression, commentCloseExpression, true],
[instructionOpenExpression, instructionCloseExpression, true],
[directiveOpenExpression, directiveCloseExpression, true],
[cdataOpenExpression, cdataCloseExpression, true],
[elementOpenExpression, elementCloseExpression, true],
[otherElementOpenExpression, elementCloseExpression, false]
]
/* Eat initial spacing. */
// Eat initial spacing.
while (index < length) {
character = value.charAt(index);
character = value.charAt(index)
if (character !== C_TAB && character !== C_SPACE) {
break;
if (character !== tab && character !== space) {
break
}
index++;
index++
}
if (value.charAt(index) !== C_LT) {
return;
if (value.charAt(index) !== lessThan) {
return
}
next = value.indexOf(C_NEWLINE, index + 1);
next = next === -1 ? length : next;
line = value.slice(index, next);
offset = -1;
count = sequences.length;
next = value.indexOf(lineFeed, 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;
sequence = sequences[offset]
break
}
}
if (!sequence) {
return;
return
}
if (silent) {
return sequence[2];
return sequence[2]
}
index = next;
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);
next = value.indexOf(lineFeed, index + 1)
next = next === -1 ? length : next
line = value.slice(index + 1, next)
if (sequence[1].test(line)) {
if (line) {
index = next;
index = next
}
break;
break
}
index = next;
index = next
}
}
subvalue = value.slice(0, index);
subvalue = value.slice(0, index)
return eat(subvalue)({type: 'html', value: subvalue});
return eat(subvalue)({type: 'html', value: subvalue})
}

View File

@ -1,54 +1,59 @@
'use strict';
'use strict'
var alphabetical = require('is-alphabetical');
var locate = require('../locate/tag');
var tag = require('../util/html').tag;
var alphabetical = require('is-alphabetical')
var locate = require('../locate/tag')
var tag = require('../util/html').tag
module.exports = inlineHTML;
inlineHTML.locator = locate;
module.exports = inlineHTML
inlineHTML.locator = locate
var EXPRESSION_HTML_LINK_OPEN = /^<a /i;
var EXPRESSION_HTML_LINK_CLOSE = /^<\/a>/i;
var lessThan = '<'
var questionMark = '?'
var exclamationMark = '!'
var slash = '/'
var htmlLinkOpenExpression = /^<a /i
var htmlLinkCloseExpression = /^<\/a>/i
function inlineHTML(eat, value, silent) {
var self = this;
var length = value.length;
var character;
var subvalue;
var self = this
var length = value.length
var character
var subvalue
if (value.charAt(0) !== '<' || length < 3) {
return;
if (value.charAt(0) !== lessThan || length < 3) {
return
}
character = value.charAt(1);
character = value.charAt(1)
if (
!alphabetical(character) &&
character !== '?' &&
character !== '!' &&
character !== '/'
character !== questionMark &&
character !== exclamationMark &&
character !== slash
) {
return;
return
}
subvalue = value.match(tag);
subvalue = value.match(tag)
if (!subvalue) {
return;
return
}
/* istanbul ignore if - not used yet. */
if (silent) {
return true;
return true
}
subvalue = subvalue[0];
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;
if (!self.inLink && htmlLinkOpenExpression.test(subvalue)) {
self.inLink = true
} else if (self.inLink && htmlLinkCloseExpression.test(subvalue)) {
self.inLink = false
}
return eat(subvalue)({type: 'html', value: subvalue});
return eat(subvalue)({type: 'html', value: subvalue})
}

View File

@ -1,392 +1,381 @@
'use strict';
'use strict'
var whitespace = require('is-whitespace-character');
var locate = require('../locate/link');
var whitespace = require('is-whitespace-character')
var locate = require('../locate/link')
module.exports = link;
link.locator = locate;
module.exports = link
link.locator = locate
var own = {}.hasOwnProperty;
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;
var lineFeed = '\n'
var exclamationMark = '!'
var quotationMark = '"'
var apostrophe = "'"
var leftParenthesis = '('
var rightParenthesis = ')'
var lessThan = '<'
var greaterThan = '>'
var leftSquareBracket = '['
var backslash = '\\'
var rightSquareBracket = ']'
var graveAccent = '`'
function link(eat, value, silent) {
var self = this;
var subvalue = '';
var index = 0;
var character = value.charAt(0);
var pedantic = self.options.pedantic;
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;
var self = this
var subvalue = ''
var index = 0
var character = value.charAt(0)
var pedantic = self.options.pedantic
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 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);
// Detect whether this is an image.
if (character === exclamationMark) {
isImage = true
subvalue = character
character = value.charAt(++index)
}
/* Eat the opening. */
if (character !== C_BRACKET_OPEN) {
return;
// Eat the opening.
if (character !== leftSquareBracket) {
return
}
/* Exit when this is a link and were already inside
* a link. */
// Exit when this is a link and were already inside a link.
if (!isImage && self.inLink) {
return;
return
}
subvalue += character;
queue = '';
index++;
subvalue += character
queue = ''
index++
/* Eat the content. */
length = value.length;
now = eat.now();
depth = 0;
// Eat the content.
length = value.length
now = eat.now()
depth = 0
now.column += index;
now.offset += index;
now.column += index
now.offset += index
while (index < length) {
character = value.charAt(index);
subqueue = character;
character = value.charAt(index)
subqueue = character
if (character === C_TICK) {
/* Inline-code in link content. */
count = 1;
if (character === graveAccent) {
// Inline-code in link content.
count = 1
while (value.charAt(index + 1) === C_TICK) {
subqueue += character;
index++;
count++;
while (value.charAt(index + 1) === graveAccent) {
subqueue += character
index++
count++
}
if (!opening) {
opening = count;
opening = count
} else if (count >= opening) {
opening = 0;
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 dont. 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) {
} else if (character === backslash) {
// Allow brackets to be escaped.
index++
subqueue += value.charAt(index)
} else if ((!opening || gfm) && character === leftSquareBracket) {
// In GFM mode, brackets in code still count. In all other modes,
// they dont.
depth++
} else if ((!opening || gfm) && character === rightSquareBracket) {
if (depth) {
depth--;
depth--
} else {
/* Allow white-space between content and
* url in GFM mode. */
// Allow white-space between content and url in GFM mode.
if (!pedantic) {
while (index < length) {
character = value.charAt(index + 1);
character = value.charAt(index + 1)
if (!whitespace(character)) {
break;
break
}
subqueue += character;
index++;
subqueue += character
index++
}
}
if (value.charAt(index + 1) !== C_PAREN_OPEN) {
return;
if (value.charAt(index + 1) !== leftParenthesis) {
return
}
subqueue += C_PAREN_OPEN;
closed = true;
index++;
subqueue += leftParenthesis
closed = true
index++
break;
break
}
}
queue += subqueue;
subqueue = '';
index++;
queue += subqueue
subqueue = ''
index++
}
/* Eat the content closing. */
// Eat the content closing.
if (!closed) {
return;
return
}
content = queue;
subvalue += queue + subqueue;
index++;
content = queue
subvalue += queue + subqueue
index++
/* Eat white-space. */
// Eat white-space.
while (index < length) {
character = value.charAt(index);
character = value.charAt(index)
if (!whitespace(character)) {
break;
break
}
subvalue += character;
index++;
subvalue += character
index++
}
/* Eat the URL. */
character = value.charAt(index);
markers = commonmark ? COMMONMARK_LINK_MARKERS : LINK_MARKERS;
queue = '';
beforeURL = subvalue;
// Eat the URL.
character = value.charAt(index)
queue = ''
beforeURL = subvalue
if (character === C_LT) {
index++;
beforeURL += C_LT;
if (character === lessThan) {
index++
beforeURL += lessThan
while (index < length) {
character = value.charAt(index);
character = value.charAt(index)
if (character === C_GT) {
break;
if (character === greaterThan) {
break
}
if (commonmark && character === '\n') {
return;
if (commonmark && character === lineFeed) {
return
}
queue += character;
index++;
queue += character
index++
}
if (value.charAt(index) !== C_GT) {
return;
if (value.charAt(index) !== greaterThan) {
return
}
subvalue += C_LT + queue + C_GT;
url = queue;
index++;
subvalue += lessThan + queue + greaterThan
url = queue
index++
} else {
character = null;
subqueue = '';
character = null
subqueue = ''
while (index < length) {
character = value.charAt(index);
character = value.charAt(index)
if (subqueue && own.call(markers, character)) {
break;
if (
subqueue &&
(character === quotationMark ||
character === apostrophe ||
(commonmark && character === leftParenthesis))
) {
break
}
if (whitespace(character)) {
if (!pedantic) {
break;
break
}
subqueue += character;
subqueue += character
} else {
if (character === C_PAREN_OPEN) {
depth++;
} else if (character === C_PAREN_CLOSE) {
if (character === leftParenthesis) {
depth++
} else if (character === rightParenthesis) {
if (depth === 0) {
break;
break
}
depth--;
depth--
}
queue += subqueue;
subqueue = '';
queue += subqueue
subqueue = ''
if (character === C_BACKSLASH) {
queue += C_BACKSLASH;
character = value.charAt(++index);
if (character === backslash) {
queue += backslash
character = value.charAt(++index)
}
queue += character;
queue += character
}
index++;
index++
}
subvalue += queue;
url = queue;
index = subvalue.length;
subvalue += queue
url = queue
index = subvalue.length
}
/* Eat white-space. */
queue = '';
// Eat white-space.
queue = ''
while (index < length) {
character = value.charAt(index);
character = value.charAt(index)
if (!whitespace(character)) {
break;
break
}
queue += character;
index++;
queue += character
index++
}
character = value.charAt(index);
subvalue += queue;
character = value.charAt(index)
subvalue += queue
/* Eat the title. */
if (queue && own.call(markers, character)) {
index++;
subvalue += character;
queue = '';
marker = markers[character];
beforeTitle = subvalue;
// Eat the title.
if (
queue &&
(character === quotationMark ||
character === apostrophe ||
(commonmark && character === leftParenthesis))
) {
index++
subvalue += character
queue = ''
marker = character === leftParenthesis ? rightParenthesis : character
beforeTitle = subvalue
/* In commonmark-mode, things are pretty easy: the
* marker cannot occur inside the title.
*
* Non-commonmark does, however, support nested
* delimiters. */
// 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);
character = value.charAt(index)
if (character === marker) {
break;
break
}
if (character === C_BACKSLASH) {
queue += C_BACKSLASH;
character = value.charAt(++index);
if (character === backslash) {
queue += backslash
character = value.charAt(++index)
}
index++;
queue += character;
index++
queue += character
}
character = value.charAt(index);
character = value.charAt(index)
if (character !== marker) {
return;
return
}
title = queue;
subvalue += queue + character;
index++;
title = queue
subvalue += queue + character
index++
while (index < length) {
character = value.charAt(index);
character = value.charAt(index)
if (!whitespace(character)) {
break;
break
}
subvalue += character;
index++;
subvalue += character
index++
}
} else {
subqueue = '';
subqueue = ''
while (index < length) {
character = value.charAt(index);
character = value.charAt(index)
if (character === marker) {
if (hasMarker) {
queue += marker + subqueue;
subqueue = '';
queue += marker + subqueue
subqueue = ''
}
hasMarker = true;
hasMarker = true
} else if (!hasMarker) {
queue += character;
} else if (character === C_PAREN_CLOSE) {
subvalue += queue + marker + subqueue;
title = queue;
break;
queue += character
} else if (character === rightParenthesis) {
subvalue += queue + marker + subqueue
title = queue
break
} else if (whitespace(character)) {
subqueue += character;
subqueue += character
} else {
queue += marker + subqueue + character;
subqueue = '';
hasMarker = false;
queue += marker + subqueue + character
subqueue = ''
hasMarker = false
}
index++;
index++
}
}
}
if (value.charAt(index) !== C_PAREN_CLOSE) {
return;
if (value.charAt(index) !== rightParenthesis) {
return
}
/* istanbul ignore if - never used (yet) */
if (silent) {
return true;
return true
}
subvalue += C_PAREN_CLOSE;
subvalue += rightParenthesis
url = self.decode.raw(self.unescape(url), eat(beforeURL).test().end, {nonTerminated: false});
url = self.decode.raw(self.unescape(url), eat(beforeURL).test().end, {
nonTerminated: false
})
if (title) {
beforeTitle = eat(beforeTitle).test().end;
title = self.decode.raw(self.unescape(title), beforeTitle);
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);
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)
}

View File

@ -1,474 +1,451 @@
'use strict';
'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')
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
module.exports = list;
var asterisk = '*'
var underscore = '_'
var plusSign = '+'
var dash = '-'
var dot = '.'
var space = ' '
var lineFeed = '\n'
var tab = '\t'
var rightParenthesis = ')'
var lowercaseX = 'x'
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;
var tabSize = 4
var looseListItemExpression = /\n\n(?!\s*$)/
var taskItemExpression = /^\[([ \t]|x|X)][ \t]/
var bulletExpression = /^([ \t]*)([*+-]|\d+[.)])( {1,4}(?! )| |\t|$|(?=\n))([^\n]*)/
var pedanticBulletExpression = /^([ \t]*)([*+-]|\d+[.)])([ \t]+)/
var initialIndentExpression = /^( {1,4}|\t)?/gm
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;
var self = this
var commonmark = self.options.commonmark
var pedantic = self.options.pedantic
var tokenizers = self.blockTokenizers
var interuptors = self.interruptList
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 spread = false
var node
var now
var end
var indented
while (index < length) {
character = value.charAt(index);
character = value.charAt(index)
if (character === C_TAB) {
size += TAB_SIZE - (size % TAB_SIZE);
} else if (character === C_SPACE) {
size++;
if (character === tab) {
size += tabSize - (size % tabSize)
} else if (character === space) {
size++
} else {
break;
break
}
index++;
index++
}
if (size >= TAB_SIZE) {
return;
if (size >= tabSize) {
return
}
character = value.charAt(index);
character = value.charAt(index)
markers = commonmark ?
LIST_ORDERED_COMMONMARK_MARKERS :
LIST_ORDERED_MARKERS;
if (LIST_UNORDERED_MARKERS[character] === true) {
marker = character;
ordered = false;
if (character === asterisk || character === plusSign || character === dash) {
marker = character
ordered = false
} else {
ordered = true;
queue = '';
ordered = true
queue = ''
while (index < length) {
character = value.charAt(index);
character = value.charAt(index)
if (!decimal(character)) {
break;
break
}
queue += character;
index++;
queue += character
index++
}
character = value.charAt(index);
character = value.charAt(index)
if (!queue || markers[character] !== true) {
return;
if (
!queue ||
!(character === dot || (commonmark && character === rightParenthesis))
) {
return
}
start = parseInt(queue, 10);
marker = character;
start = parseInt(queue, 10)
marker = character
}
character = value.charAt(++index);
character = value.charAt(++index)
if (character !== C_SPACE && character !== C_TAB) {
return;
if (
character !== space &&
character !== tab &&
(pedantic || (character !== lineFeed && character !== ''))
) {
return
}
if (silent) {
return true;
return true
}
index = 0;
items = [];
allLines = [];
emptyLines = [];
index = 0
items = []
allLines = []
emptyLines = []
while (index < length) {
nextIndex = value.indexOf(C_NEWLINE, index);
startIndex = index;
prefixed = false;
indented = false;
nextIndex = value.indexOf(lineFeed, index)
startIndex = index
prefixed = false
indented = false
if (nextIndex === -1) {
nextIndex = length;
nextIndex = length
}
end = index + TAB_SIZE;
size = 0;
end = index + tabSize
size = 0
while (index < length) {
character = value.charAt(index);
character = value.charAt(index)
if (character === C_TAB) {
size += TAB_SIZE - (size % TAB_SIZE);
} else if (character === C_SPACE) {
size++;
if (character === tab) {
size += tabSize - (size % tabSize)
} else if (character === space) {
size++
} else {
break;
break
}
index++;
index++
}
if (size >= TAB_SIZE) {
indented = true;
if (size >= tabSize) {
indented = true
}
if (item && size >= item.indent) {
indented = true;
indented = true
}
character = value.charAt(index);
currentMarker = null;
character = value.charAt(index)
currentMarker = null
if (!indented) {
if (LIST_UNORDERED_MARKERS[character] === true) {
currentMarker = character;
index++;
size++;
if (
character === asterisk ||
character === plusSign ||
character === dash
) {
currentMarker = character
index++
size++
} else {
queue = '';
queue = ''
while (index < length) {
character = value.charAt(index);
character = value.charAt(index)
if (!decimal(character)) {
break;
break
}
queue += character;
index++;
queue += character
index++
}
character = value.charAt(index);
index++;
character = value.charAt(index)
index++
if (queue && markers[character] === true) {
currentMarker = character;
size += queue.length + 1;
if (
queue &&
(character === dot || (commonmark && character === rightParenthesis))
) {
currentMarker = character
size += queue.length + 1
}
}
if (currentMarker) {
character = value.charAt(index);
character = value.charAt(index)
if (character === C_TAB) {
size += TAB_SIZE - (size % TAB_SIZE);
index++;
} else if (character === C_SPACE) {
end = index + TAB_SIZE;
if (character === tab) {
size += tabSize - (size % tabSize)
index++
} else if (character === space) {
end = index + tabSize
while (index < end) {
if (value.charAt(index) !== C_SPACE) {
break;
if (value.charAt(index) !== space) {
break
}
index++;
size++;
index++
size++
}
if (index === end && value.charAt(index) === C_SPACE) {
index -= TAB_SIZE - 1;
size -= TAB_SIZE - 1;
if (index === end && value.charAt(index) === space) {
index -= tabSize - 1
size -= tabSize - 1
}
} else if (character !== C_NEWLINE && character !== '') {
currentMarker = null;
} else if (character !== lineFeed && character !== '') {
currentMarker = null
}
}
}
if (currentMarker) {
if (!pedantic && marker !== currentMarker) {
break;
break
}
prefixed = true;
prefixed = true
} else {
if (!commonmark && !indented && value.charAt(startIndex) === C_SPACE) {
indented = true;
if (!commonmark && !indented && value.charAt(startIndex) === space) {
indented = true
} else if (commonmark && item) {
indented = size >= item.indent || size > TAB_SIZE;
indented = size >= item.indent || size > tabSize
}
prefixed = false;
index = startIndex;
prefixed = false
index = startIndex
}
line = value.slice(startIndex, nextIndex);
content = startIndex === index ? line : value.slice(index, nextIndex);
line = value.slice(startIndex, nextIndex)
content = startIndex === index ? line : value.slice(index, nextIndex)
if (
currentMarker === C_ASTERISK ||
currentMarker === C_UNDERSCORE ||
currentMarker === C_DASH
currentMarker === asterisk ||
currentMarker === underscore ||
currentMarker === dash
) {
if (tokenizers.thematicBreak.call(self, eat, line, true)) {
break;
break
}
}
prevEmpty = empty;
empty = !trim(content).length;
prevEmpty = empty
empty = !prefixed && !trim(content).length
if (indented && item) {
item.value = item.value.concat(emptyLines, line);
allLines = allLines.concat(emptyLines, line);
emptyLines = [];
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();
spread = true
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);
items.push(item)
allLines = allLines.concat(emptyLines, line)
emptyLines = []
} else if (empty) {
if (prevEmpty && !commonmark) {
break
}
emptyLines.push(line)
} else {
if (prevEmpty) {
break;
break
}
if (interrupt(interuptors, tokenizers, self, [eat, line, true])) {
break;
break
}
item.value = item.value.concat(emptyLines, line);
allLines = allLines.concat(emptyLines, line);
emptyLines = [];
item.value = item.value.concat(emptyLines, line)
allLines = allLines.concat(emptyLines, line)
emptyLines = []
}
index = nextIndex + 1;
index = nextIndex + 1
}
node = eat(allLines.join(C_NEWLINE)).reset({
node = eat(allLines.join(lineFeed)).reset({
type: 'list',
ordered: ordered,
start: start,
loose: null,
spread: spread,
children: []
});
})
enterTop = self.enterList();
exitBlockquote = self.enterBlock();
isLoose = false;
index = -1;
length = items.length;
enterTop = self.enterList()
exitBlockquote = self.enterBlock()
index = -1
length = items.length
while (++index < length) {
item = items[index].value.join(C_NEWLINE);
now = eat.now();
item = items[index].value.join(lineFeed)
now = eat.now()
item = eat(item)(listItem(self, item, now), node);
eat(item)(listItem(self, item, now), node)
if (item.loose) {
isLoose = true;
}
item = items[index].trail.join(C_NEWLINE);
item = items[index].trail.join(lineFeed)
if (index !== length - 1) {
item += C_NEWLINE;
item += lineFeed
}
eat(item);
eat(item)
}
enterTop();
exitBlockquote();
enterTop()
exitBlockquote()
node.loose = isLoose;
return node;
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;
var offsets = ctx.offset
var fn = ctx.options.pedantic ? pedanticListItem : normalListItem
var checked = null
var task
var indent
value = fn.apply(null, arguments);
value = fn.apply(null, arguments)
if (ctx.options.gfm) {
task = value.match(EXPRESSION_TASK_ITEM);
task = value.match(taskItemExpression)
if (task) {
indent = task[0].length;
checked = task[1].toLowerCase() === C_X_LOWER;
offsets[position.line] += indent;
value = value.slice(indent);
indent = task[0].length
checked = task[1].toLowerCase() === lowercaseX
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,
spread: looseListItemExpression.test(value),
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-items 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. */
// Create a list-item using overly simple mechanics.
function pedanticListItem(ctx, value, position) {
var offsets = ctx.offset
var line = position.line
// Remove the list-items bullet.
value = value.replace(pedanticBulletExpression, replacer)
// The initial line was also matched by the below, so we reset the `line`.
line = position.line
return value.replace(initialIndentExpression, 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;
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-items bullet. */
value = value.replace(EXPRESSION_BULLET, replacer);
// Remove the list-items bullet.
value = value.replace(bulletExpression, replacer)
lines = value.split(C_NEWLINE);
lines = value.split(lineFeed)
trimmedLines = removeIndent(value, getIndent(max).indent).split(C_NEWLINE);
trimmedLines = removeIndent(value, getIndent(max).indent).split(lineFeed)
/* 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;
// 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++;
offsets[line] = (offsets[line] || 0) + bullet.length
line++
index = 0;
length = lines.length;
index = 0
length = lines.length
while (++index < length) {
offsets[line] = (offsets[line] || 0) +
lines[index].length - trimmedLines[index].length;
line++;
offsets[line] =
(offsets[line] || 0) + lines[index].length - trimmedLines[index].length
line++
}
return trimmedLines.join(C_NEWLINE);
return trimmedLines.join(lineFeed)
/* eslint-disable-next-line max-params */
function replacer($0, $1, $2, $3, $4) {
bullet = $1 + $2 + $3;
rest = $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. */
// 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;
$2 = space + $2
}
max = $1 + repeat(C_SPACE, $2.length) + $3;
max = $1 + repeat(space, $2.length) + $3
return max + rest;
return max + rest
}
}

View File

@ -1,47 +1,48 @@
'use strict';
'use strict'
var whitespace = require('is-whitespace-character');
var whitespace = require('is-whitespace-character')
module.exports = newline;
module.exports = newline
var lineFeed = '\n'
/* Tokenise newline. */
function newline(eat, value, silent) {
var character = value.charAt(0);
var length;
var subvalue;
var queue;
var index;
var character = value.charAt(0)
var length
var subvalue
var queue
var index
if (character !== '\n') {
return;
if (character !== lineFeed) {
return
}
/* istanbul ignore if - never used (yet) */
if (silent) {
return true;
return true
}
index = 1;
length = value.length;
subvalue = character;
queue = '';
index = 1
length = value.length
subvalue = character
queue = ''
while (index < length) {
character = value.charAt(index);
character = value.charAt(index)
if (!whitespace(character)) {
break;
break
}
queue += character;
queue += character
if (character === '\n') {
subvalue += queue;
queue = '';
if (character === lineFeed) {
subvalue += queue
queue = ''
}
index++;
index++
}
eat(subvalue);
eat(subvalue)
}

View File

@ -1,122 +1,117 @@
'use strict';
'use strict'
var trim = require('trim');
var decimal = require('is-decimal');
var trimTrailingLines = require('trim-trailing-lines');
var interrupt = require('../util/interrupt');
var trim = require('trim')
var decimal = require('is-decimal')
var trimTrailingLines = require('trim-trailing-lines')
var interrupt = require('../util/interrupt')
module.exports = paragraph;
module.exports = paragraph
var C_NEWLINE = '\n';
var C_TAB = '\t';
var C_SPACE = ' ';
var tab = '\t'
var lineFeed = '\n'
var space = ' '
var TAB_SIZE = 4;
var tabSize = 4
/* Tokenise paragraph. */
// 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;
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(lineFeed)
var length = value.length
var position
var subvalue
var character
var size
var now
while (index < length) {
/* Eat everything if theres no following newline. */
// Eat everything if theres no following newline.
if (index === -1) {
index = length;
break;
index = length
break
}
/* Stop if the next character is NEWLINE. */
if (value.charAt(index + 1) === C_NEWLINE) {
break;
// Stop if the next character is NEWLINE.
if (value.charAt(index + 1) === lineFeed) {
break
}
/* In commonmark-mode, following indented lines
* are part of the paragraph. */
// In commonmark-mode, following indented lines are part of the paragraph.
if (commonmark) {
size = 0;
position = index + 1;
size = 0
position = index + 1
while (position < length) {
character = value.charAt(position);
character = value.charAt(position)
if (character === C_TAB) {
size = TAB_SIZE;
break;
} else if (character === C_SPACE) {
size++;
if (character === tab) {
size = tabSize
break
} else if (character === space) {
size++
} else {
break;
break
}
position++;
position++
}
if (size >= TAB_SIZE) {
index = value.indexOf(C_NEWLINE, index + 1);
continue;
if (size >= tabSize && character !== lineFeed) {
index = value.indexOf(lineFeed, index + 1)
continue
}
}
subvalue = value.slice(index + 1);
subvalue = value.slice(index + 1)
/* Check if the following code contains a possible
* block. */
// Check if the following code contains a possible block.
if (interrupt(interruptors, tokenizers, self, [eat, subvalue, true])) {
break;
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. */
// 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 ||
(self.inList ||
commonmark ||
(gfm && !decimal(trim.left(subvalue).charAt(0)))
)
(gfm && !decimal(trim.left(subvalue).charAt(0))))
) {
break;
break
}
position = index;
index = value.indexOf(C_NEWLINE, index + 1);
position = index
index = value.indexOf(lineFeed, index + 1)
if (index !== -1 && trim(value.slice(position, index)) === '') {
index = position;
break;
index = position
break
}
}
subvalue = value.slice(0, index);
subvalue = value.slice(0, index)
if (trim(subvalue) === '') {
eat(subvalue);
eat(subvalue)
return null;
return null
}
/* istanbul ignore if - never used (yet) */
if (silent) {
return true;
return true
}
now = eat.now();
subvalue = trimTrailingLines(subvalue);
now = eat.now()
subvalue = trimTrailingLines(subvalue)
return eat(subvalue)({
type: 'paragraph',
children: self.tokenizeInline(subvalue, now)
});
})
}

View File

@ -1,206 +1,221 @@
'use strict';
'use strict'
var whitespace = require('is-whitespace-character');
var locate = require('../locate/link');
var normalize = require('../util/normalize');
var whitespace = require('is-whitespace-character')
var locate = require('../locate/link')
var normalize = require('../util/normalize')
module.exports = reference;
reference.locator = locate;
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 = ']';
var link = 'link'
var image = 'image'
var footnote = 'footnote'
var shortcut = 'shortcut'
var collapsed = 'collapsed'
var full = 'full'
var space = ' '
var exclamationMark = '!'
var leftSquareBracket = '['
var backslash = '\\'
var rightSquareBracket = ']'
var caret = '^'
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;
var self = this
var commonmark = self.options.commonmark
var footnotes = self.options.footnotes
var character = value.charAt(0)
var index = 0
var length = value.length
var subvalue = ''
var intro = ''
var type = link
var referenceType = shortcut
var content
var identifier
var now
var node
var exit
var queue
var bracketed
var depth
/* Check whether were eating an image. */
if (character === '!') {
type = T_IMAGE;
intro = character;
character = value.charAt(++index);
// Check whether were eating an image.
if (character === exclamationMark) {
type = image
intro = character
character = value.charAt(++index)
}
if (character !== C_BRACKET_OPEN) {
return;
if (character !== leftSquareBracket) {
return
}
index++;
intro += character;
queue = '';
index++
intro += character
queue = ''
/* Check whether were eating a footnote. */
if (self.options.footnotes && value.charAt(index) === C_CARET) {
/* Exit if `![^` is found, so the `!` will be seen as text after this,
* and well enter this function again when `[^` is found. */
if (type === T_IMAGE) {
return;
// Check whether were eating a footnote.
if (footnotes && value.charAt(index) === caret) {
// Exit if `![^` is found, so the `!` will be seen as text after this,
// and well enter this function again when `[^` is found.
if (type === image) {
return
}
intro += C_CARET;
index++;
type = T_FOOTNOTE;
intro += caret
index++
type = footnote
}
/* Eat the text. */
depth = 0;
// Eat the text.
depth = 0
while (index < length) {
character = value.charAt(index);
character = value.charAt(index)
if (character === C_BRACKET_OPEN) {
bracketed = true;
depth++;
} else if (character === C_BRACKET_CLOSE) {
if (character === leftSquareBracket) {
bracketed = true
depth++
} else if (character === rightSquareBracket) {
if (!depth) {
break;
break
}
depth--;
depth--
}
if (character === C_BACKSLASH) {
queue += C_BACKSLASH;
character = value.charAt(++index);
if (character === backslash) {
queue += backslash
character = value.charAt(++index)
}
queue += character;
index++;
queue += character
index++
}
subvalue = queue;
content = queue;
character = value.charAt(index);
subvalue = queue
content = queue
character = value.charAt(index)
if (character !== C_BRACKET_CLOSE) {
return;
if (character !== rightSquareBracket) {
return
}
index++;
subvalue += character;
queue = '';
index++
subvalue += character
queue = ''
while (index < length) {
character = value.charAt(index);
if (!commonmark) {
// The original markdown syntax definition explicitly allows for whitespace
// between the link text and link label; commonmark departs from this, in
// part to improve support for shortcut reference links
while (index < length) {
character = value.charAt(index)
if (!whitespace(character)) {
break;
if (!whitespace(character)) {
break
}
queue += character
index++
}
queue += character;
index++;
}
character = value.charAt(index);
character = value.charAt(index)
/* Inline footnotes cannot have an identifier. */
if (type !== T_FOOTNOTE && character === C_BRACKET_OPEN) {
identifier = '';
queue += character;
index++;
// Inline footnotes cannot have a label.
// If footnotes are enabled, link labels cannot start with a caret.
if (
type !== footnote &&
character === leftSquareBracket &&
(!footnotes || value.charAt(index + 1) !== caret)
) {
identifier = ''
queue += character
index++
while (index < length) {
character = value.charAt(index);
character = value.charAt(index)
if (character === C_BRACKET_OPEN || character === C_BRACKET_CLOSE) {
break;
if (character === leftSquareBracket || character === rightSquareBracket) {
break
}
if (character === C_BACKSLASH) {
identifier += C_BACKSLASH;
character = value.charAt(++index);
if (character === backslash) {
identifier += backslash
character = value.charAt(++index)
}
identifier += character;
index++;
identifier += character
index++
}
character = value.charAt(index);
character = value.charAt(index)
if (character === C_BRACKET_CLOSE) {
referenceType = identifier ? REFERENCE_TYPE_FULL : REFERENCE_TYPE_COLLAPSED;
queue += identifier + character;
index++;
if (character === rightSquareBracket) {
referenceType = identifier ? full : collapsed
queue += identifier + character
index++
} else {
identifier = '';
identifier = ''
}
subvalue += queue;
queue = '';
subvalue += queue
queue = ''
} else {
if (!content) {
return;
return
}
identifier = content;
identifier = content
}
/* Brackets cannot be inside the identifier. */
if (referenceType !== REFERENCE_TYPE_FULL && bracketed) {
return;
// Brackets cannot be inside the identifier.
if (referenceType !== full && bracketed) {
return
}
subvalue = intro + subvalue;
subvalue = intro + subvalue
if (type === T_LINK && self.inLink) {
return null;
if (type === link && self.inLink) {
return null
}
/* istanbul ignore if - never used (yet) */
if (silent) {
return true;
return true
}
if (type === T_FOOTNOTE && content.indexOf(' ') !== -1) {
if (type === footnote && content.indexOf(space) !== -1) {
return eat(subvalue)({
type: 'footnote',
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;
now = eat.now()
now.column += intro.length
now.offset += intro.length
identifier = referenceType === full ? identifier : content
node = {
type: type + 'Reference',
identifier: normalize(identifier)
};
if (type === T_LINK || type === T_IMAGE) {
node.referenceType = referenceType;
identifier: normalize(identifier),
label: identifier
}
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;
if (type === link || type === image) {
node.referenceType = referenceType
}
return eat(subvalue)(node);
if (type === link) {
exit = self.enterLink()
node.children = self.tokenizeInline(content, now)
exit()
} else if (type === image) {
node.alt = self.decode.raw(self.unescape(content), now) || null
}
return eat(subvalue)(node)
}

View File

@ -1,84 +1,85 @@
'use strict';
'use strict'
var trim = require('trim');
var whitespace = require('is-whitespace-character');
var locate = require('../locate/strong');
var trim = require('trim')
var whitespace = require('is-whitespace-character')
var locate = require('../locate/strong')
module.exports = strong;
strong.locator = locate;
module.exports = strong
strong.locator = locate
var C_ASTERISK = '*';
var C_UNDERSCORE = '_';
var backslash = '\\'
var asterisk = '*'
var underscore = '_'
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;
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) ||
(character !== asterisk && character !== underscore) ||
value.charAt(++index) !== character
) {
return;
return
}
pedantic = self.options.pedantic;
marker = character;
subvalue = marker + marker;
length = value.length;
index++;
queue = '';
character = '';
pedantic = self.options.pedantic
marker = character
subvalue = marker + marker
length = value.length
index++
queue = ''
character = ''
if (pedantic && whitespace(value.charAt(index))) {
return;
return
}
while (index < length) {
prev = character;
character = value.charAt(index);
prev = character
character = value.charAt(index)
if (
character === marker &&
value.charAt(index + 1) === marker &&
(!pedantic || !whitespace(prev))
) {
character = value.charAt(index + 2);
character = value.charAt(index + 2)
if (character !== marker) {
if (!trim(queue)) {
return;
return
}
/* istanbul ignore if - never used (yet) */
if (silent) {
return true;
return true
}
now = eat.now();
now.column += 2;
now.offset += 2;
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);
if (!pedantic && character === backslash) {
queue += character
character = value.charAt(++index)
}
queue += character;
index++;
queue += character
index++
}
}

View File

@ -1,266 +1,232 @@
'use strict';
'use strict'
var whitespace = require('is-whitespace-character');
var whitespace = require('is-whitespace-character')
module.exports = table;
module.exports = table
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 tab = '\t'
var lineFeed = '\n'
var space = ' '
var dash = '-'
var colon = ':'
var backslash = '\\'
var verticalBar = '|'
var MIN_TABLE_COLUMNS = 1;
var MIN_TABLE_ROWS = 2;
var minColumns = 1
var minRows = 2
var TABLE_ALIGN_LEFT = 'left';
var TABLE_ALIGN_CENTER = 'center';
var TABLE_ALIGN_RIGHT = 'right';
var TABLE_ALIGN_NONE = null;
var left = 'left'
var center = 'center'
var right = 'right'
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;
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 now
var position
var lineCount
var line
var rows
var table
var lineIndex
var pipeIndex
var first
/* Exit when not in gfm-mode. */
// Exit when not in gfm-mode.
if (!self.options.gfm) {
return;
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 = [];
// 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);
lineIndex = value.indexOf(lineFeed, index)
pipeIndex = value.indexOf(verticalBar, index + 1)
if (lineIndex === -1) {
lineIndex = value.length;
lineIndex = value.length
}
if (pipeIndex === -1 || pipeIndex > lineIndex) {
if (lineCount < MIN_TABLE_ROWS) {
return;
if (lineCount < minRows) {
return
}
break;
break
}
lines.push(value.slice(index, lineIndex));
lineCount++;
index = lineIndex + 1;
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 = [];
// Parse the alignment row.
subvalue = lines.join(lineFeed)
alignments = lines.splice(1, 1)[0] || []
index = 0
length = alignments.length
lineCount--
alignment = false
align = []
while (index < length) {
character = alignments.charAt(index);
character = alignments.charAt(index)
if (character === C_PIPE) {
hasDash = null;
if (character === verticalBar) {
hasDash = null
if (alignment === false) {
if (first === false) {
return;
return
}
} else {
align.push(alignment);
alignment = false;
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;
first = false
} else if (character === dash) {
hasDash = true
alignment = alignment || null
} else if (character === colon) {
if (alignment === left) {
alignment = center
} else if (hasDash && alignment === null) {
alignment = right
} else {
alignment = TABLE_ALIGN_LEFT;
alignment = left
}
} else if (!whitespace(character)) {
return;
return
}
index++;
index++
}
if (alignment !== false) {
align.push(alignment);
align.push(alignment)
}
/* Exit when without enough columns. */
if (align.length < MIN_TABLE_COLUMNS) {
return;
// Exit when without enough columns.
if (align.length < minColumns) {
return
}
/* istanbul ignore if - never used (yet) */
if (silent) {
return true;
return true
}
/* Parse the rows. */
position = -1;
rows = [];
// Parse the rows.
position = -1
rows = []
table = eat(subvalue).reset({
type: 'table',
align: align,
children: rows
});
table = eat(subvalue).reset({type: 'table', align: align, children: rows})
while (++position < lineCount) {
line = lines[position];
row = {type: 'tableRow', children: []};
line = lines[position]
row = {type: 'tableRow', children: []}
/* Eat a newline character when this is not the
* first row. */
// Eat a newline character when this is not the first row.
if (position) {
eat(C_NEWLINE);
eat(lineFeed)
}
/* Eat the row. */
eat(line).reset(row, table);
// Eat the row.
eat(line).reset(row, table)
length = line.length + 1;
index = 0;
queue = '';
cell = '';
preamble = true;
count = null;
opening = null;
length = line.length + 1
index = 0
queue = ''
cell = ''
preamble = true
while (index < length) {
character = line.charAt(index);
character = line.charAt(index)
if (character === C_TAB || character === C_SPACE) {
if (character === tab || character === space) {
if (cell) {
queue += character;
queue += character
} else {
eat(character);
eat(character)
}
index++;
continue;
index++
continue
}
if (character === '' || character === C_PIPE) {
if (character === '' || character === verticalBar) {
if (preamble) {
eat(character);
eat(character)
} else {
if (character && opening) {
queue += character;
index++;
continue;
}
if ((cell || character) && !preamble) {
subvalue = cell;
subvalue = cell
if (queue.length > 1) {
if (character) {
subvalue += queue.slice(0, queue.length - 1);
queue = queue.charAt(queue.length - 1);
subvalue += queue.slice(0, queue.length - 1)
queue = queue.charAt(queue.length - 1)
} else {
subvalue += queue;
queue = '';
subvalue += queue
queue = ''
}
}
now = eat.now();
now = eat.now()
eat(subvalue)({
type: 'tableCell',
children: self.tokenizeInline(cell, now)
}, row);
eat(subvalue)(
{type: 'tableCell', children: self.tokenizeInline(cell, now)},
row
)
}
eat(queue + character);
eat(queue + character)
queue = '';
cell = '';
queue = ''
cell = ''
}
} else {
if (queue) {
cell += queue;
queue = '';
cell += queue
queue = ''
}
cell += character;
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;
}
if (character === backslash && index !== length - 2) {
cell += line.charAt(index + 1)
index++
}
}
preamble = false;
index++;
preamble = false
index++
}
/* Eat the alignment row. */
// Eat the alignment row.
if (!position) {
eat(C_NEWLINE + alignments);
eat(lineFeed + alignments)
}
}
return table;
return table
}

View File

@ -1,58 +1,57 @@
'use strict';
'use strict'
module.exports = text;
module.exports = 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;
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;
return true
}
methods = self.inlineMethods;
length = methods.length;
tokenizers = self.inlineTokenizers;
index = -1;
min = value.length;
methods = self.inlineMethods
length = methods.length
tokenizers = self.inlineTokenizers
index = -1
min = value.length
while (++index < length) {
name = methods[index];
name = methods[index]
if (name === 'text' || !tokenizers[name]) {
continue;
continue
}
tokenizer = tokenizers[name].locator;
tokenizer = tokenizers[name].locator
if (!tokenizer) {
eat.file.fail('Missing locator: `' + name + '`');
eat.file.fail('Missing locator: `' + name + '`')
}
position = tokenizer.call(self, value, 1);
position = tokenizer.call(self, value, 1)
if (position !== -1 && position < min) {
min = position;
min = position
}
}
subvalue = value.slice(0, min);
now = eat.now();
subvalue = value.slice(0, min)
now = eat.now()
self.decode(subvalue, now, function (content, position, source) {
eat(source || content)({
type: 'text',
value: content
});
});
self.decode(subvalue, now, handler)
function handler(content, position, source) {
eat(source || content)({type: 'text', value: content})
}
}

View File

@ -1,70 +1,70 @@
'use strict';
'use strict'
module.exports = thematicBreak;
module.exports = thematicBreak
var C_NEWLINE = '\n';
var C_TAB = '\t';
var C_SPACE = ' ';
var C_ASTERISK = '*';
var C_UNDERSCORE = '_';
var C_DASH = '-';
var tab = '\t'
var lineFeed = '\n'
var space = ' '
var asterisk = '*'
var dash = '-'
var underscore = '_'
var THEMATIC_BREAK_MARKER_COUNT = 3;
var maxCount = 3
function thematicBreak(eat, value, silent) {
var index = -1;
var length = value.length + 1;
var subvalue = '';
var character;
var marker;
var markerCount;
var queue;
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);
character = value.charAt(index)
if (character !== C_TAB && character !== C_SPACE) {
break;
if (character !== tab && character !== space) {
break
}
subvalue += character;
subvalue += character
}
if (
character !== C_ASTERISK &&
character !== C_DASH &&
character !== C_UNDERSCORE
character !== asterisk &&
character !== dash &&
character !== underscore
) {
return;
return
}
marker = character;
subvalue += character;
markerCount = 1;
queue = '';
marker = character
subvalue += character
markerCount = 1
queue = ''
while (++index < length) {
character = value.charAt(index);
character = value.charAt(index)
if (character === marker) {
markerCount++;
subvalue += queue + marker;
queue = '';
} else if (character === C_SPACE) {
queue += character;
markerCount++
subvalue += queue + marker
queue = ''
} else if (character === space) {
queue += character
} else if (
markerCount >= THEMATIC_BREAK_MARKER_COUNT &&
(!character || character === C_NEWLINE)
markerCount >= maxCount &&
(!character || character === lineFeed)
) {
subvalue += queue;
subvalue += queue
if (silent) {
return true;
return true
}
return eat(subvalue)({type: 'thematicBreak'});
return eat(subvalue)({type: 'thematicBreak'})
} else {
return;
return
}
}
}

View File

@ -1,144 +1,153 @@
'use strict';
'use strict'
var decode = require('parse-entities');
var whitespace = require('is-whitespace-character');
var locate = require('../locate/url');
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;
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 quotationMark = '"'
var apostrophe = "'"
var leftParenthesis = '('
var rightParenthesis = ')'
var comma = ','
var dot = '.'
var colon = ':'
var semicolon = ';'
var lessThan = '<'
var atSign = '@'
var leftSquareBracket = '['
var rightSquareBracket = ']'
var HTTP_PROTOCOL = 'http://';
var HTTPS_PROTOCOL = 'https://';
var MAILTO_PROTOCOL = 'mailto:';
var http = 'http://'
var https = 'https://'
var mailto = 'mailto:'
var PROTOCOLS = [
HTTP_PROTOCOL,
HTTPS_PROTOCOL,
MAILTO_PROTOCOL
];
var protocols = [http, https, mailto]
var PROTOCOLS_LENGTH = PROTOCOLS.length;
var protocolsLength = protocols.length
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;
var self = this
var subvalue
var content
var character
var index
var position
var protocol
var match
var length
var queue
var parenCount
var nextCharacter
var tokenizers
var exit
if (!self.options.gfm) {
return;
return
}
subvalue = '';
index = -1;
length = PROTOCOLS_LENGTH;
subvalue = ''
index = -1
while (++index < length) {
protocol = PROTOCOLS[index];
match = value.slice(0, protocol.length);
while (++index < protocolsLength) {
protocol = protocols[index]
match = value.slice(0, protocol.length)
if (match.toLowerCase() === protocol) {
subvalue = match;
break;
subvalue = match
break
}
}
if (!subvalue) {
return;
return
}
index = subvalue.length;
length = value.length;
queue = '';
parenCount = 0;
index = subvalue.length
length = value.length
queue = ''
parenCount = 0
while (index < length) {
character = value.charAt(index);
character = value.charAt(index)
if (whitespace(character) || character === C_LT) {
break;
if (whitespace(character) || character === lessThan) {
break
}
if (
character === '.' ||
character === ',' ||
character === ':' ||
character === ';' ||
character === '"' ||
character === '\'' ||
character === ')' ||
character === ']'
character === dot ||
character === comma ||
character === colon ||
character === semicolon ||
character === quotationMark ||
character === apostrophe ||
character === rightParenthesis ||
character === rightSquareBracket
) {
nextCharacter = value.charAt(index + 1);
nextCharacter = value.charAt(index + 1)
if (!nextCharacter || whitespace(nextCharacter)) {
break;
break
}
}
if (character === C_PAREN_OPEN || character === C_BRACKET_OPEN) {
parenCount++;
if (character === leftParenthesis || character === leftSquareBracket) {
parenCount++
}
if (character === C_PAREN_CLOSE || character === C_BRACKET_CLOSE) {
parenCount--;
if (character === rightParenthesis || character === rightSquareBracket) {
parenCount--
if (parenCount < 0) {
break;
break
}
}
queue += character;
index++;
queue += character
index++
}
if (!queue) {
return;
return
}
subvalue += queue;
content = subvalue;
subvalue += queue
content = subvalue
if (protocol === MAILTO_PROTOCOL) {
position = queue.indexOf(C_AT_SIGN);
if (protocol === mailto) {
position = queue.indexOf(atSign)
if (position === -1 || position === length - 1) {
return;
return
}
content = content.substr(MAILTO_PROTOCOL.length);
content = content.slice(mailto.length)
}
/* istanbul ignore if - never used (yet) */
if (silent) {
return true;
return true
}
exit = self.enterLink();
content = self.tokenizeInline(content, eat.now());
exit();
exit = self.enterLink()
// Temporarily remove all tokenizers except text in url.
tokenizers = self.inlineTokenizers
self.inlineTokenizers = {text: tokenizers.text}
content = self.tokenizeInline(content, eat.now())
self.inlineTokenizers = tokenizers
exit()
return eat(subvalue)({
type: 'link',
title: null,
url: decode(subvalue, {nonTerminated: false}),
children: content
});
})
}

View File

@ -1,95 +1,50 @@
'use strict';
'use strict'
module.exports = factory;
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`. */
// Construct a tokenizer. This creates both `tokenizeInline` and `tokenizeBlock`.
function factory(type) {
return tokenize;
return tokenize
/* Tokenizer for a bound `type`. */
// 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;
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. */
// Trim white space only lines.
if (!value) {
return tokens;
return tokens
}
/* Expose on `eat`. */
eat.now = now;
eat.file = self.file;
// Expose on `eat`.
eat.now = now
eat.file = self.file
/* Sync initial offset. */
updatePosition('');
// 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. */
// 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;
index = -1
length = methods.length
matched = false
while (++index < length) {
name = methods[index];
method = tokenizers[name];
name = methods[index]
method = tokenizers[name]
if (
method &&
@ -98,234 +53,262 @@ function factory(type) {
(!method.notInBlock || !self.inBlock) &&
(!method.notInLink || !self.inLink)
) {
valueLength = value.length;
valueLength = value.length
method.apply(self, [eat, value]);
method.apply(self, [eat, value])
matched = valueLength !== value.length;
matched = valueLength !== value.length
if (matched) {
break;
break
}
}
}
/* istanbul ignore if */
if (!matched) {
self.file.fail(new Error('Infinite loop'), eat.now());
self.file.fail(new Error('Infinite loop'), eat.now())
}
}
self.eof = now();
self.eof = now()
return tokens;
return tokens
/* Update line, column, and offset based on
* `value`. */
// Update line, column, and offset based on `value`.
function updatePosition(subvalue) {
var lastIndex = -1;
var index = subvalue.indexOf('\n');
var lastIndex = -1
var index = subvalue.indexOf('\n')
while (index !== -1) {
line++;
lastIndex = index;
index = subvalue.indexOf('\n', index + 1);
line++
lastIndex = index
index = subvalue.indexOf('\n', index + 1)
}
if (lastIndex === -1) {
column += subvalue.length;
column += subvalue.length
} else {
column = subvalue.length - lastIndex;
column = subvalue.length - lastIndex
}
if (line in offset) {
if (lastIndex !== -1) {
column += offset[line];
column += offset[line]
} else if (column <= offset[line]) {
column = offset[line] + 1;
column = offset[line] + 1
}
}
}
/* Get offset. Called before the first character is
* eaten to retrieve the range's offsets. */
// Get offset. Called before the first character is eaten to retrieve the
// ranges offsets.
function getOffset() {
var indentation = [];
var pos = line + 1;
var indentation = []
var pos = line + 1
/* Done. Called when the last character is
* eaten to retrieve the ranges offsets. */
return function () {
var last = line + 1;
// Done. Called when the last character is eaten to retrieve the ranges
// offsets.
return function() {
var last = line + 1
while (pos < last) {
indentation.push((offset[pos] || 0) + 1);
indentation.push((offset[pos] || 0) + 1)
pos++;
pos++
}
return indentation;
};
}
/* Get the current position. */
function now() {
var pos = {line: line, column: column};
pos.offset = self.toOffset(pos);
return pos;
}
/* Store position information for a node. */
function Position(start) {
this.start = start;
this.end = now();
}
/* Throw when a value is incorrectly eaten.
* This shouldnt happen but will throw on new,
* incorrect rules. */
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()
);
return indentation
}
}
/* Mark position and patch `node.position`. */
// Get the current position.
function now() {
var pos = {line: line, column: column}
pos.offset = self.toOffset(pos)
return pos
}
// Store position information for a node.
function Position(start) {
this.start = start
this.end = now()
}
// Throw when a value is incorrectly eaten. This shouldnt happen but will
// throw on new, incorrect rules.
function validateEat(subvalue) {
/* istanbul ignore if */
if (value.slice(0, subvalue.length) !== subvalue) {
// Capture stack-trace.
self.file.fail(
new Error(
'Incorrectly eaten value: please report this warning on https://git.io/vg5Ft'
),
now()
)
}
}
// Mark position and patch `node.position`.
function position() {
var before = now();
var before = now()
return update;
return update
/* Add the position to a node. */
// Add the position to a 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;
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);
node.position = new Position(start)
/* If there was already a `position`, this
* node was merged. Fixing `start` wasnt
* hard, but the indent is different.
* Especially because some information, the
* indent between `n` and `l` wasnt
* tracked. Luckily, that space is
* (should be?) empty, so we can safely
* check for it now. */
// If there was already a `position`, this node was merged. Fixing
// `start` wasnt hard, but the indent is different. Especially
// because some information, the indent between `n` and `l` wasnt
// tracked. Luckily, that space is (should be?) empty, so we can
// safely check for it now.
if (prev && indent && prev.indent) {
combined = prev.indent;
combined = prev.indent
if (n < l) {
while (++n < l) {
combined.push((offset[n] || 0) + 1);
combined.push((offset[n] || 0) + 1)
}
combined.push(before.column);
combined.push(before.column)
}
indent = combined.concat(indent);
indent = combined.concat(indent)
}
node.position.indent = indent || [];
node.position.indent = indent || []
return node;
return node
}
}
/* Add `node` to `parent`s children or to `tokens`.
* Performs merges where possible. */
// Add `node` to `parent`s children or to `tokens`. Performs merges where
// possible.
function add(node, parent) {
var children = parent ? parent.children : tokens;
var prev = children[children.length - 1];
var children = parent ? parent.children : tokens
var prev = children[children.length - 1]
var fn
if (
prev &&
node.type === prev.type &&
node.type in MERGEABLE_NODES &&
(node.type === 'text' || node.type === 'blockquote') &&
mergeable(prev) &&
mergeable(node)
) {
node = MERGEABLE_NODES[node.type].call(self, prev, node);
fn = node.type === 'text' ? mergeText : mergeBlockquote
node = fn.call(self, prev, node)
}
if (node !== prev) {
children.push(node);
children.push(node)
}
if (self.atStart && tokens.length !== 0) {
self.exitStart();
self.exitStart()
}
return node;
return node
}
/* Remove `subvalue` from `value`.
* `subvalue` must be at the start of `value`. */
// Remove `subvalue` from `value`. `subvalue` must be at the start of
// `value`.
function eat(subvalue) {
var indent = getOffset();
var pos = position();
var current = now();
var indent = getOffset()
var pos = position()
var current = now()
validateEat(subvalue);
validateEat(subvalue)
apply.reset = reset;
reset.test = test;
apply.test = test;
apply.reset = reset
reset.test = test
apply.test = test
value = value.substring(subvalue.length);
value = value.slice(subvalue.length)
updatePosition(subvalue);
updatePosition(subvalue)
indent = indent();
indent = indent()
return apply;
return apply
/* Add the given arguments, add `position` to
* the returned node, and return the node. */
// Add the given arguments, add `position` to the returned node, and
// return the node.
function apply(node, parent) {
return pos(add(pos(node), parent), indent);
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. */
// 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.
function reset() {
var node = apply.apply(null, arguments);
var node = apply.apply(null, arguments)
line = current.line;
column = current.column;
value = subvalue + value;
line = current.line
column = current.column
value = subvalue + value
return node;
return node
}
/* Test the position, after eating, and reverse
* to a not-eaten state. */
// Test the position, after eating, and reverse to a not-eaten state.
function test() {
var result = pos({});
var result = pos({})
line = current.line;
column = current.column;
value = subvalue + value;
line = current.line
column = current.column
value = subvalue + value
return result.position;
return result.position
}
}
}
}
// 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 or gfm modes.
function mergeBlockquote(prev, node) {
if (this.options.commonmark || this.options.gfm) {
return node
}
prev.children = prev.children.concat(node.children)
return prev
}

View File

@ -1,37 +1,36 @@
'use strict';
'use strict'
module.exports = factory;
module.exports = factory
/* Factory to de-escape a value, based on a list at `key`
* in `ctx`. */
var backslash = '\\'
// Factory to de-escape a value, based on a list at `key` in `ctx`.
function factory(ctx, key) {
return unescape;
return unescape
/* De-escape a string using the expression at `key`
* in `ctx`. */
// 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;
var prev = 0
var index = value.indexOf(backslash)
var escape = ctx[key]
var queue = []
var character
while (index !== -1) {
queue.push(value.slice(prev, index));
prev = index + 1;
character = value.charAt(prev);
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 the following character is not a valid escape, add the slash.
if (!character || escape.indexOf(character) === -1) {
queue.push('\\');
queue.push(backslash)
}
index = value.indexOf('\\', prev);
index = value.indexOf(backslash, prev + 1)
}
queue.push(value.slice(prev));
queue.push(value.slice(prev))
return queue.join('');
return queue.join('')
}
}

View File

@ -1,32 +1,33 @@
'use strict';
'use strict'
module.exports = indentation;
module.exports = indentation
/* Map of characters, and their column length,
* which can be used as indentation. */
var characters = {' ': 1, '\t': 4};
var tab = '\t'
var space = ' '
/* Gets indentation information for a line. */
var spaceSize = 1
var tabSize = 4
// Gets indentation information for a line.
function indentation(value) {
var index = 0;
var indent = 0;
var character = value.charAt(index);
var stops = {};
var size;
var index = 0
var indent = 0
var character = value.charAt(index)
var stops = {}
var size
while (character in characters) {
size = characters[character];
while (character === tab || character === space) {
size = character === tab ? tabSize : spaceSize
indent += size;
indent += size
if (size > 1) {
indent = Math.floor(indent / size) * size;
indent = Math.floor(indent / size) * size
}
stops[indent] = index;
character = value.charAt(++index);
stops[indent] = index
character = value.charAt(++index)
}
return {indent: indent, stops: stops};
return {indent: indent, stops: stops}
}

View File

@ -1,25 +1,34 @@
'use strict';
'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]*?\\]\\]>';
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.openCloseTag = new RegExp('^(?:' + openTag + '|' + closeTag + ')')
exports.tag = new RegExp('^(?:' +
openTag + '|' +
closeTag + '|' +
comment + '|' +
processing + '|' +
declaration + '|' +
cdata +
')');
exports.tag = new RegExp(
'^(?:' +
openTag +
'|' +
closeTag +
'|' +
comment +
'|' +
processing +
'|' +
declaration +
'|' +
cdata +
')'
)

View File

@ -1,43 +1,35 @@
'use strict';
'use strict'
module.exports = interrupt;
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;
var length = interruptors.length
var index = -1
var interruptor
var config
while (++index < length) {
interruptor = interruptors[index];
config = interruptor[1] || {};
fn = interruptor[0];
offset = -1;
ignore = false;
interruptor = interruptors[index]
config = interruptor[1] || {}
while (++offset < count) {
bool = bools[offset];
if (config[bool] !== undefined && config[bool] !== ctx.options[bool]) {
ignore = true;
break;
}
if (
config.pedantic !== undefined &&
config.pedantic !== ctx.options.pedantic
) {
continue
}
if (ignore) {
continue;
if (
config.commonmark !== undefined &&
config.commonmark !== ctx.options.commonmark
) {
continue
}
if (tokenizers[fn].apply(ctx, params)) {
return true;
if (tokenizers[interruptor[0]].apply(ctx, params)) {
return true
}
}
return false;
return false
}

View File

@ -0,0 +1,27 @@
'use strict'
module.exports = whitespace
var tab = 9 // '\t'
var lineFeed = 10 // '\n'
var lineTabulation = 11 // '\v'
var formFeed = 12 // '\f'
var carriageReturn = 13 // '\r'
var space = 32 // ' '
function whitespace(char) {
/* istanbul ignore next - `number` handling for future */
var code = typeof char === 'number' ? char : char.charCodeAt(0)
switch (code) {
case tab:
case lineFeed:
case lineTabulation:
case formFeed:
case carriageReturn:
case space:
return true
default:
return false
}
}

View File

@ -1,11 +1,11 @@
'use strict';
'use strict'
var collapseWhiteSpace = require('collapse-white-space');
var collapseWhiteSpace = require('collapse-white-space')
module.exports = normalize;
module.exports = normalize
/* Normalize an identifier. Collapses multiple white space
* characters into a single space, and removes casing. */
// Normalize an identifier. Collapses multiple white space characters into a
// single space, and removes casing.
function normalize(value) {
return collapseWhiteSpace(value).toLowerCase();
return collapseWhiteSpace(value).toLowerCase()
}

View File

@ -1,59 +1,59 @@
'use strict';
'use strict'
var trim = require('trim');
var repeat = require('repeat-string');
var getIndent = require('./get-indentation');
var trim = require('trim')
var repeat = require('repeat-string')
var getIndent = require('./get-indentation')
module.exports = indentation;
module.exports = indentation
var C_SPACE = ' ';
var C_NEWLINE = '\n';
var C_TAB = '\t';
var tab = '\t'
var lineFeed = '\n'
var space = ' '
var exclamationMark = '!'
/* Remove the minimum indent from every line in `value`.
* Supports both tab, spaced, and mixed indentation (as
* well as possible). */
// Remove the minimum indent from every line in `value`. Supports both tab,
// spaced, and mixed indentation (as well as possible).
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;
var values = value.split(lineFeed)
var position = values.length + 1
var minIndent = Infinity
var matrix = []
var index
var indentation
var stops
var padding
values.unshift(repeat(C_SPACE, maximum) + '!');
values.unshift(repeat(space, maximum) + exclamationMark)
while (position--) {
indentation = getIndent(values[position]);
indentation = getIndent(values[position])
matrix[position] = indentation.stops;
matrix[position] = indentation.stops
if (trim(values[position]).length === 0) {
continue;
continue
}
if (indentation.indent) {
if (indentation.indent > 0 && indentation.indent < minIndent) {
minIndent = indentation.indent;
minIndent = indentation.indent
}
} else {
minIndent = Infinity;
minIndent = Infinity
break;
break
}
}
if (minIndent !== Infinity) {
position = values.length;
position = values.length
while (position--) {
stops = matrix[position];
index = minIndent;
stops = matrix[position]
index = minIndent
while (index && !(index in stops)) {
index--;
index--
}
if (
@ -61,18 +61,17 @@ function indentation(value, maximum) {
minIndent &&
index !== minIndent
) {
padding = C_TAB;
padding = tab
} else {
padding = '';
padding = ''
}
values[position] = padding + values[position].slice(
index in stops ? stops[index] + 1 : 0
);
values[position] =
padding + values[position].slice(index in stops ? stops[index] + 1 : 0)
}
}
values.shift();
values.shift()
return values.join(C_NEWLINE);
return values.join(lineFeed)
}

View File

@ -1,27 +1,40 @@
{
"name": "remark-parse",
"version": "5.0.0",
"description": "Markdown parser for remark",
"version": "7.0.2",
"description": "remark plugin to parse Markdown",
"license": "MIT",
"keywords": [
"unified",
"remark",
"plugin",
"markdown",
"mdast",
"abstract",
"syntax",
"tree",
"ast",
"parse"
],
"homepage": "http://remark.js.org",
"types": "types/index.d.ts",
"homepage": "https://remark.js.org",
"repository": "https://github.com/remarkjs/remark/tree/master/packages/remark-parse",
"bugs": "https://github.com/remarkjs/remark/issues",
"author": "Titus Wormer <tituswormer@gmail.com> (http://wooorm.com)",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
},
"author": "Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)",
"contributors": [
"Titus Wormer <tituswormer@gmail.com> (http://wooorm.com)",
"Eugene Sharygin <eush77@gmail.com>"
"Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)",
"Eugene Sharygin <eush77@gmail.com>",
"Junyoung Choi <fluke8259@gmail.com>",
"Elijah Hamovitz <elijahhamovitz@gmail.com>",
"Ika <ikatyang@gmail.com>"
],
"files": [
"index.js",
"lib"
"lib",
"types/index.d.ts"
],
"dependencies": {
"collapse-white-space": "^1.0.2",
@ -40,5 +53,8 @@
"vfile-location": "^2.0.0",
"xtend": "^4.0.1"
},
"scripts": {
"test": "tape test.js"
},
"xo": false
}

View File

@ -1,11 +1,54 @@
# remark-parse [![Build Status][build-badge]][build-status] [![Coverage Status][coverage-badge]][coverage-status] [![Chat][chat-badge]][chat]
# remark-parse
[Parser][] for [**unified**][unified]. Parses markdown to an
[**MDAST**][mdast] syntax tree. Used in the [**remark**
processor][processor]. Can be [extended][extend] to change how
markdown is parsed.
[![Build][build-badge]][build]
[![Coverage][coverage-badge]][coverage]
[![Downloads][downloads-badge]][downloads]
[![Size][size-badge]][size]
[![Sponsors][sponsors-badge]][collective]
[![Backers][backers-badge]][collective]
[![Chat][chat-badge]][chat]
## Installation
[Parser][] for [**unified**][unified].
Parses Markdown to [**mdast**][mdast] syntax trees.
Used in the [**remark** processor][remark] but can be used on its own as well.
Can be [extended][extend] to change how markdown is parsed.
## Sponsors
<!--lint ignore no-html maximum-line-length-->
<table>
<tr valign="top">
<td width="20%" align="center">
<a href="https://zeit.co"><img src="https://avatars1.githubusercontent.com/u/14985020?s=400&v=4"></a>
<br><br>🥇
<a href="https://zeit.co">ZEIT</a>
</td>
<td width="20%" align="center">
<a href="https://www.gatsbyjs.org"><img src="https://avatars1.githubusercontent.com/u/12551863?s=400&v=4"></a>
<br><br>🥇
<a href="https://www.gatsbyjs.org">Gatsby</a>
</td>
<td width="20%" align="center">
<a href="https://www.netlify.com"><img src="https://avatars1.githubusercontent.com/u/7892489?s=400&v=4"></a>
<br><br>🥇
<a href="https://www.netlify.com">Netlify</a>
</td>
<td width="20%" align="center">
<a href="https://www.holloway.com"><img src="https://avatars1.githubusercontent.com/u/35904294?s=400&v=4"></a>
<br><br>
<a href="https://www.holloway.com">Holloway</a>
</td>
<td width="20%" align="center">
<br><br><br><br>
<a href="https://opencollective.com/unified"><strong>You?</strong>
</td>
</tr>
</table>
[**Read more about the unified collective on Medium »**][announcement]
## Install
[npm][]:
@ -13,97 +56,110 @@ markdown is parsed.
npm install remark-parse
```
## Usage
## Use
```js
var unified = require('unified');
var createStream = require('unified-stream');
var markdown = require('remark-parse');
var html = require('remark-html');
var unified = require('unified')
var createStream = require('unified-stream')
var markdown = require('remark-parse')
var remark2rehype = require('remark-rehype')
var html = require('rehype-stringify')
var processor = unified()
.use(markdown, {commonmark: true})
.use(remark2rehype)
.use(html)
process.stdin
.pipe(createStream(processor))
.pipe(process.stdout);
process.stdin.pipe(createStream(processor)).pipe(process.stdout)
```
[See **unified** for more examples »][unified]
## Table of Contents
* [API](#api)
* [processor.use(parse\[, options\])](#processoruseparse-options)
* [parse.Parser](#parseparser)
* [`processor().use(parse[, options])`](#processoruseparse-options)
* [`parse.Parser`](#parseparser)
* [Extending the Parser](#extending-the-parser)
* [Parser#blockTokenizers](#parserblocktokenizers)
* [Parser#blockMethods](#parserblockmethods)
* [Parser#inlineTokenizers](#parserinlinetokenizers)
* [Parser#inlineMethods](#parserinlinemethods)
* [function tokenizer(eat, value, silent)](#function-tokenizereat-value-silent)
* [tokenizer.locator(value, fromIndex)](#tokenizerlocatorvalue-fromindex)
* [eat(subvalue)](#eatsubvalue)
* [add(node\[, parent\])](#addnode-parent)
* [add.test()](#addtest)
* [add.reset(node\[, parent\])](#addresetnode-parent)
* [`Parser#blockTokenizers`](#parserblocktokenizers)
* [`Parser#blockMethods`](#parserblockmethods)
* [`Parser#inlineTokenizers`](#parserinlinetokenizers)
* [`Parser#inlineMethods`](#parserinlinemethods)
* [`function tokenizer(eat, value, silent)`](#function-tokenizereat-value-silent)
* [`tokenizer.locator(value, fromIndex)`](#tokenizerlocatorvalue-fromindex)
* [`eat(subvalue)`](#eatsubvalue)
* [`add(node[, parent])`](#addnode-parent)
* [`add.test()`](#addtest)
* [`add.reset(node[, parent])`](#addresetnode-parent)
* [Turning off a tokenizer](#turning-off-a-tokenizer)
* [Security](#security)
* [Contribute](#contribute)
* [License](#license)
## API
### `processor.use(parse[, options])`
[See **unified** for API docs »][unified]
Configure the `processor` to read markdown as input and process an
[**MDAST**][mdast] syntax tree.
### `processor().use(parse[, options])`
Configure the `processor` to read Markdown as input and process
[**mdast**][mdast] syntax trees.
##### `options`
Options are passed directly, or passed later through [`processor.data()`][data].
Options can be passed directly, or passed later through
[`processor.data()`][data].
##### `options.gfm`
###### `options.gfm`
```md
GFM mode (`boolean`, default: `true`).
```markdown
hello ~~hi~~ world
```
GFM mode (`boolean`, default: `true`) turns on:
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/creating-and-highlighting-code-blocks#fenced-code-blocks)
* [Autolinking of URLs](https://help.github.com/articles/autolinked-references-and-urls)
* [Deletions (strikethrough)](https://help.github.com/articles/basic-writing-and-formatting-syntax#styling-text)
* [Task lists](https://help.github.com/articles/basic-writing-and-formatting-syntax#task-lists)
* [Tables](https://help.github.com/articles/organizing-information-with-tables)
##### `options.commonmark`
###### `options.commonmark`
```md
CommonMark mode (`boolean`, default: `false`).
```markdown
This is a paragraph
and this is also part of the preceding paragraph.
```
CommonMark mode (`boolean`, default: `false`) allows:
Allows:
* Empty lines to split blockquotes
* Parentheses (`(` and `)`) around for link and image titles
* Any escaped [ASCII-punctuation][escapes] character
* Parentheses (`(` and `)`) around 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:
Disallows:
* Code directly following a paragraph
* ATX-headings (`# Hash headings`) without spacing after opening hashes
or and before closing hashes
* Indented code blocks 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
* White space in link and image URLs in auto-links (links in brackets,
`<` and `>`)
* Lazy blockquote continuation, lines not preceded by a closing angle
bracket (`>`), for lists, code, and thematicBreak
* White space in link and image URLs in auto-links (links in brackets, `<` and
`>`)
* Lazy blockquote continuation, lines not preceded by a greater than character
(`>`), for lists, code, and thematic breaks
##### `options.footnotes`
###### `options.footnotes`
```md
Footnotes mode (`boolean`, default: `false`).
```markdown
Something something[^or something?].
And something else[^1].
@ -113,35 +169,37 @@ And something else[^1].
* ...and a list
```
Footnotes mode (`boolean`, default: `false`) enables reference footnotes and
inline footnotes. Both are wrapped in square brackets and preceded by a caret
(`^`), and can be referenced from inside other footnotes.
Enables reference footnotes and inline footnotes.
Both are wrapped in square brackets and preceded by a caret (`^`), and can be
referenced from inside other footnotes.
##### `options.blocks`
###### `options.pedantic`
```md
Pedantic mode (`boolean`, default: `false`).
```markdown
Check out some_file_name.txt
```
Turns on:
* Emphasis (`_alpha_`) and importance (`__bravo__`) with underscores in words
* Unordered lists with different markers (`*`, `-`, `+`)
* If `commonmark` is also turned on, ordered lists with different markers
(`.`, `)`)
* And removes less spaces in list items (at most four, instead of the whole
indent)
###### `options.blocks`
Blocks (`Array.<string>`, default: list of [block HTML elements][blocks]).
```markdown
<block>foo
</block>
```
Blocks (`Array.<string>`, default: list of [block HTML elements][blocks])
exposes lets users define block-level HTML elements.
##### `options.pedantic`
```md
Check out some_file_name.txt
```
Pedantic mode (`boolean`, default: `false`) turns on:
* Emphasis (`_alpha_`) and importance (`__bravo__`) with underscores
in words
* Unordered lists with different markers (`*`, `-`, `+`)
* If `commonmark` is also turned on, ordered lists with different
markers (`.`, `)`)
* And pedantic mode removes less spaces in list-items (at most four,
instead of the whole indent)
Defines which HTML elements are seen as block level.
### `parse.Parser`
@ -149,46 +207,48 @@ Access to the [parser][], if you need it.
## Extending the Parser
Most often, using transformers to manipulate a syntax tree produces
the desired output. Sometimes, mainly when introducing new syntactic
entities with a certain level of precedence, interfacing with the parser
is necessary.
Typically, using [*transformers*][transformer] to manipulate a syntax tree
produces the desired output.
Sometimes, such as when introducing new syntactic entities with a certain
precedence, interfacing with the parser is necessary.
If the `remark-parse` plugin is used, it adds a [`Parser`][parser] constructor
to the `processor`. Other plugins can add tokenizers to the parsers prototype
to change how markdown is parsed.
function to the `processor`.
Other plugins can add tokenizers to its prototype to change how Markdown is
parsed.
The below plugin adds a [tokenizer][] for at-mentions.
```js
module.exports = mentions;
module.exports = mentions
function mentions() {
var Parser = this.Parser;
var tokenizers = Parser.prototype.inlineTokenizers;
var methods = Parser.prototype.inlineMethods;
var Parser = this.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')
}
```
### `Parser#blockTokenizers`
An object mapping tokenizer names to [tokenizer][]s. These
tokenizers (for example: `fencedCode`, `table`, and `paragraph`) eat
from the start of a value to a line ending.
Map of names to [tokenizer][]s (`Object.<Function>`).
These tokenizers (such as `fencedCode`, `table`, and `paragraph`) eat from the
start of a value to a line ending.
See `#blockMethods` below for a list of methods that are included by
default.
See `#blockMethods` below for a list of methods that are included by default.
### `Parser#blockMethods`
Array of `blockTokenizers` names (`string`) specifying the order in
which they run.
List of `blockTokenizers` names (`Array.<string>`).
Specifies the order in which tokenizers run.
Precedence of default block methods is as follows:
<!--methods-block start-->
@ -210,17 +270,19 @@ which they run.
### `Parser#inlineTokenizers`
An object mapping tokenizer names to [tokenizer][]s. These tokenizers
(for example: `url`, `reference`, and `emphasis`) eat from the start
of a value. To increase performance, they depend on [locator][]s.
Map of names to [tokenizer][]s (`Object.<Function>`).
These tokenizers (such as `url`, `reference`, and `emphasis`) eat from the start
of a value.
To increase performance, they depend on [locator][]s.
See `#inlineMethods` below for a list of methods that are included by
default.
See `#inlineMethods` below for a list of methods that are included by default.
### `Parser#inlineMethods`
Array of `inlineTokenizers` names (`string`) specifying the order in
which they run.
List of `inlineTokenizers` names (`Array.<string>`).
Specifies the order in which tokenizers run.
Precedence of default inline methods is as follows:
<!--methods-inline start-->
@ -241,36 +303,40 @@ which they run.
### `function tokenizer(eat, value, silent)`
There are two types of tokenizers: block level and inline level.
Both are functions, and work the same, but inline tokenizers must have a
[locator][].
The following example shows an inline tokenizer that is added by the mentions
plugin above.
```js
tokenizeMention.notInLink = true;
tokenizeMention.locator = locateMention;
tokenizeMention.notInLink = true
tokenizeMention.locator = locateMention
function tokenizeMention(eat, value, silent) {
var match = /^@(\w+)/.exec(value);
var match = /^@(\w+)/.exec(value)
if (match) {
if (silent) {
return true;
return true
}
return eat(match[0])({
type: 'link',
url: 'https://social-network/' + match[1],
children: [{type: 'text', value: match[0]}]
});
})
}
}
```
The parser knows two types of tokenizers: block level and inline level.
Block level tokenizers are the same as inline level tokenizers, with
the exception that the latter must have a [locator][].
Tokenizers *test* whether a document starts with a certain syntactic entity.
In *silent* mode, they return whether that test passes.
In *normal* mode, they consume that token, a process which is called “eating”.
Tokenizers _test_ whether a document starts with a certain syntactic
entity. In _silent_ mode, they return whether that test passes.
In _normal_ mode, they consume that token, a process which is called
“eating”. Locators enable tokenizers to function faster by providing
information on where the next entity may occur.
Locators enable inline tokenizers to function faster by providing where the next
entity may occur.
###### Signatures
@ -285,36 +351,39 @@ information on where the next entity may occur.
###### Properties
* `locator` ([`Function`][locator])
— Required for inline tokenizers
* `onlyAtStart` (`boolean`)
— 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
* `notInLink` (`boolean`)
— Whether nodes cannot be in links
* `locator` ([`Function`][locator]) — Required for inline tokenizers
* `onlyAtStart` (`boolean`) — 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
* `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`
* `boolean?`, in *silent* mode — whether a node can be found at the start of
`value`
* [`Node?`][node], In *normal* mode — If it can be found at the start of
`value`
### `tokenizer.locator(value, fromIndex)`
Locators are required for inline tokenizers.
Their role is to keep parsing performant.
The following example shows a locator that is added by the mentions tokenizer
above.
```js
function locateMention(value, fromIndex) {
return value.indexOf('@', fromIndex);
return value.indexOf('@', fromIndex)
}
```
Locators are required for inline tokenization to keep the process
performant. Locators enable inline tokenizers to function faster by
providing information on the where the next entity occurs. Locators
may be wrong, its OK if there actually isnt a node to be found at
the index they return, but they must skip any nodes.
Locators enable inline tokenizers to function faster by providing information on
where the next entity *may* occur.
Locators may be wrong, its OK if there actually isnt a node to be found at the
index they return.
###### Parameters
@ -323,21 +392,20 @@ the index they return, but they must skip any nodes.
###### Returns
Index at which an entity may start, and `-1` otherwise.
`number`Index at which an entity may start, and `-1` otherwise.
### `eat(subvalue)`
```js
var add = eat('foo');
var add = eat('foo')
```
Eat `subvalue`, which is a string at the start of the
[tokenize][tokenizer]d `value` (its tracked to ensure the correct
value is eaten).
Eat `subvalue`, which is a string at the start of the [tokenized][tokenizer]
`value`.
###### Parameters
* `subvalue` (`string`) - Value to eat.
* `subvalue` (`string`) - Value to eat
###### Returns
@ -346,60 +414,96 @@ value is eaten).
### `add(node[, parent])`
```js
var add = eat('foo');
add({type: 'text', value: 'foo'});
var add = eat('foo')
add({type: 'text', value: 'foo'})
```
Add [positional information][location] to `node` and add it to `parent`.
Add [positional information][position] to `node` and add `node` to `parent`.
###### Parameters
* `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
* `node` ([`Node`][node]) - Node to patch position on and to add
* `parent` ([`Parent`][parent], optional) - Place to add `node` to in the
syntax tree.
Defaults to the currently processed node
###### Returns
The given `node`.
[`Node`][node] — The given `node`.
### `add.test()`
Get the [positional information][location] which would be patched on
`node` by `add`.
Get the [positional information][position] that would be patched on `node` by
`add`.
###### Returns
[`Location`][location].
[`Position`][position].
### `add.reset(node[, parent])`
`add`, but resets the internal location. Useful for example in
lists, where the same content is first eaten for a list, and later
for list items
`add`, but resets the internal position.
Useful for example in lists, where the same content is first eaten for a list,
and later for list items.
###### Parameters
* `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
The given `node`.
[`Node`][node] — The given node.
### Turning off a tokenizer
In rare situations, you may want to turn off a tokenizer to avoid parsing
that syntactic feature. This can be done by deleting the tokenizer from
your Parsers `blockTokenizers` (or `blockMethods`) or `inlineTokenizers`
(or `inlineMethods`).
In some situations, you may want to turn off a tokenizer to avoid parsing that
syntactic feature.
Preferably, use the [`remark-disable-tokenizers`][remark-disable-tokenizers]
plugin to turn off tokenizers.
Alternatively, this can be done by replacing the tokenizer from
`blockTokenizers` (or `blockMethods`) or `inlineTokenizers` (or
`inlineMethods`).
The following example turns off indented code blocks:
```js
delete remarkParse.Parser.prototype.blockTokenizers.indentedCode;
remarkParse.Parser.prototype.blockTokenizers.indentedCode = indentedCode
function indentedCode() {
return true
}
```
## Security
As Markdown is sometimes used for HTML, and improper use of HTML can open you up
to a [cross-site scripting (XSS)][xss] attack, use of remark can also be unsafe.
When going to HTML, use remark in combination with the [**rehype**][rehype]
ecosystem, and use [`rehype-sanitize`][sanitize] to make the tree safe.
Use of remark plugins could also open you up to other attacks.
Carefully assess each plugin and the risks involved in using them.
## Contribute
See [`contributing.md`][contributing] in [`remarkjs/.github`][health] for ways
to get started.
See [`support.md`][support] for ways to get help.
Ideas for new plugins and tools can be posted in [`remarkjs/ideas`][ideas].
A curated list of awesome remark resources can be found in [**awesome
remark**][awesome].
This project has a [Code of Conduct][coc].
By interacting with this repository, organisation, or community you agree to
abide by its terms.
## License
[MIT][license] © [Titus Wormer][author]
@ -408,19 +512,45 @@ delete remarkParse.Parser.prototype.blockTokenizers.indentedCode;
[build-badge]: https://img.shields.io/travis/remarkjs/remark.svg
[build-status]: https://travis-ci.org/remarkjs/remark
[build]: https://travis-ci.org/remarkjs/remark
[coverage-badge]: https://img.shields.io/codecov/c/github/remarkjs/remark.svg
[coverage-status]: https://codecov.io/github/remarkjs/remark
[coverage]: https://codecov.io/github/remarkjs/remark
[chat-badge]: https://img.shields.io/gitter/room/remarkjs/Lobby.svg
[downloads-badge]: https://img.shields.io/npm/dm/remark-parse.svg
[chat]: https://gitter.im/remarkjs/Lobby
[downloads]: https://www.npmjs.com/package/remark-parse
[license]: https://github.com/remarkjs/remark/blob/master/LICENSE
[size-badge]: https://img.shields.io/bundlephobia/minzip/remark-parse.svg
[author]: http://wooorm.com
[size]: https://bundlephobia.com/result?p=remark-parse
[sponsors-badge]: https://opencollective.com/unified/sponsors/badge.svg
[backers-badge]: https://opencollective.com/unified/backers/badge.svg
[collective]: https://opencollective.com/unified
[chat-badge]: https://img.shields.io/badge/join%20the%20community-on%20spectrum-7b16ff.svg
[chat]: https://spectrum.chat/unified/remark
[health]: https://github.com/remarkjs/.github
[contributing]: https://github.com/remarkjs/.github/blob/master/contributing.md
[support]: https://github.com/remarkjs/.github/blob/master/support.md
[coc]: https://github.com/remarkjs/.github/blob/master/code-of-conduct.md
[ideas]: https://github.com/remarkjs/ideas
[awesome]: https://github.com/remarkjs/awesome-remark
[license]: https://github.com/remarkjs/remark/blob/master/license
[author]: https://wooorm.com
[npm]: https://docs.npmjs.com/cli/install
@ -428,18 +558,24 @@ delete remarkParse.Parser.prototype.blockTokenizers.indentedCode;
[data]: https://github.com/unifiedjs/unified#processordatakey-value
[processor]: https://github.com/unifiedjs/remark/blob/master/packages/remark
[remark]: https://github.com/remarkjs/remark/tree/master/packages/remark
[blocks]: https://github.com/remarkjs/remark/blob/master/packages/remark-parse/lib/block-elements.js
[mdast]: https://github.com/syntax-tree/mdast
[escapes]: http://spec.commonmark.org/0.25/#backslash-escapes
[escapes]: https://spec.commonmark.org/0.29/#backslash-escapes
[node]: https://github.com/syntax-tree/unist#node
[location]: https://github.com/syntax-tree/unist#location
[parent]: https://github.com/syntax-tree/unist#parent
[position]: https://github.com/syntax-tree/unist#position
[parser]: https://github.com/unifiedjs/unified#processorparser
[transformer]: https://github.com/unifiedjs/unified#function-transformernode-file-next
[extend]: #extending-the-parser
[tokenizer]: #function-tokenizereat-value-silent
@ -450,4 +586,12 @@ delete remarkParse.Parser.prototype.blockTokenizers.indentedCode;
[add]: #addnode-parent
[blocks]: https://github.com/remarkjs/remark/blob/master/packages/remark-parse/lib/block-elements.json
[announcement]: https://medium.com/unifiedjs/collectively-evolving-through-crowdsourcing-22c359ea95cc
[remark-disable-tokenizers]: https://github.com/zestedesavoir/zmarkdown/tree/master/packages/remark-disable-tokenizers
[xss]: https://en.wikipedia.org/wiki/Cross-site_scripting
[rehype]: https://github.com/rehypejs/rehype
[sanitize]: https://github.com/rehypejs/rehype-sanitize

View File

@ -1,6 +1,6 @@
{
"name": "eslint-plugin-markdown",
"version": "2.0.1",
"version": "2.1.0",
"description": "An ESLint plugin to lint JavaScript in Markdown code fences.",
"license": "MIT",
"author": {
@ -47,7 +47,7 @@
"nyc": "^14.1.1"
},
"dependencies": {
"remark-parse": "^5.0.0",
"remark-parse": "^7.0.0",
"unified": "^6.1.2"
},
"peerDependencies": {

View File

@ -281,7 +281,7 @@ The following companies, organizations, and individuals support ESLint's ongoing
<!--sponsorsstart-->
<h3>Platinum Sponsors</h3>
<p><a href="https://automattic.com"><img src="https://images.opencollective.com/photomatt/d0ef3e1/logo.png" alt="Automattic" height="undefined"></a></p><h3>Gold Sponsors</h3>
<p><a href="https://nx.dev"><img src="https://images.opencollective.com/nx/0efbe42/logo.png" alt="Nx (by Nrwl)" height="96"></a> <a href="https://google.com/chrome"><img src="https://images.opencollective.com/chrome/dc55bd4/logo.png" alt="Chrome's Web Framework & Tools Performance Fund" height="96"></a> <a href="https://www.shopify.com"><img src="https://images.opencollective.com/shopify/e780cd4/logo.png" alt="Shopify" height="96"></a> <a href="https://www.salesforce.com"><img src="https://images.opencollective.com/salesforce/ca8f997/logo.png" alt="Salesforce" height="96"></a> <a href="https://www.airbnb.com/"><img src="https://images.opencollective.com/airbnb/d327d66/logo.png" alt="Airbnb" height="96"></a> <a href="https://opensource.microsoft.com"><img src="https://avatars.githubusercontent.com/u/6154722?v=4" alt="Microsoft" height="96"></a> <a href="https://substack.com/"><img src="https://avatars.githubusercontent.com/u/53023767?v=4" alt="Substack" height="96"></a></p><h3>Silver Sponsors</h3>
<p><a href="https://nx.dev"><img src="https://images.opencollective.com/nx/0efbe42/logo.png" alt="Nx (by Nrwl)" height="96"></a> <a href="https://google.com/chrome"><img src="https://images.opencollective.com/chrome/dc55bd4/logo.png" alt="Chrome's Web Framework & Tools Performance Fund" height="96"></a> <a href="https://www.salesforce.com"><img src="https://images.opencollective.com/salesforce/ca8f997/logo.png" alt="Salesforce" height="96"></a> <a href="https://www.airbnb.com/"><img src="https://images.opencollective.com/airbnb/d327d66/logo.png" alt="Airbnb" height="96"></a> <a href="https://opensource.microsoft.com"><img src="https://avatars.githubusercontent.com/u/6154722?v=4" alt="Microsoft" height="96"></a> <a href="https://substack.com/"><img src="https://avatars.githubusercontent.com/u/53023767?v=4" alt="Substack" height="96"></a></p><h3>Silver Sponsors</h3>
<p><a href="https://retool.com/"><img src="https://images.opencollective.com/retool/98ea68e/logo.png" alt="Retool" height="64"></a> <a href="https://liftoff.io/"><img src="https://images.opencollective.com/liftoff/5c4fa84/logo.png" alt="Liftoff" height="64"></a></p><h3>Bronze Sponsors</h3>
<p><a href="https://buy.fineproxy.org/eng/"><img src="https://images.opencollective.com/buy-fineproxy-org/b282e39/logo.png" alt="Buy.Fineproxy.Org" height="32"></a> <a href="https://www.crosswordsolver.org/anagram-solver/"><img src="https://images.opencollective.com/anagram-solver/2666271/logo.png" alt="Anagram Solver" height="32"></a> <a href="null"><img src="https://images.opencollective.com/bugsnag-stability-monitoring/c2cef36/logo.png" alt="Bugsnag Stability Monitoring" height="32"></a> <a href="https://mixpanel.com"><img src="https://images.opencollective.com/mixpanel/cd682f7/logo.png" alt="Mixpanel" height="32"></a> <a href="https://www.vpsserver.com"><img src="https://images.opencollective.com/vpsservercom/logo.png" alt="VPS Server" height="32"></a> <a href="https://icons8.com"><img src="https://images.opencollective.com/icons8/7fa1641/logo.png" alt="Icons8: free icons, photos, illustrations, and music" height="32"></a> <a href="https://discord.com"><img src="https://images.opencollective.com/discordapp/7e3d9a9/logo.png" alt="Discord" height="32"></a> <a href="https://themeisle.com"><img src="https://images.opencollective.com/themeisle/d5592fe/logo.png" alt="ThemeIsle" height="32"></a> <a href="https://www.firesticktricks.com"><img src="https://images.opencollective.com/fire-stick-tricks/b8fbe2c/logo.png" alt="Fire Stick Tricks" height="32"></a></p>
<!--sponsorsend-->

View File

@ -27,16 +27,11 @@ const {
naming,
CascadingConfigArrayFactory,
IgnorePattern,
getUsedExtractedConfigs
getUsedExtractedConfigs,
ModuleResolver
}
} = require("@eslint/eslintrc");
/*
* For some reason, ModuleResolver must be included via filepath instead of by
* API exports in order to work properly. That's why this is separated out onto
* its own require() statement.
*/
const ModuleResolver = require("@eslint/eslintrc/lib/shared/relative-module-resolver");
const { FileEnumerator } = require("./file-enumerator");
const { Linter } = require("../linter");

View File

@ -117,6 +117,7 @@ function writeJSConfigFile(config, filePath) {
function write(config, filePath) {
switch (path.extname(filePath)) {
case ".js":
case ".cjs":
writeJSConfigFile(config, filePath);
break;

View File

@ -12,6 +12,7 @@
const util = require("util"),
path = require("path"),
fs = require("fs"),
enquirer = require("enquirer"),
ProgressBar = require("progress"),
semver = require("semver"),
@ -48,6 +49,16 @@ function writeFile(config, format) {
extname = ".yml";
} else if (format === "JSON") {
extname = ".json";
} else if (format === "JavaScript") {
const pkgJSONPath = npmUtils.findPackageJson();
if (pkgJSONPath) {
const pkgJSONContents = JSON.parse(fs.readFileSync(pkgJSONPath, "utf8"));
if (pkgJSONContents.type === "module") {
extname = ".cjs";
}
}
}
const installedESLint = config.installedESLint;
@ -531,7 +542,8 @@ function promptUser() {
choices: [
{ message: "Airbnb: https://github.com/airbnb/javascript", name: "airbnb" },
{ message: "Standard: https://github.com/standard/standard", name: "standard" },
{ message: "Google: https://github.com/google/eslint-config-google", name: "google" }
{ message: "Google: https://github.com/google/eslint-config-google", name: "google" },
{ message: "XO: https://github.com/xojs/eslint-config-xo", name: "xo" }
],
skip() {
this.state.answers.packageJsonExists = npmUtils.checkPackageJson();
@ -683,6 +695,7 @@ const init = {
hasESLintVersionConflict,
installModules,
processAnswers,
writeFile,
/* istanbul ignore next */initializeConfig() {
return promptUser();
}

View File

@ -172,6 +172,7 @@ function checkPackageJson(startDir) {
module.exports = {
installSyncSaveDev,
fetchPeerDependencies,
findPackageJson,
checkDeps,
checkDevDeps,
checkPackageJson

View File

@ -82,7 +82,8 @@ module.exports = {
description: "enforce the consistent use of the radix argument when using `parseInt()`",
category: "Best Practices",
recommended: false,
url: "https://eslint.org/docs/rules/radix"
url: "https://eslint.org/docs/rules/radix",
suggestion: true
},
schema: [
@ -95,7 +96,8 @@ module.exports = {
missingParameters: "Missing parameters.",
redundantRadix: "Redundant radix parameter.",
missingRadix: "Missing radix parameter.",
invalidRadix: "Invalid radix parameter, must be an integer between 2 and 36."
invalidRadix: "Invalid radix parameter, must be an integer between 2 and 36.",
addRadixParameter10: "Add radix parameter `10` for parsing decimal numbers."
}
},
@ -123,7 +125,21 @@ module.exports = {
if (mode === MODE_ALWAYS) {
context.report({
node,
messageId: "missingRadix"
messageId: "missingRadix",
suggest: [
{
messageId: "addRadixParameter10",
fix(fixer) {
const sourceCode = context.getSourceCode();
const tokens = sourceCode.getTokens(node);
const lastToken = tokens[tokens.length - 1]; // Parenthesis.
const secondToLastToken = tokens[tokens.length - 2]; // May or may not be a comma.
const hasTrailingComma = secondToLastToken.type === "Punctuator" && secondToLastToken.value === ",";
return fixer.insertTextBefore(lastToken, hasTrailingComma ? " 10," : ", 10");
}
}
]
});
}
break;

View File

@ -13,6 +13,10 @@
*/
function createReferenceMap(scope, outReferenceMap = new Map()) {
for (const reference of scope.references) {
if (reference.resolved === null) {
continue;
}
outReferenceMap.set(reference.identifier, reference);
}
for (const childScope of scope.childScopes) {
@ -86,42 +90,42 @@ class SegmentInfo {
* @returns {void}
*/
initialize(segment) {
const outdatedReadVariableNames = new Set();
const freshReadVariableNames = new Set();
const outdatedReadVariables = new Set();
const freshReadVariables = new Set();
for (const prevSegment of segment.prevSegments) {
const info = this.info.get(prevSegment);
if (info) {
info.outdatedReadVariableNames.forEach(Set.prototype.add, outdatedReadVariableNames);
info.freshReadVariableNames.forEach(Set.prototype.add, freshReadVariableNames);
info.outdatedReadVariables.forEach(Set.prototype.add, outdatedReadVariables);
info.freshReadVariables.forEach(Set.prototype.add, freshReadVariables);
}
}
this.info.set(segment, { outdatedReadVariableNames, freshReadVariableNames });
this.info.set(segment, { outdatedReadVariables, freshReadVariables });
}
/**
* Mark a given variable as read on given segments.
* @param {PathSegment[]} segments The segments that it read the variable on.
* @param {string} variableName The variable name to be read.
* @param {Variable} variable The variable to be read.
* @returns {void}
*/
markAsRead(segments, variableName) {
markAsRead(segments, variable) {
for (const segment of segments) {
const info = this.info.get(segment);
if (info) {
info.freshReadVariableNames.add(variableName);
info.freshReadVariables.add(variable);
// If a variable is freshly read again, then it's no more out-dated.
info.outdatedReadVariableNames.delete(variableName);
info.outdatedReadVariables.delete(variable);
}
}
}
/**
* Move `freshReadVariableNames` to `outdatedReadVariableNames`.
* Move `freshReadVariables` to `outdatedReadVariables`.
* @param {PathSegment[]} segments The segments to process.
* @returns {void}
*/
@ -130,8 +134,8 @@ class SegmentInfo {
const info = this.info.get(segment);
if (info) {
info.freshReadVariableNames.forEach(Set.prototype.add, info.outdatedReadVariableNames);
info.freshReadVariableNames.clear();
info.freshReadVariables.forEach(Set.prototype.add, info.outdatedReadVariables);
info.freshReadVariables.clear();
}
}
}
@ -139,14 +143,14 @@ class SegmentInfo {
/**
* Check if a given variable is outdated on the current segments.
* @param {PathSegment[]} segments The current segments.
* @param {string} variableName The variable name to check.
* @param {Variable} variable The variable to check.
* @returns {boolean} `true` if the variable is outdated on the segments.
*/
isOutdated(segments, variableName) {
isOutdated(segments, variable) {
for (const segment of segments) {
const info = this.info.get(segment);
if (info && info.outdatedReadVariableNames.has(variableName)) {
if (info && info.outdatedReadVariables.has(variable)) {
return true;
}
}
@ -214,14 +218,13 @@ module.exports = {
if (!reference) {
return;
}
const name = reference.identifier.name;
const variable = reference.resolved;
const writeExpr = getWriteExpr(reference);
const isMemberAccess = reference.identifier.parent.type === "MemberExpression";
// Add a fresh read variable.
if (reference.isRead() && !(writeExpr && writeExpr.parent.operator === "=")) {
segmentInfo.markAsRead(codePath.currentSegments, name);
segmentInfo.markAsRead(codePath.currentSegments, variable);
}
/*
@ -245,7 +248,7 @@ module.exports = {
/*
* Verify assignments.
* If the reference exists in `outdatedReadVariableNames` list, report it.
* If the reference exists in `outdatedReadVariables` list, report it.
*/
":expression:exit"(node) {
const { codePath, referenceMap } = stack;
@ -267,9 +270,9 @@ module.exports = {
assignmentReferences.delete(node);
for (const reference of references) {
const name = reference.identifier.name;
const variable = reference.resolved;
if (segmentInfo.isOutdated(codePath.currentSegments, name)) {
if (segmentInfo.isOutdated(codePath.currentSegments, variable)) {
context.report({
node: node.parent,
messageId: "nonAtomicUpdate",

View File

@ -58,16 +58,23 @@ function isIdentifierChar(code) {
function isIdentifierName(name) {
let isFirst = true;
for (let _i = 0, _Array$from = Array.from(name); _i < _Array$from.length; _i++) {
const char = _Array$from[_i];
const cp = char.codePointAt(0);
for (let i = 0; i < name.length; i++) {
let cp = name.charCodeAt(i);
if ((cp & 0xfc00) === 0xd800 && i + 1 < name.length) {
const trail = name.charCodeAt(++i);
if ((trail & 0xfc00) === 0xdc00) {
cp = 0x10000 + ((cp & 0x3ff) << 10) + (trail & 0x3ff);
}
}
if (isFirst) {
isFirst = false;
if (!isIdentifierStart(cp)) {
return false;
}
isFirst = false;
} else if (!isIdentifierChar(cp)) {
return false;
}

View File

@ -1,6 +1,6 @@
{
"name": "@babel/helper-validator-identifier",
"version": "7.12.11",
"version": "7.14.0",
"description": "Validate identifier/keywords name",
"repository": {
"type": "git",
@ -14,7 +14,9 @@
"main": "./lib/index.js",
"exports": "./lib/index.js",
"devDependencies": {
"charcodes": "^0.2.0",
"unicode-13.0.0": "^0.8.0"
"@babel/helper-validator-identifier-baseline": "npm:@babel/helper-validator-identifier@7.10.4",
"@unicode/unicode-13.0.0": "^1.0.6",
"benchmark": "^2.1.4",
"charcodes": "^0.2.0"
}
}

View File

@ -4,14 +4,14 @@
// https://tc39.github.io/ecma262/#sec-conformance
const version = "13.0.0";
const start = require("unicode-" +
const start = require("@unicode/unicode-" +
version +
"/Binary_Property/ID_Start/code-points.js").filter(function (ch) {
return ch > 0x7f;
});
let last = -1;
const cont = [0x200c, 0x200d].concat(
require("unicode-" +
require("@unicode/unicode-" +
version +
"/Binary_Property/ID_Continue/code-points.js").filter(function (ch) {
return ch > 0x7f && search(start, ch, last + 1) == -1;

View File

@ -1,6 +1,6 @@
{
"name": "@babel/highlight",
"version": "7.13.10",
"version": "7.14.0",
"description": "Syntax highlight JavaScript strings for output in terminals.",
"author": "suchipi <me@suchipi.com>",
"homepage": "https://babel.dev/docs/en/next/babel-highlight",
@ -15,7 +15,7 @@
},
"main": "lib/index.js",
"dependencies": {
"@babel/helper-validator-identifier": "^7.12.11",
"@babel/helper-validator-identifier": "^7.14.0",
"chalk": "^2.0.0",
"js-tokens": "^4.0.0"
},

View File

@ -14,7 +14,7 @@ const {
} = require("./config-array-factory");
const { CascadingConfigArrayFactory } = require("./cascading-config-array-factory");
const { ModuleResolver } = require("./shared/relative-module-resolver");
const ModuleResolver = require("./shared/relative-module-resolver");
const { ConfigArray, getUsedExtractedConfigs } = require("./config-array");
const { ConfigDependency } = require("./config-array/config-dependency");
const { ExtractedConfig } = require("./config-array/extracted-config");

View File

@ -5,6 +5,8 @@
"use strict";
/* eslint class-methods-use-this: "off" */
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------

View File

@ -1,6 +1,6 @@
{
"name": "@eslint/eslintrc",
"version": "0.4.0",
"version": "0.4.1",
"description": "The legacy ESLintRC config file format for ESLint",
"main": "lib/index.js",
"files": [
@ -12,7 +12,8 @@
"access": "public"
},
"scripts": {
"lint": "eslint .",
"lint": "eslint . --report-unused-disable-directives",
"fix": "npm run lint -- --fix",
"test": "mocha -R progress -c 'tests/lib/**/*.js'",
"generate-release": "eslint-generate-release",
"generate-alpharelease": "eslint-generate-prerelease alpha",
@ -34,9 +35,9 @@
"homepage": "https://github.com/eslint/eslintrc#readme",
"devDependencies": {
"chai": "^4.2.0",
"eslint": "^7.7.0",
"eslint-config-eslint": "^6.0.0",
"eslint-plugin-jsdoc": "^22.1.0",
"eslint": "^7.21.0",
"eslint-config-eslint": "^7.0.0",
"eslint-plugin-jsdoc": "^32.2.0",
"eslint-plugin-node": "^11.1.0",
"eslint-release": "^3.1.2",
"fs-teardown": "^0.1.0",

View File

@ -17,7 +17,7 @@ $ npm install eslint-visitor-keys
### Requirements
- [Node.js] 4.0.0 or later.
- [Node.js] 10.0.0 or later.
## 📖 Usage

View File

@ -211,6 +211,7 @@
"ObjectPattern": [
"properties"
],
"PrivateIdentifier": [],
"Program": [
"body"
],
@ -218,6 +219,10 @@
"key",
"value"
],
"PropertyDefinition": [
"key",
"value"
],
"RestElement": [
"argument"
],

View File

@ -1,6 +1,6 @@
{
"name": "eslint-visitor-keys",
"version": "2.0.0",
"version": "2.1.0",
"description": "Constants and utilities about visitor keys to traverse AST.",
"main": "lib/index.js",
"files": [

View File

@ -7,7 +7,7 @@ Match files using the patterns the shell uses, like stars and stuff.
This is a glob implementation in JavaScript. It uses the `minimatch`
library to do its matching.
![](logo/glob.png)
![a fun cartoon logo made of glob characters](logo/glob.png)
## Usage

View File

@ -1,5 +1,3 @@
exports.alphasort = alphasort
exports.alphasorti = alphasorti
exports.setopts = setopts
exports.ownProp = ownProp
exports.makeAbs = makeAbs
@ -17,12 +15,8 @@ var minimatch = require("minimatch")
var isAbsolute = require("path-is-absolute")
var Minimatch = minimatch.Minimatch
function alphasorti (a, b) {
return a.toLowerCase().localeCompare(b.toLowerCase())
}
function alphasort (a, b) {
return a.localeCompare(b)
return a.localeCompare(b, 'en')
}
function setupIgnores (self, options) {
@ -150,7 +144,7 @@ function finish (self) {
all = Object.keys(all)
if (!self.nosort)
all = all.sort(self.nocase ? alphasorti : alphasort)
all = all.sort(alphasort)
// at *some* point we statted all of these
if (self.mark) {

View File

@ -51,8 +51,6 @@ var assert = require('assert')
var isAbsolute = require('path-is-absolute')
var globSync = require('./sync.js')
var common = require('./common.js')
var alphasort = common.alphasort
var alphasorti = common.alphasorti
var setopts = common.setopts
var ownProp = common.ownProp
var inflight = require('inflight')

View File

@ -2,7 +2,7 @@
"author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)",
"name": "glob",
"description": "a little globber",
"version": "7.1.6",
"version": "7.1.7",
"repository": {
"type": "git",
"url": "git://github.com/isaacs/node-glob.git"
@ -27,13 +27,18 @@
"devDependencies": {
"mkdirp": "0",
"rimraf": "^2.2.8",
"tap": "^12.0.1",
"tap": "^15.0.6",
"tick": "0.0.6"
},
"tap": {
"before": "test/00-setup.js",
"after": "test/zz-cleanup.js",
"jobs": 1
},
"scripts": {
"prepublish": "npm run benchclean",
"profclean": "rm -f v8.log profile.txt",
"test": "tap test/*.js --cov",
"test": "tap",
"test-regen": "npm run profclean && TEST_REGEN=1 node test/00-setup.js",
"bench": "bash benchmark.sh",
"prof": "bash prof.sh && cat profile.txt",

View File

@ -11,8 +11,6 @@ var path = require('path')
var assert = require('assert')
var isAbsolute = require('path-is-absolute')
var common = require('./common.js')
var alphasort = common.alphasort
var alphasorti = common.alphasorti
var setopts = common.setopts
var ownProp = common.ownProp
var childrenIgnored = common.childrenIgnored

View File

@ -1,47 +0,0 @@
Copyright jQuery Foundation and other contributors <https://jquery.org/>
Based on Underscore.js, copyright Jeremy Ashkenas,
DocumentCloud and Investigative Reporters & Editors <http://underscorejs.org/>
This software consists of voluntary contributions made by many
individuals. For exact contribution history, see the revision history
available at https://github.com/lodash/lodash
The following license applies to all parts of this software except as
documented below:
====
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
====
Copyright and related rights for sample code are waived via CC0. Sample
code is defined as all source code displayed within the prose of the
documentation.
CC0: http://creativecommons.org/publicdomain/zero/1.0/
====
Files located in the node_modules and vendor directories are externally
maintained libraries used by this software which have their own
licenses; we recommend you read them, as their terms may differ from the
terms above.

View File

@ -1,18 +0,0 @@
# lodash.flatten v4.4.0
The [lodash](https://lodash.com/) method `_.flatten` exported as a [Node.js](https://nodejs.org/) module.
## Installation
Using npm:
```bash
$ {sudo -H} npm i -g npm
$ npm i --save lodash.flatten
```
In Node.js:
```js
var flatten = require('lodash.flatten');
```
See the [documentation](https://lodash.com/docs#flatten) or [package source](https://github.com/lodash/lodash/blob/4.4.0-npm-packages/lodash.flatten) for more details.

View File

@ -1,349 +0,0 @@
/**
* lodash (Custom Build) <https://lodash.com/>
* Build: `lodash modularize exports="npm" -o ./`
* Copyright jQuery Foundation and other contributors <https://jquery.org/>
* Released under MIT license <https://lodash.com/license>
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
* Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
*/
/** Used as references for various `Number` constants. */
var MAX_SAFE_INTEGER = 9007199254740991;
/** `Object#toString` result references. */
var argsTag = '[object Arguments]',
funcTag = '[object Function]',
genTag = '[object GeneratorFunction]';
/** Detect free variable `global` from Node.js. */
var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
/** Detect free variable `self`. */
var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
/** Used as a reference to the global object. */
var root = freeGlobal || freeSelf || Function('return this')();
/**
* Appends the elements of `values` to `array`.
*
* @private
* @param {Array} array The array to modify.
* @param {Array} values The values to append.
* @returns {Array} Returns `array`.
*/
function arrayPush(array, values) {
var index = -1,
length = values.length,
offset = array.length;
while (++index < length) {
array[offset + index] = values[index];
}
return array;
}
/** Used for built-in method references. */
var objectProto = Object.prototype;
/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;
/**
* Used to resolve the
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
* of values.
*/
var objectToString = objectProto.toString;
/** Built-in value references. */
var Symbol = root.Symbol,
propertyIsEnumerable = objectProto.propertyIsEnumerable,
spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined;
/**
* The base implementation of `_.flatten` with support for restricting flattening.
*
* @private
* @param {Array} array The array to flatten.
* @param {number} depth The maximum recursion depth.
* @param {boolean} [predicate=isFlattenable] The function invoked per iteration.
* @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.
* @param {Array} [result=[]] The initial result value.
* @returns {Array} Returns the new flattened array.
*/
function baseFlatten(array, depth, predicate, isStrict, result) {
var index = -1,
length = array.length;
predicate || (predicate = isFlattenable);
result || (result = []);
while (++index < length) {
var value = array[index];
if (depth > 0 && predicate(value)) {
if (depth > 1) {
// Recursively flatten arrays (susceptible to call stack limits).
baseFlatten(value, depth - 1, predicate, isStrict, result);
} else {
arrayPush(result, value);
}
} else if (!isStrict) {
result[result.length] = value;
}
}
return result;
}
/**
* Checks if `value` is a flattenable `arguments` object or array.
*
* @private
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
*/
function isFlattenable(value) {
return isArray(value) || isArguments(value) ||
!!(spreadableSymbol && value && value[spreadableSymbol]);
}
/**
* Flattens `array` a single level deep.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Array
* @param {Array} array The array to flatten.
* @returns {Array} Returns the new flattened array.
* @example
*
* _.flatten([1, [2, [3, [4]], 5]]);
* // => [1, 2, [3, [4]], 5]
*/
function flatten(array) {
var length = array ? array.length : 0;
return length ? baseFlatten(array, 1) : [];
}
/**
* Checks if `value` is likely an `arguments` object.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an `arguments` object,
* else `false`.
* @example
*
* _.isArguments(function() { return arguments; }());
* // => true
*
* _.isArguments([1, 2, 3]);
* // => false
*/
function isArguments(value) {
// Safari 8.1 makes `arguments.callee` enumerable in strict mode.
return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&
(!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);
}
/**
* Checks if `value` is classified as an `Array` object.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an array, else `false`.
* @example
*
* _.isArray([1, 2, 3]);
* // => true
*
* _.isArray(document.body.children);
* // => false
*
* _.isArray('abc');
* // => false
*
* _.isArray(_.noop);
* // => false
*/
var isArray = Array.isArray;
/**
* Checks if `value` is array-like. A value is considered array-like if it's
* not a function and has a `value.length` that's an integer greater than or
* equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is array-like, else `false`.
* @example
*
* _.isArrayLike([1, 2, 3]);
* // => true
*
* _.isArrayLike(document.body.children);
* // => true
*
* _.isArrayLike('abc');
* // => true
*
* _.isArrayLike(_.noop);
* // => false
*/
function isArrayLike(value) {
return value != null && isLength(value.length) && !isFunction(value);
}
/**
* This method is like `_.isArrayLike` except that it also checks if `value`
* is an object.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an array-like object,
* else `false`.
* @example
*
* _.isArrayLikeObject([1, 2, 3]);
* // => true
*
* _.isArrayLikeObject(document.body.children);
* // => true
*
* _.isArrayLikeObject('abc');
* // => false
*
* _.isArrayLikeObject(_.noop);
* // => false
*/
function isArrayLikeObject(value) {
return isObjectLike(value) && isArrayLike(value);
}
/**
* Checks if `value` is classified as a `Function` object.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a function, else `false`.
* @example
*
* _.isFunction(_);
* // => true
*
* _.isFunction(/abc/);
* // => false
*/
function isFunction(value) {
// The use of `Object#toString` avoids issues with the `typeof` operator
// in Safari 8-9 which returns 'object' for typed array and other constructors.
var tag = isObject(value) ? objectToString.call(value) : '';
return tag == funcTag || tag == genTag;
}
/**
* Checks if `value` is a valid array-like length.
*
* **Note:** This method is loosely based on
* [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
* @example
*
* _.isLength(3);
* // => true
*
* _.isLength(Number.MIN_VALUE);
* // => false
*
* _.isLength(Infinity);
* // => false
*
* _.isLength('3');
* // => false
*/
function isLength(value) {
return typeof value == 'number' &&
value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
}
/**
* Checks if `value` is the
* [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
* of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an object, else `false`.
* @example
*
* _.isObject({});
* // => true
*
* _.isObject([1, 2, 3]);
* // => true
*
* _.isObject(_.noop);
* // => true
*
* _.isObject(null);
* // => false
*/
function isObject(value) {
var type = typeof value;
return !!value && (type == 'object' || type == 'function');
}
/**
* Checks if `value` is object-like. A value is object-like if it's not `null`
* and has a `typeof` result of "object".
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is object-like, else `false`.
* @example
*
* _.isObjectLike({});
* // => true
*
* _.isObjectLike([1, 2, 3]);
* // => true
*
* _.isObjectLike(_.noop);
* // => false
*
* _.isObjectLike(null);
* // => false
*/
function isObjectLike(value) {
return !!value && typeof value == 'object';
}
module.exports = flatten;

View File

@ -1,17 +0,0 @@
{
"name": "lodash.flatten",
"version": "4.4.0",
"description": "The lodash method `_.flatten` exported as a module.",
"homepage": "https://lodash.com/",
"icon": "https://lodash.com/icon.svg",
"license": "MIT",
"keywords": "lodash-modularized, flatten",
"author": "John-David Dalton <john.david.dalton@gmail.com> (http://allyoucanleet.com/)",
"contributors": [
"John-David Dalton <john.david.dalton@gmail.com> (http://allyoucanleet.com/)",
"Blaine Bublitz <blaine.bublitz@gmail.com> (https://github.com/phated)",
"Mathias Bynens <mathias@qiwi.be> (https://mathiasbynens.be/)"
],
"repository": "lodash/lodash",
"scripts": { "test": "echo \"See https://travis-ci.org/lodash/lodash-cli for testing details.\"" }
}

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.alignString = void 0;
const string_width_1 = __importDefault(require("string-width"));
const utils_1 = require("./utils");
const alignLeft = (subject, width) => {
return subject + ' '.repeat(width);
};
@ -11,25 +13,31 @@ const alignRight = (subject, width) => {
return ' '.repeat(width) + subject;
};
const alignCenter = (subject, width) => {
let halfWidth;
halfWidth = width / 2;
if (width % 2 === 0) {
return ' '.repeat(halfWidth) + subject + ' '.repeat(halfWidth);
return ' '.repeat(Math.floor(width / 2)) + subject + ' '.repeat(Math.ceil(width / 2));
};
const alignJustify = (subject, width) => {
const spaceSequenceCount = utils_1.countSpaceSequence(subject);
if (spaceSequenceCount === 0) {
return alignLeft(subject, width);
}
else {
halfWidth = Math.floor(halfWidth);
return ' '.repeat(halfWidth) + subject + ' '.repeat(halfWidth + 1);
const addingSpaces = utils_1.distributeUnevenly(width, spaceSequenceCount);
if (Math.max(...addingSpaces) > 3) {
return alignLeft(subject, width);
}
let spaceSequenceIndex = 0;
return subject.replace(/\s+/g, (groupSpace) => {
return groupSpace + ' '.repeat(addingSpaces[spaceSequenceIndex++]);
});
};
/**
* Pads a string to the left and/or right to position the subject
* text in a desired alignment within a container.
*/
exports.default = (subject, containerWidth, alignment) => {
if (typeof subject !== 'string') {
throw new TypeError('Subject parameter value must be a string.');
}
const alignString = (subject, containerWidth, alignment) => {
const subjectWidth = string_width_1.default(subject);
if (subjectWidth === containerWidth) {
return subject;
}
if (subjectWidth > containerWidth) {
throw new Error('Subject parameter value width cannot be greater than the container width.');
}
@ -43,5 +51,9 @@ exports.default = (subject, containerWidth, alignment) => {
if (alignment === 'right') {
return alignRight(subject, availableWidth);
}
if (alignment === 'justify') {
return alignJustify(subject, availableWidth);
}
return alignCenter(subject, availableWidth);
};
exports.alignString = alignString;

View File

@ -1,20 +1,13 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const string_width_1 = __importDefault(require("string-width"));
const alignString_1 = __importDefault(require("./alignString"));
exports.default = (rows, config) => {
exports.alignTableData = void 0;
const alignString_1 = require("./alignString");
const alignTableData = (rows, config) => {
return rows.map((row) => {
return row.map((cell, index) => {
const column = config.columns[index];
if (string_width_1.default(cell) === column.width) {
return cell;
}
else {
return alignString_1.default(cell, column.width, column.alignment);
}
return row.map((cell, cellIndex) => {
const { width, alignment } = config.columns[cellIndex];
return alignString_1.alignString(cell, width, alignment);
});
});
};
exports.alignTableData = alignTableData;

View File

@ -1,12 +1,11 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const wrapCell_1 = __importDefault(require("./wrapCell"));
exports.default = (value, columnWidth, useWrapWord = false) => {
if (typeof value !== 'string') {
throw new TypeError('Value must be a string.');
}
return wrapCell_1.default(value, columnWidth, useWrapWord).length;
exports.calculateCellHeight = void 0;
const wrapCell_1 = require("./wrapCell");
/**
* Calculates height of cell content in regard to its width and word wrapping.
*/
const calculateCellHeight = (value, columnWidth, useWrapWord = false) => {
return wrapCell_1.wrapCell(value, columnWidth, useWrapWord).length;
};
exports.calculateCellHeight = calculateCellHeight;

View File

@ -3,14 +3,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.calculateCellWidths = void 0;
const string_width_1 = __importDefault(require("string-width"));
/**
* Calculates width of each cell contents.
* Calculates width of each cell contents in a row.
*/
exports.default = (cells) => {
return cells.map((value) => {
return Math.max(...value.split('\n').map((line) => {
return string_width_1.default(line);
}));
const calculateCellWidths = (cells) => {
return cells.map((cell) => {
return Math.max(...cell.split('\n').map(string_width_1.default));
});
};
exports.calculateCellWidths = calculateCellWidths;

View File

@ -0,0 +1,16 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const calculateCellWidths_1 = require("./calculateCellWidths");
/**
* Produces an array of values that describe the largest value length (width) in every column.
*/
exports.default = (rows) => {
const columnWidths = new Array(rows[0].length).fill(0);
rows.forEach((row) => {
const cellWidths = calculateCellWidths_1.calculateCellWidths(row);
cellWidths.forEach((cellWidth, cellIndex) => {
columnWidths[cellIndex] = Math.max(columnWidths[cellIndex], cellWidth);
});
});
return columnWidths;
};

View File

@ -1,24 +0,0 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const calculateCellWidthIndex_1 = __importDefault(require("./calculateCellWidthIndex"));
/**
* Produces an array of values that describe the largest value length (width) in every column.
*/
exports.default = (rows) => {
if (!rows[0]) {
throw new Error('Dataset must have at least one row.');
}
const columns = new Array(rows[0].length).fill(0);
rows.forEach((row) => {
const columnWidthIndex = calculateCellWidthIndex_1.default(row);
columnWidthIndex.forEach((valueWidth, index0) => {
if (columns[index0] < valueWidth) {
columns[index0] = valueWidth;
}
});
});
return columns;
};

View File

@ -1,21 +0,0 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const calculateCellHeight_1 = __importDefault(require("./calculateCellHeight"));
/**
* Calculates the vertical row span index.
*/
exports.default = (rows, config) => {
const tableWidth = rows[0].length;
const rowSpanIndex = [];
rows.forEach((cells) => {
const cellHeightIndex = new Array(tableWidth).fill(1);
cells.forEach((value, index1) => {
cellHeightIndex[index1] = calculateCellHeight_1.default(value, config.columns[index1].width, config.columns[index1].wrapWord);
});
rowSpanIndex.push(Math.max(...cellHeightIndex));
});
return rowSpanIndex;
};

View File

@ -0,0 +1,18 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.calculateRowHeights = void 0;
const calculateCellHeight_1 = require("./calculateCellHeight");
/**
* Produces an array of values that describe the largest value length (height) in every row.
*/
const calculateRowHeights = (rows, config) => {
return rows.map((row) => {
let rowHeight = 1;
row.forEach((cell, cellIndex) => {
const cellHeight = calculateCellHeight_1.calculateCellHeight(cell, config.columns[cellIndex].width, config.columns[cellIndex].wrapWord);
rowHeight = Math.max(rowHeight, cellHeight);
});
return rowHeight;
});
};
exports.calculateRowHeights = calculateRowHeights;

View File

@ -1,58 +1,56 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const alignTableData_1 = __importDefault(require("./alignTableData"));
const calculateRowHeightIndex_1 = __importDefault(require("./calculateRowHeightIndex"));
exports.createStream = void 0;
const alignTableData_1 = require("./alignTableData");
const calculateRowHeights_1 = require("./calculateRowHeights");
const drawBorder_1 = require("./drawBorder");
const drawRow_1 = __importDefault(require("./drawRow"));
const makeStreamConfig_1 = __importDefault(require("./makeStreamConfig"));
const mapDataUsingRowHeightIndex_1 = __importDefault(require("./mapDataUsingRowHeightIndex"));
const padTableData_1 = __importDefault(require("./padTableData"));
const stringifyTableData_1 = __importDefault(require("./stringifyTableData"));
const truncateTableData_1 = __importDefault(require("./truncateTableData"));
const drawRow_1 = require("./drawRow");
const makeStreamConfig_1 = require("./makeStreamConfig");
const mapDataUsingRowHeights_1 = require("./mapDataUsingRowHeights");
const padTableData_1 = require("./padTableData");
const stringifyTableData_1 = require("./stringifyTableData");
const truncateTableData_1 = require("./truncateTableData");
const prepareData = (data, config) => {
let rows = stringifyTableData_1.default(data);
rows = truncateTableData_1.default(rows, config);
const rowHeightIndex = calculateRowHeightIndex_1.default(rows, config);
rows = mapDataUsingRowHeightIndex_1.default(rows, rowHeightIndex, config);
rows = alignTableData_1.default(rows, config);
rows = padTableData_1.default(rows, config);
let rows = stringifyTableData_1.stringifyTableData(data);
rows = truncateTableData_1.truncateTableData(rows, config);
const rowHeights = calculateRowHeights_1.calculateRowHeights(rows, config);
rows = mapDataUsingRowHeights_1.mapDataUsingRowHeights(rows, rowHeights, config);
rows = alignTableData_1.alignTableData(rows, config);
rows = padTableData_1.padTableData(rows, config);
return rows;
};
const create = (row, columnWidthIndex, config) => {
const create = (row, columnWidths, config) => {
const rows = prepareData([row], config);
const body = rows.map((literalRow) => {
return drawRow_1.default(literalRow, config);
return drawRow_1.drawRow(literalRow, config);
}).join('');
let output;
output = '';
output += drawBorder_1.drawBorderTop(columnWidthIndex, config);
output += drawBorder_1.drawBorderTop(columnWidths, config);
output += body;
output += drawBorder_1.drawBorderBottom(columnWidthIndex, config);
output += drawBorder_1.drawBorderBottom(columnWidths, config);
output = output.trimEnd();
process.stdout.write(output);
};
const append = (row, columnWidthIndex, config) => {
const append = (row, columnWidths, config) => {
const rows = prepareData([row], config);
const body = rows.map((literalRow) => {
return drawRow_1.default(literalRow, config);
return drawRow_1.drawRow(literalRow, config);
}).join('');
let output = '';
const bottom = drawBorder_1.drawBorderBottom(columnWidthIndex, config);
const bottom = drawBorder_1.drawBorderBottom(columnWidths, config);
if (bottom !== '\n') {
output = '\r\u001B[K';
}
output += drawBorder_1.drawBorderJoin(columnWidthIndex, config);
output += drawBorder_1.drawBorderJoin(columnWidths, config);
output += body;
output += bottom;
output = output.trimEnd();
process.stdout.write(output);
};
exports.default = (userConfig) => {
const config = makeStreamConfig_1.default(userConfig);
const columnWidthIndex = Object.values(config.columns).map((column) => {
const createStream = (userConfig) => {
const config = makeStreamConfig_1.makeStreamConfig(userConfig);
const columnWidths = Object.values(config.columns).map((column) => {
return column.width + column.paddingLeft + column.paddingRight;
});
let empty = true;
@ -63,11 +61,12 @@ exports.default = (userConfig) => {
}
if (empty) {
empty = false;
create(row, columnWidthIndex, config);
create(row, columnWidths, config);
}
else {
append(row, columnWidthIndex, config);
append(row, columnWidths, config);
}
},
};
};
exports.createStream = createStream;

View File

@ -1,19 +1,28 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.drawBorderTop = exports.drawBorderJoin = exports.drawBorderBottom = exports.drawBorder = void 0;
const drawHorizontalContent_1 = __importDefault(require("./drawHorizontalContent"));
const drawBorder = (columnSizeIndex, config) => {
const columns = columnSizeIndex.map((size) => {
exports.drawBorderTop = exports.drawBorderJoin = exports.drawBorderBottom = exports.drawBorder = exports.createTableBorderGetter = void 0;
const drawContent_1 = require("./drawContent");
const drawBorder = (columnWidths, config) => {
const { separator, drawVerticalLine } = config;
const columns = columnWidths.map((size) => {
return config.separator.body.repeat(size);
});
return drawHorizontalContent_1.default(columns, config);
return drawContent_1.drawContent(columns, {
drawSeparator: drawVerticalLine,
separatorGetter: (index, columnCount) => {
if (index === 0) {
return separator.left;
}
if (index === columnCount) {
return separator.right;
}
return separator.join;
},
}) + '\n';
};
exports.drawBorder = drawBorder;
const drawBorderTop = (columnSizeIndex, config) => {
const result = drawBorder(columnSizeIndex, {
const drawBorderTop = (columnWidths, config) => {
const result = drawBorder(columnWidths, {
...config,
separator: {
body: config.border.topBody,
@ -28,8 +37,8 @@ const drawBorderTop = (columnSizeIndex, config) => {
return result;
};
exports.drawBorderTop = drawBorderTop;
const drawBorderJoin = (columnSizeIndex, config) => {
return drawBorder(columnSizeIndex, {
const drawBorderJoin = (columnWidths, config) => {
return drawBorder(columnWidths, {
...config,
separator: {
body: config.border.joinBody,
@ -40,8 +49,8 @@ const drawBorderJoin = (columnSizeIndex, config) => {
});
};
exports.drawBorderJoin = drawBorderJoin;
const drawBorderBottom = (columnSizeIndex, config) => {
return drawBorder(columnSizeIndex, {
const drawBorderBottom = (columnWidths, config) => {
return drawBorder(columnWidths, {
...config,
separator: {
body: config.border.bottomBody,
@ -52,3 +61,40 @@ const drawBorderBottom = (columnSizeIndex, config) => {
});
};
exports.drawBorderBottom = drawBorderBottom;
const createTableBorderGetter = (columnWidths, config) => {
return (index, size) => {
if (!config.header) {
if (index === 0) {
return drawBorderTop(columnWidths, config);
}
if (index === size) {
return drawBorderBottom(columnWidths, config);
}
return drawBorderJoin(columnWidths, config);
}
// Deal with the header
if (index === 0) {
return drawBorderTop(columnWidths, {
...config,
border: {
...config.border,
topJoin: config.border.topBody,
},
});
}
if (index === 1) {
return drawBorderJoin(columnWidths, {
...config,
border: {
...config.border,
joinJoin: config.border.headerJoin,
},
});
}
if (index === size) {
return drawBorderBottom(columnWidths, config);
}
return drawBorderJoin(columnWidths, config);
};
};
exports.createTableBorderGetter = createTableBorderGetter;

View File

@ -0,0 +1,26 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.drawContent = void 0;
/**
* Shared function to draw horizontal borders, rows or the entire table
*/
const drawContent = (contents, separatorConfig) => {
const { separatorGetter, drawSeparator } = separatorConfig;
const contentSize = contents.length;
const result = [];
if (drawSeparator(0, contentSize)) {
result.push(separatorGetter(0, contentSize));
}
contents.forEach((content, contentIndex) => {
result.push(content);
// Only append the middle separator if the content is not the last
if (contentIndex + 1 < contentSize && drawSeparator(contentIndex + 1, contentSize)) {
result.push(separatorGetter(contentIndex + 1, contentSize));
}
});
if (drawSeparator(contentSize, contentSize)) {
result.push(separatorGetter(contentSize, contentSize));
}
return result.join('');
};
exports.drawContent = drawContent;

View File

@ -0,0 +1,29 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.drawHeader = void 0;
const alignString_1 = require("./alignString");
const drawRow_1 = require("./drawRow");
const padTableData_1 = require("./padTableData");
const truncateTableData_1 = require("./truncateTableData");
const wrapCell_1 = require("./wrapCell");
const drawHeader = (width, config) => {
if (!config.header) {
throw new Error('Can not draw header without header configuration');
}
const { alignment, paddingRight, paddingLeft, wrapWord } = config.header;
let content = config.header.content;
content = truncateTableData_1.truncateString(content, config.header.truncate);
const headerLines = wrapCell_1.wrapCell(content, width, wrapWord);
return headerLines.map((headerLine) => {
let line = alignString_1.alignString(headerLine, width, alignment);
line = padTableData_1.padString(line, paddingLeft, paddingRight);
return drawRow_1.drawRow([line], {
...config,
drawVerticalLine: (index) => {
const columnCount = config.columns.length;
return config.drawVerticalLine(index === 0 ? 0 : columnCount, columnCount);
},
});
}).join('');
};
exports.drawHeader = drawHeader;

View File

@ -1,18 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function drawHorizontalContent(contents, config) {
const { separator, drawVerticalLine } = config;
const contentSize = contents.length;
const result = [];
result.push(drawVerticalLine(0, contentSize) ? separator.left : '');
contents.forEach((content, index) => {
result.push(content);
// Only append the join separator if it is not the last content
if (index + 1 < contentSize) {
result.push(drawVerticalLine(index + 1, contentSize) ? separator.join : '');
}
});
result.push(drawVerticalLine(contentSize, contentSize) ? separator.right : '');
return result.join('') + '\n';
}
exports.default = drawHorizontalContent;

View File

@ -1,16 +1,20 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const drawHorizontalContent_1 = __importDefault(require("./drawHorizontalContent"));
exports.default = (row, config) => {
return drawHorizontalContent_1.default(row, {
...config,
separator: {
join: config.border.bodyJoin,
left: config.border.bodyLeft,
right: config.border.bodyRight,
exports.drawRow = void 0;
const drawContent_1 = require("./drawContent");
const drawRow = (row, config) => {
const { border, drawVerticalLine } = config;
return drawContent_1.drawContent(row, {
drawSeparator: drawVerticalLine,
separatorGetter: (index, columnCount) => {
if (index === 0) {
return border.bodyLeft;
}
if (index === columnCount) {
return border.bodyRight;
}
return border.bodyJoin;
},
});
}) + '\n';
};
exports.drawRow = drawRow;

View File

@ -3,46 +3,36 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.drawTable = void 0;
const string_width_1 = __importDefault(require("string-width"));
const drawBorder_1 = require("./drawBorder");
const drawRow_1 = __importDefault(require("./drawRow"));
/**
* Group the array into sub-arrays by sizes.
*
* @example
* chunkBySizes(['a', 'b', 'c', 'd', 'e'], [2, 1, 2]) = [ ['a', 'b'], ['c'], ['d', 'e'] ]
*/
const groupBySizes = (array, sizes) => {
let startIndex = 0;
return sizes.map((rowHeight) => {
const chunk = array.slice(startIndex, startIndex + rowHeight);
startIndex += rowHeight;
return chunk;
});
};
const shouldDrawBorderJoin = (rowIndex, rowCount, config) => {
const { singleLine, drawHorizontalLine } = config;
return !singleLine && rowIndex + 1 < rowCount && drawHorizontalLine(rowIndex + 1, rowCount);
};
exports.default = (rows, columnWidths, rowHeights, config) => {
const { drawHorizontalLine, } = config;
const groupedRows = groupBySizes(rows, rowHeights).map((group) => {
const drawContent_1 = require("./drawContent");
const drawHeader_1 = require("./drawHeader");
const drawRow_1 = require("./drawRow");
const utils_1 = require("./utils");
const drawTable = (rows, columnWidths, rowHeights, config) => {
const { drawHorizontalLine, singleLine, } = config;
const contents = utils_1.groupBySizes(rows, rowHeights).map((group) => {
return group.map((row) => {
return drawRow_1.default(row, config);
return drawRow_1.drawRow(row, config);
}).join('');
});
const rowCount = groupedRows.length;
let output = '';
if (drawHorizontalLine(0, rowCount)) {
output += drawBorder_1.drawBorderTop(columnWidths, config);
if (config.header) {
// assume that topLeft/right border have width = 1
const headerWidth = string_width_1.default(drawRow_1.drawRow(rows[0], config)) - 2 -
config.header.paddingLeft - config.header.paddingRight;
const header = drawHeader_1.drawHeader(headerWidth, config);
contents.unshift(header);
}
groupedRows.forEach((row, rowIndex) => {
output += row;
if (shouldDrawBorderJoin(rowIndex, rowCount, config)) {
output += drawBorder_1.drawBorderJoin(columnWidths, config);
}
return drawContent_1.drawContent(contents, {
drawSeparator: (index, size) => {
// Top/bottom border
if (index === 0 || index === size) {
return drawHorizontalLine(index, size);
}
return !singleLine && drawHorizontalLine(index, size);
},
separatorGetter: drawBorder_1.createTableBorderGetter(columnWidths, config),
});
if (drawHorizontalLine(rowCount, rowCount)) {
output += drawBorder_1.drawBorderBottom(columnWidths, config);
}
return output;
};
exports.drawTable = drawTable;

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,8 @@
"use strict";
/* eslint-disable sort-keys-fix/sort-keys-fix */
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = (name) => {
exports.getBorderCharacters = void 0;
const getBorderCharacters = (name) => {
if (name === 'honeywell') {
return {
topBody: '═',
@ -15,6 +16,7 @@ exports.default = (name) => {
bodyLeft: '║',
bodyRight: '║',
bodyJoin: '│',
headerJoin: '┬',
joinBody: '─',
joinLeft: '╟',
joinRight: '╢',
@ -34,6 +36,7 @@ exports.default = (name) => {
bodyLeft: '│',
bodyRight: '│',
bodyJoin: '│',
headerJoin: '┬',
joinBody: '─',
joinLeft: '├',
joinRight: '┤',
@ -53,6 +56,7 @@ exports.default = (name) => {
bodyLeft: '|',
bodyRight: '|',
bodyJoin: '|',
headerJoin: '+',
joinBody: '-',
joinLeft: '|',
joinRight: '|',
@ -72,6 +76,7 @@ exports.default = (name) => {
bodyLeft: '',
bodyRight: '',
bodyJoin: '',
headerJoin: '',
joinBody: '',
joinLeft: '',
joinRight: '',
@ -80,3 +85,4 @@ exports.default = (name) => {
}
throw new Error('Unknown border template "' + name + '".');
};
exports.getBorderCharacters = getBorderCharacters;

View File

@ -9,15 +9,13 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (functi
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getBorderCharacters = exports.createStream = exports.table = void 0;
const createStream_1 = __importDefault(require("./createStream"));
exports.createStream = createStream_1.default;
const getBorderCharacters_1 = __importDefault(require("./getBorderCharacters"));
exports.getBorderCharacters = getBorderCharacters_1.default;
const table_1 = __importDefault(require("./table"));
exports.table = table_1.default;
// import chalk from 'chalk';
const createStream_1 = require("./createStream");
Object.defineProperty(exports, "createStream", { enumerable: true, get: function () { return createStream_1.createStream; } });
const getBorderCharacters_1 = require("./getBorderCharacters");
Object.defineProperty(exports, "getBorderCharacters", { enumerable: true, get: function () { return getBorderCharacters_1.getBorderCharacters; } });
const table_1 = require("./table");
Object.defineProperty(exports, "table", { enumerable: true, get: function () { return table_1.table; } });
__exportStar(require("./types/api"), exports);

View File

@ -3,30 +3,22 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.makeStreamConfig = void 0;
const lodash_clonedeep_1 = __importDefault(require("lodash.clonedeep"));
const getBorderCharacters_1 = __importDefault(require("./getBorderCharacters"));
const validateConfig_1 = __importDefault(require("./validateConfig"));
/**
* Merges user provided border characters with the default border ("honeywell") characters.
*
*/
const makeBorder = (border) => {
return {
...getBorderCharacters_1.default('honeywell'),
...border,
};
};
const utils_1 = require("./utils");
const validateConfig_1 = require("./validateConfig");
/**
* Creates a configuration for every column using default
* values for the missing configuration properties.
*/
const makeColumns = (columnCount, columns = {}, columnDefault) => {
const makeColumnsConfig = (columnCount, columns = {}, columnDefault) => {
return Array.from({ length: columnCount }).map((_, index) => {
return {
alignment: 'left',
paddingLeft: 1,
paddingRight: 1,
truncate: Number.POSITIVE_INFINITY,
verticalAlignment: 'top',
wrapWord: false,
...columnDefault,
...columns[index],
@ -37,23 +29,19 @@ const makeColumns = (columnCount, columns = {}, columnDefault) => {
* Makes a new configuration object out of the userConfig object
* using default values for the missing configuration properties.
*/
exports.default = (userConfig) => {
var _a;
validateConfig_1.default('streamConfig.json', userConfig);
const makeStreamConfig = (userConfig) => {
validateConfig_1.validateConfig('streamConfig.json', userConfig);
const config = lodash_clonedeep_1.default(userConfig);
if (!config.columnDefault || !config.columnDefault.width) {
if (config.columnDefault.width === undefined) {
throw new Error('Must provide config.columnDefault.width when creating a stream.');
}
if (!config.columnCount) {
throw new Error('Must provide config.columnCount.');
}
return {
...config,
border: makeBorder(config.border),
columnCount: config.columnCount,
columns: makeColumns(config.columnCount, config.columns, config.columnDefault),
drawVerticalLine: (_a = config.drawVerticalLine) !== null && _a !== void 0 ? _a : (() => {
drawVerticalLine: () => {
return true;
}),
},
...config,
border: utils_1.makeBorderConfig(config.border),
columns: makeColumnsConfig(config.columnCount, config.columns, config.columnDefault),
};
};
exports.makeStreamConfig = makeStreamConfig;

View File

@ -3,56 +3,64 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.makeTableConfig = void 0;
const lodash_clonedeep_1 = __importDefault(require("lodash.clonedeep"));
const calculateMaximumColumnWidthIndex_1 = __importDefault(require("./calculateMaximumColumnWidthIndex"));
const getBorderCharacters_1 = __importDefault(require("./getBorderCharacters"));
const validateConfig_1 = __importDefault(require("./validateConfig"));
/**
* Merges user provided border characters with the default border ("honeywell") characters.
*/
const makeBorder = (border) => {
return {
...getBorderCharacters_1.default('honeywell'),
...border,
};
};
const calculateColumnWidths_1 = __importDefault(require("./calculateColumnWidths"));
const utils_1 = require("./utils");
const validateConfig_1 = require("./validateConfig");
/**
* Creates a configuration for every column using default
* values for the missing configuration properties.
*/
const makeColumns = (rows, columns, columnDefault) => {
const maximumColumnWidthIndex = calculateMaximumColumnWidthIndex_1.default(rows);
return rows[0].map((_cell, index) => {
const makeColumnsConfig = (rows, columns, columnDefault) => {
const columnWidths = calculateColumnWidths_1.default(rows);
return rows[0].map((_, columnIndex) => {
return {
alignment: 'left',
paddingLeft: 1,
paddingRight: 1,
truncate: Number.POSITIVE_INFINITY,
width: maximumColumnWidthIndex[index],
verticalAlignment: 'top',
width: columnWidths[columnIndex],
wrapWord: false,
...columnDefault,
...columns === null || columns === void 0 ? void 0 : columns[index],
...columns === null || columns === void 0 ? void 0 : columns[columnIndex],
};
});
};
const makeHeaderConfig = (config) => {
if (!config.header) {
return undefined;
}
return {
alignment: 'center',
paddingLeft: 1,
paddingRight: 1,
truncate: Number.POSITIVE_INFINITY,
wrapWord: false,
...config.header,
};
};
/**
* Makes a new configuration object out of the userConfig object
* using default values for the missing configuration properties.
*/
exports.default = (rows, userConfig = {}) => {
const makeTableConfig = (rows, userConfig = {}) => {
var _a, _b, _c;
validateConfig_1.default('config.json', userConfig);
validateConfig_1.validateConfig('config.json', userConfig);
const config = lodash_clonedeep_1.default(userConfig);
return {
...config,
border: makeBorder(config.border),
columns: makeColumns(rows, config.columns, config.columnDefault),
border: utils_1.makeBorderConfig(config.border),
columns: makeColumnsConfig(rows, config.columns, config.columnDefault),
drawHorizontalLine: (_a = config.drawHorizontalLine) !== null && _a !== void 0 ? _a : (() => {
return true;
}),
drawVerticalLine: (_b = config.drawVerticalLine) !== null && _b !== void 0 ? _b : (() => {
return true;
}),
header: makeHeaderConfig(config),
singleLine: (_c = config.singleLine) !== null && _c !== void 0 ? _c : false,
};
};
exports.makeTableConfig = makeTableConfig;

Some files were not shown because too many files have changed in this diff Show More