function processor() {
var destination = unified();
var length = attachers.length;
var index = -1;
while (++index < length) {
destination.use.apply(null, attachers[index]);
}
destination.data(extend(true, {}, namespace));
return destination;
}n/a
function Of() {
if (!(this instanceof Of)) {
return new From(arguments);
}
return Super.apply(this, arguments);
}n/a
function Compiler(tree, file) {
this.inLink = this.inTable = false;
this.tree = tree;
this.file = file;
this.options = xtend(this.options);
this.setOptions({});
}n/a
function Of() {
if (!(this instanceof Of)) {
return new From(arguments);
}
return Super.apply(this, arguments);
}n/a
function Parser(doc, file) {
this.file = file;
this.offset = {};
this.options = xtend(this.options);
this.setOptions({});
this.inList = this.inBlock = this.inLink = false;
this.atStart = true;
this.toOffset = vfileLocation(file).toOffset;
this.unescape = unescape(this, 'escape');
this.decode = decode(this);
}n/a
function data(key, value) {
if (string(key)) {
/* Set `key`. */
if (arguments.length === 2) {
assertUnfrozen('data', frozen);
namespace[key] = value;
return processor;
}
/* Get `key`. */
return (has(namespace, key) && namespace[key]) || null;
}
/* Set space. */
if (key) {
assertUnfrozen('data', frozen);
namespace = key;
return processor;
}
/* Get space. */
return namespace;
}n/a
function freeze() {
var values;
var plugin;
var options;
var transformer;
if (frozen) {
return processor;
}
while (++freezeIndex < attachers.length) {
values = attachers[freezeIndex];
plugin = values[0];
options = values[1];
transformer = null;
if (options === false) {
continue;
}
if (options === true) {
values[1] = undefined;
}
transformer = plugin.apply(processor, values.slice(1));
if (func(transformer)) {
transformers.use(transformer);
}
}
frozen = true;
freezeIndex = Infinity;
return processor;
}...
'use strict';
var unified = require('unified');
var parse = require('remark-parse');
var stringify = require('remark-stringify');
module.exports = unified().use(parse).use(stringify).freeze();
...function processor() {
var destination = unified();
var length = attachers.length;
var index = -1;
while (++index < length) {
destination.use.apply(null, attachers[index]);
}
destination.data(extend(true, {}, namespace));
return destination;
}n/a
function parse(doc) {
var file = vfile(doc);
var Parser;
freeze();
Parser = processor.Parser;
assertParser('parse', Parser);
if (newable(Parser)) {
return new Parser(String(file), file).parse();
}
return Parser(String(file), file); // eslint-disable-line new-cap
}n/a
function process(doc, cb) {
freeze();
assertParser('process', processor.Parser);
assertCompiler('process', processor.Compiler);
if (!cb) {
return new Promise(executor);
}
executor(null, cb);
function executor(resolve, reject) {
var file = vfile(doc);
pipeline.run(processor, {file: file}, done);
function done(err) {
if (err) {
reject(err);
} else if (resolve) {
resolve(file);
} else {
cb(null, file);
}
}
}
}...
```js
var remark = require('remark');
var lint = require('remark-lint');
var html = require('remark-html');
var report = require('vfile-reporter');
remark().use(lint).use(html).process('## Hello world!', function (err, file
) {
console.error(report(err || file));
console.log(String(file));
});
```
Yields:
...function processSync(doc) {
var complete = false;
var file;
freeze();
assertParser('processSync', processor.Parser);
assertCompiler('processSync', processor.Compiler);
file = vfile(doc);
process(file, done);
assertDone('processSync', 'process', complete);
return file;
function done(err) {
complete = true;
bail(err);
}
}n/a
function run(node, file, cb) {
assertNode(node);
freeze();
if (!cb && func(file)) {
cb = file;
file = null;
}
if (!cb) {
return new Promise(executor);
}
executor(null, cb);
function executor(resolve, reject) {
transformers.run(node, vfile(file), done);
function done(err, tree, file) {
tree = tree || node;
if (err) {
reject(err);
} else if (resolve) {
resolve(tree);
} else {
cb(null, tree, file);
}
}
}
}n/a
function runSync(node, file) {
var complete = false;
var result;
run(node, file, done);
assertDone('runSync', 'run', complete);
return result;
function done(err, tree) {
complete = true;
bail(err);
result = tree;
}
}n/a
function stringify(node, doc) {
var file = vfile(doc);
var Compiler;
freeze();
Compiler = processor.Compiler;
assertCompiler('stringify', Compiler);
assertNode(node);
if (newable(Compiler)) {
return new Compiler(node, file).compile();
}
return Compiler(node, file); // eslint-disable-line new-cap
}n/a
function use(value) {
var settings;
assertUnfrozen('use', frozen);
if (value === null || value === undefined) {
/* Empty */
} else if (func(value)) {
addPlugin.apply(null, arguments);
} else if (typeof value === 'object') {
if ('length' in value) {
addList(value);
} else {
addPreset(value);
}
} else {
throw new Error('Expected usable value, not `' + value + '`');
}
if (settings) {
namespace.settings = extend(namespace.settings || {}, settings);
}
return processor;
function addPreset(result) {
addList(result.plugins);
if (result.settings) {
settings = extend(settings || {}, result.settings);
}
}
function add(value) {
if (func(value)) {
addPlugin(value);
} else if (typeof value === 'object') {
if ('length' in value) {
addPlugin.apply(null, value);
} else {
addPreset(value);
}
} else {
throw new Error('Expected usable value, not `' + value + '`');
}
}
function addList(plugins) {
var length;
var index;
if (plugins === null || plugins === undefined) {
/* Empty */
} else if (array(plugins)) {
length = plugins.length;
index = -1;
while (++index < length) {
add(plugins[index]);
}
} else {
throw new Error('Expected a list of plugins, not `' + plugins + '`');
}
}
function addPlugin(plugin, value) {
var entry = find(plugin);
if (entry) {
if (plain(entry[1]) && plain(value)) {
value = extend(entry[1], value);
}
entry[1] = value;
} else {
attachers.push(slice.call(arguments));
}
}
}...
'use strict';
var unified = require('unified');
var parse = require('remark-parse');
var stringify = require('remark-stringify');
module.exports = unified().use(parse).use(stringify).freeze();
...function Of() {
if (!(this instanceof Of)) {
return new From(arguments);
}
return Super.apply(this, arguments);
}n/a
function Compiler(tree, file) {
this.inLink = this.inTable = false;
this.tree = tree;
this.file = file;
this.options = xtend(this.options);
this.setOptions({});
}n/a
function Compiler(tree, file) {
this.inLink = this.inTable = false;
this.tree = tree;
this.file = file;
this.options = xtend(this.options);
this.setOptions({});
}n/a
function all(parent) {
var self = this;
var children = parent.children;
var length = children.length;
var results = [];
var index = -1;
while (++index < length) {
results[index] = self.visit(children[index], parent);
}
return results;
}n/a
function block(node) {
var self = this;
var values = [];
var children = node.children;
var length = children.length;
var index = -1;
var child;
var prev;
while (++index < length) {
child = children[index];
if (prev) {
/* Duplicate nodes, such as a list
* directly following another list,
* often need multiple new lines.
*
* Additionally, code blocks following a list
* might easily be mistaken for a paragraph
* in the list itself. */
if (child.type === prev.type && prev.type === 'list') {
values.push(prev.ordered === child.ordered ? '\n\n\n' : '\n\n');
} else if (prev.type === 'list' && child.type === 'code' && !child.lang) {
values.push('\n\n\n');
} else {
values.push('\n\n');
}
}
values.push(self.visit(child, node));
prev = child;
}
return values.join('');
}n/a
function compile() {
return this.visit(compact(this.tree, this.options.commonmark));
}n/a
enterLink = function () {
var context = ctx || this;
var current = context[key];
context[key] = !state;
/**
* Cancel state to its value before entering.
*/
return function () {
context[key] = current;
};
}n/a
function enter(compiler, node) {
var encode = compiler.encode;
var escape = compiler.escape;
var exit = compiler.enterLink();
if (
node.referenceType !== 'shortcut' &&
node.referenceType !== 'collapsed'
) {
return exit;
}
compiler.encode = compiler.escape = returner;
return function () {
compiler.encode = encode;
compiler.escape = escape;
exit();
};
}n/a
enterTable = function () {
var context = ctx || this;
var current = context[key];
context[key] = !state;
/**
* Cancel state to its value before entering.
*/
return function () {
context[key] = current;
};
}n/a
function setOptions(options) {
var self = this;
var current = self.options;
var ruleRepetition;
var key;
if (options == null) {
options = {};
} else if (typeof options === 'object') {
options = xtend(options);
} else {
throw new Error('Invalid value `' + options + '` for setting `options`');
}
for (key in defaults) {
validate[typeof defaults[key]](options, key, current[key], maps[key]);
}
ruleRepetition = options.ruleRepetition;
if (ruleRepetition && ruleRepetition < 3) {
raise(ruleRepetition, 'options.ruleRepetition');
}
self.encode = encodeFactory(String(options.entities));
self.escape = escapeFactory(options);
self.options = options;
return self;
}n/a
function one(node, parent) {
var self = this;
var visitors = self.visitors;
/* Fail on unknown nodes. */
if (typeof visitors[node.type] !== 'function') {
self.file.fail(
new Error(
'Missing compiler for node of type `' +
node.type + '`: `' + node + '`'
),
node
);
}
return visitors[node.type].call(self, node, parent);
}n/a
function orderedItems(node) {
var self = this;
var fn = self.visitors.listItem;
var increment = self.options.incrementListMarker;
var values = [];
var start = node.start;
var children = node.children;
var length = children.length;
var index = -1;
var bullet;
while (++index < length) {
bullet = (increment ? start + index : start) + '.';
values[index] = fn.call(self, children[index], node, index, bullet);
}
return values.join('\n');
}n/a
function unorderedItems(node) {
var self = this;
var bullet = self.options.bullet;
var fn = self.visitors.listItem;
var children = node.children;
var length = children.length;
var index = -1;
var values = [];
while (++index < length) {
values[index] = fn.call(self, children[index], node, index, bullet);
}
return values.join('\n');
}n/a
function blockquote(node) {
var values = this.block(node).split('\n');
var result = [];
var length = values.length;
var index = -1;
var value;
while (++index < length) {
value = values[index];
result[index] = (value ? ' ' : '') + value;
}
return '>' + result.join('\n>');
}n/a
function lineBreak() {
return map[this.options.commonmark];
}n/a
function code(node, parent) {
var self = this;
var value = node.value;
var options = self.options;
var marker = options.fence;
var language = self.encode(node.lang || '', node);
var fence;
/* Without (needed) fences. */
if (!language && !options.fences && value) {
/* Throw when pedantic, in a list item which
* isn’t compiled using a tab. */
if (
parent &&
parent.type === 'listItem' &&
options.listItemIndent !== 'tab' &&
options.pedantic
) {
self.file.fail(
'Cannot indent code properly. See http://git.io/vgFvT',
node.position
);
}
return pad(value, 1);
}
fence = streak(value, marker) + 1;
/* Fix GFM / RedCarpet bug, where fence-like characters
* inside fenced code can exit a code-block.
* Yes, even when the outer fence uses different
* characters, or is longer.
* Thus, we can only pad the code to make it work. */
if (FENCE.test(value)) {
value = pad(value, 1);
}
fence = repeat(marker, Math.max(fence, 3));
return fence + language + '\n' + value + '\n' + fence;
}n/a
function definition(node) {
var content = uri(node.url);
if (node.title) {
content += ' ' + title(node.title);
}
return '[' + node.identifier + ']: ' + content;
}n/a
function strikethrough(node) {
return '~~' + this.all(node).join('') + '~~';
}n/a
function emphasis(node) {
var marker = this.options.emphasis;
return marker + this.all(node).join('') + marker;
}n/a
function footnote(node) {
return '[^' + this.all(node).join('') + ']';
}n/a
function footnoteDefinition(node) {
var id = node.identifier.toLowerCase();
var content = this.all(node).join('\n\n' + repeat(' ', 4));
return '[^' + id + ']: ' + content;
}n/a
function footnoteReference(node) {
return '[^' + node.identifier + ']';
}n/a
function heading(node) {
var self = this;
var depth = node.depth;
var setext = self.options.setext;
var closeAtx = self.options.closeAtx;
var content = self.all(node).join('');
var prefix;
if (setext && depth < 3) {
return content + '\n' + repeat(depth === 1 ? '=' : '-', content.length);
}
prefix = repeat('#', node.depth);
return prefix + ' ' + content + (closeAtx ? ' ' + prefix : '');
}n/a
function html(node) {
return node.value;
}n/a
function image(node) {
var self = this;
var content = uri(self.encode(node.url || '', node));
var exit = self.enterLink();
var alt = self.encode(self.escape(node.alt || '', node));
exit();
if (node.title) {
content += ' ' + title(self.encode(node.title, node));
}
return '';
}n/a
function imageReference(node) {
return '![' + (this.encode(node.alt, node) || '') + ']' + label(node);
}n/a
function inlineCode(node) {
var value = node.value;
var ticks = repeat('`', streak(value, '`') + 1);
var start = ticks;
var end = ticks;
if (value.charAt(0) === '`') {
start += ' ';
}
if (value.charAt(value.length - 1) === '`') {
end = ' ' + end;
}
return start + value + end;
}n/a
function link(node) {
var self = this;
var content = self.encode(node.url || '', node);
var exit = self.enterLink();
var escaped = self.encode(self.escape(node.url || '', node));
var value = self.all(node).join('');
exit();
if (
node.title == null &&
PROTOCOL.test(content) &&
(escaped === value || escaped === 'mailto:' + value)
) {
/* Backslash escapes do not work in autolinks,
* so we do not escape. */
return uri(self.encode(node.url), true);
}
content = uri(content);
if (node.title) {
content += ' ' + title(self.encode(self.escape(node.title, node), node));
}
return '[' + value + '](' + content + ')';
}n/a
function linkReference(node) {
var self = this;
var type = node.referenceType;
var exit = self.enterLinkReference(self, node);
var value = self.all(node).join('');
exit();
if (type === 'shortcut' || type === 'collapsed') {
value = copy(value, node.identifier);
}
return '[' + value + ']' + label(node);
}n/a
function list(node) {
return this[ORDERED_MAP[node.ordered]](node);
}n/a
function listItem(node, parent, position, bullet) {
var self = this;
var style = self.options.listItemIndent;
var loose = node.loose;
var children = node.children;
var length = children.length;
var values = [];
var index = -1;
var value;
var indent;
var spacing;
while (++index < length) {
values[index] = self.visit(children[index], node);
}
value = CHECKBOX_MAP[node.checked] + values.join(loose ? '\n\n' : '\n');
if (style === '1' || (style === 'mixed' && value.indexOf('\n') === -1)) {
indent = bullet.length + 1;
spacing = ' ';
} else {
indent = Math.ceil((bullet.length + 1) / 4) * 4;
spacing = repeat(' ', indent - bullet.length);
}
value = bullet + spacing + pad(value, indent / 4).slice(indent);
if (loose && parent.children.length - 1 !== position) {
value += '\n';
}
return value;
}n/a
function paragraph(node) {
return this.all(node).join('');
}n/a
function root(node) {
return this.block(node) + '\n';
}n/a
function strong(node) {
var marker = repeat(this.options.strong, 2);
return marker + this.all(node).join('') + marker;
}n/a
function table(node) {
var self = this;
var loose = self.options.looseTable;
var spaced = self.options.spacedTable;
var pad = self.options.paddedTable;
var rows = node.children;
var index = rows.length;
var exit = self.enterTable();
var result = [];
var start;
var end;
while (index--) {
result[index] = self.all(rows[index]);
}
exit();
if (loose) {
start = end = '';
} else if (spaced) {
start = '| ';
end = ' |';
} else {
start = end = '|';
}
return markdownTable(result, {
align: node.align,
pad: pad,
start: start,
end: end,
delimiter: spaced ? ' | ' : '|'
});
}n/a
function tableCell(node) {
return this.all(node).join('');
}n/a
function text(node, parent) {
return this.encode(this.escape(node.value, node, parent), node);
}n/a
function thematic() {
var options = this.options;
var rule = repeat(options.rule, options.ruleRepetition);
return options.ruleSpaces ? rule.split('').join(' ') : rule;
}n/a
function yaml(node) {
var marker = repeat('-', 3);
return marker + (node.value ? '\n' + node.value : '') + '\n' + marker;
}n/a
function Of() {
if (!(this instanceof Of)) {
return new From(arguments);
}
return Super.apply(this, arguments);
}n/a
function Parser(doc, file) {
this.file = file;
this.offset = {};
this.options = xtend(this.options);
this.setOptions({});
this.inList = this.inBlock = this.inLink = false;
this.atStart = true;
this.toOffset = vfileLocation(file).toOffset;
this.unescape = unescape(this, 'escape');
this.decode = decode(this);
}n/a
function Parser(doc, file) {
this.file = file;
this.offset = {};
this.options = xtend(this.options);
this.setOptions({});
this.inList = this.inBlock = this.inLink = false;
this.atStart = true;
this.toOffset = vfileLocation(file).toOffset;
this.unescape = unescape(this, 'escape');
this.decode = decode(this);
}n/a
enterBlock = function () {
var context = ctx || this;
var current = context[key];
context[key] = !state;
/**
* Cancel state to its value before entering.
*/
return function () {
context[key] = current;
};
}n/a
enterLink = function () {
var context = ctx || this;
var current = context[key];
context[key] = !state;
/**
* Cancel state to its value before entering.
*/
return function () {
context[key] = current;
};
}n/a
enterList = function () {
var context = ctx || this;
var current = context[key];
context[key] = !state;
/**
* Cancel state to its value before entering.
*/
return function () {
context[key] = current;
};
}n/a
exitStart = function () {
var context = ctx || this;
var current = context[key];
context[key] = !state;
/**
* Cancel state to its value before entering.
*/
return function () {
context[key] = current;
};
}n/a
function parse() {
var self = this;
var value = String(self.file);
var start = {line: 1, column: 1, offset: 0};
var content = xtend(start);
var node;
/* Clean non-unix newlines: `\r\n` and `\r` are all
* changed to `\n`. This should not affect positional
* information. */
value = value.replace(EXPRESSION_LINE_BREAKS, C_NEWLINE);
if (value.charCodeAt(0) === 0xFEFF) {
value = value.slice(1);
content.column++;
content.offset++;
}
node = {
type: 'root',
children: self.tokenizeBlock(value, content),
position: {
start: start,
end: self.eof || xtend(start)
}
};
if (!self.options.position) {
removePosition(node, true);
}
return node;
}n/a
function setOptions(options) {
var self = this;
var current = self.options;
var key;
var value;
if (options == null) {
options = {};
} else if (typeof options === 'object') {
options = xtend(options);
} else {
throw new Error(
'Invalid value `' + options + '` ' +
'for setting `options`'
);
}
for (key in defaults) {
value = options[key];
if (value == null) {
value = current[key];
}
if (
(key !== 'blocks' && typeof value !== 'boolean') ||
(key === 'blocks' && typeof value !== 'object')
) {
throw new Error(
'Invalid value `' + value + '` ' +
'for setting `options.' + key + '`'
);
}
options[key] = value;
}
self.options = options;
self.escape = escapes(options);
return self;
}n/a
function tokenize(value, location) {
var self = this;
var offset = self.offset;
var tokens = [];
var methods = self[type + 'Methods'];
var tokenizers = self[type + 'Tokenizers'];
var line = location.line;
var column = location.column;
var index;
var length;
var method;
var name;
var matched;
var valueLength;
/* Trim white space only lines. */
if (!value) {
return tokens;
}
/* Expose on `eat`. */
eat.now = now;
eat.file = self.file;
/* Sync initial offset. */
updatePosition('');
/* Iterate over `value`, and iterate over all
* tokenizers. When one eats something, re-iterate
* with the remaining value. If no tokenizer eats,
* something failed (should not happen) and an
* exception is thrown. */
while (value) {
index = -1;
length = methods.length;
matched = false;
while (++index < length) {
name = methods[index];
method = tokenizers[name];
if (
method &&
(!method.onlyAtStart || self.atStart) &&
(!method.notInList || !self.inList) &&
(!method.notInBlock || !self.inBlock) &&
(!method.notInLink || !self.inLink)
) {
valueLength = value.length;
method.apply(self, [eat, value]);
matched = valueLength !== value.length;
if (matched) {
break;
}
}
}
/* istanbul ignore if */
if (!matched) {
self.file.fail(new Error('Infinite loop'), eat.now());
}
}
self.eof = now();
return tokens;
/**
* Update line, column, and offset based on
* `value`.
*
* @example
* updatePosition('foo');
*
* @param {string} subvalue - Subvalue to eat.
*/
function updatePosition(subvalue) {
var lastIndex = -1;
var index = subvalue.indexOf('\n');
while (index !== -1) {
line++;
lastIndex = index;
index = subvalue.indexOf('\n', index + 1);
}
if (lastIndex === -1) {
column += subvalue.length;
} else {
column = subvalue.length - lastIndex;
}
if (line in offset) {
if (lastIndex !== -1) {
column += offset[line];
} else if (column <= offset[line]) {
column = offset[line] + 1;
}
}
}
/**
* Get offset. Called before the first character is
* eaten to retrieve the range's offsets.
*
* @return {Function} - `done`, to be called when
* the last character is eaten.
*/
function getOffset() {
var indentation = [];
var pos = line + 1;
/**
* Done. Called when the last character is
* eaten to retrieve the range’s offsets.
*
* @return {Array.<number>} - Offset.
*/
return function () {
var last = line + 1;
while (pos < last) {
indentation.push((offset[pos] || 0) + 1);
pos++;
}
return indentation;
};
}
/**
* Get the current position.
*
* @example
* position = now(); // {line: 1, column: 1, offset: 0}
*
* @return {Object} - Current Position.
*/
function now() {
var pos = {line: line, column: column};
pos.offset = self.toOffset(pos);
return pos;
}
/**
* Store position information for a node.
*
* @example
* start = now();
* updatePosition('foo');
* location = new Position(start);
* // {
* // start: {line: 1, column: 1, offset: 0},
* // end: {line: 1, column: 3, offset: 2}
* // }
*
* @param {Object} start - Starting position.
*/
function Position(start) {
this.start = start;
this.end = now();
}
/**
* Throw when a value is incorrectly eaten.
* This shouldn’t happen but will throw on new,
* incorrect rules.
*
* @example
* // When the current value is set to `foo bar`.
* validateEat('foo');
* eat('foo');
*
* validateEat('bar');
* // throws, because the space is not eaten.
*
* @param {string} subvalue - Value to be eaten.
* @throws {Error} - When `subvalue` cannot be eaten.
*/
function validateEat(subvalue) {
/* istanbul ignore if */ ...n/a
function factory(type) {
return tokenize;
/* Tokenizer for a bound `type`. */
function tokenize(value, location) {
var self = this;
var offset = self.offset;
var tokens = [];
var methods = self[type + 'Methods'];
var tokenizers = self[type + 'Tokenizers'];
var line = location.line;
var column = location.column;
var index;
var length;
var method;
var name;
var matched;
var valueLength;
/* Trim white space only lines. */
if (!value) {
return tokens;
}
/* Expose on `eat`. */
eat.now = now;
eat.file = self.file;
/* Sync initial offset. */
updatePosition('');
/* Iterate over `value`, and iterate over all
* tokenizers. When one eats something, re-iterate
* with the remaining value. If no tokenizer eats,
* something failed (should not happen) and an
* exception is thrown. */
while (value) {
index = -1;
length = methods.length;
matched = false;
while (++index < length) {
name = methods[index];
method = tokenizers[name];
if (
method &&
(!method.onlyAtStart || self.atStart) &&
(!method.notInList || !self.inList) &&
(!method.notInBlock || !self.inBlock) &&
(!method.notInLink || !self.inLink)
) {
valueLength = value.length;
method.apply(self, [eat, value]);
matched = valueLength !== value.length;
if (matched) {
break;
}
}
}
/* istanbul ignore if */
if (!matched) {
self.file.fail(new Error('Infinite loop'), eat.now());
}
}
self.eof = now();
return tokens;
/**
* Update line, column, and offset based on
* `value`.
*
* @example
* updatePosition('foo');
*
* @param {string} subvalue - Subvalue to eat.
*/
function updatePosition(subvalue) {
var lastIndex = -1;
var index = subvalue.indexOf('\n');
while (index !== -1) {
line++;
lastIndex = index;
index = subvalue.indexOf('\n', index + 1);
}
if (lastIndex === -1) {
column += subvalue.length;
} else {
column = subvalue.length - lastIndex;
}
if (line in offset) {
if (lastIndex !== -1) {
column += offset[line];
} else if (column <= offset[line]) {
column = offset[line] + 1;
}
}
}
/**
* Get offset. Called before the first character is
* eaten to retrieve the range's offsets.
*
* @return {Function} - `done`, to be called when
* the last character is eaten.
*/
function getOffset() {
var indentation = [];
var pos = line + 1;
/**
* Done. Called when the last character is
* eaten to retrieve the range’s offsets.
*
* @return {Array.<number>} - Offset.
*/
return function () {
var last = line + 1;
while (pos < last) {
indentation.push((offset[pos] || 0) + 1);
pos++;
}
return indentation;
};
}
/**
* Get the current position.
*
* @example
* position = now(); // {line: 1, column: 1, offset: 0}
*
* @return {Object} - Current Position.
*/
function now() {
var pos = {line: line, column: column};
pos.offset = self.toOffset(pos);
return pos;
}
/**
* Store position information for a node.
*
* @example
* start = now();
* updatePosition('foo');
* location = new Position(start);
* // {
* // start: {line: 1, column: 1, offset: 0},
* // end: {line: 1, column: 3, offset: 2}
* // }
*
* @param {Object} start - Starting position.
*/
function Position(start) {
this.start = start;
this.end = now();
}
/**
* Throw when a value is incorrectly eaten.
* This shouldn’t happen but will throw on new,
* incorrect rules.
* ...n/a
function tokenize(value, location) {
var self = this;
var offset = self.offset;
var tokens = [];
var methods = self[type + 'Methods'];
var tokenizers = self[type + 'Tokenizers'];
var line = location.line;
var column = location.column;
var index;
var length;
var method;
var name;
var matched;
var valueLength;
/* Trim white space only lines. */
if (!value) {
return tokens;
}
/* Expose on `eat`. */
eat.now = now;
eat.file = self.file;
/* Sync initial offset. */
updatePosition('');
/* Iterate over `value`, and iterate over all
* tokenizers. When one eats something, re-iterate
* with the remaining value. If no tokenizer eats,
* something failed (should not happen) and an
* exception is thrown. */
while (value) {
index = -1;
length = methods.length;
matched = false;
while (++index < length) {
name = methods[index];
method = tokenizers[name];
if (
method &&
(!method.onlyAtStart || self.atStart) &&
(!method.notInList || !self.inList) &&
(!method.notInBlock || !self.inBlock) &&
(!method.notInLink || !self.inLink)
) {
valueLength = value.length;
method.apply(self, [eat, value]);
matched = valueLength !== value.length;
if (matched) {
break;
}
}
}
/* istanbul ignore if */
if (!matched) {
self.file.fail(new Error('Infinite loop'), eat.now());
}
}
self.eof = now();
return tokens;
/**
* Update line, column, and offset based on
* `value`.
*
* @example
* updatePosition('foo');
*
* @param {string} subvalue - Subvalue to eat.
*/
function updatePosition(subvalue) {
var lastIndex = -1;
var index = subvalue.indexOf('\n');
while (index !== -1) {
line++;
lastIndex = index;
index = subvalue.indexOf('\n', index + 1);
}
if (lastIndex === -1) {
column += subvalue.length;
} else {
column = subvalue.length - lastIndex;
}
if (line in offset) {
if (lastIndex !== -1) {
column += offset[line];
} else if (column <= offset[line]) {
column = offset[line] + 1;
}
}
}
/**
* Get offset. Called before the first character is
* eaten to retrieve the range's offsets.
*
* @return {Function} - `done`, to be called when
* the last character is eaten.
*/
function getOffset() {
var indentation = [];
var pos = line + 1;
/**
* Done. Called when the last character is
* eaten to retrieve the range’s offsets.
*
* @return {Array.<number>} - Offset.
*/
return function () {
var last = line + 1;
while (pos < last) {
indentation.push((offset[pos] || 0) + 1);
pos++;
}
return indentation;
};
}
/**
* Get the current position.
*
* @example
* position = now(); // {line: 1, column: 1, offset: 0}
*
* @return {Object} - Current Position.
*/
function now() {
var pos = {line: line, column: column};
pos.offset = self.toOffset(pos);
return pos;
}
/**
* Store position information for a node.
*
* @example
* start = now();
* updatePosition('foo');
* location = new Position(start);
* // {
* // start: {line: 1, column: 1, offset: 0},
* // end: {line: 1, column: 3, offset: 2}
* // }
*
* @param {Object} start - Starting position.
*/
function Position(start) {
this.start = start;
this.end = now();
}
/**
* Throw when a value is incorrectly eaten.
* This shouldn’t happen but will throw on new,
* incorrect rules.
*
* @example
* // When the current value is set to `foo bar`.
* validateEat('foo');
* eat('foo');
*
* validateEat('bar');
* // throws, because the space is not eaten.
*
* @param {string} subvalue - Value to be eaten.
* @throws {Error} - When `subvalue` cannot be eaten.
*/
function validateEat(subvalue) {
/* istanbul ignore if */ ...n/a
function atxHeading(eat, value, silent) {
var self = this;
var settings = self.options;
var length = value.length + 1;
var index = -1;
var now = eat.now();
var subvalue = '';
var content = '';
var character;
var queue;
var depth;
/* Eat initial spacing. */
while (++index < length) {
character = value.charAt(index);
if (character !== C_SPACE && character !== C_TAB) {
index--;
break;
}
subvalue += character;
}
/* Eat hashes. */
depth = 0;
while (++index <= length) {
character = value.charAt(index);
if (character !== C_HASH) {
index--;
break;
}
subvalue += character;
depth++;
}
if (depth > MAX_ATX_COUNT) {
return;
}
if (
!depth ||
(!settings.pedantic && value.charAt(index + 1) === C_HASH)
) {
return;
}
length = value.length + 1;
/* Eat intermediate white-space. */
queue = '';
while (++index < length) {
character = value.charAt(index);
if (character !== C_SPACE && character !== C_TAB) {
index--;
break;
}
queue += character;
}
/* Exit when not in pedantic mode without spacing. */
if (
!settings.pedantic &&
queue.length === 0 &&
character &&
character !== C_NEWLINE
) {
return;
}
if (silent) {
return true;
}
/* Eat content. */
subvalue += queue;
queue = content = '';
while (++index < length) {
character = value.charAt(index);
if (!character || character === C_NEWLINE) {
break;
}
if (
character !== C_SPACE &&
character !== C_TAB &&
character !== C_HASH
) {
content += queue + character;
queue = '';
continue;
}
while (character === C_SPACE || character === C_TAB) {
queue += character;
character = value.charAt(++index);
}
while (character === C_HASH) {
queue += character;
character = value.charAt(++index);
}
while (character === C_SPACE || character === C_TAB) {
queue += character;
character = value.charAt(++index);
}
index--;
}
now.column += subvalue.length;
now.offset += subvalue.length;
subvalue += content + queue;
return eat(subvalue)({
type: 'heading',
depth: depth,
children: self.tokenizeInline(content, now)
});
}n/a
function blockquote(eat, value, silent) {
var self = this;
var offsets = self.offset;
var tokenizers = self.blockTokenizers;
var interruptors = self.interruptBlockquote;
var now = eat.now();
var currentLine = now.line;
var length = value.length;
var values = [];
var contents = [];
var indents = [];
var add;
var index = 0;
var character;
var rest;
var nextIndex;
var content;
var line;
var startIndex;
var prefixed;
var exit;
while (index < length) {
character = value.charAt(index);
if (character !== C_SPACE && character !== C_TAB) {
break;
}
index++;
}
if (value.charAt(index) !== C_GT) {
return;
}
if (silent) {
return true;
}
index = 0;
while (index < length) {
nextIndex = value.indexOf(C_NEWLINE, index);
startIndex = index;
prefixed = false;
if (nextIndex === -1) {
nextIndex = length;
}
while (index < length) {
character = value.charAt(index);
if (character !== C_SPACE && character !== C_TAB) {
break;
}
index++;
}
if (value.charAt(index) === C_GT) {
index++;
prefixed = true;
if (value.charAt(index) === C_SPACE) {
index++;
}
} else {
index = startIndex;
}
content = value.slice(index, nextIndex);
if (!prefixed && !trim(content)) {
index = startIndex;
break;
}
if (!prefixed) {
rest = value.slice(index);
/* Check if the following code contains a possible
* block. */
if (interrupt(interruptors, tokenizers, self, [eat, rest, true])) {
break;
}
}
line = startIndex === index ? content : value.slice(startIndex, nextIndex);
indents.push(index - startIndex);
values.push(line);
contents.push(content);
index = nextIndex + 1;
}
index = -1;
length = indents.length;
add = eat(values.join(C_NEWLINE));
while (++index < length) {
offsets[currentLine] = (offsets[currentLine] || 0) + indents[index];
currentLine++;
}
exit = self.enterBlock();
contents = self.tokenizeBlock(contents.join(C_NEWLINE), now);
exit();
return add({
type: 'blockquote',
children: contents
});
}n/a
function definition(eat, value, silent) {
var self = this;
var commonmark = self.options.commonmark;
var index = 0;
var length = value.length;
var subvalue = '';
var beforeURL;
var beforeTitle;
var queue;
var character;
var test;
var identifier;
var url;
var title;
while (index < length) {
character = value.charAt(index);
if (character !== C_SPACE && character !== C_TAB) {
break;
}
subvalue += character;
index++;
}
character = value.charAt(index);
if (character !== C_BRACKET_OPEN) {
return;
}
index++;
subvalue += character;
queue = '';
while (index < length) {
character = value.charAt(index);
if (character === C_BRACKET_CLOSE) {
break;
} else if (character === C_BACKSLASH) {
queue += character;
index++;
character = value.charAt(index);
}
queue += character;
index++;
}
if (
!queue ||
value.charAt(index) !== C_BRACKET_CLOSE ||
value.charAt(index + 1) !== C_COLON
) {
return;
}
identifier = queue;
subvalue += queue + C_BRACKET_CLOSE + C_COLON;
index = subvalue.length;
queue = '';
while (index < length) {
character = value.charAt(index);
if (
character !== C_TAB &&
character !== C_SPACE &&
character !== C_NEWLINE
) {
break;
}
subvalue += character;
index++;
}
character = value.charAt(index);
queue = '';
beforeURL = subvalue;
if (character === C_LT) {
index++;
while (index < length) {
character = value.charAt(index);
if (!isEnclosedURLCharacter(character)) {
break;
}
queue += character;
index++;
}
character = value.charAt(index);
if (character === isEnclosedURLCharacter.delimiter) {
subvalue += C_LT + queue + character;
index++;
} else {
if (commonmark) {
return;
}
index -= queue.length + 1;
queue = '';
}
}
if (!queue) {
while (index < length) {
character = value.charAt(index);
if (!isUnclosedURLCharacter(character)) {
break;
}
queue += character;
index++;
}
subvalue += queue;
}
if (!queue) {
return;
}
url = queue;
queue = '';
while (index < length) {
character = value.charAt(index);
if (
character !== C_TAB &&
character !== C_SPACE &&
character !== C_NEWLINE
) {
break;
}
queue += character;
index++;
}
character = value.charAt(index);
test = null;
if (character === C_DOUBLE_QUOTE) {
test = C_DOUBLE_QUOTE;
} else if (character === C_SINGLE_QUOTE) {
test = C_SINGLE_QUOTE;
} else if (character === C_PAREN_OPEN) {
test = C_PAREN_CLOSE;
}
if (!test) {
queue = '';
index = subvalue.length;
} else if (queue) {
subvalue += queue + character;
index = subvalue.length;
queue = '';
while (index < length) {
character = value.charAt(index);
if (character === test) {
break;
}
if (character === C_NEWLINE) {
index++;
character = value.charAt(index);
if (character === C_NEWLINE || character === test) {
return;
}
queue += C_NEWLINE;
}
queue += character;
index++;
}
character = value.charAt(index);
if (character !== test) {
return;
}
beforeTitle = subvalue;
subvalue += queue + character;
index++;
title = queue;
queue = '';
} else {
return;
}
while (index < length) {
character = value.charAt(index);
if (character !== C_TAB && character !== C_SPACE) {
break;
}
subvalue += character;
index++;
}
character = value.charAt(index);
if (!character || character === C_NEWLINE) {
if (silent) {
return true;
}
beforeURL = eat(beforeURL).test().end;
url = self.decode.raw(self.unescape(url), beforeURL);
if (title) {
beforeTitle = eat(beforeTitle).test().end;
title = self.decode.raw(self.unescape(title), before ...n/a
function fencedCode(eat, value, silent) {
var self = this;
var settings = self.options;
var length = value.length + 1;
var index = 0;
var subvalue = '';
var fenceCount;
var marker;
var character;
var flag;
var queue;
var content;
var exdentedContent;
var closing;
var exdentedClosing;
var indent;
var now;
if (!settings.gfm) {
return;
}
/* Eat initial spacing. */
while (index < length) {
character = value.charAt(index);
if (character !== C_SPACE && character !== C_TAB) {
break;
}
subvalue += character;
index++;
}
indent = index;
/* Eat the fence. */
character = value.charAt(index);
if (character !== C_TILDE && character !== C_TICK) {
return;
}
index++;
marker = character;
fenceCount = 1;
subvalue += character;
while (index < length) {
character = value.charAt(index);
if (character !== marker) {
break;
}
subvalue += character;
fenceCount++;
index++;
}
if (fenceCount < MIN_FENCE_COUNT) {
return;
}
/* Eat spacing before flag. */
while (index < length) {
character = value.charAt(index);
if (character !== C_SPACE && character !== C_TAB) {
break;
}
subvalue += character;
index++;
}
/* Eat flag. */
flag = queue = '';
while (index < length) {
character = value.charAt(index);
if (
character === C_NEWLINE ||
character === C_TILDE ||
character === C_TICK
) {
break;
}
if (character === C_SPACE || character === C_TAB) {
queue += character;
} else {
flag += queue + character;
queue = '';
}
index++;
}
character = value.charAt(index);
if (character && character !== C_NEWLINE) {
return;
}
if (silent) {
return true;
}
now = eat.now();
now.column += subvalue.length;
now.offset += subvalue.length;
subvalue += flag;
flag = self.decode.raw(self.unescape(flag), now);
if (queue) {
subvalue += queue;
}
queue = closing = exdentedClosing = content = exdentedContent = '';
/* Eat content. */
while (index < length) {
character = value.charAt(index);
content += closing;
exdentedContent += exdentedClosing;
closing = exdentedClosing = '';
if (character !== C_NEWLINE) {
content += character;
exdentedClosing += character;
index++;
continue;
}
/* Add the newline to `subvalue` if its the first
* character. Otherwise, add it to the `closing`
* queue. */
if (content) {
closing += character;
exdentedClosing += character;
} else {
subvalue += character;
}
queue = '';
index++;
while (index < length) {
character = value.charAt(index);
if (character !== C_SPACE) {
break;
}
queue += character;
index++;
}
closing += queue;
exdentedClosing += queue.slice(indent);
if (queue.length >= CODE_INDENT_COUNT) {
continue;
}
queue = '';
while (index < length) {
character = value.charAt(index);
if (character !== marker) {
break;
}
queue += character;
index++;
}
closing += queue;
exdentedClosing += queue;
if (queue.length < fenceCount) {
continue;
}
queue = '';
while (index < length) {
character = value.charAt(index);
if (character !== C_SPACE && character !== C_TAB) {
break;
}
closing += character;
exdentedClosing += character;
index++;
}
if (!character || character === C_NEWLINE) {
break;
}
}
subvalue += content + closing;
return eat(subvalue)({
type: 'code',
lang: flag || null,
value: trim(exdentedContent)
});
}n/a
function footnoteDefinition(eat, value, silent) {
var self = this;
var offsets = self.offset;
var index;
var length;
var subvalue;
var now;
var currentLine;
var content;
var queue;
var subqueue;
var character;
var identifier;
var add;
var exit;
if (!self.options.footnotes) {
return;
}
index = 0;
length = value.length;
subvalue = '';
now = eat.now();
currentLine = now.line;
while (index < length) {
character = value.charAt(index);
if (!whitespace(character)) {
break;
}
subvalue += character;
index++;
}
if (
value.charAt(index) !== C_BRACKET_OPEN ||
value.charAt(index + 1) !== C_CARET
) {
return;
}
subvalue += C_BRACKET_OPEN + C_CARET;
index = subvalue.length;
queue = '';
while (index < length) {
character = value.charAt(index);
if (character === C_BRACKET_CLOSE) {
break;
} else if (character === C_BACKSLASH) {
queue += character;
index++;
character = value.charAt(index);
}
queue += character;
index++;
}
if (
!queue ||
value.charAt(index) !== C_BRACKET_CLOSE ||
value.charAt(index + 1) !== C_COLON
) {
return;
}
if (silent) {
return true;
}
identifier = normalize(queue);
subvalue += queue + C_BRACKET_CLOSE + C_COLON;
index = subvalue.length;
while (index < length) {
character = value.charAt(index);
if (character !== C_TAB && character !== C_SPACE) {
break;
}
subvalue += character;
index++;
}
now.column += subvalue.length;
now.offset += subvalue.length;
queue = content = subqueue = '';
while (index < length) {
character = value.charAt(index);
if (character === C_NEWLINE) {
subqueue = character;
index++;
while (index < length) {
character = value.charAt(index);
if (character !== C_NEWLINE) {
break;
}
subqueue += character;
index++;
}
queue += subqueue;
subqueue = '';
while (index < length) {
character = value.charAt(index);
if (character !== C_SPACE) {
break;
}
subqueue += character;
index++;
}
if (subqueue.length === 0) {
break;
}
queue += subqueue;
}
if (queue) {
content += queue;
queue = '';
}
content += character;
index++;
}
subvalue += content;
content = content.replace(EXPRESSION_INITIAL_TAB, function (line) {
offsets[currentLine] = (offsets[currentLine] || 0) + line.length;
currentLine++;
return '';
});
add = eat(subvalue);
exit = self.enterBlock();
content = self.tokenizeBlock(content, now);
exit();
return add({
type: 'footnoteDefinition',
identifier: identifier,
children: content
});
}n/a
function blockHTML(eat, value, silent) {
var self = this;
var blocks = self.options.blocks;
var length = value.length;
var index = 0;
var next;
var line;
var offset;
var character;
var count;
var sequence;
var subvalue;
var sequences = [
[/^<(script|pre|style)(?=(\s|>|$))/i, /<\/(script|pre|style)>/i, true],
[/^<!--/, /-->/, true],
[/^<\?/, /\?>/, true],
[/^<![A-Za-z]/, />/, true],
[/^<!\[CDATA\[/, /\]\]>/, true],
[new RegExp('^</?(' + blocks.join('|') + ')(?=(\\s|/?>|$))', 'i'), /^$/, true],
[new RegExp(openCloseTag.source + '\\s*$'), /^$/, false]
];
/* Eat initial spacing. */
while (index < length) {
character = value.charAt(index);
if (character !== C_TAB && character !== C_SPACE) {
break;
}
index++;
}
if (value.charAt(index) !== C_LT) {
return;
}
next = value.indexOf(C_NEWLINE, index + 1);
next = next === -1 ? length : next;
line = value.slice(index, next);
offset = -1;
count = sequences.length;
while (++offset < count) {
if (sequences[offset][0].test(line)) {
sequence = sequences[offset];
break;
}
}
if (!sequence) {
return;
}
if (silent) {
return sequence[2];
}
index = next;
if (!sequence[1].test(line)) {
while (index < length) {
next = value.indexOf(C_NEWLINE, index + 1);
next = next === -1 ? length : next;
line = value.slice(index + 1, next);
if (sequence[1].test(line)) {
if (line) {
index = next;
}
break;
}
index = next;
}
}
subvalue = value.slice(0, index);
return eat(subvalue)({type: 'html', value: subvalue});
}n/a
function indentedCode(eat, value, silent) {
var index = -1;
var length = value.length;
var subvalue = '';
var content = '';
var subvalueQueue = '';
var contentQueue = '';
var character;
var blankQueue;
var indent;
while (++index < length) {
character = value.charAt(index);
if (indent) {
indent = false;
subvalue += subvalueQueue;
content += contentQueue;
subvalueQueue = contentQueue = '';
if (character === C_NEWLINE) {
subvalueQueue = contentQueue = character;
} else {
subvalue += character;
content += character;
while (++index < length) {
character = value.charAt(index);
if (!character || character === C_NEWLINE) {
contentQueue = subvalueQueue = character;
break;
}
subvalue += character;
content += character;
}
}
} else if (
character === C_SPACE &&
value.charAt(index + 1) === character &&
value.charAt(index + 2) === character &&
value.charAt(index + 3) === character
) {
subvalueQueue += CODE_INDENT;
index += 3;
indent = true;
} else if (character === C_TAB) {
subvalueQueue += character;
indent = true;
} else {
blankQueue = '';
while (character === C_TAB || character === C_SPACE) {
blankQueue += character;
character = value.charAt(++index);
}
if (character !== C_NEWLINE) {
break;
}
subvalueQueue += blankQueue + character;
contentQueue += character;
}
}
if (content) {
if (silent) {
return true;
}
return eat(subvalue)({
type: 'code',
lang: null,
value: trim(content)
});
}
}n/a
function list(eat, value, silent) {
var self = this;
var commonmark = self.options.commonmark;
var pedantic = self.options.pedantic;
var tokenizers = self.blockTokenizers;
var interuptors = self.interruptList;
var markers;
var index = 0;
var length = value.length;
var start = null;
var size = 0;
var queue;
var ordered;
var character;
var marker;
var nextIndex;
var startIndex;
var prefixed;
var currentMarker;
var content;
var line;
var prevEmpty;
var empty;
var items;
var allLines;
var emptyLines;
var item;
var enterTop;
var exitBlockquote;
var isLoose;
var node;
var now;
var end;
var indented;
while (index < length) {
character = value.charAt(index);
if (character === C_TAB) {
size += TAB_SIZE - (size % TAB_SIZE);
} else if (character === C_SPACE) {
size++;
} else {
break;
}
index++;
}
if (size >= TAB_SIZE) {
return;
}
character = value.charAt(index);
markers = commonmark ?
LIST_ORDERED_COMMONMARK_MARKERS :
LIST_ORDERED_MARKERS;
if (LIST_UNORDERED_MARKERS[character] === true) {
marker = character;
ordered = false;
} else {
ordered = true;
queue = '';
while (index < length) {
character = value.charAt(index);
if (!decimal(character)) {
break;
}
queue += character;
index++;
}
character = value.charAt(index);
if (!queue || markers[character] !== true) {
return;
}
start = parseInt(queue, 10);
marker = character;
}
character = value.charAt(++index);
if (character !== C_SPACE && character !== C_TAB) {
return;
}
if (silent) {
return true;
}
index = 0;
items = [];
allLines = [];
emptyLines = [];
while (index < length) {
nextIndex = value.indexOf(C_NEWLINE, index);
startIndex = index;
prefixed = false;
indented = false;
if (nextIndex === -1) {
nextIndex = length;
}
end = index + TAB_SIZE;
size = 0;
while (index < length) {
character = value.charAt(index);
if (character === C_TAB) {
size += TAB_SIZE - (size % TAB_SIZE);
} else if (character === C_SPACE) {
size++;
} else {
break;
}
index++;
}
if (size >= TAB_SIZE) {
indented = true;
}
if (item && size >= item.indent) {
indented = true;
}
character = value.charAt(index);
currentMarker = null;
if (!indented) {
if (LIST_UNORDERED_MARKERS[character] === true) {
currentMarker = character;
index++;
size++;
} else {
queue = '';
while (index < length) {
character = value.charAt(index);
if (!decimal(character)) {
break;
}
queue += character;
index++;
}
character = value.charAt(index);
index++;
if (queue && markers[character] === true) {
currentMarker = character;
size += queue.length + 1;
}
}
if (currentMarker) {
character = value.charAt(index);
if (character === C_TAB) {
size += TAB_SIZE - (size % TAB_SIZE);
index++;
} else if (character === C_SPACE) {
end = index + TAB_SIZE;
while (index < end) {
if (value.charAt(index) !== C_SPACE) {
break;
}
index++;
size++;
}
if (index === end && value.charAt(index) === C_SPACE) {
index -= TAB_SIZE - 1;
size -= TAB_SIZE - 1;
}
} else if (character !== C_NEWLINE && character !== '') {
currentMarker = null;
}
}
}
if (currentMarker) {
if (!pedantic && marker !== currentMarker) {
break;
}
prefixed = true;
} else {
if (!commonmark && !indented && value.charAt(startIndex) === C_SPACE) {
indented = true;
} else if (commonmark && item) {
indented = size >= item.indent || size ...n/a
function newline(eat, value, silent) {
var character = value.charAt(0);
var length;
var subvalue;
var queue;
var index;
if (character !== '\n') {
return;
}
/* istanbul ignore if - never used (yet) */
if (silent) {
return true;
}
index = 1;
length = value.length;
subvalue = character;
queue = '';
while (index < length) {
character = value.charAt(index);
if (!whitespace(character)) {
break;
}
queue += character;
if (character === '\n') {
subvalue += queue;
queue = '';
}
index++;
}
eat(subvalue);
}n/a
function paragraph(eat, value, silent) {
var self = this;
var settings = self.options;
var commonmark = settings.commonmark;
var gfm = settings.gfm;
var tokenizers = self.blockTokenizers;
var interruptors = self.interruptParagraph;
var index = value.indexOf(C_NEWLINE);
var length = value.length;
var position;
var subvalue;
var character;
var size;
var now;
while (index < length) {
/* Eat everything if there’s no following newline. */
if (index === -1) {
index = length;
break;
}
/* Stop if the next character is NEWLINE. */
if (value.charAt(index + 1) === C_NEWLINE) {
break;
}
/* In commonmark-mode, following indented lines
* are part of the paragraph. */
if (commonmark) {
size = 0;
position = index + 1;
while (position < length) {
character = value.charAt(position);
if (character === C_TAB) {
size = TAB_SIZE;
break;
} else if (character === C_SPACE) {
size++;
} else {
break;
}
position++;
}
if (size >= TAB_SIZE) {
index = value.indexOf(C_NEWLINE, index + 1);
continue;
}
}
subvalue = value.slice(index + 1);
/* Check if the following code contains a possible
* block. */
if (interrupt(interruptors, tokenizers, self, [eat, subvalue, true])) {
break;
}
/* Break if the following line starts a list, when
* already in a list, or when in commonmark, or when
* in gfm mode and the bullet is *not* numeric. */
if (
tokenizers.list.call(self, eat, subvalue, true) &&
(
self.inList ||
commonmark ||
(gfm && !decimal(trim.left(subvalue).charAt(0)))
)
) {
break;
}
position = index;
index = value.indexOf(C_NEWLINE, index + 1);
if (index !== -1 && trim(value.slice(position, index)) === '') {
index = position;
break;
}
}
subvalue = value.slice(0, index);
if (trim(subvalue) === '') {
eat(subvalue);
return null;
}
/* istanbul ignore if - never used (yet) */
if (silent) {
return true;
}
now = eat.now();
subvalue = trimTrailingLines(subvalue);
return eat(subvalue)({
type: 'paragraph',
children: self.tokenizeInline(subvalue, now)
});
}n/a
function setextHeading(eat, value, silent) {
var self = this;
var now = eat.now();
var length = value.length;
var index = -1;
var subvalue = '';
var content;
var queue;
var character;
var marker;
var depth;
/* Eat initial indentation. */
while (++index < length) {
character = value.charAt(index);
if (character !== C_SPACE || index >= MAX_HEADING_INDENT) {
index--;
break;
}
subvalue += character;
}
/* Eat content. */
content = queue = '';
while (++index < length) {
character = value.charAt(index);
if (character === C_NEWLINE) {
index--;
break;
}
if (character === C_SPACE || character === C_TAB) {
queue += character;
} else {
content += queue + character;
queue = '';
}
}
now.column += subvalue.length;
now.offset += subvalue.length;
subvalue += content + queue;
/* Ensure the content is followed by a newline and a
* valid marker. */
character = value.charAt(++index);
marker = value.charAt(++index);
if (character !== C_NEWLINE || !SETEXT_MARKERS[marker]) {
return;
}
subvalue += character;
/* Eat Setext-line. */
queue = marker;
depth = SETEXT_MARKERS[marker];
while (++index < length) {
character = value.charAt(index);
if (character !== marker) {
if (character !== C_NEWLINE) {
return;
}
index--;
break;
}
queue += character;
}
if (silent) {
return true;
}
return eat(subvalue + queue)({
type: 'heading',
depth: depth,
children: self.tokenizeInline(content, now)
});
}n/a
function table(eat, value, silent) {
var self = this;
var index;
var alignments;
var alignment;
var subvalue;
var row;
var length;
var lines;
var queue;
var character;
var hasDash;
var align;
var cell;
var preamble;
var count;
var opening;
var now;
var position;
var lineCount;
var line;
var rows;
var table;
var lineIndex;
var pipeIndex;
var first;
/* Exit when not in gfm-mode. */
if (!self.options.gfm) {
return;
}
/* Get the rows.
* Detecting tables soon is hard, so there are some
* checks for performance here, such as the minimum
* number of rows, and allowed characters in the
* alignment row. */
index = lineCount = 0;
length = value.length + 1;
lines = [];
while (index < length) {
lineIndex = value.indexOf(C_NEWLINE, index);
pipeIndex = value.indexOf(C_PIPE, index + 1);
if (lineIndex === -1) {
lineIndex = value.length;
}
if (pipeIndex === -1 || pipeIndex > lineIndex) {
if (lineCount < MIN_TABLE_ROWS) {
return;
}
break;
}
lines.push(value.slice(index, lineIndex));
lineCount++;
index = lineIndex + 1;
}
/* Parse the alignment row. */
subvalue = lines.join(C_NEWLINE);
alignments = lines.splice(1, 1)[0] || [];
index = 0;
length = alignments.length;
lineCount--;
alignment = false;
align = [];
while (index < length) {
character = alignments.charAt(index);
if (character === C_PIPE) {
hasDash = null;
if (alignment === false) {
if (first === false) {
return;
}
} else {
align.push(alignment);
alignment = false;
}
first = false;
} else if (character === C_DASH) {
hasDash = true;
alignment = alignment || TABLE_ALIGN_NONE;
} else if (character === C_COLON) {
if (alignment === TABLE_ALIGN_LEFT) {
alignment = TABLE_ALIGN_CENTER;
} else if (hasDash && alignment === TABLE_ALIGN_NONE) {
alignment = TABLE_ALIGN_RIGHT;
} else {
alignment = TABLE_ALIGN_LEFT;
}
} else if (!whitespace(character)) {
return;
}
index++;
}
if (alignment !== false) {
align.push(alignment);
}
/* Exit when without enough columns. */
if (align.length < MIN_TABLE_COLUMNS) {
return;
}
/* istanbul ignore if - never used (yet) */
if (silent) {
return true;
}
/* Parse the rows. */
position = -1;
rows = [];
table = eat(subvalue).reset({
type: 'table',
align: align,
children: rows
});
while (++position < lineCount) {
line = lines[position];
row = {type: 'tableRow', children: []};
/* Eat a newline character when this is not the
* first row. */
if (position) {
eat(C_NEWLINE);
}
/* Eat the row. */
eat(line).reset(row, table);
length = line.length + 1;
index = 0;
queue = cell = '';
preamble = true;
count = opening = null;
while (index < length) {
character = line.charAt(index);
if (character === C_TAB || character === C_SPACE) {
if (cell) {
queue += character;
} else {
eat(character);
}
index++;
continue;
}
if (character === '' || character === C_PIPE) {
if (preamble) {
eat(character);
} else {
if (character && opening) {
queue += character;
index++;
continue;
}
if ((cell || character) && !preamble) {
subvalue = cell;
if (queue.length > 1) {
if (character) {
subvalue += queue.slice(0, queue.length - 1);
queue = queue.charAt(queue.length - 1);
} else {
subvalue += queue;
queue = '';
}
}
now = eat.now();
eat(subvalue)({
type: 'tableCell',
children: self.tokenizeInline(cell, now)
}, row);
}
eat(queue + character ...n/a
function thematicBreak(eat, value, silent) {
var index = -1;
var length = value.length + 1;
var subvalue = '';
var character;
var marker;
var markerCount;
var queue;
while (++index < length) {
character = value.charAt(index);
if (character !== C_TAB && character !== C_SPACE) {
break;
}
subvalue += character;
}
if (
character !== C_ASTERISK &&
character !== C_DASH &&
character !== C_UNDERSCORE
) {
return;
}
marker = character;
subvalue += character;
markerCount = 1;
queue = '';
while (++index < length) {
character = value.charAt(index);
if (character === marker) {
markerCount++;
subvalue += queue + marker;
queue = '';
} else if (character === C_SPACE) {
queue += character;
} else if (
markerCount >= THEMATIC_BREAK_MARKER_COUNT &&
(!character || character === C_NEWLINE)
) {
subvalue += queue;
if (silent) {
return true;
}
return eat(subvalue)({type: 'thematicBreak'});
} else {
return;
}
}
}n/a
function yaml(eat, value, silent) {
var self = this;
var subvalue;
var content;
var index;
var length;
var character;
var queue;
if (
!self.options.yaml ||
value.charAt(0) !== C_DASH ||
value.charAt(1) !== C_DASH ||
value.charAt(2) !== C_DASH ||
value.charAt(3) !== C_NEWLINE
) {
return;
}
subvalue = FENCE + C_NEWLINE;
content = queue = '';
index = 3;
length = value.length;
while (++index < length) {
character = value.charAt(index);
if (
character === C_DASH &&
(queue || !content) &&
value.charAt(index + 1) === C_DASH &&
value.charAt(index + 2) === C_DASH
) {
/* istanbul ignore if - never used (yet) */
if (silent) {
return true;
}
subvalue += queue + FENCE;
return eat(subvalue)({
type: 'yaml',
value: content
});
}
if (character === C_NEWLINE) {
queue += character;
} else {
subvalue += queue + character;
content += queue + character;
queue = '';
}
}
}n/a
function autoLink(eat, value, silent) {
var self;
var subvalue;
var length;
var index;
var queue;
var character;
var hasAtCharacter;
var link;
var now;
var content;
var tokenize;
var exit;
if (value.charAt(0) !== C_LT) {
return;
}
self = this;
subvalue = '';
length = value.length;
index = 0;
queue = '';
hasAtCharacter = false;
link = '';
index++;
subvalue = C_LT;
while (index < length) {
character = value.charAt(index);
if (
character === ' ' ||
character === C_GT ||
character === C_AT_SIGN ||
(character === ':' && value.charAt(index + 1) === C_SLASH)
) {
break;
}
queue += character;
index++;
}
if (!queue) {
return;
}
link += queue;
queue = '';
character = value.charAt(index);
link += character;
index++;
if (character === C_AT_SIGN) {
hasAtCharacter = true;
} else {
if (
character !== ':' ||
value.charAt(index + 1) !== C_SLASH
) {
return;
}
link += C_SLASH;
index++;
}
while (index < length) {
character = value.charAt(index);
if (character === ' ' || character === C_GT) {
break;
}
queue += character;
index++;
}
character = value.charAt(index);
if (!queue || character !== C_GT) {
return;
}
/* istanbul ignore if - never used (yet) */
if (silent) {
return true;
}
link += queue;
content = link;
subvalue += link + character;
now = eat.now();
now.column++;
now.offset++;
if (hasAtCharacter) {
if (link.slice(0, MAILTO_LENGTH).toLowerCase() === MAILTO) {
content = content.substr(MAILTO_LENGTH);
now.column += MAILTO_LENGTH;
now.offset += MAILTO_LENGTH;
} else {
link = MAILTO + link;
}
}
/* Temporarily remove support for escapes in autolinks. */
tokenize = self.inlineTokenizers.escape;
self.inlineTokenizers.escape = null;
exit = self.enterLink();
content = self.tokenizeInline(content, now);
self.inlineTokenizers.escape = tokenize;
exit();
return eat(subvalue)({
type: 'link',
title: null,
url: decode(link),
children: content
});
}n/a
function hardBreak(eat, value, silent) {
var self = this;
var breaks = self.options.breaks;
var length = value.length;
var index = -1;
var queue = '';
var character;
while (++index < length) {
character = value.charAt(index);
if (character === '\n') {
if (!breaks && index < MIN_BREAK_LENGTH) {
return;
}
/* istanbul ignore if - never used (yet) */
if (silent) {
return true;
}
queue += character;
return eat(queue)({type: 'break'});
}
if (character !== ' ') {
return;
}
queue += character;
}
}n/a
function inlineCode(eat, value, silent) {
var length = value.length;
var index = 0;
var queue = '';
var tickQueue = '';
var contentQueue;
var subqueue;
var count;
var openingCount;
var subvalue;
var character;
var found;
var next;
while (index < length) {
if (value.charAt(index) !== C_TICK) {
break;
}
queue += C_TICK;
index++;
}
if (!queue) {
return;
}
subvalue = queue;
openingCount = index;
queue = '';
next = value.charAt(index);
count = 0;
while (index < length) {
character = next;
next = value.charAt(index + 1);
if (character === C_TICK) {
count++;
tickQueue += character;
} else {
count = 0;
queue += character;
}
if (count && next !== C_TICK) {
if (count === openingCount) {
subvalue += queue + tickQueue;
found = true;
break;
}
queue += tickQueue;
tickQueue = '';
}
index++;
}
if (!found) {
if (openingCount % 2 !== 0) {
return;
}
queue = '';
}
/* istanbul ignore if - never used (yet) */
if (silent) {
return true;
}
contentQueue = subqueue = '';
length = queue.length;
index = -1;
while (++index < length) {
character = queue.charAt(index);
if (whitespace(character)) {
subqueue += character;
continue;
}
if (subqueue) {
if (contentQueue) {
contentQueue += subqueue;
}
subqueue = '';
}
contentQueue += character;
}
return eat(subvalue)({
type: 'inlineCode',
value: contentQueue
});
}n/a
function strikethrough(eat, value, silent) {
var self = this;
var character = '';
var previous = '';
var preceding = '';
var subvalue = '';
var index;
var length;
var now;
if (
!self.options.gfm ||
value.charAt(0) !== C_TILDE ||
value.charAt(1) !== C_TILDE ||
whitespace(value.charAt(2))
) {
return;
}
index = 1;
length = value.length;
now = eat.now();
now.column += 2;
now.offset += 2;
while (++index < length) {
character = value.charAt(index);
if (
character === C_TILDE &&
previous === C_TILDE &&
(!preceding || !whitespace(preceding))
) {
/* istanbul ignore if - never used (yet) */
if (silent) {
return true;
}
return eat(DOUBLE + subvalue + DOUBLE)({
type: 'delete',
children: self.tokenizeInline(subvalue, now)
});
}
subvalue += previous;
preceding = previous;
previous = character;
}
}n/a
function emphasis(eat, value, silent) {
var self = this;
var index = 0;
var character = value.charAt(index);
var now;
var pedantic;
var marker;
var queue;
var subvalue;
var length;
var prev;
if (character !== C_ASTERISK && character !== C_UNDERSCORE) {
return;
}
pedantic = self.options.pedantic;
subvalue = marker = character;
length = value.length;
index++;
queue = character = '';
if (pedantic && whitespace(value.charAt(index))) {
return;
}
while (index < length) {
prev = character;
character = value.charAt(index);
if (character === marker && (!pedantic || !whitespace(prev))) {
character = value.charAt(++index);
if (character !== marker) {
if (!trim(queue) || prev === marker) {
return;
}
if (!pedantic && marker === C_UNDERSCORE && word(character)) {
queue += marker;
continue;
}
/* istanbul ignore if - never used (yet) */
if (silent) {
return true;
}
now = eat.now();
now.column++;
now.offset++;
return eat(subvalue + queue + marker)({
type: 'emphasis',
children: self.tokenizeInline(queue, now)
});
}
queue += marker;
}
if (!pedantic && character === '\\') {
queue += character;
character = value.charAt(++index);
}
queue += character;
index++;
}
}n/a
function escape(eat, value, silent) {
var self = this;
var character;
var node;
if (value.charAt(0) === '\\') {
character = value.charAt(1);
if (self.escape.indexOf(character) !== -1) {
/* istanbul ignore if - never used (yet) */
if (silent) {
return true;
}
if (character === '\n') {
node = {type: 'break'};
} else {
node = {
type: 'text',
value: character
};
}
return eat('\\' + character)(node);
}
}
}n/a
function inlineHTML(eat, value, silent) {
var self = this;
var length = value.length;
var character;
var subvalue;
if (value.charAt(0) !== '<' || length < 3) {
return;
}
character = value.charAt(1);
if (
!alphabetical(character) &&
character !== '?' &&
character !== '!' &&
character !== '/'
) {
return;
}
subvalue = value.match(tag);
if (!subvalue) {
return;
}
/* istanbul ignore if - not used yet. */
if (silent) {
return true;
}
subvalue = subvalue[0];
if (!self.inLink && EXPRESSION_HTML_LINK_OPEN.test(subvalue)) {
self.inLink = true;
} else if (self.inLink && EXPRESSION_HTML_LINK_CLOSE.test(subvalue)) {
self.inLink = false;
}
return eat(subvalue)({type: 'html', value: subvalue});
}n/a
function link(eat, value, silent) {
var self = this;
var subvalue = '';
var index = 0;
var character = value.charAt(0);
var commonmark = self.options.commonmark;
var gfm = self.options.gfm;
var closed;
var count;
var opening;
var beforeURL;
var beforeTitle;
var subqueue;
var hasMarker;
var markers;
var isImage;
var content;
var marker;
var length;
var title;
var depth;
var queue;
var url;
var now;
var exit;
var node;
/* Detect whether this is an image. */
if (character === '!') {
isImage = true;
subvalue = character;
character = value.charAt(++index);
}
/* Eat the opening. */
if (character !== C_BRACKET_OPEN) {
return;
}
/* Exit when this is a link and we’re already inside
* a link. */
if (!isImage && self.inLink) {
return;
}
subvalue += character;
queue = '';
index++;
/* Eat the content. */
length = value.length;
now = eat.now();
depth = 0;
now.column += index;
now.offset += index;
while (index < length) {
subqueue = character = value.charAt(index);
if (character === C_TICK) {
/* Inline-code in link content. */
count = 1;
while (value.charAt(index + 1) === C_TICK) {
subqueue += character;
index++;
count++;
}
if (!opening) {
opening = count;
} else if (count >= opening) {
opening = 0;
}
} else if (character === C_BACKSLASH) {
/* Allow brackets to be escaped. */
index++;
subqueue += value.charAt(index);
/* In GFM mode, brackets in code still count.
* In all other modes, they don’t. This empty
* block prevents the next statements are
* entered. */
} else if ((!opening || gfm) && character === C_BRACKET_OPEN) {
depth++;
} else if ((!opening || gfm) && character === C_BRACKET_CLOSE) {
if (depth) {
depth--;
} else {
/* Allow white-space between content and
* url in GFM mode. */
if (gfm) {
while (index < length) {
character = value.charAt(index + 1);
if (!whitespace(character)) {
break;
}
subqueue += character;
index++;
}
}
if (value.charAt(index + 1) !== C_PAREN_OPEN) {
return;
}
subqueue += C_PAREN_OPEN;
closed = true;
index++;
break;
}
}
queue += subqueue;
subqueue = '';
index++;
}
/* Eat the content closing. */
if (!closed) {
return;
}
content = queue;
subvalue += queue + subqueue;
index++;
/* Eat white-space. */
while (index < length) {
character = value.charAt(index);
if (!whitespace(character)) {
break;
}
subvalue += character;
index++;
}
/* Eat the URL. */
character = value.charAt(index);
markers = commonmark ? COMMONMARK_LINK_MARKERS : LINK_MARKERS;
queue = '';
beforeURL = subvalue;
if (character === C_LT) {
index++;
beforeURL += C_LT;
while (index < length) {
character = value.charAt(index);
if (character === C_GT) {
break;
}
if (commonmark && character === '\n') {
return;
}
queue += character;
index++;
}
if (value.charAt(index) !== C_GT) {
return;
}
subvalue += C_LT + queue + C_GT;
url = queue;
index++;
} else {
character = null;
subqueue = '';
while (index < length) {
character = value.charAt(index);
if (subqueue && has(markers, character)) {
break;
}
if (whitespace(character)) {
if (commonmark) {
break;
}
subqueue += character;
} else {
if (character === C_PAREN_OPEN) {
depth++;
} else if (character === C_PAREN_CLOSE) {
if (depth === 0) {
break;
}
depth--;
}
queue += subqueue;
subqueue = '';
if (character === C_BACKSLASH) {
queue += C_BACKSLASH; ...n/a
function reference(eat, value, silent) {
var self = this;
var character = value.charAt(0);
var index = 0;
var length = value.length;
var subvalue = '';
var intro = '';
var type = T_LINK;
var referenceType = REFERENCE_TYPE_SHORTCUT;
var content;
var identifier;
var now;
var node;
var exit;
var queue;
var bracketed;
var depth;
/* Check whether we’re eating an image. */
if (character === '!') {
type = T_IMAGE;
intro = character;
character = value.charAt(++index);
}
if (character !== C_BRACKET_OPEN) {
return;
}
index++;
intro += character;
queue = '';
/* Check whether we’re eating a footnote. */
if (
self.options.footnotes &&
type === T_LINK &&
value.charAt(index) === C_CARET
) {
intro += C_CARET;
index++;
type = T_FOOTNOTE;
}
/* Eat the text. */
depth = 0;
while (index < length) {
character = value.charAt(index);
if (character === C_BRACKET_OPEN) {
bracketed = true;
depth++;
} else if (character === C_BRACKET_CLOSE) {
if (!depth) {
break;
}
depth--;
}
if (character === C_BACKSLASH) {
queue += C_BACKSLASH;
character = value.charAt(++index);
}
queue += character;
index++;
}
subvalue = content = queue;
character = value.charAt(index);
if (character !== C_BRACKET_CLOSE) {
return;
}
index++;
subvalue += character;
queue = '';
while (index < length) {
character = value.charAt(index);
if (!whitespace(character)) {
break;
}
queue += character;
index++;
}
character = value.charAt(index);
if (character === C_BRACKET_OPEN) {
identifier = '';
queue += character;
index++;
while (index < length) {
character = value.charAt(index);
if (character === C_BRACKET_OPEN || character === C_BRACKET_CLOSE) {
break;
}
if (character === C_BACKSLASH) {
identifier += C_BACKSLASH;
character = value.charAt(++index);
}
identifier += character;
index++;
}
character = value.charAt(index);
if (character === C_BRACKET_CLOSE) {
referenceType = identifier ? REFERENCE_TYPE_FULL : REFERENCE_TYPE_COLLAPSED;
queue += identifier + character;
index++;
} else {
identifier = '';
}
subvalue += queue;
queue = '';
} else {
if (!content) {
return;
}
identifier = content;
}
/* Brackets cannot be inside the identifier. */
if (referenceType !== REFERENCE_TYPE_FULL && bracketed) {
return;
}
/* Inline footnotes cannot have an identifier. */
if (type === T_FOOTNOTE && referenceType !== REFERENCE_TYPE_SHORTCUT) {
type = T_LINK;
intro = C_BRACKET_OPEN + C_CARET;
content = C_CARET + content;
}
subvalue = intro + subvalue;
if (type === T_LINK && self.inLink) {
return null;
}
/* istanbul ignore if - never used (yet) */
if (silent) {
return true;
}
if (type === T_FOOTNOTE && content.indexOf(' ') !== -1) {
return eat(subvalue)({
type: 'footnote',
children: this.tokenizeInline(content, eat.now())
});
}
now = eat.now();
now.column += intro.length;
now.offset += intro.length;
identifier = referenceType === REFERENCE_TYPE_FULL ? identifier : content;
node = {
type: type + 'Reference',
identifier: normalize(identifier)
};
if (type === T_LINK || type === T_IMAGE) {
node.referenceType = referenceType;
}
if (type === T_LINK) {
exit = self.enterLink();
node.children = self.tokenizeInline(content, now);
exit();
} else if (type === T_IMAGE) {
node.alt = self.decode.raw(self.unescape(content), now) || null;
}
return eat(subvalue)(node);
}n/a
function strong(eat, value, silent) {
var self = this;
var index = 0;
var character = value.charAt(index);
var now;
var pedantic;
var marker;
var queue;
var subvalue;
var length;
var prev;
if (
(character !== C_ASTERISK && character !== C_UNDERSCORE) ||
value.charAt(++index) !== character
) {
return;
}
pedantic = self.options.pedantic;
marker = character;
subvalue = marker + marker;
length = value.length;
index++;
queue = character = '';
if (pedantic && whitespace(value.charAt(index))) {
return;
}
while (index < length) {
prev = character;
character = value.charAt(index);
if (
character === marker &&
value.charAt(index + 1) === marker &&
(!pedantic || !whitespace(prev))
) {
character = value.charAt(index + 2);
if (character !== marker) {
if (!trim(queue)) {
return;
}
/* istanbul ignore if - never used (yet) */
if (silent) {
return true;
}
now = eat.now();
now.column += 2;
now.offset += 2;
return eat(subvalue + queue + subvalue)({
type: 'strong',
children: self.tokenizeInline(queue, now)
});
}
}
if (!pedantic && character === '\\') {
queue += character;
character = value.charAt(++index);
}
queue += character;
index++;
}
}n/a
function text(eat, value, silent) {
var self = this;
var methods;
var tokenizers;
var index;
var length;
var subvalue;
var position;
var tokenizer;
var name;
var min;
var now;
/* istanbul ignore if - never used (yet) */
if (silent) {
return true;
}
methods = self.inlineMethods;
length = methods.length;
tokenizers = self.inlineTokenizers;
index = -1;
min = value.length;
while (++index < length) {
name = methods[index];
if (name === 'text' || !tokenizers[name]) {
continue;
}
tokenizer = tokenizers[name].locator;
if (!tokenizer) {
eat.file.fail('Missing locator: `' + name + '`');
}
position = tokenizer.call(self, value, 1);
if (position !== -1 && position < min) {
min = position;
}
}
subvalue = value.slice(0, min);
now = eat.now();
self.decode(subvalue, now, function (content, position, source) {
eat(source || content)({
type: 'text',
value: content
});
});
}n/a
function url(eat, value, silent) {
var self = this;
var subvalue;
var content;
var character;
var index;
var position;
var protocol;
var match;
var length;
var queue;
var parenCount;
var nextCharacter;
var exit;
if (!self.options.gfm) {
return;
}
subvalue = '';
index = -1;
length = PROTOCOLS_LENGTH;
while (++index < length) {
protocol = PROTOCOLS[index];
match = value.slice(0, protocol.length);
if (match.toLowerCase() === protocol) {
subvalue = match;
break;
}
}
if (!subvalue) {
return;
}
index = subvalue.length;
length = value.length;
queue = '';
parenCount = 0;
while (index < length) {
character = value.charAt(index);
if (whitespace(character) || character === C_LT) {
break;
}
if (
character === '.' ||
character === ',' ||
character === ':' ||
character === ';' ||
character === '"' ||
character === '\'' ||
character === ')' ||
character === ']'
) {
nextCharacter = value.charAt(index + 1);
if (!nextCharacter || whitespace(nextCharacter)) {
break;
}
}
if (character === C_PAREN_OPEN || character === C_BRACKET_OPEN) {
parenCount++;
}
if (character === C_PAREN_CLOSE || character === C_BRACKET_CLOSE) {
parenCount--;
if (parenCount < 0) {
break;
}
}
queue += character;
index++;
}
if (!queue) {
return;
}
subvalue += queue;
content = subvalue;
if (protocol === MAILTO_PROTOCOL) {
position = queue.indexOf(C_AT_SIGN);
if (position === -1 || position === length - 1) {
return;
}
content = content.substr(MAILTO_PROTOCOL.length);
}
/* istanbul ignore if - never used (yet) */
if (silent) {
return true;
}
exit = self.enterLink();
content = self.tokenizeInline(content, eat.now());
exit();
return eat(subvalue)({
type: 'link',
title: null,
url: decode(subvalue),
children: content
});
}n/a
function processor() {
var destination = unified();
var length = attachers.length;
var index = -1;
while (++index < length) {
destination.use.apply(null, attachers[index]);
}
destination.data(extend(true, {}, namespace));
return destination;
}n/a
function Of() {
if (!(this instanceof Of)) {
return new From(arguments);
}
return Super.apply(this, arguments);
}n/a
function Of() {
if (!(this instanceof Of)) {
return new From(arguments);
}
return Super.apply(this, arguments);
}n/a
function data(key, value) {
if (string(key)) {
/* Set `key`. */
if (arguments.length === 2) {
assertUnfrozen('data', frozen);
namespace[key] = value;
return processor;
}
/* Get `key`. */
return (has(namespace, key) && namespace[key]) || null;
}
/* Set space. */
if (key) {
assertUnfrozen('data', frozen);
namespace = key;
return processor;
}
/* Get space. */
return namespace;
}n/a
function freeze() {
var values;
var plugin;
var options;
var transformer;
if (frozen) {
return processor;
}
while (++freezeIndex < attachers.length) {
values = attachers[freezeIndex];
plugin = values[0];
options = values[1];
transformer = null;
if (options === false) {
continue;
}
if (options === true) {
values[1] = undefined;
}
transformer = plugin.apply(processor, values.slice(1));
if (func(transformer)) {
transformers.use(transformer);
}
}
frozen = true;
freezeIndex = Infinity;
return processor;
}...
'use strict';
var unified = require('unified');
var parse = require('remark-parse');
var stringify = require('remark-stringify');
module.exports = unified().use(parse).use(stringify).freeze();
...function parse(doc) {
var file = vfile(doc);
var Parser;
freeze();
Parser = processor.Parser;
assertParser('parse', Parser);
if (newable(Parser)) {
return new Parser(String(file), file).parse();
}
return Parser(String(file), file); // eslint-disable-line new-cap
}n/a
function process(doc, cb) {
freeze();
assertParser('process', processor.Parser);
assertCompiler('process', processor.Compiler);
if (!cb) {
return new Promise(executor);
}
executor(null, cb);
function executor(resolve, reject) {
var file = vfile(doc);
pipeline.run(processor, {file: file}, done);
function done(err) {
if (err) {
reject(err);
} else if (resolve) {
resolve(file);
} else {
cb(null, file);
}
}
}
}...
```js
var remark = require('remark');
var lint = require('remark-lint');
var html = require('remark-html');
var report = require('vfile-reporter');
remark().use(lint).use(html).process('## Hello world!', function (err, file
) {
console.error(report(err || file));
console.log(String(file));
});
```
Yields:
...function processSync(doc) {
var complete = false;
var file;
freeze();
assertParser('processSync', processor.Parser);
assertCompiler('processSync', processor.Compiler);
file = vfile(doc);
process(file, done);
assertDone('processSync', 'process', complete);
return file;
function done(err) {
complete = true;
bail(err);
}
}n/a
function run(node, file, cb) {
assertNode(node);
freeze();
if (!cb && func(file)) {
cb = file;
file = null;
}
if (!cb) {
return new Promise(executor);
}
executor(null, cb);
function executor(resolve, reject) {
transformers.run(node, vfile(file), done);
function done(err, tree, file) {
tree = tree || node;
if (err) {
reject(err);
} else if (resolve) {
resolve(tree);
} else {
cb(null, tree, file);
}
}
}
}n/a
function runSync(node, file) {
var complete = false;
var result;
run(node, file, done);
assertDone('runSync', 'run', complete);
return result;
function done(err, tree) {
complete = true;
bail(err);
result = tree;
}
}n/a
function stringify(node, doc) {
var file = vfile(doc);
var Compiler;
freeze();
Compiler = processor.Compiler;
assertCompiler('stringify', Compiler);
assertNode(node);
if (newable(Compiler)) {
return new Compiler(node, file).compile();
}
return Compiler(node, file); // eslint-disable-line new-cap
}n/a
function use(value) {
var settings;
assertUnfrozen('use', frozen);
if (value === null || value === undefined) {
/* Empty */
} else if (func(value)) {
addPlugin.apply(null, arguments);
} else if (typeof value === 'object') {
if ('length' in value) {
addList(value);
} else {
addPreset(value);
}
} else {
throw new Error('Expected usable value, not `' + value + '`');
}
if (settings) {
namespace.settings = extend(namespace.settings || {}, settings);
}
return processor;
function addPreset(result) {
addList(result.plugins);
if (result.settings) {
settings = extend(settings || {}, result.settings);
}
}
function add(value) {
if (func(value)) {
addPlugin(value);
} else if (typeof value === 'object') {
if ('length' in value) {
addPlugin.apply(null, value);
} else {
addPreset(value);
}
} else {
throw new Error('Expected usable value, not `' + value + '`');
}
}
function addList(plugins) {
var length;
var index;
if (plugins === null || plugins === undefined) {
/* Empty */
} else if (array(plugins)) {
length = plugins.length;
index = -1;
while (++index < length) {
add(plugins[index]);
}
} else {
throw new Error('Expected a list of plugins, not `' + plugins + '`');
}
}
function addPlugin(plugin, value) {
var entry = find(plugin);
if (entry) {
if (plain(entry[1]) && plain(value)) {
value = extend(entry[1], value);
}
entry[1] = value;
} else {
attachers.push(slice.call(arguments));
}
}
}...
'use strict';
var unified = require('unified');
var parse = require('remark-parse');
var stringify = require('remark-stringify');
module.exports = unified().use(parse).use(stringify).freeze();
...