WIP - add extractor, generate snippet_data
This commit is contained in:
21
node_modules/unified/LICENSE
generated
vendored
Normal file
21
node_modules/unified/LICENSE
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2015 Titus Wormer <tituswormer@gmail.com>
|
||||
|
||||
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.
|
||||
466
node_modules/unified/index.js
generated
vendored
Normal file
466
node_modules/unified/index.js
generated
vendored
Normal file
@ -0,0 +1,466 @@
|
||||
'use strict'
|
||||
|
||||
/* Dependencies. */
|
||||
var extend = require('extend')
|
||||
var bail = require('bail')
|
||||
var vfile = require('vfile')
|
||||
var trough = require('trough')
|
||||
var string = require('x-is-string')
|
||||
var plain = require('is-plain-obj')
|
||||
|
||||
/* Expose a frozen processor. */
|
||||
module.exports = unified().freeze()
|
||||
|
||||
var slice = [].slice
|
||||
var own = {}.hasOwnProperty
|
||||
|
||||
/* Process pipeline. */
|
||||
var pipeline = trough()
|
||||
.use(pipelineParse)
|
||||
.use(pipelineRun)
|
||||
.use(pipelineStringify)
|
||||
|
||||
function pipelineParse(p, ctx) {
|
||||
ctx.tree = p.parse(ctx.file)
|
||||
}
|
||||
|
||||
function pipelineRun(p, ctx, next) {
|
||||
p.run(ctx.tree, ctx.file, done)
|
||||
|
||||
function done(err, tree, file) {
|
||||
if (err) {
|
||||
next(err)
|
||||
} else {
|
||||
ctx.tree = tree
|
||||
ctx.file = file
|
||||
next()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function pipelineStringify(p, ctx) {
|
||||
ctx.file.contents = p.stringify(ctx.tree, ctx.file)
|
||||
}
|
||||
|
||||
/* Function to create the first processor. */
|
||||
function unified() {
|
||||
var attachers = []
|
||||
var transformers = trough()
|
||||
var namespace = {}
|
||||
var frozen = false
|
||||
var freezeIndex = -1
|
||||
|
||||
/* Data management. */
|
||||
processor.data = data
|
||||
|
||||
/* Lock. */
|
||||
processor.freeze = freeze
|
||||
|
||||
/* Plug-ins. */
|
||||
processor.attachers = attachers
|
||||
processor.use = use
|
||||
|
||||
/* API. */
|
||||
processor.parse = parse
|
||||
processor.stringify = stringify
|
||||
processor.run = run
|
||||
processor.runSync = runSync
|
||||
processor.process = process
|
||||
processor.processSync = processSync
|
||||
|
||||
/* Expose. */
|
||||
return processor
|
||||
|
||||
/* Create a new processor based on the processor
|
||||
* in the current scope. */
|
||||
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
|
||||
}
|
||||
|
||||
/* Freeze: used to signal a processor that has finished
|
||||
* configuration.
|
||||
*
|
||||
* For example, take unified itself. It’s frozen.
|
||||
* Plug-ins should not be added to it. Rather, it should
|
||||
* be extended, by invoking it, before modifying it.
|
||||
*
|
||||
* In essence, always invoke this when exporting a
|
||||
* processor. */
|
||||
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 (typeof transformer === 'function') {
|
||||
transformers.use(transformer)
|
||||
}
|
||||
}
|
||||
|
||||
frozen = true
|
||||
freezeIndex = Infinity
|
||||
|
||||
return processor
|
||||
}
|
||||
|
||||
/* Data management.
|
||||
* Getter / setter for processor-specific informtion. */
|
||||
function data(key, value) {
|
||||
if (string(key)) {
|
||||
/* Set `key`. */
|
||||
if (arguments.length === 2) {
|
||||
assertUnfrozen('data', frozen)
|
||||
|
||||
namespace[key] = value
|
||||
|
||||
return processor
|
||||
}
|
||||
|
||||
/* Get `key`. */
|
||||
return (own.call(namespace, key) && namespace[key]) || null
|
||||
}
|
||||
|
||||
/* Set space. */
|
||||
if (key) {
|
||||
assertUnfrozen('data', frozen)
|
||||
namespace = key
|
||||
return processor
|
||||
}
|
||||
|
||||
/* Get space. */
|
||||
return namespace
|
||||
}
|
||||
|
||||
/* Plug-in management.
|
||||
*
|
||||
* Pass it:
|
||||
* * an attacher and options,
|
||||
* * a preset,
|
||||
* * a list of presets, attachers, and arguments (list
|
||||
* of attachers and options). */
|
||||
function use(value) {
|
||||
var settings
|
||||
|
||||
assertUnfrozen('use', frozen)
|
||||
|
||||
if (value === null || value === undefined) {
|
||||
/* Empty */
|
||||
} else if (typeof value === 'function') {
|
||||
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 (typeof value === 'function') {
|
||||
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 (typeof plugins === 'object' && 'length' in 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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function find(plugin) {
|
||||
var length = attachers.length
|
||||
var index = -1
|
||||
var entry
|
||||
|
||||
while (++index < length) {
|
||||
entry = attachers[index]
|
||||
|
||||
if (entry[0] === plugin) {
|
||||
return entry
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse a file (in string or VFile representation)
|
||||
* into a Unist node using the `Parser` on the
|
||||
* processor. */
|
||||
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
|
||||
}
|
||||
|
||||
/* Run transforms on a Unist node representation of a file
|
||||
* (in string or VFile representation), async. */
|
||||
function run(node, file, cb) {
|
||||
assertNode(node)
|
||||
freeze()
|
||||
|
||||
if (!cb && typeof file === 'function') {
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Run transforms on a Unist node representation of a file
|
||||
* (in string or VFile representation), sync. */
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
/* Stringify a Unist node representation of a file
|
||||
* (in string or VFile representation) into a string
|
||||
* using the `Compiler` on the processor. */
|
||||
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
|
||||
}
|
||||
|
||||
/* Parse a file (in string or VFile representation)
|
||||
* into a Unist node using the `Parser` on the processor,
|
||||
* then run transforms on that node, and compile the
|
||||
* resulting node using the `Compiler` on the processor,
|
||||
* and store that result on the VFile. */
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Process the given document (in string or VFile
|
||||
* representation), sync. */
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if `func` is a constructor. */
|
||||
function newable(value) {
|
||||
return typeof value === 'function' && keys(value.prototype)
|
||||
}
|
||||
|
||||
/* Check if `value` is an object with keys. */
|
||||
function keys(value) {
|
||||
var key
|
||||
for (key in value) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/* Assert a parser is available. */
|
||||
function assertParser(name, Parser) {
|
||||
if (typeof Parser !== 'function') {
|
||||
throw new Error('Cannot `' + name + '` without `Parser`')
|
||||
}
|
||||
}
|
||||
|
||||
/* Assert a compiler is available. */
|
||||
function assertCompiler(name, Compiler) {
|
||||
if (typeof Compiler !== 'function') {
|
||||
throw new Error('Cannot `' + name + '` without `Compiler`')
|
||||
}
|
||||
}
|
||||
|
||||
/* Assert the processor is not frozen. */
|
||||
function assertUnfrozen(name, frozen) {
|
||||
if (frozen) {
|
||||
throw new Error(
|
||||
[
|
||||
'Cannot invoke `' + name + '` on a frozen processor.\nCreate a new ',
|
||||
'processor first, by invoking it: use `processor()` instead of ',
|
||||
'`processor`.'
|
||||
].join('')
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/* Assert `node` is a Unist node. */
|
||||
function assertNode(node) {
|
||||
if (!node || !string(node.type)) {
|
||||
throw new Error('Expected node, got `' + node + '`')
|
||||
}
|
||||
}
|
||||
|
||||
/* Assert that `complete` is `true`. */
|
||||
function assertDone(name, asyncName, complete) {
|
||||
if (!complete) {
|
||||
throw new Error(
|
||||
'`' + name + '` finished async. Use `' + asyncName + '` instead'
|
||||
)
|
||||
}
|
||||
}
|
||||
21
node_modules/unified/node_modules/vfile/LICENSE
generated
vendored
Normal file
21
node_modules/unified/node_modules/vfile/LICENSE
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2015 Titus Wormer <tituswormer@gmail.com>
|
||||
|
||||
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.
|
||||
169
node_modules/unified/node_modules/vfile/core.js
generated
vendored
Normal file
169
node_modules/unified/node_modules/vfile/core.js
generated
vendored
Normal file
@ -0,0 +1,169 @@
|
||||
'use strict';
|
||||
|
||||
var path = require('path');
|
||||
var replace = require('replace-ext');
|
||||
var buffer = require('is-buffer');
|
||||
|
||||
module.exports = VFile;
|
||||
|
||||
var own = {}.hasOwnProperty;
|
||||
var proto = VFile.prototype;
|
||||
|
||||
proto.toString = toString;
|
||||
|
||||
/* Order of setting (least specific to most), we need this because
|
||||
* otherwise `{stem: 'a', path: '~/b.js'}` would throw, as a path
|
||||
* is needed before a stem can be set. */
|
||||
var order = [
|
||||
'history',
|
||||
'path',
|
||||
'basename',
|
||||
'stem',
|
||||
'extname',
|
||||
'dirname'
|
||||
];
|
||||
|
||||
/* Construct a new file. */
|
||||
function VFile(options) {
|
||||
var prop;
|
||||
var index;
|
||||
var length;
|
||||
|
||||
if (!options) {
|
||||
options = {};
|
||||
} else if (typeof options === 'string' || buffer(options)) {
|
||||
options = {contents: options};
|
||||
} else if ('message' in options && 'messages' in options) {
|
||||
return options;
|
||||
}
|
||||
|
||||
if (!(this instanceof VFile)) {
|
||||
return new VFile(options);
|
||||
}
|
||||
|
||||
this.data = {};
|
||||
this.messages = [];
|
||||
this.history = [];
|
||||
this.cwd = process.cwd();
|
||||
|
||||
/* Set path related properties in the correct order. */
|
||||
index = -1;
|
||||
length = order.length;
|
||||
|
||||
while (++index < length) {
|
||||
prop = order[index];
|
||||
|
||||
if (own.call(options, prop)) {
|
||||
this[prop] = options[prop];
|
||||
}
|
||||
}
|
||||
|
||||
/* Set non-path related properties. */
|
||||
for (prop in options) {
|
||||
if (order.indexOf(prop) === -1) {
|
||||
this[prop] = options[prop];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Access full path (`~/index.min.js`). */
|
||||
Object.defineProperty(proto, 'path', {
|
||||
get: function () {
|
||||
return this.history[this.history.length - 1];
|
||||
},
|
||||
set: function (path) {
|
||||
assertNonEmpty(path, 'path');
|
||||
|
||||
if (path !== this.path) {
|
||||
this.history.push(path);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/* Access parent path (`~`). */
|
||||
Object.defineProperty(proto, 'dirname', {
|
||||
get: function () {
|
||||
return typeof this.path === 'string' ? path.dirname(this.path) : undefined;
|
||||
},
|
||||
set: function (dirname) {
|
||||
assertPath(this.path, 'dirname');
|
||||
this.path = path.join(dirname || '', this.basename);
|
||||
}
|
||||
});
|
||||
|
||||
/* Access basename (`index.min.js`). */
|
||||
Object.defineProperty(proto, 'basename', {
|
||||
get: function () {
|
||||
return typeof this.path === 'string' ? path.basename(this.path) : undefined;
|
||||
},
|
||||
set: function (basename) {
|
||||
assertNonEmpty(basename, 'basename');
|
||||
assertPart(basename, 'basename');
|
||||
this.path = path.join(this.dirname || '', basename);
|
||||
}
|
||||
});
|
||||
|
||||
/* Access extname (`.js`). */
|
||||
Object.defineProperty(proto, 'extname', {
|
||||
get: function () {
|
||||
return typeof this.path === 'string' ? path.extname(this.path) : undefined;
|
||||
},
|
||||
set: function (extname) {
|
||||
var ext = extname || '';
|
||||
|
||||
assertPart(ext, 'extname');
|
||||
assertPath(this.path, 'extname');
|
||||
|
||||
if (ext) {
|
||||
if (ext.charAt(0) !== '.') {
|
||||
throw new Error('`extname` must start with `.`');
|
||||
}
|
||||
|
||||
if (ext.indexOf('.', 1) !== -1) {
|
||||
throw new Error('`extname` cannot contain multiple dots');
|
||||
}
|
||||
}
|
||||
|
||||
this.path = replace(this.path, ext);
|
||||
}
|
||||
});
|
||||
|
||||
/* Access stem (`index.min`). */
|
||||
Object.defineProperty(proto, 'stem', {
|
||||
get: function () {
|
||||
return typeof this.path === 'string' ? path.basename(this.path, this.extname) : undefined;
|
||||
},
|
||||
set: function (stem) {
|
||||
assertNonEmpty(stem, 'stem');
|
||||
assertPart(stem, 'stem');
|
||||
this.path = path.join(this.dirname || '', stem + (this.extname || ''));
|
||||
}
|
||||
});
|
||||
|
||||
/* Get the value of the file. */
|
||||
function toString(encoding) {
|
||||
var value = this.contents || '';
|
||||
return buffer(value) ? value.toString(encoding) : String(value);
|
||||
}
|
||||
|
||||
/* Assert that `part` is not a path (i.e., does
|
||||
* not contain `path.sep`). */
|
||||
function assertPart(part, name) {
|
||||
if (part.indexOf(path.sep) !== -1) {
|
||||
throw new Error('`' + name + '` cannot be a path: did not expect `' + path.sep + '`');
|
||||
}
|
||||
}
|
||||
|
||||
/* Assert that `part` is not empty. */
|
||||
function assertNonEmpty(part, name) {
|
||||
if (!part) {
|
||||
throw new Error('`' + name + '` cannot be empty');
|
||||
}
|
||||
}
|
||||
|
||||
/* Assert `path` exists. */
|
||||
function assertPath(path, name) {
|
||||
if (!path) {
|
||||
throw new Error('Setting `' + name + '` requires `path` to be set too');
|
||||
}
|
||||
}
|
||||
53
node_modules/unified/node_modules/vfile/index.js
generated
vendored
Normal file
53
node_modules/unified/node_modules/vfile/index.js
generated
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
'use strict';
|
||||
|
||||
var VMessage = require('vfile-message');
|
||||
var VFile = require('./core.js');
|
||||
|
||||
module.exports = VFile;
|
||||
|
||||
var proto = VFile.prototype;
|
||||
|
||||
proto.message = message;
|
||||
proto.info = info;
|
||||
proto.fail = fail;
|
||||
|
||||
/* Slight backwards compatibility. Remove in the future. */
|
||||
proto.warn = message;
|
||||
|
||||
/* Create a message with `reason` at `position`.
|
||||
* When an error is passed in as `reason`, copies the stack. */
|
||||
function message(reason, position, origin) {
|
||||
var filePath = this.path;
|
||||
var message = new VMessage(reason, position, origin);
|
||||
|
||||
if (filePath) {
|
||||
message.name = filePath + ':' + message.name;
|
||||
message.file = filePath;
|
||||
}
|
||||
|
||||
message.fatal = false;
|
||||
|
||||
this.messages.push(message);
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
/* Fail. Creates a vmessage, associates it with the file,
|
||||
* and throws it. */
|
||||
function fail() {
|
||||
var message = this.message.apply(this, arguments);
|
||||
|
||||
message.fatal = true;
|
||||
|
||||
throw message;
|
||||
}
|
||||
|
||||
/* Info. Creates a vmessage, associates it with the file,
|
||||
* and marks the fatality as null. */
|
||||
function info() {
|
||||
var message = this.message.apply(this, arguments);
|
||||
|
||||
message.fatal = null;
|
||||
|
||||
return message;
|
||||
}
|
||||
132
node_modules/unified/node_modules/vfile/package.json
generated
vendored
Normal file
132
node_modules/unified/node_modules/vfile/package.json
generated
vendored
Normal file
@ -0,0 +1,132 @@
|
||||
{
|
||||
"_from": "vfile@^2.0.0",
|
||||
"_id": "vfile@2.3.0",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-ASt4mBUHcTpMKD/l5Q+WJXNtshlWxOogYyGYYrg4lt/vuRjC1EFQtlAofL5VmtVNIZJzWYFJjzGWZ0Gw8pzW1w==",
|
||||
"_location": "/unified/vfile",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "vfile@^2.0.0",
|
||||
"name": "vfile",
|
||||
"escapedName": "vfile",
|
||||
"rawSpec": "^2.0.0",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "^2.0.0"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/unified"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/vfile/-/vfile-2.3.0.tgz",
|
||||
"_shasum": "e62d8e72b20e83c324bc6c67278ee272488bf84a",
|
||||
"_spec": "vfile@^2.0.0",
|
||||
"_where": "/Users/stefanfejes/Projects/30-seconds-of-python-code/node_modules/unified",
|
||||
"author": {
|
||||
"name": "Titus Wormer",
|
||||
"email": "tituswormer@gmail.com",
|
||||
"url": "http://wooorm.com"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/vfile/vfile/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Titus Wormer",
|
||||
"email": "tituswormer@gmail.com",
|
||||
"url": "http://wooorm.com"
|
||||
},
|
||||
{
|
||||
"name": "Brendan Abbott",
|
||||
"email": "brendan.abbott@temando.com"
|
||||
},
|
||||
{
|
||||
"name": "Denys Dovhan",
|
||||
"email": "email@denysdovhan.com"
|
||||
},
|
||||
{
|
||||
"name": "Kyle Mathews",
|
||||
"email": "mathews.kyle@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Shinnosuke Watanabe",
|
||||
"email": "snnskwtnb@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Sindre Sorhus",
|
||||
"email": "sindresorhus@gmail.com"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"is-buffer": "^1.1.4",
|
||||
"replace-ext": "1.0.0",
|
||||
"unist-util-stringify-position": "^1.0.0",
|
||||
"vfile-message": "^1.0.0"
|
||||
},
|
||||
"deprecated": false,
|
||||
"description": "Virtual file format for text processing",
|
||||
"devDependencies": {
|
||||
"browserify": "^14.0.0",
|
||||
"esmangle": "^1.0.0",
|
||||
"nyc": "^11.0.0",
|
||||
"remark-cli": "^4.0.0",
|
||||
"remark-preset-wooorm": "^3.0.0",
|
||||
"tape": "^4.4.0",
|
||||
"xo": "^0.18.0"
|
||||
},
|
||||
"files": [
|
||||
"core.js",
|
||||
"index.js"
|
||||
],
|
||||
"homepage": "https://github.com/vfile/vfile#readme",
|
||||
"keywords": [
|
||||
"virtual",
|
||||
"file",
|
||||
"text",
|
||||
"processing",
|
||||
"message",
|
||||
"warning",
|
||||
"error",
|
||||
"remark",
|
||||
"retext"
|
||||
],
|
||||
"license": "MIT",
|
||||
"name": "vfile",
|
||||
"nyc": {
|
||||
"check-coverage": true,
|
||||
"lines": 100,
|
||||
"functions": 100,
|
||||
"branches": 100
|
||||
},
|
||||
"remarkConfig": {
|
||||
"plugins": [
|
||||
"preset-wooorm"
|
||||
]
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/vfile/vfile.git"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "npm run build-md && npm run build-bundle && npm run build-mangle",
|
||||
"build-bundle": "browserify index.js -s VFile > vfile.js",
|
||||
"build-mangle": "esmangle vfile.js > vfile.min.js",
|
||||
"build-md": "remark . -qfo",
|
||||
"lint": "xo",
|
||||
"test": "npm run build && npm run lint && npm run test-coverage",
|
||||
"test-api": "node test",
|
||||
"test-coverage": "nyc --reporter lcov tape test.js"
|
||||
},
|
||||
"version": "2.3.0",
|
||||
"xo": {
|
||||
"space": true,
|
||||
"esnext": false,
|
||||
"rules": {
|
||||
"unicorn/no-new-buffer": "off"
|
||||
},
|
||||
"ignores": [
|
||||
"vfile.js"
|
||||
]
|
||||
}
|
||||
}
|
||||
285
node_modules/unified/node_modules/vfile/readme.md
generated
vendored
Normal file
285
node_modules/unified/node_modules/vfile/readme.md
generated
vendored
Normal file
@ -0,0 +1,285 @@
|
||||
# ![vfile][]
|
||||
|
||||
[![Build Status][build-badge]][build-status]
|
||||
[![Coverage Status][coverage-badge]][coverage-status]
|
||||
|
||||
**VFile** is a virtual file format used by [**unified**][unified],
|
||||
a text processing umbrella (it powers [**retext**][retext] for
|
||||
natural language, [**remark**][remark] for markdown, and
|
||||
[**rehype**][rehype] for HTML). Each processors that parse, transform,
|
||||
and compile text, and need a virtual representation of files and a
|
||||
place to store [messages][] about them. Plus, they work in the browser.
|
||||
**VFile** provides these requirements at a small size, in IE 9 and up.
|
||||
|
||||
> **VFile** is different from the excellent [**vinyl**][vinyl]
|
||||
> in that it has a smaller API, a smaller size, and focuses on
|
||||
> [messages][].
|
||||
|
||||
VFile can be used anywhere where files need a lightweight representation.
|
||||
For example, it’s used in:
|
||||
|
||||
* [`documentation`](https://github.com/documentationjs/documentation)
|
||||
— The documentation system for modern JavaScript
|
||||
* [`weh`](https://github.com/wehjs/weh)
|
||||
— Declarative small site generator
|
||||
* [`geojsonhint`](https://github.com/mapbox/geojsonhint)
|
||||
— Complete, fast, standards-based validation for geojson
|
||||
|
||||
## Installation
|
||||
|
||||
[npm][]:
|
||||
|
||||
```bash
|
||||
npm install vfile
|
||||
```
|
||||
|
||||
## Table of Contents
|
||||
|
||||
* [Usage](#usage)
|
||||
* [Utilities](#utilities)
|
||||
* [Reporters](#reporters)
|
||||
* [API](#api)
|
||||
* [VFile(\[options\])](#vfileoptions)
|
||||
* [vfile.contents](#vfilecontents)
|
||||
* [vfile.cwd](#vfilecwd)
|
||||
* [vfile.path](#vfilepath)
|
||||
* [vfile.basename](#vfilebasename)
|
||||
* [vfile.stem](#vfilestem)
|
||||
* [vfile.extname](#vfileextname)
|
||||
* [vfile.dirname](#vfiledirname)
|
||||
* [vfile.history](#vfilehistory)
|
||||
* [vfile.messages](#vfilemessages)
|
||||
* [vfile.data](#vfiledata)
|
||||
* [VFile#toString(\[encoding\])](#vfiletostringencoding)
|
||||
* [VFile#message(reason\[, position\]\[, origin\])](#vfilemessagereason-position-origin)
|
||||
* [VFile#info(reason\[, position\]\[, origin\])](#vfileinforeason-position-origin)
|
||||
* [VFile#fail(reason\[, position\]\[, origin\])](#vfilefailreason-position-origin)
|
||||
* [License](#license)
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
var vfile = require('vfile');
|
||||
|
||||
var file = vfile({path: '~/example.txt', contents: 'Alpha *braavo* charlie.'});
|
||||
|
||||
file.path; //=> '~/example.txt'
|
||||
file.dirname; //=> '~'
|
||||
|
||||
file.extname = '.md';
|
||||
|
||||
file.basename; //=> 'example.md'
|
||||
|
||||
file.basename = 'index.text';
|
||||
|
||||
file.history; //=> ['~/example.txt', '~/example.md', '~/index.text']
|
||||
|
||||
file.message('`braavo` is misspelt; did you mean `bravo`?', {line: 1, column: 8});
|
||||
|
||||
console.log(file.messages);
|
||||
```
|
||||
|
||||
Yields:
|
||||
|
||||
```js
|
||||
[ { [~/index.text:1:8: `braavo` is misspelt; did you mean `bravo`?]
|
||||
message: '`braavo` is misspelt; did you mean `bravo`?',
|
||||
name: '~/index.text:1:8',
|
||||
file: '~/index.text',
|
||||
reason: '`braavo` is misspelt; did you mean `bravo`?',
|
||||
line: 1,
|
||||
column: 8,
|
||||
location: { start: [Object], end: [Object] },
|
||||
ruleId: null,
|
||||
source: null,
|
||||
fatal: false } ]
|
||||
```
|
||||
|
||||
## Utilities
|
||||
|
||||
The following list of projects includes tools for working with virtual
|
||||
files. See [**Unist**][unist] for projects working with nodes.
|
||||
|
||||
* [`convert-vinyl-to-vfile`](https://github.com/dustinspecker/convert-vinyl-to-vfile)
|
||||
— Convert from [Vinyl][]
|
||||
* [`is-vfile-message`](https://github.com/shinnn/is-vfile-message)
|
||||
— Check if a value is a `VMessage` object
|
||||
* [`to-vfile`](https://github.com/vfile/to-vfile)
|
||||
— Create a virtual file from a file-path (and optionally read it)
|
||||
* [`vfile-find-down`](https://github.com/vfile/vfile-find-down)
|
||||
— Find files by searching the file system downwards
|
||||
* [`vfile-find-up`](https://github.com/vfile/vfile-find-up)
|
||||
— Find files by searching the file system upwards
|
||||
* [`vfile-location`](https://github.com/vfile/vfile-location)
|
||||
— Convert between line/column- and range-based locations
|
||||
* [`vfile-statistics`](https://github.com/vfile/vfile-statistics)
|
||||
— Count messages per category
|
||||
* [`vfile-messages-to-vscode-diagnostics`](https://github.com/shinnn/vfile-messages-to-vscode-diagnostics)
|
||||
— Convert to VS Code diagnostics
|
||||
* [`vfile-sort`](https://github.com/vfile/vfile-sort)
|
||||
— Sort messages by line/column
|
||||
* [`vfile-to-eslint`](https://github.com/vfile/vfile-to-eslint)
|
||||
— Convert VFiles to ESLint formatter compatible output
|
||||
|
||||
## Reporters
|
||||
|
||||
The following list of projects show linting results for given virtual files.
|
||||
Reporters _must_ accept `Array.<VFile>` as their first argument, and return
|
||||
`string`. Reporters _may_ accept other values too, in which case it’s suggested
|
||||
to stick to `vfile-reporter`s interface.
|
||||
|
||||
* [`vfile-reporter`][reporter]
|
||||
— Stylish reporter
|
||||
* [`vfile-reporter-json`](https://github.com/vfile/vfile-reporter-json)
|
||||
— JSON reporter
|
||||
* [`vfile-reporter-pretty`](https://github.com/vfile/vfile-reporter-pretty)
|
||||
— Pretty reporter
|
||||
|
||||
## API
|
||||
|
||||
### `VFile([options])`
|
||||
|
||||
Create a new virtual file. If `options` is `string` or `Buffer`, treats
|
||||
it as `{contents: options}`. If `options` is a `VFile`, returns it.
|
||||
All other options are set on the newly created `vfile`.
|
||||
|
||||
Path related properties are set in the following order (least specific
|
||||
to most specific): `history`, `path`, `basename`, `stem`, `extname`,
|
||||
`dirname`.
|
||||
|
||||
It’s not possible to set either `dirname` or `extname` without setting
|
||||
either `history`, `path`, `basename`, or `stem` as well.
|
||||
|
||||
###### Example
|
||||
|
||||
```js
|
||||
vfile();
|
||||
vfile('console.log("alpha");');
|
||||
vfile(Buffer.from('exit 1'));
|
||||
vfile({path: path.join(__dirname, 'readme.md')});
|
||||
vfile({stem: 'readme', extname: '.md', dirname: __dirname});
|
||||
vfile({other: 'properties', are: 'copied', ov: {e: 'r'}});
|
||||
```
|
||||
|
||||
### `vfile.contents`
|
||||
|
||||
`Buffer`, `string`, `null` — Raw value.
|
||||
|
||||
### `vfile.cwd`
|
||||
|
||||
`string` — Base of `path`. Defaults to `process.cwd()`.
|
||||
|
||||
### `vfile.path`
|
||||
|
||||
`string?` — Path of `vfile`. Cannot be nullified.
|
||||
|
||||
### `vfile.basename`
|
||||
|
||||
`string?` — Current name (including extension) of `vfile`. Cannot
|
||||
contain path separators. Cannot be nullified either (use
|
||||
`file.path = file.dirname` instead).
|
||||
|
||||
### `vfile.stem`
|
||||
|
||||
`string?` — Name (without extension) of `vfile`. Cannot be nullified,
|
||||
and cannot contain path separators.
|
||||
|
||||
### `vfile.extname`
|
||||
|
||||
`string?` — Extension (with dot) of `vfile`. Cannot be set if
|
||||
there’s no `path` yet and cannot contain path separators.
|
||||
|
||||
### `vfile.dirname`
|
||||
|
||||
`string?` — Path to parent directory of `vfile`. Cannot be set if
|
||||
there’s no `path` yet.
|
||||
|
||||
### `vfile.history`
|
||||
|
||||
`Array.<string>` — List of file-paths the file moved between.
|
||||
|
||||
### `vfile.messages`
|
||||
|
||||
[`Array.<VMessage>`][message] — List of messages associated with the file.
|
||||
|
||||
### `vfile.data`
|
||||
|
||||
`Object` — Place to store custom information. It’s OK to store custom
|
||||
data directly on the `vfile`, moving it to `data` gives a _little_ more
|
||||
privacy.
|
||||
|
||||
### `VFile#toString([encoding])`
|
||||
|
||||
Convert contents of `vfile` to string. If `contents` is a buffer,
|
||||
`encoding` is used to stringify buffers (default: `'utf8'`).
|
||||
|
||||
### `VFile#message(reason[, position][, origin])`
|
||||
|
||||
Associates a message with the file, where `fatal` is set to `false`.
|
||||
Constructs a new [`VMessage`][vmessage] and adds it to
|
||||
[`vfile.messages`][messages].
|
||||
|
||||
##### Returns
|
||||
|
||||
[`VMessage`][vmessage].
|
||||
|
||||
### `VFile#info(reason[, position][, origin])`
|
||||
|
||||
Associates an informational message with the file, where `fatal` is set to
|
||||
`null`. Calls [`#message()`][message] internally.
|
||||
|
||||
##### Returns
|
||||
|
||||
[`VMessage`][vmessage].
|
||||
|
||||
### `VFile#fail(reason[, position][, origin])`
|
||||
|
||||
Associates a fatal message with the file, then immediately throws it.
|
||||
Note: fatal errors mean a file is no longer processable.
|
||||
Calls [`#message()`][message] internally.
|
||||
|
||||
##### Throws
|
||||
|
||||
[`VMessage`][vmessage].
|
||||
|
||||
## License
|
||||
|
||||
[MIT][license] © [Titus Wormer][author]
|
||||
|
||||
<!-- Definitions -->
|
||||
|
||||
[build-badge]: https://img.shields.io/travis/vfile/vfile.svg
|
||||
|
||||
[build-status]: https://travis-ci.org/vfile/vfile
|
||||
|
||||
[coverage-badge]: https://img.shields.io/codecov/c/github/vfile/vfile.svg
|
||||
|
||||
[coverage-status]: https://codecov.io/github/vfile/vfile
|
||||
|
||||
[npm]: https://docs.npmjs.com/cli/install
|
||||
|
||||
[license]: LICENSE
|
||||
|
||||
[author]: http://wooorm.com
|
||||
|
||||
[vfile]: https://cdn.rawgit.com/vfile/vfile/f65510e/logo.svg
|
||||
|
||||
[unified]: https://github.com/unifiedjs/unified
|
||||
|
||||
[retext]: https://github.com/wooorm/retext
|
||||
|
||||
[remark]: https://github.com/wooorm/remark
|
||||
|
||||
[rehype]: https://github.com/wooorm/rehype
|
||||
|
||||
[vinyl]: https://github.com/gulpjs/vinyl
|
||||
|
||||
[unist]: https://github.com/syntax-tree/unist#list-of-utilities
|
||||
|
||||
[reporter]: https://github.com/vfile/vfile-reporter
|
||||
|
||||
[vmessage]: https://github.com/vfile/vfile-message
|
||||
|
||||
[messages]: #vfilemessages
|
||||
|
||||
[message]: #vfilemessagereason-position-origin
|
||||
130
node_modules/unified/package.json
generated
vendored
Normal file
130
node_modules/unified/package.json
generated
vendored
Normal file
@ -0,0 +1,130 @@
|
||||
{
|
||||
"_from": "unified@^6.1.5",
|
||||
"_id": "unified@6.2.0",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-1k+KPhlVtqmG99RaTbAv/usu85fcSRu3wY8X+vnsEhIxNP5VbVIDiXnLqyKIG+UMdyTg0ZX9EI6k2AfjJkHPtA==",
|
||||
"_location": "/unified",
|
||||
"_phantomChildren": {
|
||||
"is-buffer": "1.1.6",
|
||||
"replace-ext": "1.0.0",
|
||||
"unist-util-stringify-position": "1.1.2",
|
||||
"vfile-message": "1.1.1"
|
||||
},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "unified@^6.1.5",
|
||||
"name": "unified",
|
||||
"escapedName": "unified",
|
||||
"rawSpec": "^6.1.5",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "^6.1.5"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/gatsby-transformer-remark"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/unified/-/unified-6.2.0.tgz",
|
||||
"_shasum": "7fbd630f719126d67d40c644b7e3f617035f6dba",
|
||||
"_spec": "unified@^6.1.5",
|
||||
"_where": "/Users/stefanfejes/Projects/30-seconds-of-python-code/node_modules/gatsby-transformer-remark",
|
||||
"author": {
|
||||
"name": "Titus Wormer",
|
||||
"email": "tituswormer@gmail.com",
|
||||
"url": "http://wooorm.com"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/unifiedjs/unified/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Titus Wormer",
|
||||
"email": "tituswormer@gmail.com",
|
||||
"url": "http://wooorm.com"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"bail": "^1.0.0",
|
||||
"extend": "^3.0.0",
|
||||
"is-plain-obj": "^1.1.0",
|
||||
"trough": "^1.0.0",
|
||||
"vfile": "^2.0.0",
|
||||
"x-is-string": "^0.1.0"
|
||||
},
|
||||
"deprecated": false,
|
||||
"description": "Pluggable text processing interface",
|
||||
"devDependencies": {
|
||||
"browserify": "^16.0.0",
|
||||
"esmangle": "^1.0.0",
|
||||
"nyc": "^11.0.0",
|
||||
"prettier": "^1.12.1",
|
||||
"remark-cli": "^5.0.0",
|
||||
"remark-preset-wooorm": "^4.0.0",
|
||||
"tape": "^4.4.0",
|
||||
"xo": "^0.20.0"
|
||||
},
|
||||
"files": [
|
||||
"index.js",
|
||||
"lib"
|
||||
],
|
||||
"homepage": "https://github.com/unifiedjs/unified#readme",
|
||||
"keywords": [
|
||||
"process",
|
||||
"parse",
|
||||
"transform",
|
||||
"compile",
|
||||
"stringify",
|
||||
"rehype",
|
||||
"retext",
|
||||
"remark"
|
||||
],
|
||||
"license": "MIT",
|
||||
"name": "unified",
|
||||
"nyc": {
|
||||
"check-coverage": true,
|
||||
"lines": 100,
|
||||
"functions": 100,
|
||||
"branches": 100
|
||||
},
|
||||
"prettier": {
|
||||
"tabWidth": 2,
|
||||
"useTabs": false,
|
||||
"singleQuote": true,
|
||||
"bracketSpacing": false,
|
||||
"semi": false,
|
||||
"trailingComma": "none"
|
||||
},
|
||||
"remarkConfig": {
|
||||
"plugins": [
|
||||
"preset-wooorm"
|
||||
]
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/unifiedjs/unified.git"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "npm run build-bundle && npm run build-mangle",
|
||||
"build-bundle": "browserify index.js -s unified > unified.js",
|
||||
"build-mangle": "esmangle unified.js > unified.min.js",
|
||||
"format": "remark . -qfo && prettier --write '**/*.js' && xo --fix",
|
||||
"test": "npm run format && npm run build && npm run test-coverage",
|
||||
"test-api": "node test",
|
||||
"test-coverage": "nyc --reporter lcov tape test"
|
||||
},
|
||||
"version": "6.2.0",
|
||||
"xo": {
|
||||
"prettier": true,
|
||||
"esnext": false,
|
||||
"rules": {
|
||||
"guard-for-in": "off",
|
||||
"no-var": "off",
|
||||
"object-shorthand": "off",
|
||||
"prefer-arrow-callback": "off",
|
||||
"unicorn/prefer-type-error": "off"
|
||||
},
|
||||
"ignores": [
|
||||
"unified.js"
|
||||
]
|
||||
}
|
||||
}
|
||||
993
node_modules/unified/readme.md
generated
vendored
Normal file
993
node_modules/unified/readme.md
generated
vendored
Normal file
@ -0,0 +1,993 @@
|
||||
# ![unified][logo]
|
||||
|
||||
[![Build Status][travis-badge]][travis]
|
||||
[![Coverage Status][codecov-badge]][codecov]
|
||||
[![Chat][chat-badge]][chat]
|
||||
|
||||
**unified** is an interface for processing text using syntax trees. It’s what
|
||||
powers [**remark**][remark], [**retext**][retext], and [**rehype**][rehype],
|
||||
but it also allows for processing between multiple syntaxes.
|
||||
|
||||
The website for **unified**, [`unifiedjs.github.io`][site], provides a less
|
||||
technical and more practical introduction to unified. Make sure to visit it
|
||||
and try its introductory [Guides][].
|
||||
|
||||
## Installation
|
||||
|
||||
[npm][]:
|
||||
|
||||
```bash
|
||||
npm install unified
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
var unified = require('unified')
|
||||
var markdown = require('remark-parse')
|
||||
var remark2rehype = require('remark-rehype')
|
||||
var doc = require('rehype-document')
|
||||
var format = require('rehype-format')
|
||||
var html = require('rehype-stringify')
|
||||
var report = require('vfile-reporter')
|
||||
|
||||
unified()
|
||||
.use(markdown)
|
||||
.use(remark2rehype)
|
||||
.use(doc)
|
||||
.use(format)
|
||||
.use(html)
|
||||
.process('# Hello world!', function(err, file) {
|
||||
console.error(report(err || file))
|
||||
console.log(String(file))
|
||||
})
|
||||
```
|
||||
|
||||
Yields:
|
||||
|
||||
```html
|
||||
no issues found
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello world!</h1>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
## Table of Contents
|
||||
|
||||
* [Description](#description)
|
||||
* [API](#api)
|
||||
* [processor()](#processor)
|
||||
* [processor.use(plugin\[, options\])](#processoruseplugin-options)
|
||||
* [processor.parse(file|value)](#processorparsefilevalue)
|
||||
* [processor.stringify(node\[, file\])](#processorstringifynode-file)
|
||||
* [processor.run(node\[, file\]\[, done\])](#processorrunnode-file-done)
|
||||
* [processor.runSync(node\[, file\])](#processorrunsyncnode-file)
|
||||
* [processor.process(file|value\[, done\])](#processorprocessfilevalue-done)
|
||||
* [processor.processSync(file|value)](#processorprocesssyncfilevalue)
|
||||
* [processor.data(key\[, value\])](#processordatakey-value)
|
||||
* [processor.freeze()](#processorfreeze)
|
||||
* [Plugin](#plugin)
|
||||
* [function attacher(\[options\])](#function-attacheroptions)
|
||||
* [function transformer(node, file\[, next\])](#function-transformernode-file-next)
|
||||
* [Preset](#preset)
|
||||
* [Contribute](#contribute)
|
||||
* [Acknowledgments](#acknowledgments)
|
||||
* [License](#license)
|
||||
|
||||
## Description
|
||||
|
||||
**unified** is an interface for processing text using syntax trees. Syntax
|
||||
trees are a representation understandable to programs. Those programs, called
|
||||
[**plugin**][plugin]s, take these trees and modify them, amongst other things.
|
||||
To get to the syntax tree from input text there’s a [**parser**][parser]. To
|
||||
get from that back to text there’s a [**compiler**][compiler]. This is the
|
||||
[**process**][process] of a **processor**.
|
||||
|
||||
```ascii
|
||||
| ....................... process() ......................... |
|
||||
| ......... parse() ..... | run() | ..... stringify() ....... |
|
||||
|
||||
+--------+ +----------+
|
||||
Input ->- | Parser | ->- Syntax Tree ->- | Compiler | ->- Output
|
||||
+--------+ | +----------+
|
||||
X
|
||||
|
|
||||
+--------------+
|
||||
| Transformers |
|
||||
+--------------+
|
||||
```
|
||||
|
||||
###### Processors
|
||||
|
||||
Every processor implements another processor. To create a new processor invoke
|
||||
another processor. This creates a processor that is configured to function the
|
||||
same as its ancestor. But when the descendant processor is configured in the
|
||||
future it does not affect the ancestral processor.
|
||||
|
||||
When processors are exposed from a module (for example, unified itself) they
|
||||
should not be configured directly, as that would change their behaviour for all
|
||||
module users. Those processors are [**frozen**][freeze] and they should be
|
||||
invoked to create a new processor before they are used.
|
||||
|
||||
###### Node
|
||||
|
||||
The syntax trees used in **unified** are [**Unist**][unist] nodes: plain
|
||||
JavaScript objects with a `type` property. The semantics of those `type`s are
|
||||
defined by other projects.
|
||||
|
||||
There are several [utilities][unist-utilities] for working with these nodes.
|
||||
|
||||
###### List of Processors
|
||||
|
||||
The following projects process different syntax trees. They parse text to
|
||||
their respective syntax tree and they compile their syntax trees back to text.
|
||||
These processors can be used as-is, or their parsers and compilers can be mixed
|
||||
and matched with **unified** and other plugins to process between different
|
||||
syntaxes.
|
||||
|
||||
* [**rehype**][rehype] ([**HAST**][hast]) — HTML
|
||||
* [**remark**][remark] ([**MDAST**][mdast]) — Markdown
|
||||
* [**retext**][retext] ([**NLCST**][nlcst]) — Natural language
|
||||
|
||||
###### List of Plugins
|
||||
|
||||
The below plugins work with **unified**, unrelated to what flavour the syntax
|
||||
tree is in:
|
||||
|
||||
* [`unified-diff`](https://github.com/unifiedjs/unified-diff)
|
||||
— Ignore messages for unchanged lines in Travis
|
||||
|
||||
See [**remark**][remark-plugins], [**rehype**][rehype-plugins], and
|
||||
[**retext**][retext-plugins] for lists of their plugins.
|
||||
|
||||
###### File
|
||||
|
||||
When processing documents metadata is often gathered about that document.
|
||||
[**VFile**][vfile] is a virtual file format which stores data and handles
|
||||
metadata and messages for **unified** and its plugins.
|
||||
|
||||
There are several [utilities][vfile-utilities] for working with these files.
|
||||
|
||||
###### Configuration
|
||||
|
||||
To configure a processor invoke its [`use`][use] method, supply it a
|
||||
[**plugin**][plugin], and optionally settings.
|
||||
|
||||
###### Integrations
|
||||
|
||||
**unified** can integrate with the file-system through
|
||||
[`unified-engine`][engine]. On top of that, CLI apps can be created with
|
||||
[`unified-args`][args], Gulp plugins with [`unified-engine-gulp`][gulp], and
|
||||
Atom Linters with [`unified-engine-atom`][atom].
|
||||
|
||||
A streaming interface is provided through [`unified-stream`][stream].
|
||||
|
||||
###### Programming interface
|
||||
|
||||
The API gives access to processing metadata (such as lint messages) and
|
||||
supports multiple passed through files:
|
||||
|
||||
```js
|
||||
var unified = require('unified')
|
||||
var markdown = require('remark-parse')
|
||||
var styleGuide = require('remark-preset-lint-markdown-style-guide')
|
||||
var remark2retext = require('remark-retext')
|
||||
var english = require('retext-english')
|
||||
var equality = require('retext-equality')
|
||||
var remark2rehype = require('remark-rehype')
|
||||
var html = require('rehype-stringify')
|
||||
var report = require('vfile-reporter')
|
||||
|
||||
unified()
|
||||
.use(markdown)
|
||||
.use(styleGuide)
|
||||
.use(
|
||||
remark2retext,
|
||||
unified()
|
||||
.use(english)
|
||||
.use(equality)
|
||||
)
|
||||
.use(remark2rehype)
|
||||
.use(html)
|
||||
.process('*Emphasis* and _importance_, you guys!', function(err, file) {
|
||||
console.error(report(err || file))
|
||||
console.log(String(file))
|
||||
})
|
||||
```
|
||||
|
||||
Yields:
|
||||
|
||||
```txt
|
||||
1:16-1:28 warning Emphasis should use `*` as a marker emphasis-marker remark-lint
|
||||
1:34-1:38 warning `guys` may be insensitive, use `people`, `persons`, `folks` instead gals-men retext-equality
|
||||
|
||||
⚠ 2 warnings
|
||||
<p><em>Emphasis</em> and <em>importance</em>, you guys!</p>
|
||||
```
|
||||
|
||||
###### Processing between syntaxes
|
||||
|
||||
The processors can be combined in two modes.
|
||||
|
||||
**Bridge** mode transforms the syntax tree from one flavour (the origin) to
|
||||
another (the destination). Then, transformations are applied on that tree.
|
||||
Finally, the origin processor continues transforming the original syntax tree.
|
||||
|
||||
**Mutate** mode also transforms the syntax tree from one flavour to another.
|
||||
But then the origin processor continues transforming the destination syntax
|
||||
tree.
|
||||
|
||||
In the previous example (“Programming interface”), `remark-retext` is used in
|
||||
bridge mode: the origin syntax tree is kept after retext is done; whereas
|
||||
`remark-rehype` is used in mutate mode: it sets a new syntax tree and discards
|
||||
the original.
|
||||
|
||||
* [`remark-retext`][remark-retext]
|
||||
* [`remark-rehype`][remark-rehype]
|
||||
* [`rehype-retext`][rehype-retext]
|
||||
* [`rehype-remark`][rehype-remark]
|
||||
|
||||
## API
|
||||
|
||||
### `processor()`
|
||||
|
||||
Object describing how to process text.
|
||||
|
||||
###### Returns
|
||||
|
||||
`Function` — New [**unfrozen**][freeze] processor which is configured to
|
||||
function the same as its ancestor. But when the descendant processor is
|
||||
configured in the future it does not affect the ancestral processor.
|
||||
|
||||
###### Example
|
||||
|
||||
The following example shows how a new processor can be created (from the remark
|
||||
processor) and linked to **stdin**(4) and **stdout**(4).
|
||||
|
||||
```js
|
||||
var remark = require('remark')
|
||||
var concat = require('concat-stream')
|
||||
|
||||
process.stdin.pipe(concat(onconcat))
|
||||
|
||||
function onconcat(buf) {
|
||||
var doc = remark()
|
||||
.processSync(buf)
|
||||
.toString()
|
||||
|
||||
process.stdout.write(doc)
|
||||
}
|
||||
```
|
||||
|
||||
### `processor.use(plugin[, options])`
|
||||
|
||||
Configure the processor to use a [**plugin**][plugin] and optionally configure
|
||||
that plugin with options.
|
||||
|
||||
###### Signatures
|
||||
|
||||
* `processor.use(plugin[, options])`
|
||||
* `processor.use(preset)`
|
||||
* `processor.use(list)`
|
||||
|
||||
###### Parameters
|
||||
|
||||
* `plugin` ([`Plugin`][plugin])
|
||||
* `options` (`*`, optional) — Configuration for `plugin`
|
||||
* `preset` (`Object`) — Object with an optional `plugins` (set to `list`),
|
||||
and/or an optional `settings` object
|
||||
* `list` (`Array`) — List of plugins, presets, and pairs (`plugin` and
|
||||
`options` in an array)
|
||||
|
||||
###### Returns
|
||||
|
||||
`processor` — The processor on which `use` is invoked.
|
||||
|
||||
###### Note
|
||||
|
||||
`use` cannot be called on [frozen][freeze] processors. Invoke the processor
|
||||
first to create a new unfrozen processor.
|
||||
|
||||
###### Example
|
||||
|
||||
There are many ways to pass plugins to `.use()`. The below example gives an
|
||||
overview.
|
||||
|
||||
```js
|
||||
var unified = require('unified')
|
||||
|
||||
unified()
|
||||
// Plugin with options:
|
||||
.use(plugin, {})
|
||||
// Plugins:
|
||||
.use([plugin, pluginB])
|
||||
// Two plugins, the second with options:
|
||||
.use([plugin, [pluginB, {}]])
|
||||
// Preset with plugins and settings:
|
||||
.use({plugins: [plugin, [pluginB, {}]], settings: {position: false}})
|
||||
// Settings only:
|
||||
.use({settings: {position: false}})
|
||||
|
||||
function plugin() {}
|
||||
function pluginB() {}
|
||||
```
|
||||
|
||||
### `processor.parse(file|value)`
|
||||
|
||||
Parse text to a syntax tree.
|
||||
|
||||
###### Parameters
|
||||
|
||||
* `file` ([`VFile`][file])
|
||||
— Or anything which can be given to `vfile()`
|
||||
|
||||
###### Returns
|
||||
|
||||
[`Node`][node] — Syntax tree representation of input.
|
||||
|
||||
###### Note
|
||||
|
||||
`parse` [freezes][freeze] the processor if not already frozen.
|
||||
|
||||
#### `processor.Parser`
|
||||
|
||||
Function handling the parsing of text to a syntax tree. Used in the
|
||||
[**parse**][parse] phase in the process and invoked with a `string` and
|
||||
[`VFile`][file] representation of the document to parse.
|
||||
|
||||
`Parser` can be a normal function in which case it must return a
|
||||
[`Node`][node]: the syntax tree representation of the given file.
|
||||
|
||||
`Parser` can also be a constructor function (a function with keys in its
|
||||
`prototype`) in which case it’s invoked with `new`. Instances must have a
|
||||
`parse` method which is invoked without arguments and must return a
|
||||
[`Node`][node].
|
||||
|
||||
### `processor.stringify(node[, file])`
|
||||
|
||||
Compile a syntax tree to text.
|
||||
|
||||
###### Parameters
|
||||
|
||||
* `node` ([`Node`][node])
|
||||
* `file` ([`VFile`][file], optional);
|
||||
— Or anything which can be given to `vfile()`
|
||||
|
||||
###### Returns
|
||||
|
||||
`string` — String representation of the syntax tree file.
|
||||
|
||||
###### Note
|
||||
|
||||
`stringify` [freezes][freeze] the processor if not already frozen.
|
||||
|
||||
#### `processor.Compiler`
|
||||
|
||||
Function handling the compilation of syntax tree to a text. Used in the
|
||||
[**stringify**][stringify] phase in the process and invoked with a
|
||||
[`Node`][node] and [`VFile`][file] representation of the document to stringify.
|
||||
|
||||
`Compiler` can be a normal function in which case it must return a `string`:
|
||||
the text representation of the given syntax tree.
|
||||
|
||||
`Compiler` can also be a constructor function (a function with keys in its
|
||||
`prototype`) in which case it’s invoked with `new`. Instances must have a
|
||||
`compile` method which is invoked without arguments and must return a `string`.
|
||||
|
||||
### `processor.run(node[, file][, done])`
|
||||
|
||||
Transform a syntax tree by applying [**plugin**][plugin]s to it.
|
||||
|
||||
###### Parameters
|
||||
|
||||
* `node` ([`Node`][node])
|
||||
* `file` ([`VFile`][file], optional)
|
||||
— Or anything which can be given to `vfile()`
|
||||
* `done` ([`Function`][run-done], optional)
|
||||
|
||||
###### Returns
|
||||
|
||||
[`Promise`][promise] if `done` is not given. Rejected with an error, or
|
||||
resolved with the resulting syntax tree.
|
||||
|
||||
###### Note
|
||||
|
||||
`run` [freezes][freeze] the processor if not already frozen.
|
||||
|
||||
##### `function done(err[, node, file])`
|
||||
|
||||
Invoked when transformation is complete. Either invoked with an error or a
|
||||
syntax tree and a file.
|
||||
|
||||
###### Parameters
|
||||
|
||||
* `err` (`Error`) — Fatal error
|
||||
* `node` ([`Node`][node])
|
||||
* `file` ([`VFile`][file])
|
||||
|
||||
### `processor.runSync(node[, file])`
|
||||
|
||||
Transform a syntax tree by applying [**plugin**][plugin]s to it.
|
||||
|
||||
If asynchronous [**plugin**][plugin]s are configured an error is thrown.
|
||||
|
||||
###### Parameters
|
||||
|
||||
* `node` ([`Node`][node])
|
||||
* `file` ([`VFile`][file], optional)
|
||||
— Or anything which can be given to `vfile()`
|
||||
|
||||
###### Returns
|
||||
|
||||
[`Node`][node] — The given syntax tree.
|
||||
|
||||
###### Note
|
||||
|
||||
`runSync` [freezes][freeze] the processor if not already frozen.
|
||||
|
||||
### `processor.process(file|value[, done])`
|
||||
|
||||
Process the given representation of a file as configured on the processor. The
|
||||
process invokes `parse`, `run`, and `stringify` internally.
|
||||
|
||||
###### Parameters
|
||||
|
||||
* `file` ([`VFile`][file])
|
||||
* `value` (`string`) — String representation of a file
|
||||
* `done` ([`Function`][process-done], optional)
|
||||
|
||||
###### Returns
|
||||
|
||||
[`Promise`][promise] if `done` is not given. Rejected with an error or
|
||||
resolved with the resulting file.
|
||||
|
||||
###### Note
|
||||
|
||||
`process` [freezes][freeze] the processor if not already frozen.
|
||||
|
||||
#### `function done(err, file)`
|
||||
|
||||
Invoked when the process is complete. Invoked with a fatal error, if any, and
|
||||
the [`VFile`][file].
|
||||
|
||||
###### Parameters
|
||||
|
||||
* `err` (`Error`, optional) — Fatal error
|
||||
* `file` ([`VFile`][file])
|
||||
|
||||
###### Example
|
||||
|
||||
```js
|
||||
var unified = require('unified')
|
||||
var markdown = require('remark-parse')
|
||||
var remark2rehype = require('remark-rehype')
|
||||
var doc = require('rehype-document')
|
||||
var format = require('rehype-format')
|
||||
var html = require('rehype-stringify')
|
||||
|
||||
unified()
|
||||
.use(markdown)
|
||||
.use(remark2rehype)
|
||||
.use(doc)
|
||||
.use(format)
|
||||
.use(html)
|
||||
.process('# Hello world!')
|
||||
.then(
|
||||
function(file) {
|
||||
console.log(String(file))
|
||||
},
|
||||
function(err) {
|
||||
console.error(String(err))
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
Yields:
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello world!</h1>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
### `processor.processSync(file|value)`
|
||||
|
||||
Process the given representation of a file as configured on the processor. The
|
||||
process invokes `parse`, `run`, and `stringify` internally.
|
||||
|
||||
If asynchronous [**plugin**][plugin]s are configured an error is thrown.
|
||||
|
||||
###### Parameters
|
||||
|
||||
* `file` ([`VFile`][file])
|
||||
* `value` (`string`) — String representation of a file
|
||||
|
||||
###### Returns
|
||||
|
||||
[`VFile`][file] — Virtual file with modified [`contents`][vfile-contents].
|
||||
|
||||
###### Note
|
||||
|
||||
`processSync` [freezes][freeze] the processor if not already frozen.
|
||||
|
||||
###### Example
|
||||
|
||||
```js
|
||||
var unified = require('unified')
|
||||
var markdown = require('remark-parse')
|
||||
var remark2rehype = require('remark-rehype')
|
||||
var doc = require('rehype-document')
|
||||
var format = require('rehype-format')
|
||||
var html = require('rehype-stringify')
|
||||
|
||||
var processor = unified()
|
||||
.use(markdown)
|
||||
.use(remark2rehype)
|
||||
.use(doc)
|
||||
.use(format)
|
||||
.use(html)
|
||||
|
||||
console.log(processor.processSync('# Hello world!').toString())
|
||||
```
|
||||
|
||||
Yields:
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello world!</h1>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
### `processor.data(key[, value])`
|
||||
|
||||
Get or set information in an in-memory key-value store accessible to all phases
|
||||
of the process. An example is a list of HTML elements which are self-closing,
|
||||
which is needed when parsing, transforming, and compiling HTML.
|
||||
|
||||
###### Parameters
|
||||
|
||||
* `key` (`string`) — Identifier
|
||||
* `value` (`*`, optional) — Value to set. Omit if getting `key`
|
||||
|
||||
###### Returns
|
||||
|
||||
* `processor` — If setting, the processor on which `data` is invoked
|
||||
* `*` — If getting, the value at `key`
|
||||
|
||||
###### Note
|
||||
|
||||
Setting information with `data` cannot occur on [frozen][freeze] processors.
|
||||
Invoke the processor first to create a new unfrozen processor.
|
||||
|
||||
###### Example
|
||||
|
||||
The following example show how to get and set information:
|
||||
|
||||
```js
|
||||
var unified = require('unified')
|
||||
|
||||
console.log(
|
||||
unified()
|
||||
.data('alpha', 'bravo')
|
||||
.data('alpha')
|
||||
)
|
||||
```
|
||||
|
||||
Yields:
|
||||
|
||||
```txt
|
||||
bravo
|
||||
```
|
||||
|
||||
### `processor.freeze()`
|
||||
|
||||
Freeze a processor. Frozen processors are meant to be extended and not to be
|
||||
configured or processed directly.
|
||||
|
||||
Once a processor is frozen it cannot be unfrozen. New processors functioning
|
||||
just like it can be created by invoking the processor.
|
||||
|
||||
It’s possible to freeze processors explicitly, by calling `.freeze()`, but
|
||||
[`.parse()`][parse], [`.run()`][run], [`.stringify()`][stringify], and
|
||||
[`.process()`][process] call `.freeze()` to freeze a processor too.
|
||||
|
||||
###### Returns
|
||||
|
||||
`Processor` — The processor on which `freeze` is invoked.
|
||||
|
||||
###### Example
|
||||
|
||||
The following example, `index.js`, shows how [**rehype**][rehype] prevents
|
||||
extensions to itself:
|
||||
|
||||
```js
|
||||
var unified = require('unified')
|
||||
var parse = require('rehype-parse')
|
||||
var stringify = require('rehype-stringify')
|
||||
|
||||
module.exports = unified()
|
||||
.use(parse)
|
||||
.use(stringify)
|
||||
.freeze()
|
||||
```
|
||||
|
||||
The below example, `a.js`, shows how that processor can be used and configured.
|
||||
|
||||
```js
|
||||
var rehype = require('rehype')
|
||||
var format = require('rehype-format')
|
||||
// ...
|
||||
|
||||
rehype()
|
||||
.use(format)
|
||||
// ...
|
||||
```
|
||||
|
||||
The below example, `b.js`, shows a similar looking example which operates on
|
||||
the frozen [**rehype**][rehype] interface. If this behaviour was allowed it
|
||||
would result in unexpected behaviour so an error is thrown. **This is
|
||||
invalid**:
|
||||
|
||||
```js
|
||||
var rehype = require('rehype')
|
||||
var format = require('rehype-format')
|
||||
// ...
|
||||
|
||||
rehype
|
||||
.use(format)
|
||||
// ...
|
||||
```
|
||||
|
||||
Yields:
|
||||
|
||||
```txt
|
||||
~/node_modules/unified/index.js:440
|
||||
throw new Error(
|
||||
^
|
||||
|
||||
Error: Cannot invoke `use` on a frozen processor.
|
||||
Create a new processor first, by invoking it: use `processor()` instead of `processor`.
|
||||
at assertUnfrozen (~/node_modules/unified/index.js:440:11)
|
||||
at Function.use (~/node_modules/unified/index.js:172:5)
|
||||
at Object.<anonymous> (~/b.js:6:4)
|
||||
```
|
||||
|
||||
## `Plugin`
|
||||
|
||||
**unified** plugins change the way the applied-on processor works in the
|
||||
following ways:
|
||||
|
||||
* They modify the [**processor**][processor]: such as changing the parser,
|
||||
the compiler, or linking it to other processors
|
||||
* They transform [**syntax tree**][node] representation of files
|
||||
* They modify metadata of files
|
||||
|
||||
Plugins are a concept. They materialise as [`attacher`][attacher]s.
|
||||
|
||||
###### Example
|
||||
|
||||
`move.js`:
|
||||
|
||||
```js
|
||||
module.exports = move
|
||||
|
||||
function move(options) {
|
||||
var expected = (options || {}).extname
|
||||
|
||||
if (!expected) {
|
||||
throw new Error('Missing `extname` in options')
|
||||
}
|
||||
|
||||
return transformer
|
||||
|
||||
function transformer(tree, file) {
|
||||
if (file.extname && file.extname !== expected) {
|
||||
file.extname = expected
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`index.js`:
|
||||
|
||||
```js
|
||||
var unified = require('unified')
|
||||
var parse = require('remark-parse')
|
||||
var remark2rehype = require('remark-rehype')
|
||||
var stringify = require('rehype-stringify')
|
||||
var vfile = require('to-vfile')
|
||||
var report = require('vfile-reporter')
|
||||
var move = require('./move')
|
||||
|
||||
unified()
|
||||
.use(parse)
|
||||
.use(remark2rehype)
|
||||
.use(move, {extname: '.html'})
|
||||
.use(stringify)
|
||||
.process(vfile.readSync('index.md'), function(err, file) {
|
||||
console.error(report(err || file))
|
||||
if (file) {
|
||||
vfile.writeSync(file) // Written to `index.html`.
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
### `function attacher([options])`
|
||||
|
||||
An attacher is the thing passed to [`use`][use]. It configures the processor
|
||||
and in turn can receive options.
|
||||
|
||||
Attachers can configure processors, such as by interacting with parsers and
|
||||
compilers, linking them to other processors, or by specifying how the syntax
|
||||
tree is handled.
|
||||
|
||||
###### Context
|
||||
|
||||
The context object is set to the invoked on [`processor`][processor].
|
||||
|
||||
###### Parameters
|
||||
|
||||
* `options` (`*`, optional) — Configuration
|
||||
|
||||
###### Returns
|
||||
|
||||
[`transformer`][transformer] — Optional.
|
||||
|
||||
###### Note
|
||||
|
||||
Attachers are invoked when the processor is [frozen][freeze]: either when
|
||||
`.freeze()` is called explicitly, or when [`.parse()`][parse], [`.run()`][run],
|
||||
[`.stringify()`][stringify], or [`.process()`][process] is called for the first
|
||||
time.
|
||||
|
||||
### `function transformer(node, file[, next])`
|
||||
|
||||
Transformers modify the syntax tree or metadata of a file. A transformer is a
|
||||
function which is invoked each time a file is passed through the transform
|
||||
phase. If an error occurs (either because it’s thrown, returned, rejected, or
|
||||
passed to [`next`][next]), the process stops.
|
||||
|
||||
The transformation process in **unified** is handled by [`trough`][trough], see
|
||||
it’s documentation for the exact semantics of transformers.
|
||||
|
||||
###### Parameters
|
||||
|
||||
* `node` ([`Node`][node])
|
||||
* `file` ([`VFile`][file])
|
||||
* `next` ([`Function`][next], optional)
|
||||
|
||||
###### Returns
|
||||
|
||||
* `Error` — Can be returned to stop the process
|
||||
* [`Node`][node] — Can be returned and results in further transformations
|
||||
and `stringify`s to be performed on the new tree
|
||||
* `Promise` — If a promise is returned, the function is asynchronous, and
|
||||
**must** be resolved (optionally with a [`Node`][node]) or rejected
|
||||
(optionally with an `Error`)
|
||||
|
||||
#### `function next(err[, tree[, file]])`
|
||||
|
||||
If the signature of a transformer includes `next` (third argument), the
|
||||
function **may** finish asynchronous, and **must** invoke `next()`.
|
||||
|
||||
###### Parameters
|
||||
|
||||
* `err` (`Error`, optional) — Stop the process
|
||||
* `node` ([`Node`][node], optional) — New syntax tree
|
||||
* `file` ([`VFile`][file], optional) — New virtual file
|
||||
|
||||
## `Preset`
|
||||
|
||||
Presets provide a potentially sharable way to configure processors. They can
|
||||
contain multiple plugins and optionally settings as well.
|
||||
|
||||
###### Example
|
||||
|
||||
`preset.js`:
|
||||
|
||||
```js
|
||||
exports.settings = {bullet: '*', fences: true}
|
||||
|
||||
exports.plugins = [
|
||||
require('remark-preset-lint-recommended'),
|
||||
require('remark-comment-config'),
|
||||
require('remark-preset-lint-markdown-style-guide'),
|
||||
[require('remark-toc'), {maxDepth: 3, tight: true}],
|
||||
require('remark-github')
|
||||
]
|
||||
```
|
||||
|
||||
`index.js`:
|
||||
|
||||
```js
|
||||
var remark = require('remark')
|
||||
var vfile = require('to-vfile')
|
||||
var report = require('vfile-reporter')
|
||||
var preset = require('./preset')
|
||||
|
||||
remark()
|
||||
.use(preset)
|
||||
.process(vfile.readSync('index.md'), function(err, file) {
|
||||
console.error(report(err || file))
|
||||
|
||||
if (file) {
|
||||
vfile.writeSync(file)
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
## Contribute
|
||||
|
||||
**unified** is built by people just like you! Check out
|
||||
[`contributing.md`][contributing] for ways to get started.
|
||||
|
||||
This project has a [Code of Conduct][coc]. By interacting with this repository,
|
||||
organisation, or community you agree to abide by its terms.
|
||||
|
||||
Want to chat with the community and contributors? Join us in [Gitter][chat]!
|
||||
|
||||
Have an idea for a cool new utility or tool? That’s great! If you want
|
||||
feedback, help, or just to share it with the world you can do so by creating
|
||||
an issue in the [`unifiedjs/ideas`][ideas] repository!
|
||||
|
||||
## Acknowledgments
|
||||
|
||||
Preliminary work for unified was done [in 2014][preliminary] for
|
||||
[**retext**][retext] and inspired by [`ware`][ware]. Further incubation
|
||||
happened in [**remark**][remark]. The project was finally [externalised][]
|
||||
in 2015 and [published][] as `unified`. The project was authored by
|
||||
[**@wooorm**](https://github.com/wooorm).
|
||||
|
||||
Although `unified` since moved it’s plugin architecture to [`trough`][trough],
|
||||
thanks to [**@calvinfo**](https://github.com/calvinfo),
|
||||
[**@ianstormtaylor**](https://github.com/ianstormtaylor), and others for their
|
||||
work on [`ware`][ware], which was a huge initial inspiration.
|
||||
|
||||
## License
|
||||
|
||||
[MIT][license] © [Titus Wormer][author]
|
||||
|
||||
<!-- Definitions -->
|
||||
|
||||
[logo]: https://cdn.rawgit.com/unifiedjs/unified/0cd3a41/logo.svg
|
||||
|
||||
[travis-badge]: https://img.shields.io/travis/unifiedjs/unified.svg
|
||||
|
||||
[travis]: https://travis-ci.org/unifiedjs/unified
|
||||
|
||||
[codecov-badge]: https://img.shields.io/codecov/c/github/unifiedjs/unified.svg
|
||||
|
||||
[codecov]: https://codecov.io/github/unifiedjs/unified
|
||||
|
||||
[chat-badge]: https://img.shields.io/gitter/room/unifiedjs/Lobby.svg
|
||||
|
||||
[chat]: https://gitter.im/unifiedjs/Lobby
|
||||
|
||||
[npm]: https://docs.npmjs.com/cli/install
|
||||
|
||||
[license]: LICENSE
|
||||
|
||||
[author]: http://wooorm.com
|
||||
|
||||
[site]: https://unifiedjs.github.io
|
||||
|
||||
[guides]: https://unifiedjs.github.io/#guides
|
||||
|
||||
[rehype]: https://github.com/rehypejs/rehype
|
||||
|
||||
[remark]: https://github.com/remarkjs/remark
|
||||
|
||||
[retext]: https://github.com/retextjs/retext
|
||||
|
||||
[hast]: https://github.com/syntax-tree/hast
|
||||
|
||||
[mdast]: https://github.com/syntax-tree/mdast
|
||||
|
||||
[nlcst]: https://github.com/syntax-tree/nlcst
|
||||
|
||||
[unist]: https://github.com/syntax-tree/unist
|
||||
|
||||
[engine]: https://github.com/unifiedjs/unified-engine
|
||||
|
||||
[args]: https://github.com/unifiedjs/unified-args
|
||||
|
||||
[gulp]: https://github.com/unifiedjs/unified-engine-gulp
|
||||
|
||||
[atom]: https://github.com/unifiedjs/unified-engine-atom
|
||||
|
||||
[remark-rehype]: https://github.com/remarkjs/remark-rehype
|
||||
|
||||
[remark-retext]: https://github.com/remarkjs/remark-retext
|
||||
|
||||
[rehype-retext]: https://github.com/rehypejs/rehype-retext
|
||||
|
||||
[rehype-remark]: https://github.com/rehypejs/rehype-remark
|
||||
|
||||
[unist-utilities]: https://github.com/syntax-tree/unist#list-of-utilities
|
||||
|
||||
[vfile]: https://github.com/vfile/vfile
|
||||
|
||||
[vfile-contents]: https://github.com/vfile/vfile#vfilecontents
|
||||
|
||||
[vfile-utilities]: https://github.com/vfile/vfile#related-tools
|
||||
|
||||
[file]: #file
|
||||
|
||||
[node]: #node
|
||||
|
||||
[processor]: #processor
|
||||
|
||||
[process]: #processorprocessfilevalue-done
|
||||
|
||||
[parse]: #processorparsefilevalue
|
||||
|
||||
[parser]: #processorparser
|
||||
|
||||
[stringify]: #processorstringifynode-file
|
||||
|
||||
[run]: #processorrunnode-file-done
|
||||
|
||||
[compiler]: #processorcompiler
|
||||
|
||||
[use]: #processoruseplugin-options
|
||||
|
||||
[attacher]: #function-attacheroptions
|
||||
|
||||
[transformer]: #function-transformernode-file-next
|
||||
|
||||
[next]: #function-nexterr-tree-file
|
||||
|
||||
[freeze]: #processorfreeze
|
||||
|
||||
[plugin]: #plugin
|
||||
|
||||
[run-done]: #function-doneerr-node-file
|
||||
|
||||
[process-done]: #function-doneerr-file
|
||||
|
||||
[trough]: https://github.com/wooorm/trough#function-fninput-next
|
||||
|
||||
[promise]: https://developer.mozilla.org/Web/JavaScript/Reference/Global_Objects/Promise
|
||||
|
||||
[remark-plugins]: https://github.com/remarkjs/remark/blob/master/doc/plugins.md#list-of-plugins
|
||||
|
||||
[rehype-plugins]: https://github.com/rehypejs/rehype/blob/master/doc/plugins.md#list-of-plugins
|
||||
|
||||
[retext-plugins]: https://github.com/retextjs/retext/blob/master/doc/plugins.md#list-of-plugins
|
||||
|
||||
[stream]: https://github.com/unifiedjs/unified-stream
|
||||
|
||||
[contributing]: contributing.md
|
||||
|
||||
[coc]: code-of-conduct.md
|
||||
|
||||
[ideas]: https://github.com/unifiedjs/ideas
|
||||
|
||||
[preliminary]: https://github.com/retextjs/retext/commit/8fcb1f#diff-168726dbe96b3ce427e7fedce31bb0bc
|
||||
|
||||
[externalised]: https://github.com/remarkjs/remark/commit/9892ec#diff-168726dbe96b3ce427e7fedce31bb0bc
|
||||
|
||||
[published]: https://github.com/unifiedjs/unified/commit/2ba1cf
|
||||
|
||||
[ware]: https://github.com/segmentio/ware
|
||||
Reference in New Issue
Block a user