|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386 |
- # [![unified][logo]][site]
-
- [![Build][build-badge]][build]
- [![Coverage][coverage-badge]][coverage]
- [![Downloads][downloads-badge]][downloads]
- [![Size][size-badge]][size]
- [![Sponsors][sponsors-badge]][collective]
- [![Backers][backers-badge]][collective]
- [![Chat][chat-badge]][chat]
-
- **unified** is an interface for processing text using syntax trees.
- It’s what powers [**remark**][remark] (Markdown), [**retext**][retext] (natural
- language), and [**rehype**][rehype] (HTML), and allows for processing between
- formats.
-
- ## Intro
-
- **unified** enables new exciting projects like [Gatsby][] to pull in Markdown,
- [MDX][] to embed [JSX][], and [Prettier][] to format it.
- It’s used in about 500k projects on GitHub and has about 25m downloads each
- month on npm: you’re probably using it.
- Some notable users are [Node.js][], [Vercel][], [Netlify][], [GitHub][],
- [Mozilla][], [WordPress][], [Adobe][], [Facebook][], [Google][], and many more.
-
- * To read about what we are up to, follow us [Twitter][]
- * For a less technical and more practical introduction to unified, visit
- [`unifiedjs.com`][site] and peruse its [Learn][] section
- * Browse [awesome unified][awesome] to find out more about the ecosystem
- * Questions?
- Get help on [Discussions][chat]!
- * Check out [Contribute][] below to find out how to help out, or become a
- backer or sponsor on [OpenCollective][collective]
-
- ## Sponsors
-
- Support this effort and give back by sponsoring on [OpenCollective][collective]!
-
- <!--lint ignore no-html-->
-
- <table>
- <tr valign="middle">
- <td width="20%" align="center" colspan="2">
- <a href="https://www.gatsbyjs.org">Gatsby</a> 🥇<br><br>
- <a href="https://www.gatsbyjs.org"><img src="https://avatars1.githubusercontent.com/u/12551863?s=256&v=4" width="128"></a>
- </td>
- <td width="20%" align="center" colspan="2">
- <a href="https://vercel.com">Vercel</a> 🥇<br><br>
- <a href="https://vercel.com"><img src="https://avatars1.githubusercontent.com/u/14985020?s=256&v=4" width="128"></a>
- </td>
- <td width="20%" align="center" colspan="2">
- <a href="https://www.netlify.com">Netlify</a><br><br>
- <!--OC has a sharper image-->
- <a href="https://www.netlify.com"><img src="https://images.opencollective.com/netlify/4087de2/logo/256.png" width="128"></a>
- </td>
- <td width="10%" align="center">
- <a href="https://www.holloway.com">Holloway</a><br><br>
- <a href="https://www.holloway.com"><img src="https://avatars1.githubusercontent.com/u/35904294?s=128&v=4" width="64"></a>
- </td>
- <td width="10%" align="center">
- <a href="https://themeisle.com">ThemeIsle</a><br><br>
- <a href="https://themeisle.com"><img src="https://avatars1.githubusercontent.com/u/58979018?s=128&v=4" width="64"></a>
- </td>
- <td width="10%" align="center">
- <a href="https://boosthub.io">Boost Hub</a><br><br>
- <a href="https://boosthub.io"><img src="https://images.opencollective.com/boosthub/6318083/logo/128.png" width="64"></a>
- </td>
- <td width="10%" align="center">
- <a href="https://expo.io">Expo</a><br><br>
- <a href="https://expo.io"><img src="https://avatars1.githubusercontent.com/u/12504344?s=128&v=4" width="64"></a>
- </td>
- </tr>
- <tr valign="middle">
- <td width="100%" align="center" colspan="10">
- <br>
- <a href="https://opencollective.com/unified"><strong>You?</strong></a>
- <br><br>
- </td>
- </tr>
- </table>
-
- ## Install
-
- [npm][]:
-
- ```sh
- npm install unified
- ```
-
- This package comes with types.
- If you’re using TypeScript, make sure to also install
- [`@types/unist`][ts-unist].
-
- ## Use
-
- ```js
- var unified = require('unified')
- var markdown = require('remark-parse')
- var remark2rehype = require('remark-rehype')
- var doc = require('rehype-document')
- var format = require('rehype-format')
- var html = require('rehype-stringify')
- var report = require('vfile-reporter')
-
- unified()
- .use(markdown)
- .use(remark2rehype)
- .use(doc, {title: '👋🌍'})
- .use(format)
- .use(html)
- .process('# Hello world!', function (err, file) {
- console.error(report(err || file))
- console.log(String(file))
- })
- ```
-
- Yields:
-
- ```txt
- no issues found
- ```
-
- ```html
- <!doctype html>
- <html lang="en">
- <head>
- <meta charset="utf-8">
- <title>👋🌍</title>
- <meta name="viewport" content="width=device-width, initial-scale=1">
- </head>
- <body>
- <h1>Hello world!</h1>
- </body>
- </html>
- ```
-
- ## Contents
-
- * [Description](#description)
- * [API](#api)
- * [`processor()`](#processor)
- * [`processor.use(plugin[, options])`](#processoruseplugin-options)
- * [`processor.parse(file)`](#processorparsefile)
- * [`processor.stringify(node[, file])`](#processorstringifynode-file)
- * [`processor.run(node[, file][, done])`](#processorrunnode-file-done)
- * [`processor.runSync(node[, file])`](#processorrunsyncnode-file)
- * [`processor.process(file[, done])`](#processorprocessfile-done)
- * [`processor.processSync(file|value)`](#processorprocesssyncfilevalue)
- * [`processor.data([key[, value]])`](#processordatakey-value)
- * [`processor.freeze()`](#processorfreeze)
- * [`Plugin`](#plugin)
- * [`function attacher([options])`](#function-attacheroptions)
- * [`function transformer(node, file[, next])`](#function-transformernode-file-next)
- * [`Preset`](#preset)
- * [Contribute](#contribute)
- * [Acknowledgments](#acknowledgments)
- * [License](#license)
-
- ## Description
-
- **unified** is an interface for processing text using syntax trees.
- Syntax trees are a representation of text understandable to programs.
- Those programs, called [*plugin*][plugin]s, take these trees and inspect and
- modify them.
- To get to the syntax tree from text, there is a [*parser*][parser].
- To get from that back to text, there is a [*compiler*][compiler].
- This is the [*process*][process] of a *processor*.
-
- ```ascii
- | ........................ process ........................... |
- | .......... parse ... | ... run ... | ... stringify ..........|
-
- +--------+ +----------+
- Input ->- | Parser | ->- Syntax Tree ->- | Compiler | ->- Output
- +--------+ | +----------+
- X
- |
- +--------------+
- | Transformers |
- +--------------+
- ```
-
- ###### Processors
-
- Every **processor** implements another processor.
- To create a processor, call another processor.
- The new processor is configured to work the same as its ancestor.
- But when the descendant processor is configured in the future it does not affect
- the ancestral processor.
-
- When processors are exposed from a module (for example, `unified` itself) they
- should not be configured directly, as that would change their behavior for all
- module users.
- Those processors are [*frozen*][freeze] and they should be called to create a
- new processor before they are used.
-
- ###### Syntax trees
-
- The **syntax trees** used in **unified** are [**unist**][unist] nodes.
- A [**node**][node] is a plain JavaScript objects with a `type` field.
- The semantics of nodes and format of syntax trees is defined by other projects.
-
- There are several [*utilities*][unist-utilities] for working with nodes.
-
- * [**hast**][hast] — HTML
- * [**mdast**][mdast] — Markdown
- * [**nlcst**][nlcst] — Natural language
- * [**xast**][xast] — XML
-
- ###### List of processors
-
- The following projects process different [*syntax tree*][syntax-tree] formats.
- They parse text to a syntax tree and compile that back to text.
- These processors can be used as is, or their parser and compiler can be mixed
- and matched with **unified** and plugins to process between different syntaxes.
-
- * [**rehype**][rehype] ([*hast*][hast]) — HTML
- * [**remark**][remark] ([*mdast*][mdast]) — Markdown
- * [**retext**][retext] ([*nlcst*][nlcst]) — Natural language
-
- ###### List of plugins
-
- The below [**plugins**][plugin] work with **unified**, on all [*syntax
- tree*][syntax-tree] formats:
-
- * [`unified-diff`](https://github.com/unifiedjs/unified-diff)
- — Ignore messages for unchanged lines in Travis
- * [`unified-message-control`](https://github.com/unifiedjs/unified-message-control)
- — Enable, disable, and ignore messages
-
- See [**remark**][remark-plugins], [**rehype**][rehype-plugins], and
- [**retext**][retext-plugins] for their lists of plugins.
-
- ###### File
-
- When processing a document, **metadata** is often gathered about that document.
- [**vfile**][vfile] is a virtual file format that stores data, metadata, and
- messages about files for **unified** and its plugins.
-
- There are several [*utilities*][vfile-utilities] for working with these files.
-
- ###### Configuration
-
- [*Processors*][processors] are configured with [*plugin*][plugin]s or
- with the [`data`][data] method.
-
- ###### Integrations
-
- **unified** can integrate with the file system with [`unified-engine`][engine].
- CLI apps can be created with [`unified-args`][args], Gulp plugins with
- [`unified-engine-gulp`][gulp], and Atom Linters with
- [`unified-engine-atom`][atom].
-
- [`unified-stream`][stream] provides a streaming interface.
-
- ###### Programming interface
-
- The API provided by **unified** allows multiple files to be processed and gives
- access to *metadata* (such as lint messages):
-
- ```js
- var unified = require('unified')
- var markdown = require('remark-parse')
- var styleGuide = require('remark-preset-lint-markdown-style-guide')
- var remark2retext = require('remark-retext')
- var english = require('retext-english')
- var equality = require('retext-equality')
- var remark2rehype = require('remark-rehype')
- var html = require('rehype-stringify')
- var report = require('vfile-reporter')
-
- unified()
- .use(markdown)
- .use(styleGuide)
- .use(remark2retext, unified().use(english).use(equality))
- .use(remark2rehype)
- .use(html)
- .process('*Emphasis* and _stress_, you guys!', function (err, file) {
- console.error(report(err || file))
- console.log(String(file))
- })
- ```
-
- Yields:
-
- ```txt
- 1:16-1:24 warning Emphasis should use `*` as a marker emphasis-marker remark-lint
- 1:30-1:34 warning `guys` may be insensitive, use `people`, `persons`, `folks` instead gals-men retext-equality
-
- ⚠ 2 warnings
- ```
-
- ```html
- <p><em>Emphasis</em> and <em>stress</em>, you guys!</p>
- ```
-
- ###### Processing between syntaxes
-
- [*Processors*][processors] can be combined in two modes.
-
- **Bridge** mode transforms the [*syntax tree*][syntax-tree] from one format
- (*origin*) to another (*destination*).
- Another processor runs on the destination tree.
- Finally, the original processor continues transforming the origin tree.
-
- **Mutate** mode also transforms the syntax tree from one format to another.
- But the original processor continues transforming the destination tree.
-
- In the previous example (“Programming interface”), `remark-retext` is used in
- *bridge* mode: the origin syntax tree is kept after [**retext**][retext] is
- done; whereas `remark-rehype` is used in *mutate* mode: it sets a new syntax
- tree and discards the origin tree.
-
- * [`remark-retext`][remark-retext]
- * [`remark-rehype`][remark-rehype]
- * [`rehype-retext`][rehype-retext]
- * [`rehype-remark`][rehype-remark]
-
- ## API
-
- ### `processor()`
-
- [*Processor*][processors] describing how to *process* text.
-
- ###### Returns
-
- `Function` — New [*unfrozen*][freeze] processor that is configured to work the
- same as its ancestor.
- When the descendant processor is configured in the future it does not affect the
- ancestral processor.
-
- ###### Example
-
- The following example shows how a new processor can be created (from the remark
- processor) and linked to **stdin**(4) and **stdout**(4).
-
- ```js
- var remark = require('remark')
- var concat = require('concat-stream')
-
- process.stdin.pipe(concat(onconcat))
-
- function onconcat(buf) {
- var doc = remark().processSync(buf).toString()
-
- process.stdout.write(doc)
- }
- ```
-
- ### `processor.use(plugin[, options])`
-
- [*Configure*][configuration] the processor to use a [*plugin*][plugin] and
- optionally configure that plugin with options.
-
- If the processor is already using this plugin, the previous plugin configuration
- is changed based on the options that are passed in.
- The plugin is not added a second time.
-
- ###### Signatures
-
- * `processor.use(plugin[, options])`
- * `processor.use(preset)`
- * `processor.use(list)`
-
- ###### Parameters
-
- * `plugin` ([`Attacher`][plugin])
- * `options` (`*`, optional) — Configuration for `plugin`
- * `preset` (`Object`) — Object with an optional `plugins` (set to `list`),
- and/or an optional `settings` object
- * `list` (`Array`) — List of plugins, presets, and pairs (`plugin` and
- `options` in an array)
-
- ###### Returns
-
- `processor` — The processor that `use` was called on.
-
- ###### Note
-
- `use` cannot be called on [*frozen*][freeze] processors.
- Call the processor first to create a new unfrozen processor.
-
- ###### Example
-
- There are many ways to pass plugins to `.use()`.
- The below example gives an overview.
-
- ```js
- var unified = require('unified')
-
- unified()
- // Plugin with options:
- .use(pluginA, {x: true, y: true})
- // Passing the same plugin again merges configuration (to `{x: true, y: false, z: true}`):
- .use(pluginA, {y: false, z: true})
- // Plugins:
- .use([pluginB, pluginC])
- // Two plugins, the second with options:
- .use([pluginD, [pluginE, {}]])
- // Preset with plugins and settings:
- .use({plugins: [pluginF, [pluginG, {}]], settings: {position: false}})
- // Settings only:
- .use({settings: {position: false}})
- ```
-
- ### `processor.parse(file)`
-
- Parse text to a [*syntax tree*][syntax-tree].
-
- ###### Parameters
-
- * `file` ([`VFile`][vfile]) — [*File*][file], any value accepted by `vfile()`
-
- ###### Returns
-
- [`Node`][node] — Parsed [*syntax tree*][syntax-tree] representing `file`.
-
- ###### Note
-
- `parse` freezes the processor if not already [*frozen*][freeze].
-
- `parse` performs the [*parse phase*][description], not the *run phase* or other
- phases.
-
- ###### Example
-
- The below example shows how `parse` can be used to create a syntax tree from a
- file.
-
- ```js
- var unified = require('unified')
- var markdown = require('remark-parse')
-
- var tree = unified().use(markdown).parse('# Hello world!')
-
- console.log(tree)
- ```
-
- Yields:
-
- ```js
- {
- type: 'root',
- children: [
- {type: 'heading', depth: 1, children: [Array], position: [Position]}
- ],
- position: {
- start: {line: 1, column: 1, offset: 0},
- end: {line: 1, column: 15, offset: 14}
- }
- }
- ```
-
- #### `processor.Parser`
-
- A **parser** handles the parsing of text to a [*syntax tree*][syntax-tree].
- Used in the [*parse phase*][description] and called with a `string` and
- [`VFile`][vfile] representation of the text to parse.
-
- `Parser` can be a function, in which case it must return a [`Node`][node]: the
- syntax tree representation of the given file.
-
- `Parser` can also be a constructor function (a function with a `parse` field, or
- other fields, in its `prototype`), in which case it’s constructed with `new`.
- Instances must have a `parse` method that is called without arguments and must
- return a [`Node`][node].
-
- ### `processor.stringify(node[, file])`
-
- Compile a [*syntax tree*][syntax-tree].
-
- ###### Parameters
-
- * `node` ([`Node`][node]) — [*Syntax tree*][syntax-tree] to compile
- * `file` ([`VFile`][vfile], optional) — [*File*][file], any value accepted by
- `vfile()`
-
- ###### Returns
-
- `string` or `Buffer` (see notes) — Textual representation of the [*syntax
- tree*][syntax-tree]
-
- ###### Note
-
- `stringify` freezes the processor if not already [*frozen*][freeze].
-
- `stringify` performs the [*stringify phase*][description], not the *run phase*
- or other phases.
-
- unified typically compiles by serializing: most [*compiler*][compiler]s return
- `string` (or `Buffer`).
- Some compilers, such as the one configured with [`rehype-react`][rehype-react],
- return other values (in this case, a React tree).
- If you’re using a compiler doesn’t serialize, expect different result values.
- When using TypeScript, cast the type on your side.
-
- ###### Example
-
- The below example shows how `stringify` can be used to serialize a syntax tree.
-
- ```js
- var unified = require('unified')
- var html = require('rehype-stringify')
- var h = require('hastscript')
-
- var tree = h('h1', 'Hello world!')
-
- var doc = unified().use(html).stringify(tree)
-
- console.log(doc)
- ```
-
- Yields:
-
- ```html
- <h1>Hello world!</h1>
- ```
-
- #### `processor.Compiler`
-
- A **compiler** handles the compiling of a [*syntax tree*][syntax-tree] to text.
- Used in the [*stringify phase*][description] and called with a [`Node`][node]
- and [`VFile`][file] representation of syntax tree to compile.
-
- `Compiler` can be a function, in which case it should return a `string`: the
- textual representation of the syntax tree.
-
- `Compiler` can also be a constructor function (a function with a `compile`
- field, or other fields, in its `prototype`), in which case it’s constructed with
- `new`.
- Instances must have a `compile` method that is called without arguments and
- should return a `string`.
-
- ### `processor.run(node[, file][, done])`
-
- Run [*transformers*][transformer] on a [*syntax tree*][syntax-tree].
-
- ###### Parameters
-
- * `node` ([`Node`][node]) — [*Syntax tree*][syntax-tree] to run on
- * `file` ([`VFile`][vfile], optional) — [*File*][file], any value accepted by
- `vfile()`
- * `done` ([`Function`][run-done], optional) — Callback
-
- ###### Returns
-
- [`Promise`][promise] if `done` is not given.
- The returned promise is rejected with a fatal error, or resolved with the
- transformed [*syntax tree*][syntax-tree].
-
- ###### Note
-
- `run` freezes the processor if not already [*frozen*][freeze].
-
- `run` performs the [*run phase*][description], not other phases.
-
- #### `function done(err[, node, file])`
-
- Callback called when [*transformers*][transformer] are done.
- Called with either an error or results.
-
- ###### Parameters
-
- * `err` (`Error`, optional) — Fatal error
- * `node` ([`Node`][node], optional) — Transformed [*syntax tree*][syntax-tree]
- * `file` ([`VFile`][vfile], optional) — [*File*][file]
-
- ###### Example
-
- The below example shows how `run` can be used to transform a syntax tree.
-
- ```js
- var unified = require('unified')
- var references = require('remark-reference-links')
- var u = require('unist-builder')
-
- var tree = u('root', [
- u('paragraph', [
- u('link', {href: 'https://example.com'}, [u('text', 'Example Domain')])
- ])
- ])
-
- unified()
- .use(references)
- .run(tree, function (err, tree) {
- if (err) throw err
- console.log(tree)
- })
- ```
-
- Yields:
-
- ```js
- {
- type: 'root',
- children: [
- {type: 'paragraph', children: [Array]},
- {type: 'definition', identifier: '1', title: undefined, url: undefined}
- ]
- }
- ```
-
- ### `processor.runSync(node[, file])`
-
- Run [*transformers*][transformer] on a [*syntax tree*][syntax-tree].
-
- An error is thrown if asynchronous [*plugin*][plugin]s are configured.
-
- ###### Parameters
-
- * `node` ([`Node`][node]) — [*Syntax tree*][syntax-tree] to run on
- * `file` ([`VFile`][vfile], optional) — [*File*][file], any value accepted by
- `vfile()`
-
- ###### Returns
-
- [`Node`][node] — Transformed [*syntax tree*][syntax-tree].
-
- ###### Note
-
- `runSync` freezes the processor if not already [*frozen*][freeze].
-
- `runSync` performs the [*run phase*][description], not other phases.
-
- ### `processor.process(file[, done])`
-
- [*Process*][description] the given [*file*][file] as configured on the
- processor.
-
- ###### Parameters
-
- * `file` ([`VFile`][vfile]) — [*File*][file], any value accepted by `vfile()`
- * `done` ([`Function`][process-done], optional) — Callback
-
- ###### Returns
-
- [`Promise`][promise] if `done` is not given.
- The returned promise is rejected with a fatal error, or resolved with the
- processed [*file*][file].
-
- The parsed, transformed, and compiled value is exposed on
- [`file.contents`][vfile-contents] or `file.result` (see notes).
-
- ###### Note
-
- `process` freezes the processor if not already [*frozen*][freeze].
-
- `process` performs the [*parse*, *run*, and *stringify* phases][description].
-
- unified typically compiles by serializing: most [*compiler*][compiler]s return
- `string` (or `Buffer`).
- Some compilers, such as the one configured with [`rehype-react`][rehype-react],
- return other values (in this case, a React tree).
- If you’re using a compiler that serializes, the result is available at
- `file.contents`.
- Otherwise, the result is available at `file.result`.
-
- ###### Example
-
- The below example shows how `process` can be used to process a file, whether
- transformers are asynchronous or not, with promises.
-
- ```js
- var unified = require('unified')
- var markdown = require('remark-parse')
- var remark2rehype = require('remark-rehype')
- var doc = require('rehype-document')
- var format = require('rehype-format')
- var html = require('rehype-stringify')
-
- unified()
- .use(markdown)
- .use(remark2rehype)
- .use(doc, {title: '👋🌍'})
- .use(format)
- .use(html)
- .process('# Hello world!')
- .then(
- function (file) {
- console.log(String(file))
- },
- function (err) {
- console.error(String(err))
- }
- )
- ```
-
- Yields:
-
- ```html
- <!doctype html>
- <html lang="en">
- <head>
- <meta charset="utf-8">
- <title>👋🌍</title>
- <meta name="viewport" content="width=device-width, initial-scale=1">
- </head>
- <body>
- <h1>Hello world!</h1>
- </body>
- </html>
- ```
-
- #### `function done(err, file)`
-
- Callback called when the [*process*][description] is done.
- Called with a fatal error, if any, and a [*file*][file].
-
- ###### Parameters
-
- * `err` (`Error`, optional) — Fatal error
- * `file` ([`VFile`][vfile]) — Processed [*file*][file]
-
- ###### Example
-
- The below example shows how `process` can be used to process a file, whether
- transformers are asynchronous or not, with a callback.
-
- ```js
- var unified = require('unified')
- var parse = require('remark-parse')
- var stringify = require('remark-stringify')
- var github = require('remark-github')
- var report = require('vfile-reporter')
-
- unified()
- .use(parse)
- .use(github)
- .use(stringify)
- .process('@wooorm', function (err, file) {
- console.error(report(err || file))
- console.log(String(file))
- })
- ```
-
- Yields:
-
- ```txt
- no issues found
- ```
-
- ```markdown
- [**@wooorm**](https://github.com/wooorm)
- ```
-
- ### `processor.processSync(file|value)`
-
- [*Process*][description] the given [*file*][file] as configured on the
- processor.
-
- An error is thrown if asynchronous [*plugin*][plugin]s are configured.
-
- ###### Parameters
-
- * `file` ([`VFile`][vfile]) — [*File*][file], any value accepted by `vfile()`
-
- ###### Returns
-
- ([`VFile`][vfile]) — Processed [*file*][file]
-
- The parsed, transformed, and compiled value is exposed on
- [`file.contents`][vfile-contents] or `file.result` (see notes).
-
- ###### Note
-
- `processSync` freezes the processor if not already [*frozen*][freeze].
-
- `processSync` performs the [*parse*, *run*, and *stringify*
- phases][description].
-
- unified typically compiles by serializing: most [*compiler*][compiler]s return
- `string` (or `Buffer`).
- Some compilers, such as the one configured with [`rehype-react`][rehype-react],
- return other values (in this case, a React tree).
- If you’re using a compiler that serializes, the result is available at
- `file.contents`.
- Otherwise, the result is available at `file.result`.
-
- ###### Example
-
- The below example shows how `processSync` can be used to process a file, if all
- transformers are synchronous.
-
- ```js
- var unified = require('unified')
- var markdown = require('remark-parse')
- var remark2rehype = require('remark-rehype')
- var doc = require('rehype-document')
- var format = require('rehype-format')
- var html = require('rehype-stringify')
-
- var processor = unified()
- .use(markdown)
- .use(remark2rehype)
- .use(doc, {title: '👋🌍'})
- .use(format)
- .use(html)
-
- console.log(processor.processSync('# Hello world!').toString())
- ```
-
- Yields:
-
- ```html
- <!doctype html>
- <html lang="en">
- <head>
- <meta charset="utf-8">
- <title>👋🌍</title>
- <meta name="viewport" content="width=device-width, initial-scale=1">
- </head>
- <body>
- <h1>Hello world!</h1>
- </body>
- </html>
- ```
-
- ### `processor.data([key[, value]])`
-
- [*Configure*][configuration] the processor with information available to all
- [*plugin*][plugin]s.
- Information is stored in an in-memory key-value store.
-
- Typically, options can be given to a specific plugin, but sometimes it makes
- sense to have information shared with several plugins.
- For example, a list of HTML elements that are self-closing, which is needed
- during all [*phases*][description] of the *process*.
-
- ###### Signatures
-
- * `processor = processor.data(key, value)`
- * `processor = processor.data(values)`
- * `value = processor.data(key)`
- * `info = processor.data()`
-
- ###### Parameters
-
- * `key` (`string`, optional) — Identifier
- * `value` (`*`, optional) — Value to set
- * `values` (`Object`, optional) — Values to set
-
- ###### Returns
-
- * `processor` — If setting, the processor that `data` is called on
- * `value` (`*`) — If getting, the value at `key`
- * `info` (`Object`) — Without arguments, the key-value store
-
- ###### Note
-
- Setting information cannot occur on [*frozen*][freeze] processors.
- Call the processor first to create a new unfrozen processor.
-
- ###### Example
-
- The following example show how to get and set information:
-
- ```js
- var unified = require('unified')
-
- var processor = unified().data('alpha', 'bravo')
-
- processor.data('alpha') // => 'bravo'
-
- processor.data() // {alpha: 'bravo'}
-
- processor.data({charlie: 'delta'})
-
- processor.data() // {charlie: 'delta'}
- ```
-
- ### `processor.freeze()`
-
- **Freeze** a processor.
- *Frozen* processors are meant to be extended and not to be configured directly.
-
- Once a processor is frozen it cannot be *unfrozen*.
- New processors working the same way can be created by calling the processor.
-
- It’s possible to freeze processors explicitly by calling `.freeze()`.
- Processors freeze implicitly when [`.parse()`][parse], [`.run()`][run],
- [`.runSync()`][run-sync], [`.stringify()`][stringify], [`.process()`][process],
- or [`.processSync()`][process-sync] are called.
-
- ###### Returns
-
- `processor` — The processor that `freeze` was called on.
-
- ###### Example
-
- The following example, `index.js`, shows how rehype prevents extensions to
- itself:
-
- ```js
- var unified = require('unified')
- var parse = require('rehype-parse')
- var stringify = require('rehype-stringify')
-
- module.exports = unified().use(parse).use(stringify).freeze()
- ```
-
- The below example, `a.js`, shows how that processor can be used and configured.
-
- ```js
- var rehype = require('rehype')
- var format = require('rehype-format')
- // …
-
- rehype()
- .use(format)
- // …
- ```
-
- The below example, `b.js`, shows a similar looking example that operates on the
- frozen rehype interface because it does not call `rehype`.
- If this behavior was allowed it would result in unexpected behavior so an
- error is thrown.
- **This is invalid**:
-
- ```js
- var rehype = require('rehype')
- var format = require('rehype-format')
- // …
-
- rehype
- .use(format)
- // …
- ```
-
- Yields:
-
- ```txt
- ~/node_modules/unified/index.js:440
- throw new Error(
- ^
-
- Error: Cannot invoke `use` on a frozen processor.
- Create a new processor first, by invoking it: use `processor()` instead of `processor`.
- at assertUnfrozen (~/node_modules/unified/index.js:440:11)
- at Function.use (~/node_modules/unified/index.js:172:5)
- at Object.<anonymous> (~/b.js:6:4)
- ```
-
- ## `Plugin`
-
- **Plugins** [*configure*][configuration] the processors they are applied on in
- the following ways:
-
- * They change the processor: such as the [*parser*][parser], the
- [*compiler*][compiler], or configuring [*data*][data]
- * They specify how to handle [*syntax trees*][syntax-tree] and [*files*][file]
-
- Plugins are a concept.
- They materialize as [`attacher`][attacher]s.
-
- ###### Example
-
- `move.js`:
-
- ```js
- module.exports = move
-
- function move(options) {
- var expected = (options || {}).extname
-
- if (!expected) {
- throw new Error('Missing `extname` in options')
- }
-
- return transformer
-
- function transformer(tree, file) {
- if (file.extname && file.extname !== expected) {
- file.extname = expected
- }
- }
- }
- ```
-
- `index.md`:
-
- ```markdown
- # Hello, world!
- ```
-
- `index.js`:
-
- ```js
- var unified = require('unified')
- var parse = require('remark-parse')
- var remark2rehype = require('remark-rehype')
- var stringify = require('rehype-stringify')
- var vfile = require('to-vfile')
- var report = require('vfile-reporter')
- var move = require('./move')
-
- unified()
- .use(parse)
- .use(remark2rehype)
- .use(move, {extname: '.html'})
- .use(stringify)
- .process(vfile.readSync('index.md'), function (err, file) {
- console.error(report(err || file))
- if (file) {
- vfile.writeSync(file) // Written to `index.html`.
- }
- })
- ```
-
- Yields:
-
- ```txt
- index.md: no issues found
- ```
-
- `index.html`:
-
- ```html
- <h1>Hello, world!</h1>
- ```
-
- ### `function attacher([options])`
-
- **Attachers** are materialized [*plugin*][plugin]s.
- An attacher is a function that can receive options and
- [*configures*][configuration] the processor.
-
- Attachers change the processor, such as the [*parser*][parser], the
- [*compiler*][compiler], configuring [*data*][data], or by specifying how the
- [*syntax tree*][syntax-tree] or [*file*][file] are handled.
-
- ###### Context
-
- The context object (`this`) is set to the processor the attacher is applied on.
-
- ###### Parameters
-
- * `options` (`*`, optional) — Configuration
-
- ###### Returns
-
- [`transformer`][transformer] — Optional.
-
- ###### Note
-
- Attachers are called when the processor is [*frozen*][freeze], not when they are
- applied.
-
- ### `function transformer(node, file[, next])`
-
- **Transformers** handle [*syntax tree*][syntax-tree]s and [*file*][file]s.
- A transformer is a function that is called each time a syntax tree and file are
- passed through the [*run phase*][description].
- If an error occurs (either because it’s thrown, returned, rejected, or passed to
- [`next`][next]), the process stops.
-
- The *run phase* is handled by [`trough`][trough], see its documentation for the
- exact semantics of these functions.
-
- ###### Parameters
-
- * `node` ([`Node`][node]) — [*Syntax tree*][syntax-tree] to handle
- * `file` ([`VFile`][vfile]) — [*File*][file] to handle
- * `next` ([`Function`][next], optional)
-
- ###### Returns
-
- * `void` — If nothing is returned, the next transformer keeps using same tree.
- * `Error` — Fatal error to stop the process
- * `node` ([`Node`][node]) — New [*syntax tree*][syntax-tree].
- If returned, the next transformer is given this new tree
- * `Promise` — Returned to perform an asynchronous operation.
- The promise **must** be resolved (optionally with a [`Node`][node]) or
- rejected (optionally with an `Error`)
-
- #### `function next(err[, tree[, file]])`
-
- If the signature of a [*transformer*][transformer] includes `next` (the third
- argument), the transformer **may** perform asynchronous operations, and **must**
- call `next()`.
-
- ###### Parameters
-
- * `err` (`Error`, optional) — Fatal error to stop the process
- * `node` ([`Node`][node], optional) — New [*syntax tree*][syntax-tree].
- If given, the next transformer is given this new tree
- * `file` ([`VFile`][vfile], optional) — New [*file*][file].
- If given, the next transformer is given this new file
-
- ## `Preset`
-
- **Presets** are sharable [*configuration*][configuration].
- They can contain [*plugins*][plugin] and settings.
-
- ###### Example
-
- `preset.js`:
-
- ```js
- exports.settings = {bullet: '*', emphasis: '*', fences: true}
-
- exports.plugins = [
- require('remark-preset-lint-recommended'),
- require('remark-preset-lint-consistent'),
- require('remark-comment-config'),
- [require('remark-toc'), {maxDepth: 3, tight: true}],
- require('remark-license')
- ]
- ```
-
- `readme.md`:
-
- ```markdown
- # Hello, world!
-
- _Emphasis_ and **importance**.
-
- ## Table of contents
-
- ## API
-
- ## License
- ```
-
- `index.js`:
-
- ```js
- var remark = require('remark')
- var vfile = require('to-vfile')
- var report = require('vfile-reporter')
- var preset = require('./preset')
-
- remark()
- .use(preset)
- .process(vfile.readSync('readme.md'), function (err, file) {
- console.error(report(err || file))
-
- if (file) {
- vfile.writeSync(file)
- }
- })
- ```
-
- Yields:
-
- ```txt
- readme.md: no issues found
- ```
-
- `readme.md` now contains:
-
- ```markdown
- # Hello, world!
-
- *Emphasis* and **importance**.
-
- ## Table of contents
-
- * [API](#api)
- * [License](#license)
-
- ## API
-
- ## License
-
- [MIT](license) © [Titus Wormer](https://wooorm.com)
- ```
-
- ## Contribute
-
- See [`contributing.md`][contributing] in [`unifiedjs/.github`][health] for ways
- to get started.
- See [`support.md`][support] for ways to get help.
- Ideas for new plugins and tools can be posted in [`unifiedjs/ideas`][ideas].
-
- A curated list of awesome unified resources can be found in [**awesome
- unified**][awesome].
-
- This project has a [code of conduct][coc].
- By interacting with this repository, organization, or community you agree to
- abide by its terms.
-
- ## Acknowledgments
-
- Preliminary work for unified was done [in 2014][preliminary] for
- [**retext**][retext] and inspired by [`ware`][ware].
- Further incubation happened in [**remark**][remark].
- The project was finally [externalised][] in 2015 and [published][] as `unified`.
- The project was authored by [**@wooorm**](https://github.com/wooorm).
-
- Although `unified` since moved its plugin architecture to [`trough`][trough],
- thanks to [**@calvinfo**](https://github.com/calvinfo),
- [**@ianstormtaylor**](https://github.com/ianstormtaylor), and others for their
- work on [`ware`][ware], as it was a huge initial inspiration.
-
- ## License
-
- [MIT][license] © [Titus Wormer][author]
-
- <!-- Definitions -->
-
- [logo]: https://raw.githubusercontent.com/unifiedjs/unified/93862e5/logo.svg?sanitize=true
-
- [build-badge]: https://github.com/unifiedjs/unified/workflows/main/badge.svg
-
- [build]: https://github.com/unifiedjs/unified/actions
-
- [coverage-badge]: https://img.shields.io/codecov/c/github/unifiedjs/unified.svg
-
- [coverage]: https://codecov.io/github/unifiedjs/unified
-
- [downloads-badge]: https://img.shields.io/npm/dm/unified.svg
-
- [downloads]: https://www.npmjs.com/package/unified
-
- [size-badge]: https://img.shields.io/bundlephobia/minzip/unified.svg
-
- [size]: https://bundlephobia.com/result?p=unified
-
- [sponsors-badge]: https://opencollective.com/unified/sponsors/badge.svg
-
- [backers-badge]: https://opencollective.com/unified/backers/badge.svg
-
- [collective]: https://opencollective.com/unified
-
- [chat-badge]: https://img.shields.io/badge/chat-discussions-success.svg
-
- [chat]: https://github.com/unifiedjs/unified/discussions
-
- [health]: https://github.com/unifiedjs/.github
-
- [contributing]: https://github.com/unifiedjs/.github/blob/HEAD/contributing.md
-
- [support]: https://github.com/unifiedjs/.github/blob/HEAD/support.md
-
- [coc]: https://github.com/unifiedjs/.github/blob/HEAD/code-of-conduct.md
-
- [awesome]: https://github.com/unifiedjs/awesome-unified
-
- [license]: license
-
- [author]: https://wooorm.com
-
- [npm]: https://docs.npmjs.com/cli/install
-
- [ts-unist]: https://www.npmjs.com/package/@types/unist
-
- [site]: https://unifiedjs.com
-
- [twitter]: https://twitter.com/unifiedjs
-
- [learn]: https://unifiedjs.com/learn/
-
- [rehype]: https://github.com/rehypejs/rehype
-
- [remark]: https://github.com/remarkjs/remark
-
- [retext]: https://github.com/retextjs/retext
-
- [hast]: https://github.com/syntax-tree/hast
-
- [mdast]: https://github.com/syntax-tree/mdast
-
- [nlcst]: https://github.com/syntax-tree/nlcst
-
- [xast]: https://github.com/syntax-tree/xast
-
- [unist]: https://github.com/syntax-tree/unist
-
- [engine]: https://github.com/unifiedjs/unified-engine
-
- [args]: https://github.com/unifiedjs/unified-args
-
- [gulp]: https://github.com/unifiedjs/unified-engine-gulp
-
- [atom]: https://github.com/unifiedjs/unified-engine-atom
-
- [remark-rehype]: https://github.com/remarkjs/remark-rehype
-
- [remark-retext]: https://github.com/remarkjs/remark-retext
-
- [rehype-retext]: https://github.com/rehypejs/rehype-retext
-
- [rehype-remark]: https://github.com/rehypejs/rehype-remark
-
- [unist-utilities]: https://github.com/syntax-tree/unist#list-of-utilities
-
- [vfile]: https://github.com/vfile/vfile
-
- [vfile-contents]: https://github.com/vfile/vfile#vfilecontents
-
- [vfile-utilities]: https://github.com/vfile/vfile#related-tools
-
- [node]: https://github.com/syntax-tree/unist#node
-
- [description]: #description
-
- [syntax-tree]: #syntax-trees
-
- [configuration]: #configuration
-
- [file]: #file
-
- [processors]: #processors
-
- [process]: #processorprocessfile-done
-
- [process-sync]: #processorprocesssyncfilevalue
-
- [parse]: #processorparsefile
-
- [parser]: #processorparser
-
- [stringify]: #processorstringifynode-file
-
- [run]: #processorrunnode-file-done
-
- [run-sync]: #processorrunsyncnode-file
-
- [compiler]: #processorcompiler
-
- [data]: #processordatakey-value
-
- [attacher]: #function-attacheroptions
-
- [transformer]: #function-transformernode-file-next
-
- [next]: #function-nexterr-tree-file
-
- [freeze]: #processorfreeze
-
- [plugin]: #plugin
-
- [run-done]: #function-doneerr-node-file
-
- [process-done]: #function-doneerr-file
-
- [contribute]: #contribute
-
- [rehype-react]: https://github.com/rhysd/rehype-react
-
- [trough]: https://github.com/wooorm/trough#function-fninput-next
-
- [promise]: https://developer.mozilla.org/Web/JavaScript/Reference/Global_Objects/Promise
-
- [remark-plugins]: https://github.com/remarkjs/remark/blob/HEAD/doc/plugins.md#list-of-plugins
-
- [rehype-plugins]: https://github.com/rehypejs/rehype/blob/HEAD/doc/plugins.md#list-of-plugins
-
- [retext-plugins]: https://github.com/retextjs/retext/blob/HEAD/doc/plugins.md#list-of-plugins
-
- [stream]: https://github.com/unifiedjs/unified-stream
-
- [ideas]: https://github.com/unifiedjs/ideas
-
- [preliminary]: https://github.com/retextjs/retext/commit/8fcb1f#diff-168726dbe96b3ce427e7fedce31bb0bc
-
- [externalised]: https://github.com/remarkjs/remark/commit/9892ec#diff-168726dbe96b3ce427e7fedce31bb0bc
-
- [published]: https://github.com/unifiedjs/unified/commit/2ba1cf
-
- [ware]: https://github.com/segmentio/ware
-
- [gatsby]: https://www.gatsbyjs.org
-
- [mdx]: https://mdxjs.com
-
- [jsx]: https://reactjs.org/docs/jsx-in-depth.html
-
- [prettier]: https://prettier.io
-
- [node.js]: https://nodejs.org
-
- [vercel]: https://vercel.com
-
- [netlify]: https://www.netlify.com
-
- [github]: https://github.com
-
- [mozilla]: https://www.mozilla.org
-
- [wordpress]: https://wordpress.com
-
- [adobe]: https://www.adobe.com
-
- [facebook]: https://www.facebook.com
-
- [google]: https://www.google.com
|