Skip to content

Commit

Permalink
Add support for inspecting the syntax tree
Browse files Browse the repository at this point in the history
  • Loading branch information
wooorm committed Jan 18, 2018
1 parent 1bfba98 commit 93392cd
Show file tree
Hide file tree
Showing 8 changed files with 197 additions and 3 deletions.
58 changes: 56 additions & 2 deletions doc/options.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
* [options.tree](#optionstree)
* [options.treeIn](#optionstreein)
* [options.treeOut](#optionstreeout)
* [options.inspect](#optionsinspect)
* [options.rcName](#optionsrcname)
* [options.packageField](#optionspackagefield)
* [options.detectConfig](#optionsdetectconfig)
Expand Down Expand Up @@ -341,7 +342,8 @@ Whether to write successfully processed files and where to.

Note that if [`treeIn`][tree-in] is turned on, generated files get the first
defined [`extensions`][extensions]. If [`treeOut`][tree-out] is turned on,
generated files receive the `'json'` extension.
generated files receive the `'json'` extension. If [`inspect`][inspect] is
turned on, generated files receive the `'txt'` extension.

<!-- Info: -->

Expand Down Expand Up @@ -538,6 +540,54 @@ Yields:
}
```

## `options.inspect`

Skip the [compilation phase][unified-description] and output a syntax tree
formatted with [`unist-util-inspect`][unist-util-inspect].

Sets the extension of processed files to `txt` if possible.

Uses ANSI colour sequences in the formatted syntax tree if `color` is turned on.

* Type: `boolean`, optional
* Default: `false`

###### Example

The following example shows a script which reads and parses `doc.md`, then
[`remark-unlink`][remark-unlink] transforms the syntax tree, the tree is
formatted with [`unist-util-inspect`][unist-util-inspect], and finally written
to **stdout**(4).

```js
var engine = require('unified-engine');
var remark = require('remark');
var unlink = require('remark-unlink');

engine({
processor: remark(),
plugins: [unlink],
files: ['doc.md'],
inspect: true
}, function (err) {
if (err) throw err;
});
```

Where `doc.md` looks as follows:

```md
[foo](https://example.com)
```

Yields:

```txt
root[1] (1:1-2:1, 0-27)
└─ paragraph[1] (1:1-1:27, 0-26)
└─ text: "foo" (1:2-1:5, 1-4)
```

## `options.rcName`

Name of [configuration][configure] file to load. If given and
Expand Down Expand Up @@ -970,7 +1020,7 @@ See [`options.reporter`][reporter] for an example.

## `options.color`

Whether to [report][reporter] with ANSI colour sequences.
Whether to [report][reporter] or [inspect][] with ANSI colour sequences.

* Type: `boolean`, default: `false`

Expand Down Expand Up @@ -1147,6 +1197,8 @@ engine({

[tree-out]: #optionstreeout

[inspect]: #optionsinspect

[detect-config]: #optionsdetectconfig

[rc-name]: #optionsrcname
Expand Down Expand Up @@ -1176,3 +1228,5 @@ engine({
[reporters]: https://github.com/vfile/vfile#reporters

[json]: https://github.com/vfile/vfile-reporter-json

[unist-util-inspect]: https://github.com/syntax-tree/unist-util-inspect
10 changes: 9 additions & 1 deletion lib/file-pipeline/stringify.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

var debug = require('debug')('unified-engine:file-pipeline:stringify');
var stats = require('vfile-statistics');
var inspect = require('unist-util-inspect');

module.exports = stringify;

Expand All @@ -23,7 +24,14 @@ function stringify(context, file) {

debug('Compiling `%s`', file.path);

if (context.treeOut) {
if (context.inspect) {
/* Add a `txt` extension if there’s a path. */
if (file.path) {
file.extname = '.txt';
}

value = inspect[context.color ? 'color' : 'noColor'](tree) + '\n';
} else if (context.treeOut) {
/* Add a `json` extension to ensure the file is correctly seen as JSON.
* Only add it if there’s a path — not if the file is for example stdin. */
if (file.path) {
Expand Down
2 changes: 2 additions & 0 deletions lib/file-set-pipeline/transform.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ function transform(context, settings, next) {
pluginPrefix: settings.pluginPrefix,
treeIn: settings.treeIn,
treeOut: settings.treeOut,
inspect: settings.inspect,
color: settings.color,
out: settings.out,
output: settings.output,
streamOut: settings.streamOut,
Expand Down
1 change: 1 addition & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ function run(options, callback) {

settings.treeIn = options.treeIn;
settings.treeOut = options.treeOut;
settings.inspect = options.inspect;

if (settings.treeIn === null || settings.treeIn === undefined) {
settings.treeIn = tree;
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"parse-json": "^4.0.0",
"to-vfile": "^2.0.0",
"trough": "^1.0.0",
"unist-util-inspect": "^4.1.2",
"vfile-reporter": "^4.0.0",
"vfile-statistics": "^1.1.0",
"x-is-function": "^1.0.4",
Expand Down
4 changes: 4 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ done.
— Whether to treat input as a syntax tree
* [`treeOut`][tree-out] (`boolean`, default: `tree`)
— Whether to treat output as a syntax tree
* [`inspect`][inspect] (`boolean`, default: `false`)
— Whether to output a formatted syntax tree
* [`rcName`][rc-name] (`string`, optional)
— Name of configuration files to load
* [`packageField`][package-field] (`string`, optional)
Expand Down Expand Up @@ -228,6 +230,8 @@ repository, organisation, or community you agree to abide by its terms.

[tree-out]: doc/options.md#optionstreeout

[inspect]: doc/options.md#optionsinspect

[detect-config]: doc/options.md#optionsdetectconfig

[rc-name]: doc/options.md#optionsrcname
Expand Down
1 change: 1 addition & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ require('./configuration-default');
require('./stdin');
require('./output');
require('./tree');
require('./inspect');
require('./file-path');
require('./color');
require('./reporting');
Expand Down
123 changes: 123 additions & 0 deletions test/inspect.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
'use strict';

var fs = require('fs');
var path = require('path');
var PassThrough = require('stream').PassThrough;
var test = require('tape');
var noop = require('./util/noop-processor');
var spy = require('./util/spy');
var engine = require('..');

var join = path.join;
var read = fs.readFileSync;
var unlink = fs.unlinkSync;

var fixtures = join(__dirname, 'fixtures');

test('inspect', function (t) {
t.plan(3);

t.test('should write text when `inspect` is given', function (st) {
var cwd = join(fixtures, 'one-file');
var stderr = spy();

st.plan(4);

engine({
processor: noop(),
cwd: cwd,
streamError: stderr.stream,
output: 'formatted.txt',
inspect: true,
files: ['.'],
extensions: ['txt']
}, function (err, code) {
var doc = read(join(cwd, 'formatted.txt'), 'utf8');

/* Remove the file. */
unlink(join(cwd, 'formatted.txt'));

st.error(err, 'should not fail fatally');
st.equal(code, 0, 'should exit with `0`');

st.equal(
stderr(),
'one.txt > formatted.txt: written\n',
'should report'
);

st.equal(
doc,
'text: ""\n',
'should write the transformed doc as a formatted syntax tree'
);
});
});

t.test('should support `inspect` for stdin', function (st) {
var stdin = new PassThrough();
var stdout = spy();
var stderr = spy();

setTimeout(send, 50);

function send() {
stdin.end('\n');
}

st.plan(1);

engine({
processor: noop,
streamIn: stdin,
streamOut: stdout.stream,
streamError: stderr.stream,
inspect: true
}, function (err, code) {
st.deepEqual(
[err, code, stderr(), stdout()],
[
null,
0,
'<stdin>: no issues found\n',
'text: "\\n"\n'
],
'should work'
);
});
});

t.test('should support `inspect` with colour', function (st) {
var stdin = new PassThrough();
var stdout = spy();
var stderr = spy();

setTimeout(send, 50);

function send() {
stdin.end('\n');
}

st.plan(1);

engine({
processor: noop,
streamIn: stdin,
streamOut: stdout.stream,
streamError: stderr.stream,
inspect: true,
color: true
}, function (err, code) {
st.deepEqual(
[err, code, stderr(), stdout()],
[
null,
0,
'\x1b[4m\x1b[32m<stdin>\x1b[39m\x1b[24m: no issues found\n',
'text\x1b[2m: \x1b[22m\x1b[32m"\\n"\x1b[39m\n'
],
'should work'
);
});
});
});

0 comments on commit 93392cd

Please sign in to comment.