• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# ![unified][logo]
2
3[![Build Status][travis-badge]][travis]
4[![Coverage Status][codecov-badge]][codecov]
5[![Chat][chat-badge]][chat]
6
7**unified** is an interface for processing text using syntax trees.  It’s what
8powers [**remark**][remark], [**retext**][retext], and [**rehype**][rehype],
9but it also allows for processing between multiple syntaxes.
10
11The website for **unified**, [`unifiedjs.github.io`][site], provides a less
12technical and more practical introduction to unified.  Make sure to visit it
13and try its introductory [Guides][].
14
15## Installation
16
17[npm][]:
18
19```bash
20npm install unified
21```
22
23## Usage
24
25```js
26var unified = require('unified')
27var markdown = require('remark-parse')
28var remark2rehype = require('remark-rehype')
29var doc = require('rehype-document')
30var format = require('rehype-format')
31var html = require('rehype-stringify')
32var report = require('vfile-reporter')
33
34unified()
35  .use(markdown)
36  .use(remark2rehype)
37  .use(doc)
38  .use(format)
39  .use(html)
40  .process('# Hello world!', function(err, file) {
41    console.error(report(err || file))
42    console.log(String(file))
43  })
44```
45
46Yields:
47
48```html
49no issues found
50<!DOCTYPE html>
51<html lang="en">
52  <head>
53    <meta charset="utf-8">
54    <meta name="viewport" content="width=device-width, initial-scale=1">
55  </head>
56  <body>
57    <h1>Hello world!</h1>
58  </body>
59</html>
60```
61
62## Table of Contents
63
64*   [Description](#description)
65*   [API](#api)
66    *   [processor()](#processor)
67    *   [processor.use(plugin\[, options\])](#processoruseplugin-options)
68    *   [processor.parse(file|value)](#processorparsefilevalue)
69    *   [processor.stringify(node\[, file\])](#processorstringifynode-file)
70    *   [processor.run(node\[, file\]\[, done\])](#processorrunnode-file-done)
71    *   [processor.runSync(node\[, file\])](#processorrunsyncnode-file)
72    *   [processor.process(file|value\[, done\])](#processorprocessfilevalue-done)
73    *   [processor.processSync(file|value)](#processorprocesssyncfilevalue)
74    *   [processor.data(key\[, value\])](#processordatakey-value)
75    *   [processor.freeze()](#processorfreeze)
76*   [Plugin](#plugin)
77    *   [function attacher(\[options\])](#function-attacheroptions)
78    *   [function transformer(node, file\[, next\])](#function-transformernode-file-next)
79*   [Preset](#preset)
80*   [Contribute](#contribute)
81*   [Acknowledgments](#acknowledgments)
82*   [License](#license)
83
84## Description
85
86**unified** is an interface for processing text using syntax trees.  Syntax
87trees are a representation understandable to programs.  Those programs, called
88[**plugin**][plugin]s, take these trees and modify them, amongst other things.
89To get to the syntax tree from input text there’s a [**parser**][parser].  To
90get from that back to text there’s a [**compiler**][compiler].  This is the
91[**process**][process] of a **processor**.
92
93```ascii
94| ....................... process() ......................... |
95| ......... parse() ..... | run() | ..... stringify() ....... |
96
97          +--------+                     +----------+
98Input ->- | Parser | ->- Syntax Tree ->- | Compiler | ->- Output
99          +--------+          |          +----------+
100                              X
101                              |
102                       +--------------+
103                       | Transformers |
104                       +--------------+
105```
106
107###### Processors
108
109Every processor implements another processor.  To create a new processor invoke
110another processor.  This creates a processor that is configured to function the
111same as its ancestor.  But when the descendant processor is configured in the
112future it does not affect the ancestral processor.
113
114When processors are exposed from a module (for example, unified itself) they
115should not be configured directly, as that would change their behaviour for all
116module users.  Those processors are [**frozen**][freeze] and they should be
117invoked to create a new processor before they are used.
118
119###### Node
120
121The syntax trees used in **unified** are [**Unist**][unist] nodes: plain
122JavaScript objects with a `type` property.  The semantics of those `type`s are
123defined by other projects.
124
125There are several [utilities][unist-utilities] for working with these nodes.
126
127###### List of Processors
128
129The following projects process different syntax trees.  They parse text to
130their respective syntax tree and they compile their syntax trees back to text.
131These processors can be used as-is, or their parsers and compilers can be mixed
132and matched with **unified** and other plugins to process between different
133syntaxes.
134
135*   [**rehype**][rehype] ([**HAST**][hast]) — HTML
136*   [**remark**][remark] ([**MDAST**][mdast]) — Markdown
137*   [**retext**][retext] ([**NLCST**][nlcst]) — Natural language
138
139###### List of Plugins
140
141The below plugins work with **unified**, unrelated to what flavour the syntax
142tree is in:
143
144*   [`unified-diff`](https://github.com/unifiedjs/unified-diff)
145    — Ignore messages for unchanged lines in Travis
146
147See [**remark**][remark-plugins], [**rehype**][rehype-plugins], and
148[**retext**][retext-plugins] for lists of their plugins.
149
150###### File
151
152When processing documents metadata is often gathered about that document.
153[**VFile**][vfile] is a virtual file format which stores data and handles
154metadata and messages for **unified** and its plugins.
155
156There are several [utilities][vfile-utilities] for working with these files.
157
158###### Configuration
159
160To configure a processor invoke its [`use`][use] method, supply it a
161[**plugin**][plugin], and optionally settings.
162
163###### Integrations
164
165**unified** can integrate with the file-system through
166[`unified-engine`][engine].  On top of that, CLI apps can be created with
167[`unified-args`][args], Gulp plugins with [`unified-engine-gulp`][gulp], and
168Atom Linters with [`unified-engine-atom`][atom].
169
170A streaming interface is provided through [`unified-stream`][stream].
171
172###### Programming interface
173
174The API gives access to processing metadata (such as lint messages) and
175supports multiple passed through files:
176
177```js
178var unified = require('unified')
179var markdown = require('remark-parse')
180var styleGuide = require('remark-preset-lint-markdown-style-guide')
181var remark2retext = require('remark-retext')
182var english = require('retext-english')
183var equality = require('retext-equality')
184var remark2rehype = require('remark-rehype')
185var html = require('rehype-stringify')
186var report = require('vfile-reporter')
187
188unified()
189  .use(markdown)
190  .use(styleGuide)
191  .use(
192    remark2retext,
193    unified()
194      .use(english)
195      .use(equality)
196  )
197  .use(remark2rehype)
198  .use(html)
199  .process('*Emphasis* and _importance_, you guys!', function(err, file) {
200    console.error(report(err || file))
201    console.log(String(file))
202  })
203```
204
205Yields:
206
207```txt
208  1:16-1:28  warning  Emphasis should use `*` as a marker                                  emphasis-marker  remark-lint
209  1:34-1:38  warning  `guys` may be insensitive, use `people`, `persons`, `folks` instead  gals-men         retext-equality
210
211⚠ 2 warnings
212<p><em>Emphasis</em> and <em>importance</em>, you guys!</p>
213```
214
215###### Processing between syntaxes
216
217The processors can be combined in two modes.
218
219**Bridge** mode transforms the syntax tree from one flavour (the origin) to
220another (the destination).  Then, transformations are applied on that tree.
221Finally, the origin processor continues transforming the original syntax tree.
222
223**Mutate** mode also transforms the syntax tree from one flavour to another.
224But then the origin processor continues transforming the destination syntax
225tree.
226
227In the previous example (“Programming interface”), `remark-retext` is used in
228bridge mode: the origin syntax tree is kept after retext is done; whereas
229`remark-rehype` is used in mutate mode: it sets a new syntax tree and discards
230the original.
231
232*   [`remark-retext`][remark-retext]
233*   [`remark-rehype`][remark-rehype]
234*   [`rehype-retext`][rehype-retext]
235*   [`rehype-remark`][rehype-remark]
236
237## API
238
239### `processor()`
240
241Object describing how to process text.
242
243###### Returns
244
245`Function` — New [**unfrozen**][freeze] processor which is configured to
246function the same as its ancestor.  But when the descendant processor is
247configured in the future it does not affect the ancestral processor.
248
249###### Example
250
251The following example shows how a new processor can be created (from the remark
252processor) and linked to **stdin**(4) and **stdout**(4).
253
254```js
255var remark = require('remark')
256var concat = require('concat-stream')
257
258process.stdin.pipe(concat(onconcat))
259
260function onconcat(buf) {
261  var doc = remark()
262    .processSync(buf)
263    .toString()
264
265  process.stdout.write(doc)
266}
267```
268
269### `processor.use(plugin[, options])`
270
271Configure the processor to use a [**plugin**][plugin] and optionally configure
272that plugin with options.
273
274###### Signatures
275
276*   `processor.use(plugin[, options])`
277*   `processor.use(preset)`
278*   `processor.use(list)`
279
280###### Parameters
281
282*   `plugin` ([`Plugin`][plugin])
283*   `options` (`*`, optional) — Configuration for `plugin`
284*   `preset` (`Object`) — Object with an optional `plugins` (set to `list`),
285    and/or an optional `settings` object
286*   `list` (`Array`) — List of plugins, presets, and pairs (`plugin` and
287    `options` in an array)
288
289###### Returns
290
291`processor` — The processor on which `use` is invoked.
292
293###### Note
294
295`use` cannot be called on [frozen][freeze] processors.  Invoke the processor
296first to create a new unfrozen processor.
297
298###### Example
299
300There are many ways to pass plugins to `.use()`.  The below example gives an
301overview.
302
303```js
304var unified = require('unified')
305
306unified()
307  // Plugin with options:
308  .use(plugin, {})
309  // Plugins:
310  .use([plugin, pluginB])
311  // Two plugins, the second with options:
312  .use([plugin, [pluginB, {}]])
313  // Preset with plugins and settings:
314  .use({plugins: [plugin, [pluginB, {}]], settings: {position: false}})
315  // Settings only:
316  .use({settings: {position: false}})
317
318function plugin() {}
319function pluginB() {}
320```
321
322### `processor.parse(file|value)`
323
324Parse text to a syntax tree.
325
326###### Parameters
327
328*   `file` ([`VFile`][file])
329    — Or anything which can be given to `vfile()`
330
331###### Returns
332
333[`Node`][node] — Syntax tree representation of input.
334
335###### Note
336
337`parse` [freezes][freeze] the processor if not already frozen.
338
339#### `processor.Parser`
340
341Function handling the parsing of text to a syntax tree.  Used in the
342[**parse**][parse] phase in the process and invoked with a `string` and
343[`VFile`][file] representation of the document to parse.
344
345`Parser` can be a normal function in which case it must return a
346[`Node`][node]: the syntax tree representation of the given file.
347
348`Parser` can also be a constructor function (a function with keys in its
349`prototype`) in which case it’s invoked with `new`.  Instances must have a
350`parse` method which is invoked without arguments and must return a
351[`Node`][node].
352
353### `processor.stringify(node[, file])`
354
355Compile a syntax tree to text.
356
357###### Parameters
358
359*   `node` ([`Node`][node])
360*   `file` ([`VFile`][file], optional);
361    — Or anything which can be given to `vfile()`
362
363###### Returns
364
365`string` — String representation of the syntax tree file.
366
367###### Note
368
369`stringify` [freezes][freeze] the processor if not already frozen.
370
371#### `processor.Compiler`
372
373Function handling the compilation of syntax tree to a text.  Used in the
374[**stringify**][stringify] phase in the process and invoked with a
375[`Node`][node] and [`VFile`][file] representation of the document to stringify.
376
377`Compiler` can be a normal function in which case it must return a `string`:
378the text representation of the given syntax tree.
379
380`Compiler` can also be a constructor function (a function with keys in its
381`prototype`) in which case it’s invoked with `new`.  Instances must have a
382`compile` method which is invoked without arguments and must return a `string`.
383
384### `processor.run(node[, file][, done])`
385
386Transform a syntax tree by applying [**plugin**][plugin]s to it.
387
388###### Parameters
389
390*   `node` ([`Node`][node])
391*   `file` ([`VFile`][file], optional)
392    — Or anything which can be given to `vfile()`
393*   `done` ([`Function`][run-done], optional)
394
395###### Returns
396
397[`Promise`][promise] if `done` is not given.  Rejected with an error, or
398resolved with the resulting syntax tree.
399
400###### Note
401
402`run` [freezes][freeze] the processor if not already frozen.
403
404##### `function done(err[, node, file])`
405
406Invoked when transformation is complete.  Either invoked with an error or a
407syntax tree and a file.
408
409###### Parameters
410
411*   `err` (`Error`) — Fatal error
412*   `node` ([`Node`][node])
413*   `file` ([`VFile`][file])
414
415### `processor.runSync(node[, file])`
416
417Transform a syntax tree by applying [**plugin**][plugin]s to it.
418
419If asynchronous [**plugin**][plugin]s are configured an error is thrown.
420
421###### Parameters
422
423*   `node` ([`Node`][node])
424*   `file` ([`VFile`][file], optional)
425    — Or anything which can be given to `vfile()`
426
427###### Returns
428
429[`Node`][node] — The given syntax tree.
430
431###### Note
432
433`runSync` [freezes][freeze] the processor if not already frozen.
434
435### `processor.process(file|value[, done])`
436
437Process the given representation of a file as configured on the processor.  The
438process invokes `parse`, `run`, and `stringify` internally.
439
440###### Parameters
441
442*   `file` ([`VFile`][file])
443*   `value` (`string`) — String representation of a file
444*   `done` ([`Function`][process-done], optional)
445
446###### Returns
447
448[`Promise`][promise] if `done` is not given.  Rejected with an error or
449resolved with the resulting file.
450
451###### Note
452
453`process` [freezes][freeze] the processor if not already frozen.
454
455#### `function done(err, file)`
456
457Invoked when the process is complete.  Invoked with a fatal error, if any, and
458the [`VFile`][file].
459
460###### Parameters
461
462*   `err` (`Error`, optional) — Fatal error
463*   `file` ([`VFile`][file])
464
465###### Example
466
467```js
468var unified = require('unified')
469var markdown = require('remark-parse')
470var remark2rehype = require('remark-rehype')
471var doc = require('rehype-document')
472var format = require('rehype-format')
473var html = require('rehype-stringify')
474
475unified()
476  .use(markdown)
477  .use(remark2rehype)
478  .use(doc)
479  .use(format)
480  .use(html)
481  .process('# Hello world!')
482  .then(
483    function(file) {
484      console.log(String(file))
485    },
486    function(err) {
487      console.error(String(err))
488    }
489  )
490```
491
492Yields:
493
494```html
495<!DOCTYPE html>
496<html lang="en">
497  <head>
498    <meta charset="utf-8">
499    <meta name="viewport" content="width=device-width, initial-scale=1">
500  </head>
501  <body>
502    <h1>Hello world!</h1>
503  </body>
504</html>
505```
506
507### `processor.processSync(file|value)`
508
509Process the given representation of a file as configured on the processor.  The
510process invokes `parse`, `run`, and `stringify` internally.
511
512If asynchronous [**plugin**][plugin]s are configured an error is thrown.
513
514###### Parameters
515
516*   `file` ([`VFile`][file])
517*   `value` (`string`) — String representation of a file
518
519###### Returns
520
521[`VFile`][file] — Virtual file with modified [`contents`][vfile-contents].
522
523###### Note
524
525`processSync` [freezes][freeze] the processor if not already frozen.
526
527###### Example
528
529```js
530var unified = require('unified')
531var markdown = require('remark-parse')
532var remark2rehype = require('remark-rehype')
533var doc = require('rehype-document')
534var format = require('rehype-format')
535var html = require('rehype-stringify')
536
537var processor = unified()
538  .use(markdown)
539  .use(remark2rehype)
540  .use(doc)
541  .use(format)
542  .use(html)
543
544console.log(processor.processSync('# Hello world!').toString())
545```
546
547Yields:
548
549```html
550<!DOCTYPE html>
551<html lang="en">
552  <head>
553    <meta charset="utf-8">
554    <meta name="viewport" content="width=device-width, initial-scale=1">
555  </head>
556  <body>
557    <h1>Hello world!</h1>
558  </body>
559</html>
560```
561
562### `processor.data(key[, value])`
563
564Get or set information in an in-memory key-value store accessible to all phases
565of the process.  An example is a list of HTML elements which are self-closing,
566which is needed when parsing, transforming, and compiling HTML.
567
568###### Parameters
569
570*   `key` (`string`) — Identifier
571*   `value` (`*`, optional) — Value to set.  Omit if getting `key`
572
573###### Returns
574
575*   `processor` — If setting, the processor on which `data` is invoked
576*   `*` — If getting, the value at `key`
577
578###### Note
579
580Setting information with `data` cannot occur on [frozen][freeze] processors.
581Invoke the processor first to create a new unfrozen processor.
582
583###### Example
584
585The following example show how to get and set information:
586
587```js
588var unified = require('unified')
589
590console.log(
591  unified()
592    .data('alpha', 'bravo')
593    .data('alpha')
594)
595```
596
597Yields:
598
599```txt
600bravo
601```
602
603### `processor.freeze()`
604
605Freeze a processor.  Frozen processors are meant to be extended and not to be
606configured or processed directly.
607
608Once a processor is frozen it cannot be unfrozen.  New processors functioning
609just like it can be created by invoking the processor.
610
611It’s possible to freeze processors explicitly, by calling `.freeze()`, but
612[`.parse()`][parse], [`.run()`][run], [`.stringify()`][stringify], and
613[`.process()`][process] call `.freeze()` to freeze a processor too.
614
615###### Returns
616
617`Processor` — The processor on which `freeze` is invoked.
618
619###### Example
620
621The following example, `index.js`, shows how [**rehype**][rehype] prevents
622extensions to itself:
623
624```js
625var unified = require('unified')
626var parse = require('rehype-parse')
627var stringify = require('rehype-stringify')
628
629module.exports = unified()
630  .use(parse)
631  .use(stringify)
632  .freeze()
633```
634
635The below example, `a.js`, shows how that processor can be used and configured.
636
637```js
638var rehype = require('rehype')
639var format = require('rehype-format')
640// ...
641
642rehype()
643  .use(format)
644  // ...
645```
646
647The below example, `b.js`, shows a similar looking example which operates on
648the frozen [**rehype**][rehype] interface.  If this behaviour was allowed it
649would result in unexpected behaviour so an error is thrown.  **This is
650invalid**:
651
652```js
653var rehype = require('rehype')
654var format = require('rehype-format')
655// ...
656
657rehype
658  .use(format)
659  // ...
660```
661
662Yields:
663
664```txt
665~/node_modules/unified/index.js:440
666    throw new Error(
667    ^
668
669Error: Cannot invoke `use` on a frozen processor.
670Create a new processor first, by invoking it: use `processor()` instead of `processor`.
671    at assertUnfrozen (~/node_modules/unified/index.js:440:11)
672    at Function.use (~/node_modules/unified/index.js:172:5)
673    at Object.<anonymous> (~/b.js:6:4)
674```
675
676## `Plugin`
677
678**unified** plugins change the way the applied-on processor works in the
679following ways:
680
681*   They modify the [**processor**][processor]: such as changing the parser,
682    the compiler, or linking it to other processors
683*   They transform [**syntax tree**][node] representation of files
684*   They modify metadata of files
685
686Plugins are a concept.  They materialise as [`attacher`][attacher]s.
687
688###### Example
689
690`move.js`:
691
692```js
693module.exports = move
694
695function move(options) {
696  var expected = (options || {}).extname
697
698  if (!expected) {
699    throw new Error('Missing `extname` in options')
700  }
701
702  return transformer
703
704  function transformer(tree, file) {
705    if (file.extname && file.extname !== expected) {
706      file.extname = expected
707    }
708  }
709}
710```
711
712`index.js`:
713
714```js
715var unified = require('unified')
716var parse = require('remark-parse')
717var remark2rehype = require('remark-rehype')
718var stringify = require('rehype-stringify')
719var vfile = require('to-vfile')
720var report = require('vfile-reporter')
721var move = require('./move')
722
723unified()
724  .use(parse)
725  .use(remark2rehype)
726  .use(move, {extname: '.html'})
727  .use(stringify)
728  .process(vfile.readSync('index.md'), function(err, file) {
729    console.error(report(err || file))
730    if (file) {
731      vfile.writeSync(file) // Written to `index.html`.
732    }
733  })
734```
735
736### `function attacher([options])`
737
738An attacher is the thing passed to [`use`][use].  It configures the processor
739and in turn can receive options.
740
741Attachers can configure processors, such as by interacting with parsers and
742compilers, linking them to other processors, or by specifying how the syntax
743tree is handled.
744
745###### Context
746
747The context object is set to the invoked on [`processor`][processor].
748
749###### Parameters
750
751*   `options` (`*`, optional) — Configuration
752
753###### Returns
754
755[`transformer`][transformer] — Optional.
756
757###### Note
758
759Attachers are invoked when the processor is [frozen][freeze]: either when
760`.freeze()` is called explicitly, or when [`.parse()`][parse], [`.run()`][run],
761[`.stringify()`][stringify], or [`.process()`][process] is called for the first
762time.
763
764### `function transformer(node, file[, next])`
765
766Transformers modify the syntax tree or metadata of a file.  A transformer is a
767function which is invoked each time a file is passed through the transform
768phase.  If an error occurs (either because it’s thrown, returned, rejected, or
769passed to [`next`][next]), the process stops.
770
771The transformation process in **unified** is handled by [`trough`][trough], see
772it’s documentation for the exact semantics of transformers.
773
774###### Parameters
775
776*   `node` ([`Node`][node])
777*   `file` ([`VFile`][file])
778*   `next` ([`Function`][next], optional)
779
780###### Returns
781
782*   `Error` — Can be returned to stop the process
783*   [`Node`][node] — Can be returned and results in further transformations
784    and `stringify`s to be performed on the new tree
785*   `Promise` — If a promise is returned, the function is asynchronous, and
786    **must** be resolved (optionally with a [`Node`][node]) or rejected
787    (optionally with an `Error`)
788
789#### `function next(err[, tree[, file]])`
790
791If the signature of a transformer includes `next` (third argument), the
792function **may** finish asynchronous, and **must** invoke `next()`.
793
794###### Parameters
795
796*   `err` (`Error`, optional) — Stop the process
797*   `node` ([`Node`][node], optional) — New syntax tree
798*   `file` ([`VFile`][file], optional) — New virtual file
799
800## `Preset`
801
802Presets provide a potentially sharable way to configure processors.  They can
803contain multiple plugins and optionally settings as well.
804
805###### Example
806
807`preset.js`:
808
809```js
810exports.settings = {bullet: '*', fences: true}
811
812exports.plugins = [
813  require('remark-preset-lint-recommended'),
814  require('remark-comment-config'),
815  require('remark-preset-lint-markdown-style-guide'),
816  [require('remark-toc'), {maxDepth: 3, tight: true}],
817  require('remark-github')
818]
819```
820
821`index.js`:
822
823```js
824var remark = require('remark')
825var vfile = require('to-vfile')
826var report = require('vfile-reporter')
827var preset = require('./preset')
828
829remark()
830  .use(preset)
831  .process(vfile.readSync('index.md'), function(err, file) {
832    console.error(report(err || file))
833
834    if (file) {
835      vfile.writeSync(file)
836    }
837  })
838```
839
840## Contribute
841
842**unified** is built by people just like you!  Check out
843[`contributing.md`][contributing] for ways to get started.
844
845This project has a [Code of Conduct][coc].  By interacting with this repository,
846organisation, or community you agree to abide by its terms.
847
848Want to chat with the community and contributors?  Join us in [Gitter][chat]!
849
850Have an idea for a cool new utility or tool?  That’s great!  If you want
851feedback, help, or just to share it with the world you can do so by creating
852an issue in the [`unifiedjs/ideas`][ideas] repository!
853
854## Acknowledgments
855
856Preliminary work for unified was done [in 2014][preliminary] for
857[**retext**][retext] and inspired by [`ware`][ware].  Further incubation
858happened in [**remark**][remark].  The project was finally [externalised][]
859in 2015 and [published][] as `unified`.  The project was authored by
860[**@wooorm**](https://github.com/wooorm).
861
862Although `unified` since moved it’s plugin architecture to [`trough`][trough],
863thanks to [**@calvinfo**](https://github.com/calvinfo),
864[**@ianstormtaylor**](https://github.com/ianstormtaylor), and others for their
865work on [`ware`][ware], which was a huge initial inspiration.
866
867## License
868
869[MIT][license] © [Titus Wormer][author]
870
871<!-- Definitions -->
872
873[logo]: https://cdn.rawgit.com/unifiedjs/unified/0cd3a41/logo.svg
874
875[travis-badge]: https://img.shields.io/travis/unifiedjs/unified.svg
876
877[travis]: https://travis-ci.org/unifiedjs/unified
878
879[codecov-badge]: https://img.shields.io/codecov/c/github/unifiedjs/unified.svg
880
881[codecov]: https://codecov.io/github/unifiedjs/unified
882
883[chat-badge]: https://img.shields.io/gitter/room/unifiedjs/Lobby.svg
884
885[chat]: https://gitter.im/unifiedjs/Lobby
886
887[npm]: https://docs.npmjs.com/cli/install
888
889[license]: LICENSE
890
891[author]: http://wooorm.com
892
893[site]: https://unifiedjs.github.io
894
895[guides]: https://unifiedjs.github.io/#guides
896
897[rehype]: https://github.com/rehypejs/rehype
898
899[remark]: https://github.com/remarkjs/remark
900
901[retext]: https://github.com/retextjs/retext
902
903[hast]: https://github.com/syntax-tree/hast
904
905[mdast]: https://github.com/syntax-tree/mdast
906
907[nlcst]: https://github.com/syntax-tree/nlcst
908
909[unist]: https://github.com/syntax-tree/unist
910
911[engine]: https://github.com/unifiedjs/unified-engine
912
913[args]: https://github.com/unifiedjs/unified-args
914
915[gulp]: https://github.com/unifiedjs/unified-engine-gulp
916
917[atom]: https://github.com/unifiedjs/unified-engine-atom
918
919[remark-rehype]: https://github.com/remarkjs/remark-rehype
920
921[remark-retext]: https://github.com/remarkjs/remark-retext
922
923[rehype-retext]: https://github.com/rehypejs/rehype-retext
924
925[rehype-remark]: https://github.com/rehypejs/rehype-remark
926
927[unist-utilities]: https://github.com/syntax-tree/unist#list-of-utilities
928
929[vfile]: https://github.com/vfile/vfile
930
931[vfile-contents]: https://github.com/vfile/vfile#vfilecontents
932
933[vfile-utilities]: https://github.com/vfile/vfile#related-tools
934
935[file]: #file
936
937[node]: #node
938
939[processor]: #processor
940
941[process]: #processorprocessfilevalue-done
942
943[parse]: #processorparsefilevalue
944
945[parser]: #processorparser
946
947[stringify]: #processorstringifynode-file
948
949[run]: #processorrunnode-file-done
950
951[compiler]: #processorcompiler
952
953[use]: #processoruseplugin-options
954
955[attacher]: #function-attacheroptions
956
957[transformer]: #function-transformernode-file-next
958
959[next]: #function-nexterr-tree-file
960
961[freeze]: #processorfreeze
962
963[plugin]: #plugin
964
965[run-done]: #function-doneerr-node-file
966
967[process-done]: #function-doneerr-file
968
969[trough]: https://github.com/wooorm/trough#function-fninput-next
970
971[promise]: https://developer.mozilla.org/Web/JavaScript/Reference/Global_Objects/Promise
972
973[remark-plugins]: https://github.com/remarkjs/remark/blob/master/doc/plugins.md#list-of-plugins
974
975[rehype-plugins]: https://github.com/rehypejs/rehype/blob/master/doc/plugins.md#list-of-plugins
976
977[retext-plugins]: https://github.com/retextjs/retext/blob/master/doc/plugins.md#list-of-plugins
978
979[stream]: https://github.com/unifiedjs/unified-stream
980
981[contributing]: contributing.md
982
983[coc]: code-of-conduct.md
984
985[ideas]: https://github.com/unifiedjs/ideas
986
987[preliminary]: https://github.com/retextjs/retext/commit/8fcb1f#diff-168726dbe96b3ce427e7fedce31bb0bc
988
989[externalised]: https://github.com/remarkjs/remark/commit/9892ec#diff-168726dbe96b3ce427e7fedce31bb0bc
990
991[published]: https://github.com/unifiedjs/unified/commit/2ba1cf
992
993[ware]: https://github.com/segmentio/ware
994