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.
|
12 | It’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.
|
19 | It’s used in about 200k projects on GitHub and has about 10m downloads each
|
20 | month on npm: you’re probably using it.
|
21 | Some 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 |
|
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
|
72 | npm install unified
|
73 | ```
|
74 |
|
75 | This package comes with types.
|
76 | If you’re using TypeScript, make sure to also install [`@types/unist`][ts-unist]
|
77 | and [`@types/vfile`][ts-vfile].
|
78 |
|
79 | ## Use
|
80 |
|
81 | ```js
|
82 | var unified = require('unified')
|
83 | var markdown = require('remark-parse')
|
84 | var remark2rehype = require('remark-rehype')
|
85 | var doc = require('rehype-document')
|
86 | var format = require('rehype-format')
|
87 | var html = require('rehype-stringify')
|
88 | var report = require('vfile-reporter')
|
89 |
|
90 | unified()
|
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 |
|
102 | Yields:
|
103 |
|
104 | ```txt
|
105 | no 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.
|
147 | Syntax trees are a representation understandable to programs.
|
148 | Those programs, called [*plugin*][plugin]s, take these trees and inspect and
|
149 | modify them.
|
150 | To get to the syntax tree from text, there is a [*parser*][parser].
|
151 | To get from that back to text, there is a [*compiler*][compiler].
|
152 | This is the [*process*][process] of a *processor*.
|
153 |
|
154 | ```ascii
|
155 | | ........................ process ........................... |
|
156 | | .......... parse ... | ... run ... | ... stringify ..........|
|
157 |
|
158 | +--------+ +----------+
|
159 | Input ->- | Parser | ->- Syntax Tree ->- | Compiler | ->- Output
|
160 | +--------+ | +----------+
|
161 | X
|
162 | |
|
163 | +--------------+
|
164 | | Transformers |
|
165 | +--------------+
|
166 | ```
|
167 |
|
168 | ###### Processors
|
169 |
|
170 | Every **processor** implements another processor.
|
171 | To create a processor, call another processor.
|
172 | The new processor is configured to work the same as its ancestor.
|
173 | But when the descendant processor is configured in the future it does not affect
|
174 | the ancestral processor.
|
175 |
|
176 | When processors are exposed from a module (for example, `unified` itself) they
|
177 | should not be configured directly, as that would change their behaviour for all
|
178 | module users.
|
179 | Those processors are [*frozen*][freeze] and they should be called to create a
|
180 | new processor before they are used.
|
181 |
|
182 | ###### Syntax trees
|
183 |
|
184 | The **syntax trees** used in **unified** are [**unist**][unist] nodes.
|
185 | A [**node**][node] is a plain JavaScript objects with a `type` field.
|
186 | The semantics of nodes and format of syntax trees is defined by other projects.
|
187 |
|
188 | There 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 |
|
196 | The following projects process different [*syntax tree*][syntax-tree] formats.
|
197 | They parse text to a syntax tree and compile that back to text.
|
198 | These processors can be used as is, or their parser and stringifier can be mixed
|
199 | and 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 |
|
207 | The below [**plugins**][plugin] work with **unified**, on all [*syntax
|
208 | tree*][syntax-tree] formats:
|
209 |
|
210 | * [`unified-diff`](https://github.com/unifiedjs/unified-diff)
|
211 | — Ignore messages for unchanged lines in Travis
|
212 |
|
213 | See [**remark**][remark-plugins], [**rehype**][rehype-plugins], and
|
214 | [**retext**][retext-plugins] for their lists of plugins.
|
215 |
|
216 | ###### File
|
217 |
|
218 | When processing a document, **metadata** is often gathered about that document.
|
219 | [**vfile**][vfile] is a virtual file format that stores data, metadata, and
|
220 | messages about files for **unified** and its plugins.
|
221 |
|
222 | There are several [*utilities*][vfile-utilities] for working with these files.
|
223 |
|
224 | ###### Configuration
|
225 |
|
226 | [*Processors*][processors] are configured with [*plugin*][plugin]s or
|
227 | with the [`data`][data] method.
|
228 |
|
229 | ###### Integrations
|
230 |
|
231 | **unified** can integrate with the file system with [`unified-engine`][engine].
|
232 | CLI 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 |
|
240 | The API provided by **unified** allows multiple files to be processed and gives
|
241 | access to *metadata* (such as lint messages):
|
242 |
|
243 | ```js
|
244 | var unified = require('unified')
|
245 | var markdown = require('remark-parse')
|
246 | var styleGuide = require('remark-preset-lint-markdown-style-guide')
|
247 | var remark2retext = require('remark-retext')
|
248 | var english = require('retext-english')
|
249 | var equality = require('retext-equality')
|
250 | var remark2rehype = require('remark-rehype')
|
251 | var html = require('rehype-stringify')
|
252 | var report = require('vfile-reporter')
|
253 |
|
254 | unified()
|
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 |
|
271 | Yields:
|
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*).
|
290 | Another processor runs on the destination tree.
|
291 | Finally, the original processor continues transforming the origin tree.
|
292 |
|
293 | **Mutate** mode also transforms the syntax tree from one format to another.
|
294 | But the original processor continues transforming the destination tree.
|
295 |
|
296 | In the previous example (“Programming interface”), `remark-retext` is used in
|
297 | *bridge* mode: the origin syntax tree is kept after [**retext**][retext] is
|
298 | done; whereas `remark-rehype` is used in *mutate* mode: it sets a new syntax
|
299 | tree 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
|
315 | same as its ancestor.
|
316 | When the descendant processor is configured in the future it does not affect the
|
317 | ancestral processor.
|
318 |
|
319 | ###### Example
|
320 |
|
321 | The following example shows how a new processor can be created (from the remark
|
322 | processor) and linked to **stdin**(4) and **stdout**(4).
|
323 |
|
324 | ```js
|
325 | var remark = require('remark')
|
326 | var concat = require('concat-stream')
|
327 |
|
328 | process.stdin.pipe(concat(onconcat))
|
329 |
|
330 | function 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
|
342 | optionally 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.
|
366 | Call the processor first to create a new unfrozen processor.
|
367 |
|
368 | ###### Example
|
369 |
|
370 | There are many ways to pass plugins to `.use()`.
|
371 | The below example gives an overview.
|
372 |
|
373 | ```js
|
374 | var unified = require('unified')
|
375 |
|
376 | unified()
|
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 |
|
388 | function plugin() {}
|
389 | function pluginB() {}
|
390 | ```
|
391 |
|
392 | ### `processor.parse(file)`
|
393 |
|
394 | Parse 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
|
409 | phases.
|
410 |
|
411 | ###### Example
|
412 |
|
413 | The below example shows how `parse` can be used to create a syntax tree from a
|
414 | file.
|
415 |
|
416 | ```js
|
417 | var unified = require('unified')
|
418 | var markdown = require('remark-parse')
|
419 |
|
420 | var tree = unified()
|
421 | .use(markdown)
|
422 | .parse('# Hello world!')
|
423 |
|
424 | console.log(tree)
|
425 | ```
|
426 |
|
427 | Yields:
|
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 |
|
443 | A **parser** handles the parsing of text to a [*syntax tree*][syntax-tree].
|
444 | Used 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
|
448 | syntax tree representation of the given file.
|
449 |
|
450 | `Parser` can also be a constructor function (a function with a `parse` field, or
|
451 | other fields, in its `prototype`), in which case it’s constructed with `new`.
|
452 | Instances must have a `parse` method that is called without arguments and must
|
453 | return a [`Node`][node].
|
454 |
|
455 | ### `processor.stringify(node[, file])`
|
456 |
|
457 | Stringify 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
|
468 | tree*][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*
|
475 | or other phases.
|
476 |
|
477 | Be aware that [*compiler*][compiler]s typically, but not always, return
|
478 | `string`.
|
479 | Some compilers, such as the one configured with [`rehype-react`][rehype-react],
|
480 | return other values (in this case, a React tree).
|
481 | When using TypeScript, cast the type on your side.
|
482 |
|
483 | ###### Example
|
484 |
|
485 | The below example shows how `stringify` can be used to stringify a syntax tree.
|
486 |
|
487 | ```js
|
488 | var unified = require('unified')
|
489 | var html = require('rehype-stringify')
|
490 | var h = require('hastscript')
|
491 |
|
492 | var tree = h('h1', 'Hello world!')
|
493 |
|
494 | var doc = unified()
|
495 | .use(html)
|
496 | .stringify(tree)
|
497 |
|
498 | console.log(doc)
|
499 | ```
|
500 |
|
501 | Yields:
|
502 |
|
503 | ```html
|
504 | <h1>Hello world!</h1>
|
505 | ```
|
506 |
|
507 | #### `processor.Compiler`
|
508 |
|
509 | A **compiler** handles the compiling of a [*syntax tree*][syntax-tree] to text.
|
510 | Used in the [*stringify phase*][description] and called with a [`Node`][node]
|
511 | and [`VFile`][file] representation of syntax tree to compile.
|
512 |
|
513 | `Compiler` can be a function, in which case it should return a `string`: the
|
514 | textual representation of the syntax tree.
|
515 |
|
516 | `Compiler` can also be a constructor function (a function with a `compile`
|
517 | field, or other fields, in its `prototype`), in which case it’s constructed with
|
518 | `new`.
|
519 | Instances must have a `compile` method that is called without arguments and
|
520 | should return a `string`.
|
521 |
|
522 | ### `processor.run(node[, file][, done])`
|
523 |
|
524 | Run [*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.
|
536 | The returned promise is rejected with a fatal error, or resolved with the
|
537 | transformed [*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 |
|
547 | Callback called when [*transformers*][transformer] are done.
|
548 | Called 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 |
|
558 | The below example shows how `run` can be used to transform a syntax tree.
|
559 |
|
560 | ```js
|
561 | var unified = require('unified')
|
562 | var references = require('remark-reference-links')
|
563 | var u = require('unist-builder')
|
564 |
|
565 | var tree = u('root', [
|
566 | u('paragraph', [
|
567 | u('link', {href: 'https://example.com'}, [u('text', 'Example Domain')])
|
568 | ])
|
569 | ])
|
570 |
|
571 | unified()
|
572 | .use(references)
|
573 | .run(tree, function(err, tree) {
|
574 | if (err) throw err
|
575 | console.log(tree)
|
576 | })
|
577 | ```
|
578 |
|
579 | Yields:
|
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 |
|
593 | Run [*transformers*][transformer] on a [*syntax tree*][syntax-tree].
|
594 |
|
595 | An 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
|
616 | processor.
|
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.
|
626 | The returned promise is rejected with a fatal error, or resolved with the
|
627 | processed [*file*][file].
|
628 |
|
629 | The 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 |
|
638 | Be aware that [*compiler*][compiler]s typically, but not always, return
|
639 | `string`.
|
640 | Some compilers, such as the one configured with [`rehype-react`][rehype-react],
|
641 | return other values (in this case, a React tree).
|
642 | When using TypeScript, cast the type of [`file.contents`][vfile-contents] on
|
643 | your side.
|
644 |
|
645 | ###### Example
|
646 |
|
647 | The below example shows how `process` can be used to process a file, whether
|
648 | transformers are asynchronous or not, with promises.
|
649 |
|
650 | ```js
|
651 | var unified = require('unified')
|
652 | var markdown = require('remark-parse')
|
653 | var remark2rehype = require('remark-rehype')
|
654 | var doc = require('rehype-document')
|
655 | var format = require('rehype-format')
|
656 | var html = require('rehype-stringify')
|
657 |
|
658 | unified()
|
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 |
|
675 | Yields:
|
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 |
|
693 | Callback called when the [*process*][description] is done.
|
694 | Called 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 |
|
703 | The below example shows how `process` can be used to process a file, whether
|
704 | transformers are asynchronous or not, with a callback.
|
705 |
|
706 | ```js
|
707 | var unified = require('unified')
|
708 | var parse = require('remark-parse')
|
709 | var stringify = require('remark-stringify')
|
710 | var github = require('remark-github')
|
711 | var report = require('vfile-reporter')
|
712 |
|
713 | unified()
|
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 |
|
723 | Yields:
|
724 |
|
725 | ```txt
|
726 | no 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
|
736 | processor.
|
737 |
|
738 | An 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*
|
753 | phases][description].
|
754 |
|
755 | Be aware that [*compiler*][compiler]s typically, but not always, return
|
756 | `string`.
|
757 | Some compilers, such as the one configured with [`rehype-react`][rehype-react],
|
758 | return other values (in this case, a React tree).
|
759 | When using TypeScript, cast the type of [`file.contents`][vfile-contents] on
|
760 | your side.
|
761 |
|
762 | ###### Example
|
763 |
|
764 | The below example shows how `processSync` can be used to process a file, if all
|
765 | transformers are synchronous.
|
766 |
|
767 | ```js
|
768 | var unified = require('unified')
|
769 | var markdown = require('remark-parse')
|
770 | var remark2rehype = require('remark-rehype')
|
771 | var doc = require('rehype-document')
|
772 | var format = require('rehype-format')
|
773 | var html = require('rehype-stringify')
|
774 |
|
775 | var processor = unified()
|
776 | .use(markdown)
|
777 | .use(remark2rehype)
|
778 | .use(doc, {title: '👋🌍'})
|
779 | .use(format)
|
780 | .use(html)
|
781 |
|
782 | console.log(processor.processSync('# Hello world!').toString())
|
783 | ```
|
784 |
|
785 | Yields:
|
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.
|
805 | Information is stored in an in-memory key-value store.
|
806 |
|
807 | Typically, options can be given to a specific plugin, but sometimes it makes
|
808 | sense to have information shared with several plugins.
|
809 | For example, a list of HTML elements that are self-closing, which is needed
|
810 | during 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 |
|
833 | Setting information cannot occur on [*frozen*][freeze] processors.
|
834 | Call the processor first to create a new unfrozen processor.
|
835 |
|
836 | ###### Example
|
837 |
|
838 | The following example show how to get and set information:
|
839 |
|
840 | ```js
|
841 | var unified = require('unified')
|
842 |
|
843 | var processor = unified().data('alpha', 'bravo')
|
844 |
|
845 | processor.data('alpha') // => 'bravo'
|
846 |
|
847 | processor.data() // {alpha: 'bravo'}
|
848 |
|
849 | processor.data({charlie: 'delta'})
|
850 |
|
851 | processor.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 |
|
859 | Once a processor is frozen it cannot be *unfrozen*.
|
860 | New processors working the same way can be created by calling the processor.
|
861 |
|
862 | It’s possible to freeze processors explicitly by calling `.freeze()`.
|
863 | Processors freeze implicitly when [`.parse()`][parse], [`.run()`][run],
|
864 | [`.runSync()`][run-sync], [`.stringify()`][stringify], [`.process()`][process],
|
865 | or [`.processSync()`][process-sync] are called.
|
866 |
|
867 | ###### Returns
|
868 |
|
869 | `processor` — The processor that `freeze` was called on.
|
870 |
|
871 | ###### Example
|
872 |
|
873 | The following example, `index.js`, shows how rehype prevents extensions to
|
874 | itself:
|
875 |
|
876 | ```js
|
877 | var unified = require('unified')
|
878 | var parse = require('rehype-parse')
|
879 | var stringify = require('rehype-stringify')
|
880 |
|
881 | module.exports = unified()
|
882 | .use(parse)
|
883 | .use(stringify)
|
884 | .freeze()
|
885 | ```
|
886 |
|
887 | The below example, `a.js`, shows how that processor can be used and configured.
|
888 |
|
889 | ```js
|
890 | var rehype = require('rehype')
|
891 | var format = require('rehype-format')
|
892 | // …
|
893 |
|
894 | rehype()
|
895 | .use(format)
|
896 | // …
|
897 | ```
|
898 |
|
899 | The below example, `b.js`, shows a similar looking example that operates on the
|
900 | frozen rehype interface because it does not call `rehype`.
|
901 | If this behaviour was allowed it would result in unexpected behaviour so an
|
902 | error is thrown.
|
903 | **This is invalid**:
|
904 |
|
905 | ```js
|
906 | var rehype = require('rehype')
|
907 | var format = require('rehype-format')
|
908 | // …
|
909 |
|
910 | rehype
|
911 | .use(format)
|
912 | // …
|
913 | ```
|
914 |
|
915 | Yields:
|
916 |
|
917 | ```txt
|
918 | ~/node_modules/unified/index.js:440
|
919 | throw new Error(
|
920 | ^
|
921 |
|
922 | Error: Cannot invoke `use` on a frozen processor.
|
923 | Create 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
|
932 | the 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 |
|
938 | Plugins are a concept.
|
939 | They materialise as [`attacher`][attacher]s.
|
940 |
|
941 | ###### Example
|
942 |
|
943 | `move.js`:
|
944 |
|
945 | ```js
|
946 | module.exports = move
|
947 |
|
948 | function 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
|
974 | var unified = require('unified')
|
975 | var parse = require('remark-parse')
|
976 | var remark2rehype = require('remark-rehype')
|
977 | var stringify = require('rehype-stringify')
|
978 | var vfile = require('to-vfile')
|
979 | var report = require('vfile-reporter')
|
980 | var move = require('./move')
|
981 |
|
982 | unified()
|
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 |
|
995 | Yields:
|
996 |
|
997 | ```txt
|
998 | index.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.
|
1010 | An attacher is a function that can receive options and
|
1011 | [*configures*][configuration] the processor.
|
1012 |
|
1013 | Attachers 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 |
|
1019 | The 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 |
|
1031 | Attachers are called when the processor is [*frozen*][freeze], not when they are
|
1032 | applied.
|
1033 |
|
1034 | ### `function transformer(node, file[, next])`
|
1035 |
|
1036 | **Transformers** handle [*syntax tree*][syntax-tree]s and [*file*][file]s.
|
1037 | A transformer is a function that is called each time a syntax tree and file are
|
1038 | passed through the [*run phase*][description].
|
1039 | If an error occurs (either because it’s thrown, returned, rejected, or passed to
|
1040 | [`next`][next]), the process stops.
|
1041 |
|
1042 | The *run phase* is handled by [`trough`][trough], see its documentation for the
|
1043 | exact 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 |
|
1062 | If the signature of a [*transformer*][transformer] includes `next` (the third
|
1063 | argument), the transformer **may** perform asynchronous operations, and **must**
|
1064 | call `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].
|
1077 | They can contain [*plugins*][plugin] and settings.
|
1078 |
|
1079 | ###### Example
|
1080 |
|
1081 | `preset.js`:
|
1082 |
|
1083 | ```js
|
1084 | exports.settings = {bullet: '*', emphasis: '*', fences: true}
|
1085 |
|
1086 | exports.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
|
1112 | var remark = require('remark')
|
1113 | var vfile = require('to-vfile')
|
1114 | var report = require('vfile-reporter')
|
1115 | var preset = require('./preset')
|
1116 |
|
1117 | remark()
|
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 |
|
1128 | Yields:
|
1129 |
|
1130 | ```txt
|
1131 | readme.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 |
|
1155 | See [`contributing.md`][contributing] in [`unifiedjs/.github`][health] for ways
|
1156 | to get started.
|
1157 | See [`support.md`][support] for ways to get help.
|
1158 | Ideas for new plugins and tools can be posted in [`unifiedjs/ideas`][ideas].
|
1159 |
|
1160 | A curated list of awesome unified resources can be found in [**awesome
|
1161 | unified**][awesome].
|
1162 |
|
1163 | This project has a [Code of Conduct][coc].
|
1164 | By interacting with this repository, organisation, or community you agree to
|
1165 | abide by its terms.
|
1166 |
|
1167 | ## Acknowledgments
|
1168 |
|
1169 | Preliminary work for unified was done [in 2014][preliminary] for
|
1170 | [**retext**][retext] and inspired by [`ware`][ware].
|
1171 | Further incubation happened in [**remark**][remark].
|
1172 | The project was finally [externalised][] in 2015 and [published][] as `unified`.
|
1173 | The project was authored by [**@wooorm**](https://github.com/wooorm).
|
1174 |
|
1175 | Although `unified` since moved its plugin architecture to [`trough`][trough],
|
1176 | thanks to [**@calvinfo**](https://github.com/calvinfo),
|
1177 | [**@ianstormtaylor**](https://github.com/ianstormtaylor), and others for their
|
1178 | work on [`ware`][ware], as it was a huge initial inspiration.
|
1179 |
|
1180 | ## License
|
1181 |
|
1182 | [MIT][license] © [Titus Wormer][author]
|
1183 |
|
1184 |
|
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
|