Skip to content

Commit

Permalink
Add support for injecting plugins into remark(1)
Browse files Browse the repository at this point in the history
Previously, there was support for injecting plugins by their name,
but it was not possible to inject real functions into remark(3)
through remark(1).

This feature enables remark(1) users through the Node API to inject
attachers (see **ATTACHER** in remarkplugin(3)), through a new
`use` function exposed on the CLI object:

```js
var CLI = require('remark/lib/cli/cli');
var engine = require('remark/lib/cli');
var html = require('remark-html');

var cli = new CLI({
    'files': 'readme.md'
}).use(html);

run(cli, function (err, success) {
    console.log('done!', err, 'successfully?', success);
});
```

Yields:

```txt
readme.md: no issues found
done! null successfully? true
```

In addition, it’s now possible to pass a `CLI` object (exposed from
`lib/cli/cli`) directly into the engine (exposed from `lib/cli`).
  • Loading branch information
wooorm committed Dec 31, 2015
1 parent 76f1412 commit 4e65d70
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 10 deletions.
24 changes: 24 additions & 0 deletions lib/cli/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -267,8 +267,17 @@ function CLI(argv) {
var self = this;
var config = argv;

/*
* Allow passing in a CLI object.
*/

if (argv instanceof CLI) {
return argv;
}

self.cache = new Cache();
self.spinner = new Spinner();
self.injectedPlugins = [];

if ('length' in config) {
program.parse(argv);
Expand Down Expand Up @@ -338,6 +347,20 @@ function usage() {
return program.outputHelp();
}

/**
* Cache plug-ins.
*
* @param {Function} plugin - Plugin to use.
* @param {Object?} [options] - Optional plug-in
* configuration.
* @this {CLI}
*/
function use(plugin, options) {
this.injectedPlugins.push([plugin, options]);

return this;
}

/*
* Prototype.
*/
Expand All @@ -348,6 +371,7 @@ CLI.prototype.stdout = process.stdout;
CLI.prototype.stderr = process.stderr;
CLI.prototype.log = log;
CLI.prototype.usage = usage;
CLI.prototype.use = use;

/*
* Expose.
Expand Down
49 changes: 39 additions & 10 deletions lib/cli/file-pipeline/configure.js
Original file line number Diff line number Diff line change
Expand Up @@ -170,25 +170,29 @@ function configure(context, next) {
}

config.getConfiguration(file.filePath(), function (err, options) {
var option;
var plugin;
var length;
var index;
var name;

debug('Setting output `%s`', options.output);

debug('Using settings `%j`', options.settings);

plugins = Object.keys(options.plugins);
length = plugins.length;
index = -1;

debug('Using plug-ins `%j`', plugins);

/*
* Use, with options.
*/

plugins.forEach(function (name) {
var option = options.plugins[name];
var plugin;
while (++index < length) {
name = plugins[index];
option = options.plugins[name];

if (option === false) {
debug('Ignoring plug-in `%s`', name);
return;
continue;
}

try {
Expand All @@ -199,9 +203,34 @@ function configure(context, next) {
processor.use(plugin, option, context.fileSet);
} catch (err) {
next(err);
return false;
return;
}
});
}

plugins = cli.injectedPlugins;
length = plugins.length;
index = -1;

debug('Using `%d` injected plugins', length);

while (++index < length) {
plugin = plugins[index][0];
option = plugins[index][1];
name = plugin.displayName || plugin.name || '';

try {
debug('Applying options `%j` to `%s`', option, name);

processor.use(plugin, option, context.fileSet);
} catch (err) {
next(err);
return;
}
}

/*
* Store some configuration on the context object.
*/

context.output = options.output;
context.settings = options.settings;
Expand Down

0 comments on commit 4e65d70

Please sign in to comment.