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