UNPKG

37 kBMarkdownView Raw
1# [![unified][logo]](https://unified.js.org/)
2
3[![Build][build-badge]][build]
4[![Coverage][coverage-badge]][coverage]
5[![Downloads][downloads-badge]][downloads]
6[![Size][size-badge]][size]
7[![Sponsors][sponsors-badge]][collective]
8[![Backers][backers-badge]][collective]
9[![Chat][chat-badge]][chat]
10
11**unified** is an interface for processing text using syntax trees.
12It’s what powers [**remark**][remark], [**retext**][retext], and
13[**rehype**][rehype], and allows for processing between formats.
14
15## Intro
16
17**unified** enables new exciting projects like [Gatsby][] to pull in Markdown,
18[MDX][] to embed [JSX][], and [Prettier][] to format it.
19It’s used in about 200k projects on GitHub and has about 10m downloads each
20month on npm: you’re probably using it.
21Some notable users are [Node.js][], [ZEIT][], [Netlify][], [GitHub][],
22[Mozilla][], [WordPress][], [Adobe][], [Facebook][], [Google][], and many more.
23
24* To read about what we are up to, follow us on [Medium][] and [Twitter][]
25* For a less technical and more practical introduction to unified, visit
26 [`unified.js.org`][site] and try its introductory [Guides][]
27* Browse [awesome unified][awesome] to find out more about the ecosystem
28* Questions?
29 Get help on [our Spectrum community][spectrum]!
30* Check out [Contribute][] below to find out how to help out, or become a
31 backer or sponsor on [Open Collective][collective]
32
33## Sponsors
34
35<!--lint ignore no-html maximum-line-length-->
36
37<table>
38 <tr valign="top">
39 <td width="20%" align="center">
40 <a href="https://zeit.co"><img src="https://avatars1.githubusercontent.com/u/14985020?s=400&v=4"></a>
41 <br><br>🥇
42 <a href="https://zeit.co">ZEIT</a>
43 </td>
44 <td width="20%" align="center">
45 <a href="https://www.gatsbyjs.org"><img src="https://avatars1.githubusercontent.com/u/12551863?s=400&v=4"></a>
46 <br><br>🥇
47 <a href="https://www.gatsbyjs.org">Gatsby</a></td>
48 <td width="20%" align="center">
49 <a href="https://compositor.io"><img src="https://avatars1.githubusercontent.com/u/19245838?s=400&v=4"></a>
50 <br><br>🥉
51 <a href="https://compositor.io">Compositor</a>
52 </td>
53 <td width="20%" align="center">
54 <a href="https://www.holloway.com"><img src="https://avatars1.githubusercontent.com/u/35904294?s=400&v=4"></a>
55 <br><br>
56 <a href="https://www.holloway.com">Holloway</a>
57 </td>
58 <td width="20%" align="center">
59 <br><br><br><br>
60 <a href="https://opencollective.com/unified"><strong>You?</strong>
61 </td>
62 </tr>
63</table>
64
65[**Read more about the unified collective on Medium »**][announcement]
66
67## Install
68
69[npm][]:
70
71```sh
72npm install unified
73```
74
75This package comes with types.
76If you’re using TypeScript, make sure to also install [`@types/unist`][ts-unist]
77and [`@types/vfile`][ts-vfile].
78
79## Use
80
81```js
82var unified = require('unified')
83var markdown = require('remark-parse')
84var remark2rehype = require('remark-rehype')
85var doc = require('rehype-document')
86var format = require('rehype-format')
87var html = require('rehype-stringify')
88var report = require('vfile-reporter')
89
90unified()
91 .use(markdown)
92 .use(remark2rehype)
93 .use(doc, {title: '👋🌍'})
94 .use(format)
95 .use(html)
96 .process('# Hello world!', function(err, file) {
97 console.error(report(err || file))
98 console.log(String(file))
99 })
100```
101
102Yields:
103
104```txt
105no issues found
106```
107
108```html
109<!doctype html>
110<html lang="en">
111 <head>
112 <meta charset="utf-8">
113 <title>👋🌍</title>
114 <meta name="viewport" content="width=device-width, initial-scale=1">
115 </head>
116 <body>
117 <h1>Hello world!</h1>
118 </body>
119</html>
120```
121
122## Table of Contents
123
124* [Description](#description)
125* [API](#api)
126 * [processor()](#processor)
127 * [processor.use(plugin\[, options\])](#processoruseplugin-options)
128 * [processor.parse(file)](#processorparsefile)
129 * [processor.stringify(node\[, file\])](#processorstringifynode-file)
130 * [processor.run(node\[, file\]\[, done\])](#processorrunnode-file-done)
131 * [processor.runSync(node\[, file\])](#processorrunsyncnode-file)
132 * [processor.process(file\[, done\])](#processorprocessfile-done)
133 * [processor.processSync(file|value)](#processorprocesssyncfilevalue)
134 * [processor.data(\[key\[, value\]\])](#processordatakey-value)
135 * [processor.freeze()](#processorfreeze)
136* [Plugin](#plugin)
137 * [function attacher(\[options\])](#function-attacheroptions)
138 * [function transformer(node, file\[, next\])](#function-transformernode-file-next)
139* [Preset](#preset)
140* [Contribute](#contribute)
141* [Acknowledgments](#acknowledgments)
142* [License](#license)
143
144## Description
145
146**unified** is an interface for processing text using syntax trees.
147Syntax trees are a representation understandable to programs.
148Those programs, called [*plugin*][plugin]s, take these trees and inspect and
149modify them.
150To get to the syntax tree from text, there is a [*parser*][parser].
151To get from that back to text, there is a [*compiler*][compiler].
152This is the [*process*][process] of a *processor*.
153
154```ascii
155| ........................ process ........................... |
156| .......... parse ... | ... run ... | ... stringify ..........|
157
158 +--------+ +----------+
159Input ->- | Parser | ->- Syntax Tree ->- | Compiler | ->- Output
160 +--------+ | +----------+
161 X
162 |
163 +--------------+
164 | Transformers |
165 +--------------+
166```
167
168###### Processors
169
170Every **processor** implements another processor.
171To create a processor, call another processor.
172The new processor is configured to work the same as its ancestor.
173But when the descendant processor is configured in the future it does not affect
174the ancestral processor.
175
176When processors are exposed from a module (for example, `unified` itself) they
177should not be configured directly, as that would change their behaviour for all
178module users.
179Those processors are [*frozen*][freeze] and they should be called to create a
180new processor before they are used.
181
182###### Syntax trees
183
184The **syntax trees** used in **unified** are [**unist**][unist] nodes.
185A [**node**][node] is a plain JavaScript objects with a `type` field.
186The semantics of nodes and format of syntax trees is defined by other projects.
187
188There are several [*utilities*][unist-utilities] for working with nodes.
189
190* [**hast**][hast] — HTML
191* [**mdast**][mdast] — Markdown
192* [**nlcst**][nlcst] — Natural language
193
194###### List of Processors
195
196The following projects process different [*syntax tree*][syntax-tree] formats.
197They parse text to a syntax tree and compile that back to text.
198These processors can be used as is, or their parser and stringifier can be mixed
199and matched with **unified** and plugins to process between different syntaxes.
200
201* [**rehype**][rehype] ([*hast*][hast]) — HTML
202* [**remark**][remark] ([*mdast*][mdast]) — Markdown
203* [**retext**][retext] ([*nlcst*][nlcst]) — Natural language
204
205###### List of Plugins
206
207The below [**plugins**][plugin] work with **unified**, on all [*syntax
208tree*][syntax-tree] formats:
209
210* [`unified-diff`](https://github.com/unifiedjs/unified-diff)
211 — Ignore messages for unchanged lines in Travis
212
213See [**remark**][remark-plugins], [**rehype**][rehype-plugins], and
214[**retext**][retext-plugins] for their lists of plugins.
215
216###### File
217
218When processing a document, **metadata** is often gathered about that document.
219[**vfile**][vfile] is a virtual file format that stores data, metadata, and
220messages about files for **unified** and its plugins.
221
222There are several [*utilities*][vfile-utilities] for working with these files.
223
224###### Configuration
225
226[*Processors*][processors] are configured with [*plugin*][plugin]s or
227with the [`data`][data] method.
228
229###### Integrations
230
231**unified** can integrate with the file system with [`unified-engine`][engine].
232CLI apps can be created with [`unified-args`][args], Gulp plugins with
233[`unified-engine-gulp`][gulp], and Atom Linters with
234[`unified-engine-atom`][atom].
235
236[`unified-stream`][stream] provides a streaming interface.
237
238###### Programming interface
239
240The API provided by **unified** allows multiple files to be processed and gives
241access to *metadata* (such as lint messages):
242
243```js
244var unified = require('unified')
245var markdown = require('remark-parse')
246var styleGuide = require('remark-preset-lint-markdown-style-guide')
247var remark2retext = require('remark-retext')
248var english = require('retext-english')
249var equality = require('retext-equality')
250var remark2rehype = require('remark-rehype')
251var html = require('rehype-stringify')
252var report = require('vfile-reporter')
253
254unified()
255 .use(markdown)
256 .use(styleGuide)
257 .use(
258 remark2retext,
259 unified()
260 .use(english)
261 .use(equality)
262 )
263 .use(remark2rehype)
264 .use(html)
265 .process('*Emphasis* and _stress_, you guys!', function(err, file) {
266 console.error(report(err || file))
267 console.log(String(file))
268 })
269```
270
271Yields:
272
273```txt
274 1:16-1:24 warning Emphasis should use `*` as a marker emphasis-marker remark-lint
275 1:30-1:34 warning `guys` may be insensitive, use `people`, `persons`, `folks` instead gals-men retext-equality
276
277⚠ 2 warnings
278```
279
280```html
281<p><em>Emphasis</em> and <em>stress</em>, you guys!</p>
282```
283
284###### Processing between syntaxes
285
286[*Processors*][processors] can be combined in two modes.
287
288**Bridge** mode transforms the [*syntax tree*][syntax-tree] from one format
289(*origin*) to another (*destination*).
290Another processor runs on the destination tree.
291Finally, the original processor continues transforming the origin tree.
292
293**Mutate** mode also transforms the syntax tree from one format to another.
294But the original processor continues transforming the destination tree.
295
296In the previous example (“Programming interface”), `remark-retext` is used in
297*bridge* mode: the origin syntax tree is kept after [**retext**][retext] is
298done; whereas `remark-rehype` is used in *mutate* mode: it sets a new syntax
299tree and discards the origin tree.
300
301* [`remark-retext`][remark-retext]
302* [`remark-rehype`][remark-rehype]
303* [`rehype-retext`][rehype-retext]
304* [`rehype-remark`][rehype-remark]
305
306## API
307
308### `processor()`
309
310[*Processor*][processors] describing how to *process* text.
311
312###### Returns
313
314`Function` — New [*unfrozen*][freeze] processor that is configured to work the
315same as its ancestor.
316When the descendant processor is configured in the future it does not affect the
317ancestral processor.
318
319###### Example
320
321The following example shows how a new processor can be created (from the remark
322processor) and linked to **stdin**(4) and **stdout**(4).
323
324```js
325var remark = require('remark')
326var concat = require('concat-stream')
327
328process.stdin.pipe(concat(onconcat))
329
330function onconcat(buf) {
331 var doc = remark()
332 .processSync(buf)
333 .toString()
334
335 process.stdout.write(doc)
336}
337```
338
339### `processor.use(plugin[, options])`
340
341[*Configure*][configuration] the processor to use a [*plugin*][plugin] and
342optionally configure that plugin with options.
343
344###### Signatures
345
346* `processor.use(plugin[, options])`
347* `processor.use(preset)`
348* `processor.use(list)`
349
350###### Parameters
351
352* `plugin` ([`Attacher`][plugin])
353* `options` (`*`, optional) — Configuration for `plugin`
354* `preset` (`Object`) — Object with an optional `plugins` (set to `list`),
355 and/or an optional `settings` object
356* `list` (`Array`) — List of plugins, presets, and pairs (`plugin` and
357 `options` in an array)
358
359###### Returns
360
361`processor` — The processor that `use` was called on.
362
363###### Note
364
365`use` cannot be called on [*frozen*][freeze] processors.
366Call the processor first to create a new unfrozen processor.
367
368###### Example
369
370There are many ways to pass plugins to `.use()`.
371The below example gives an overview.
372
373```js
374var unified = require('unified')
375
376unified()
377 // Plugin with options:
378 .use(plugin, {})
379 // Plugins:
380 .use([plugin, pluginB])
381 // Two plugins, the second with options:
382 .use([plugin, [pluginB, {}]])
383 // Preset with plugins and settings:
384 .use({plugins: [plugin, [pluginB, {}]], settings: {position: false}})
385 // Settings only:
386 .use({settings: {position: false}})
387
388function plugin() {}
389function pluginB() {}
390```
391
392### `processor.parse(file)`
393
394Parse text to a [*syntax tree*][syntax-tree].
395
396###### Parameters
397
398* `file` ([`VFile`][vfile]) — [*File*][file], any value accepted by `vfile()`
399
400###### Returns
401
402[`Node`][node] — Parsed [*syntax tree*][syntax-tree] representing `file`.
403
404###### Note
405
406`parse` freezes the processor if not already [*frozen*][freeze].
407
408`parse` performs the [*parse phase*][description], not the *run phase* or other
409phases.
410
411###### Example
412
413The below example shows how `parse` can be used to create a syntax tree from a
414file.
415
416```js
417var unified = require('unified')
418var markdown = require('remark-parse')
419
420var tree = unified()
421 .use(markdown)
422 .parse('# Hello world!')
423
424console.log(tree)
425```
426
427Yields:
428
429```js
430{ type: 'root',
431 children:
432 [ { type: 'heading',
433 depth: 1,
434 children: [Array],
435 position: [Position] } ],
436 position:
437 { start: { line: 1, column: 1, offset: 0 },
438 end: { line: 1, column: 15, offset: 14 } } }
439```
440
441#### `processor.Parser`
442
443A **parser** handles the parsing of text to a [*syntax tree*][syntax-tree].
444Used in the [*parse phase*][description] and called with a `string` and
445[`VFile`][vfile] representation of the text to parse.
446
447`Parser` can be a function, in which case it must return a [`Node`][node]: the
448syntax tree representation of the given file.
449
450`Parser` can also be a constructor function (a function with a `parse` field, or
451other fields, in its `prototype`), in which case it’s constructed with `new`.
452Instances must have a `parse` method that is called without arguments and must
453return a [`Node`][node].
454
455### `processor.stringify(node[, file])`
456
457Stringify a [*syntax tree*][syntax-tree] to text.
458
459###### Parameters
460
461* `node` ([`Node`][node]) — [*Syntax tree*][syntax-tree] to stringify
462* `file` ([`VFile`][vfile], optional) — [*File*][file], any value accepted by
463 `vfile()`
464
465###### Returns
466
467`string` (see notes) — Textual representation of the [*syntax
468tree*][syntax-tree]
469
470###### Note
471
472`stringify` freezes the processor if not already [*frozen*][freeze].
473
474`stringify` performs the [*stringify phase*][description], not the *run phase*
475or other phases.
476
477Be aware that [*compiler*][compiler]s typically, but not always, return
478`string`.
479Some compilers, such as the one configured with [`rehype-react`][rehype-react],
480return other values (in this case, a React tree).
481When using TypeScript, cast the type on your side.
482
483###### Example
484
485The below example shows how `stringify` can be used to stringify a syntax tree.
486
487```js
488var unified = require('unified')
489var html = require('rehype-stringify')
490var h = require('hastscript')
491
492var tree = h('h1', 'Hello world!')
493
494var doc = unified()
495 .use(html)
496 .stringify(tree)
497
498console.log(doc)
499```
500
501Yields:
502
503```html
504<h1>Hello world!</h1>
505```
506
507#### `processor.Compiler`
508
509A **compiler** handles the compiling of a [*syntax tree*][syntax-tree] to text.
510Used in the [*stringify phase*][description] and called with a [`Node`][node]
511and [`VFile`][file] representation of syntax tree to compile.
512
513`Compiler` can be a function, in which case it should return a `string`: the
514textual representation of the syntax tree.
515
516`Compiler` can also be a constructor function (a function with a `compile`
517field, or other fields, in its `prototype`), in which case it’s constructed with
518`new`.
519Instances must have a `compile` method that is called without arguments and
520should return a `string`.
521
522### `processor.run(node[, file][, done])`
523
524Run [*transformers*][transformer] on a [*syntax tree*][syntax-tree].
525
526###### Parameters
527
528* `node` ([`Node`][node]) — [*Syntax tree*][syntax-tree] to run on
529* `file` ([`VFile`][vfile], optional) — [*File*][file], any value accepted by
530 `vfile()`
531* `done` ([`Function`][run-done], optional) — Callback
532
533###### Returns
534
535[`Promise`][promise] if `done` is not given.
536The returned promise is rejected with a fatal error, or resolved with the
537transformed [*syntax tree*][syntax-tree].
538
539###### Note
540
541`run` freezes the processor if not already [*frozen*][freeze].
542
543`run` performs the [*run phase*][description], not other phases.
544
545#### `function done(err[, node, file])`
546
547Callback called when [*transformers*][transformer] are done.
548Called with either an error or results.
549
550###### Parameters
551
552* `err` (`Error`, optional) — Fatal error
553* `node` ([`Node`][node], optional) — Transformed [*syntax tree*][syntax-tree]
554* `file` ([`VFile`][vfile], optional) — [*File*][file]
555
556###### Example
557
558The below example shows how `run` can be used to transform a syntax tree.
559
560```js
561var unified = require('unified')
562var references = require('remark-reference-links')
563var u = require('unist-builder')
564
565var tree = u('root', [
566 u('paragraph', [
567 u('link', {href: 'https://example.com'}, [u('text', 'Example Domain')])
568 ])
569])
570
571unified()
572 .use(references)
573 .run(tree, function(err, tree) {
574 if (err) throw err
575 console.log(tree)
576 })
577```
578
579Yields:
580
581```js
582{ type: 'root',
583 children:
584 [ { type: 'paragraph', children: [Array] },
585 { type: 'definition',
586 identifier: '1',
587 title: undefined,
588 url: undefined } ] }
589```
590
591### `processor.runSync(node[, file])`
592
593Run [*transformers*][transformer] on a [*syntax tree*][syntax-tree].
594
595An error is thrown if asynchronous [*plugin*][plugin]s are configured.
596
597###### Parameters
598
599* `node` ([`Node`][node]) — [*Syntax tree*][syntax-tree] to run on
600* `file` ([`VFile`][vfile], optional) — [*File*][file], any value accepted by
601 `vfile()`
602
603###### Returns
604
605[`Node`][node] — Transformed [*syntax tree*][syntax-tree].
606
607###### Note
608
609`runSync` freezes the processor if not already [*frozen*][freeze].
610
611`runSync` performs the [*run phase*][description], not other phases.
612
613### `processor.process(file[, done])`
614
615[*Process*][description] the given [*file*][file] as configured on the
616processor.
617
618###### Parameters
619
620* `file` ([`VFile`][vfile]) — [*File*][file], any value accepted by `vfile()`
621* `done` ([`Function`][process-done], optional) — Callback
622
623###### Returns
624
625[`Promise`][promise] if `done` is not given.
626The returned promise is rejected with a fatal error, or resolved with the
627processed [*file*][file].
628
629The parsed, transformed, and stringified value is exposed on
630[`file.contents`][vfile-contents].
631
632###### Note
633
634`process` freezes the processor if not already [*frozen*][freeze].
635
636`process` performs the [*parse*, *run*, and *stringify* phases][description].
637
638Be aware that [*compiler*][compiler]s typically, but not always, return
639`string`.
640Some compilers, such as the one configured with [`rehype-react`][rehype-react],
641return other values (in this case, a React tree).
642When using TypeScript, cast the type of [`file.contents`][vfile-contents] on
643your side.
644
645###### Example
646
647The below example shows how `process` can be used to process a file, whether
648transformers are asynchronous or not, with promises.
649
650```js
651var unified = require('unified')
652var markdown = require('remark-parse')
653var remark2rehype = require('remark-rehype')
654var doc = require('rehype-document')
655var format = require('rehype-format')
656var html = require('rehype-stringify')
657
658unified()
659 .use(markdown)
660 .use(remark2rehype)
661 .use(doc, {title: '👋🌍'})
662 .use(format)
663 .use(html)
664 .process('# Hello world!')
665 .then(
666 function(file) {
667 console.log(String(file))
668 },
669 function(err) {
670 console.error(String(err))
671 }
672 )
673```
674
675Yields:
676
677```html
678<!doctype html>
679<html lang="en">
680 <head>
681 <meta charset="utf-8">
682 <title>👋🌍</title>
683 <meta name="viewport" content="width=device-width, initial-scale=1">
684 </head>
685 <body>
686 <h1>Hello world!</h1>
687 </body>
688</html>
689```
690
691#### `function done(err, file)`
692
693Callback called when the [*process*][description] is done.
694Called with a fatal error, if any, and a [*file*][file].
695
696###### Parameters
697
698* `err` (`Error`, optional) — Fatal error
699* `file` ([`VFile`][vfile]) — Processed [*file*][file]
700
701###### Example
702
703The below example shows how `process` can be used to process a file, whether
704transformers are asynchronous or not, with a callback.
705
706```js
707var unified = require('unified')
708var parse = require('remark-parse')
709var stringify = require('remark-stringify')
710var github = require('remark-github')
711var report = require('vfile-reporter')
712
713unified()
714 .use(parse)
715 .use(github)
716 .use(stringify)
717 .process('@wooorm', function(err, file) {
718 console.error(report(err || file))
719 console.log(String(file))
720 })
721```
722
723Yields:
724
725```txt
726no issues found
727```
728
729```markdown
730[**@wooorm**](https://github.com/wooorm)
731```
732
733### `processor.processSync(file|value)`
734
735[*Process*][description] the given [*file*][file] as configured on the
736processor.
737
738An error is thrown if asynchronous [*plugin*][plugin]s are configured.
739
740###### Parameters
741
742* `file` ([`VFile`][vfile]) — [*File*][file], any value accepted by `vfile()`
743
744###### Returns
745
746([`VFile`][vfile]) — Processed [*file*][file]
747
748###### Note
749
750`processSync` freezes the processor if not already [*frozen*][freeze].
751
752`processSync` performs the [*parse*, *run*, and *stringify*
753phases][description].
754
755Be aware that [*compiler*][compiler]s typically, but not always, return
756`string`.
757Some compilers, such as the one configured with [`rehype-react`][rehype-react],
758return other values (in this case, a React tree).
759When using TypeScript, cast the type of [`file.contents`][vfile-contents] on
760your side.
761
762###### Example
763
764The below example shows how `processSync` can be used to process a file, if all
765transformers are synchronous.
766
767```js
768var unified = require('unified')
769var markdown = require('remark-parse')
770var remark2rehype = require('remark-rehype')
771var doc = require('rehype-document')
772var format = require('rehype-format')
773var html = require('rehype-stringify')
774
775var processor = unified()
776 .use(markdown)
777 .use(remark2rehype)
778 .use(doc, {title: '👋🌍'})
779 .use(format)
780 .use(html)
781
782console.log(processor.processSync('# Hello world!').toString())
783```
784
785Yields:
786
787```html
788<!doctype html>
789<html lang="en">
790 <head>
791 <meta charset="utf-8">
792 <title>👋🌍</title>
793 <meta name="viewport" content="width=device-width, initial-scale=1">
794 </head>
795 <body>
796 <h1>Hello world!</h1>
797 </body>
798</html>
799```
800
801### `processor.data([key[, value]])`
802
803[*Configure*][configuration] the processor with information available to all
804[*plugin*][plugin]s.
805Information is stored in an in-memory key-value store.
806
807Typically, options can be given to a specific plugin, but sometimes it makes
808sense to have information shared with several plugins.
809For example, a list of HTML elements that are self-closing, which is needed
810during all [*phases*][description] of the *process*.
811
812###### Signatures
813
814* `processor = processor.data(key, value)`
815* `processor = processor.data(values)`
816* `value = processor.data(key)`
817* `info = processor.data()`
818
819###### Parameters
820
821* `key` (`string`, optional) — Identifier
822* `value` (`*`, optional) — Value to set
823* `values` (`Object`, optional) — Values to set
824
825###### Returns
826
827* `processor` — If setting, the processor that `data` is called on
828* `value` (`*`) — If getting, the value at `key`
829* `info` (`Object`) — Without arguments, the key-value store
830
831###### Note
832
833Setting information cannot occur on [*frozen*][freeze] processors.
834Call the processor first to create a new unfrozen processor.
835
836###### Example
837
838The following example show how to get and set information:
839
840```js
841var unified = require('unified')
842
843var processor = unified().data('alpha', 'bravo')
844
845processor.data('alpha') // => 'bravo'
846
847processor.data() // {alpha: 'bravo'}
848
849processor.data({charlie: 'delta'})
850
851processor.data() // {charlie: 'delta'}
852```
853
854### `processor.freeze()`
855
856**Freeze** a processor.
857*Frozen* processors are meant to be extended and not to be configured directly.
858
859Once a processor is frozen it cannot be *unfrozen*.
860New processors working the same way can be created by calling the processor.
861
862It’s possible to freeze processors explicitly by calling `.freeze()`.
863Processors freeze implicitly when [`.parse()`][parse], [`.run()`][run],
864[`.runSync()`][run-sync], [`.stringify()`][stringify], [`.process()`][process],
865or [`.processSync()`][process-sync] are called.
866
867###### Returns
868
869`processor` — The processor that `freeze` was called on.
870
871###### Example
872
873The following example, `index.js`, shows how rehype prevents extensions to
874itself:
875
876```js
877var unified = require('unified')
878var parse = require('rehype-parse')
879var stringify = require('rehype-stringify')
880
881module.exports = unified()
882 .use(parse)
883 .use(stringify)
884 .freeze()
885```
886
887The below example, `a.js`, shows how that processor can be used and configured.
888
889```js
890var rehype = require('rehype')
891var format = require('rehype-format')
892// …
893
894rehype()
895 .use(format)
896 // …
897```
898
899The below example, `b.js`, shows a similar looking example that operates on the
900frozen rehype interface because it does not call `rehype`.
901If this behaviour was allowed it would result in unexpected behaviour so an
902error is thrown.
903**This is invalid**:
904
905```js
906var rehype = require('rehype')
907var format = require('rehype-format')
908// …
909
910rehype
911 .use(format)
912 // …
913```
914
915Yields:
916
917```txt
918~/node_modules/unified/index.js:440
919 throw new Error(
920 ^
921
922Error: Cannot invoke `use` on a frozen processor.
923Create a new processor first, by invoking it: use `processor()` instead of `processor`.
924 at assertUnfrozen (~/node_modules/unified/index.js:440:11)
925 at Function.use (~/node_modules/unified/index.js:172:5)
926 at Object.<anonymous> (~/b.js:6:4)
927```
928
929## `Plugin`
930
931**Plugins** [*configure*][configuration] the processors they are applied on in
932the following ways:
933
934* They change the processor: such as the [*parser*][parser], the
935 [*compiler*][compiler], or configuring [*data*][data]
936* They specify how to handle [*syntax trees*][syntax-tree] and [*files*][file]
937
938Plugins are a concept.
939They materialise as [`attacher`][attacher]s.
940
941###### Example
942
943`move.js`:
944
945```js
946module.exports = move
947
948function move(options) {
949 var expected = (options || {}).extname
950
951 if (!expected) {
952 throw new Error('Missing `extname` in options')
953 }
954
955 return transformer
956
957 function transformer(tree, file) {
958 if (file.extname && file.extname !== expected) {
959 file.extname = expected
960 }
961 }
962}
963```
964
965`index.md`:
966
967```markdown
968# Hello, World!
969```
970
971`index.js`:
972
973```js
974var unified = require('unified')
975var parse = require('remark-parse')
976var remark2rehype = require('remark-rehype')
977var stringify = require('rehype-stringify')
978var vfile = require('to-vfile')
979var report = require('vfile-reporter')
980var move = require('./move')
981
982unified()
983 .use(parse)
984 .use(remark2rehype)
985 .use(move, {extname: '.html'})
986 .use(stringify)
987 .process(vfile.readSync('index.md'), function(err, file) {
988 console.error(report(err || file))
989 if (file) {
990 vfile.writeSync(file) // Written to `index.html`.
991 }
992 })
993```
994
995Yields:
996
997```txt
998index.md: no issues found
999```
1000
1001`index.html`:
1002
1003```html
1004<h1>Hello, World!</h1>
1005```
1006
1007### `function attacher([options])`
1008
1009**Attachers** are materialised [*plugin*][plugin]s.
1010An attacher is a function that can receive options and
1011[*configures*][configuration] the processor.
1012
1013Attachers change the processor, such as the [*parser*][parser], the
1014[*compiler*][compiler], configuring [*data*][data], or by specifying how the
1015[*syntax tree*][syntax-tree] or [*file*][file] are handled.
1016
1017###### Context
1018
1019The context object (`this`) is set to the processor the attacher is applied on.
1020
1021###### Parameters
1022
1023* `options` (`*`, optional) — Configuration
1024
1025###### Returns
1026
1027[`transformer`][transformer] — Optional.
1028
1029###### Note
1030
1031Attachers are called when the processor is [*frozen*][freeze], not when they are
1032applied.
1033
1034### `function transformer(node, file[, next])`
1035
1036**Transformers** handle [*syntax tree*][syntax-tree]s and [*file*][file]s.
1037A transformer is a function that is called each time a syntax tree and file are
1038passed through the [*run phase*][description].
1039If an error occurs (either because it’s thrown, returned, rejected, or passed to
1040[`next`][next]), the process stops.
1041
1042The *run phase* is handled by [`trough`][trough], see its documentation for the
1043exact semantics of these functions.
1044
1045###### Parameters
1046
1047* `node` ([`Node`][node]) — [*Syntax tree*][syntax-tree] to handle
1048* `file` ([`VFile`][vfile]) — [*File*][file] to handle
1049* `next` ([`Function`][next], optional)
1050
1051###### Returns
1052
1053* `Error` — Fatal error to stop the process
1054* `node` ([`Node`][node]) — New [*syntax tree*][syntax-tree].
1055 If returned, the next transformer is given this new tree
1056* `Promise` — Returned to perform an asynchronous operation.
1057 The promise **must** be resolved (optionally with a [`Node`][node]) or
1058 rejected (optionally with an `Error`)
1059
1060#### `function next(err[, tree[, file]])`
1061
1062If the signature of a [*transformer*][transformer] includes `next` (the third
1063argument), the transformer **may** perform asynchronous operations, and **must**
1064call `next()`.
1065
1066###### Parameters
1067
1068* `err` (`Error`, optional) — Fatal error to stop the process
1069* `node` ([`Node`][node], optional) — New [*syntax tree*][syntax-tree].
1070 If given, the next transformer is given this new tree
1071* `file` ([`VFile`][vfile], optional) — New [*file*][file].
1072 If given, the next transformer is given this new file
1073
1074## `Preset`
1075
1076**Presets** are sharable [*configuration*][configuration].
1077They can contain [*plugins*][plugin] and settings.
1078
1079###### Example
1080
1081`preset.js`:
1082
1083```js
1084exports.settings = {bullet: '*', emphasis: '*', fences: true}
1085
1086exports.plugins = [
1087 require('remark-preset-lint-recommended'),
1088 require('remark-preset-lint-consistent'),
1089 require('remark-comment-config'),
1090 [require('remark-toc'), {maxDepth: 3, tight: true}],
1091 require('remark-license')
1092]
1093```
1094
1095`readme.md`:
1096
1097```markdown
1098# Hello, World!
1099
1100_Emphasis_ and **importance**.
1101
1102## Table of Contents
1103
1104## API
1105
1106## License
1107```
1108
1109`index.js`:
1110
1111```js
1112var remark = require('remark')
1113var vfile = require('to-vfile')
1114var report = require('vfile-reporter')
1115var preset = require('./preset')
1116
1117remark()
1118 .use(preset)
1119 .process(vfile.readSync('readme.md'), function(err, file) {
1120 console.error(report(err || file))
1121
1122 if (file) {
1123 vfile.writeSync(file)
1124 }
1125 })
1126```
1127
1128Yields:
1129
1130```txt
1131readme.md: no issues found
1132```
1133
1134`readme.md` now contains:
1135
1136```markdown
1137# Hello, World!
1138
1139*Emphasis* and **importance**.
1140
1141## Table of Contents
1142
1143* [API](#api)
1144* [License](#license)
1145
1146## API
1147
1148## License
1149
1150[MIT](license) © [Titus Wormer](https://wooorm.com)
1151```
1152
1153## Contribute
1154
1155See [`contributing.md`][contributing] in [`unifiedjs/.github`][health] for ways
1156to get started.
1157See [`support.md`][support] for ways to get help.
1158Ideas for new plugins and tools can be posted in [`unifiedjs/ideas`][ideas].
1159
1160A curated list of awesome unified resources can be found in [**awesome
1161unified**][awesome].
1162
1163This project has a [Code of Conduct][coc].
1164By interacting with this repository, organisation, or community you agree to
1165abide by its terms.
1166
1167## Acknowledgments
1168
1169Preliminary work for unified was done [in 2014][preliminary] for
1170[**retext**][retext] and inspired by [`ware`][ware].
1171Further incubation happened in [**remark**][remark].
1172The project was finally [externalised][] in 2015 and [published][] as `unified`.
1173The project was authored by [**@wooorm**](https://github.com/wooorm).
1174
1175Although `unified` since moved its plugin architecture to [`trough`][trough],
1176thanks to [**@calvinfo**](https://github.com/calvinfo),
1177[**@ianstormtaylor**](https://github.com/ianstormtaylor), and others for their
1178work on [`ware`][ware], as it was a huge initial inspiration.
1179
1180## License
1181
1182[MIT][license] © [Titus Wormer][author]
1183
1184<!-- Definitions -->
1185
1186[logo]: https://raw.githubusercontent.com/unifiedjs/unified/39917ea/logo.svg?sanitize=true
1187
1188[build-badge]: https://img.shields.io/travis/unifiedjs/unified.svg
1189
1190[build]: https://travis-ci.org/unifiedjs/unified
1191
1192[coverage-badge]: https://img.shields.io/codecov/c/github/unifiedjs/unified.svg
1193
1194[coverage]: https://codecov.io/github/unifiedjs/unified
1195
1196[downloads-badge]: https://img.shields.io/npm/dm/unified.svg
1197
1198[downloads]: https://www.npmjs.com/package/unified
1199
1200[size-badge]: https://img.shields.io/bundlephobia/minzip/unified.svg
1201
1202[size]: https://bundlephobia.com/result?p=unified
1203
1204[sponsors-badge]: https://opencollective.com/unified/sponsors/badge.svg
1205
1206[backers-badge]: https://opencollective.com/unified/backers/badge.svg
1207
1208[collective]: https://opencollective.com/unified
1209
1210[chat-badge]: https://img.shields.io/badge/join%20the%20community-on%20spectrum-7b16ff.svg
1211
1212[chat]: https://spectrum.chat/unified
1213
1214[health]: https://github.com/unifiedjs/.github
1215
1216[contributing]: https://github.com/unifiedjs/.github/blob/master/contributing.md
1217
1218[support]: https://github.com/unifiedjs/.github/blob/master/support.md
1219
1220[coc]: https://github.com/unifiedjs/.github/blob/master/code-of-conduct.md
1221
1222[awesome]: https://github.com/unifiedjs/awesome-unified
1223
1224[license]: license
1225
1226[author]: https://wooorm.com
1227
1228[npm]: https://docs.npmjs.com/cli/install
1229
1230[ts-unist]: https://www.npmjs.com/package/@types/unist
1231
1232[ts-vfile]: https://www.npmjs.com/package/@types/vfile
1233
1234[site]: https://unified.js.org
1235
1236[medium]: https://medium.com/unifiedjs
1237
1238[announcement]: https://medium.com/unifiedjs/collectively-evolving-through-crowdsourcing-22c359ea95cc
1239
1240[twitter]: https://twitter.com/unifiedjs
1241
1242[guides]: https://unified.js.org/#guides
1243
1244[spectrum]: https://spectrum.chat/unified
1245
1246[rehype]: https://github.com/rehypejs/rehype
1247
1248[remark]: https://github.com/remarkjs/remark
1249
1250[retext]: https://github.com/retextjs/retext
1251
1252[hast]: https://github.com/syntax-tree/hast
1253
1254[mdast]: https://github.com/syntax-tree/mdast
1255
1256[nlcst]: https://github.com/syntax-tree/nlcst
1257
1258[unist]: https://github.com/syntax-tree/unist
1259
1260[engine]: https://github.com/unifiedjs/unified-engine
1261
1262[args]: https://github.com/unifiedjs/unified-args
1263
1264[gulp]: https://github.com/unifiedjs/unified-engine-gulp
1265
1266[atom]: https://github.com/unifiedjs/unified-engine-atom
1267
1268[remark-rehype]: https://github.com/remarkjs/remark-rehype
1269
1270[remark-retext]: https://github.com/remarkjs/remark-retext
1271
1272[rehype-retext]: https://github.com/rehypejs/rehype-retext
1273
1274[rehype-remark]: https://github.com/rehypejs/rehype-remark
1275
1276[unist-utilities]: https://github.com/syntax-tree/unist#list-of-utilities
1277
1278[vfile]: https://github.com/vfile/vfile
1279
1280[vfile-contents]: https://github.com/vfile/vfile#vfilecontents
1281
1282[vfile-utilities]: https://github.com/vfile/vfile#related-tools
1283
1284[node]: https://github.com/syntax-tree/unist#node
1285
1286[description]: #description
1287
1288[syntax-tree]: #syntax-trees
1289
1290[configuration]: #configuration
1291
1292[file]: #file
1293
1294[processors]: #processors
1295
1296[process]: #processorprocessfile-done
1297
1298[process-sync]: #processorprocesssyncfilevalue
1299
1300[parse]: #processorparsefile
1301
1302[parser]: #processorparser
1303
1304[stringify]: #processorstringifynode-file
1305
1306[run]: #processorrunnode-file-done
1307
1308[run-sync]: #processorrunsyncnode-file
1309
1310[compiler]: #processorcompiler
1311
1312[data]: #processordatakey-value
1313
1314[attacher]: #function-attacheroptions
1315
1316[transformer]: #function-transformernode-file-next
1317
1318[next]: #function-nexterr-tree-file
1319
1320[freeze]: #processorfreeze
1321
1322[plugin]: #plugin
1323
1324[run-done]: #function-doneerr-node-file
1325
1326[process-done]: #function-doneerr-file
1327
1328[contribute]: #contribute
1329
1330[rehype-react]: https://github.com/rhysd/rehype-react
1331
1332[trough]: https://github.com/wooorm/trough#function-fninput-next
1333
1334[promise]: https://developer.mozilla.org/Web/JavaScript/Reference/Global_Objects/Promise
1335
1336[remark-plugins]: https://github.com/remarkjs/remark/blob/master/doc/plugins.md#list-of-plugins
1337
1338[rehype-plugins]: https://github.com/rehypejs/rehype/blob/master/doc/plugins.md#list-of-plugins
1339
1340[retext-plugins]: https://github.com/retextjs/retext/blob/master/doc/plugins.md#list-of-plugins
1341
1342[stream]: https://github.com/unifiedjs/unified-stream
1343
1344[ideas]: https://github.com/unifiedjs/ideas
1345
1346[preliminary]: https://github.com/retextjs/retext/commit/8fcb1f#diff-168726dbe96b3ce427e7fedce31bb0bc
1347
1348[externalised]: https://github.com/remarkjs/remark/commit/9892ec#diff-168726dbe96b3ce427e7fedce31bb0bc
1349
1350[published]: https://github.com/unifiedjs/unified/commit/2ba1cf
1351
1352[ware]: https://github.com/segmentio/ware
1353
1354[gatsby]: https://www.gatsbyjs.org
1355
1356[mdx]: https://mdxjs.com
1357
1358[jsx]: https://reactjs.org/docs/jsx-in-depth.html
1359
1360[prettier]: https://prettier.io
1361
1362[node.js]: https://nodejs.org
1363
1364[zeit]: https://zeit.co
1365
1366[netlify]: https://www.netlify.com
1367
1368[github]: https://github.com
1369
1370[mozilla]: https://www.mozilla.org
1371
1372[wordpress]: https://wordpress.com
1373
1374[adobe]: https://www.adobe.com
1375
1376[facebook]: https://www.facebook.com
1377
1378[google]: https://www.google.com