Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

☔️ interface for parsing, inspecting, transforming, and serializing content through syntax trees

License

NotificationsYou must be signed in to change notification settings

unifiedjs/unified

Repository files navigation

unified

BuildCoverageDownloadsSizeSponsorsBackersChat

unified lets you inspect and transform content with plugins.

Contents

What is this?

unified is two things:

  • unified is a collective of 500+ free and open source packages that workwith content as structured data (ASTs)
  • unified (this project) is the core package, used in 1.3m+ projects on GH,to process content with plugins

Several ecosystems are built on unified around different kinds of content.Notably,remark (markdown),rehype (HTML), andretext (naturallanguage).These ecosystems can be connected together.

When should I use this?

In some cases, you are already using unified.For example, it’s used in MDX, Gatsby, Docusaurus, etc.In those cases, you don’t need to addunified yourself but you can includeplugins into those projects.

But the real fun (for some) is to get your hands dirty and work with syntaxtrees and build with it yourself.You can create those projects, or things like Prettier, or your own sitegenerator.You can connect utilities together and make your own plugins that check forproblems and transform from one thing to another.

When you are dealing with one type of content (such as markdown), you can usethe main package of that ecosystem instead (soremark).When you are dealing with different kinds of content (such as markdown andHTML), it’s recommended to useunified itself, and pick and choose the pluginsyou need.

Install

This package isESM only.In Node.js (version 16+), install withnpm:

npm install unified

In Deno withesm.sh:

import{unified}from'https://esm.sh/unified@11'

In browsers withesm.sh:

<scripttype="module">import{unified}from'https://esm.sh/unified@11?bundle'</script>

Use

importrehypeDocumentfrom'rehype-document'importrehypeFormatfrom'rehype-format'importrehypeStringifyfrom'rehype-stringify'importremarkParsefrom'remark-parse'importremarkRehypefrom'remark-rehype'import{unified}from'unified'import{reporter}from'vfile-reporter'constfile=awaitunified().use(remarkParse).use(remarkRehype).use(rehypeDocument,{title:'👋🌍'}).use(rehypeFormat).use(rehypeStringify).process('# Hello world!')console.error(reporter(file))console.log(String(file))

Yields:

no issues found
<!doctype html><htmllang="en"><head><metacharset="utf-8"><title>👋🌍</title><metaname="viewport"content="width=device-width, initial-scale=1"></head><body><h1>Hello world!</h1></body></html>

Overview

unified is an interface for processing content with syntax trees.Syntax trees are a representation of content understandable to programs.Those programs, calledplugins, take these trees and inspect andmodify them.To get to the syntax tree from text, there is aparser.To get from that back to text, there is acompiler.This is theprocess of aprocessor.

| ........................ process ........................... || .......... parse ... | ... run ... | ... stringify ..........|          +--------+                     +----------+Input ->- | Parser | ->- Syntax Tree ->- | Compiler | ->- Output          +--------+          |          +----------+                              X                              |                       +--------------+                       | Transformers |                       +--------------+
Processors

Processors process content.On its own,unified (the root processor) doesn’t work.It needs to be configured with plugins to work.For example:

constprocessor=unified().use(remarkParse).use(remarkRehype).use(rehypeDocument,{title:'👋🌍'}).use(rehypeFormat).use(rehypeStringify)

That processor can do different things.It can:

  • …parse markdown (parse)
  • …turn parsed markdown into HTML and format the HTML (run)
  • …compile HTML (stringify)
  • …do all of the above (process)

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 affectthe ancestral processor.

When processors are exposed from a module (for example,unified itself) theyshould not be configured directly, as that would change their behavior for allmodule users.Those processors arefrozen and they should be called to createa new processor before they are used.

File

When processing a document, metadata is gathered about that document.vfile is the file format that stores data, metadata, and messagesabout files for unified and plugins.

There are severalutilities for working with these files.

Syntax tree

The syntax trees used in unified areunist nodes.A tree represents a whole document and eachnode is a plain JavaScriptobject with atype field.The semantics of nodes and the format of syntax trees is defined by otherprojects:

There are many utilities for working with trees listed in each aforementionedproject and maintained in thesyntax-tree organization.These utilities are a level lower than unified itself and are building blocksthat can be used to make plugins.

Ecosystems

Around each syntax tree is an ecosystem that focusses on that particular kindof content.At their core, they parse text to a tree and compile that tree back to text.They also provide plugins that work with the syntax tree, without requiringthat the end user has knowledge about that tree.

Plugins

Each aforementioned ecosystem comes with a large set of plugins that you canpick and choose from to do all kinds of things.

There are also a few plugins that work in any ecosystem:

Configuration

Processors are configured withplugins or with thedata method.Most plugins also accept configuration through options.See each plugin’s readme for more info.

Integrations

unified can integrate with the file system throughunified-engine.CLI apps can be created withunified-args, Gulp plugins withunified-engine-gulp, and language servers withunified-language-server.A streaming interface can be created withunified-stream.

Programming interface

TheAPI provided byunified allows multiple files to be processed andgives access to metadata (such as lint messages):

importrehypeStringifyfrom'rehype-stringify'importremarkParsefrom'remark-parse'importremarkPresetLintMarkdownStyleGuidefrom'remark-preset-lint-markdown-style-guide'importremarkRehypefrom'remark-rehype'importremarkRetextfrom'remark-retext'importretextEnglishfrom'retext-english'importretextEqualityfrom'retext-equality'import{unified}from'unified'import{reporter}from'vfile-reporter'constfile=awaitunified().use(remarkParse).use(remarkPresetLintMarkdownStyleGuide).use(remarkRetext,unified().use(retextEnglish).use(retextEquality)).use(remarkRehype).use(rehypeStringify).process('*Emphasis* and _stress_, you guys!')console.error(reporter(file))console.log(String(file))

Yields:

1:16-1:24 warning Emphasis should use `*` as a marker                                 emphasis-marker remark-lint1:30-1:34 warning `guys` may be insensitive, use `people`, `persons`, `folks` instead gals-man        retext-equality⚠ 2 warnings
<p><em>Emphasis</em> and<em>stress</em>, you guys!</p>

Transforming between ecosystems

Ecosystems can be combined in two modes.

Bridge mode transforms the tree from one format (origin) to another(destination).A different processor runs on the destination tree.Afterwards, the original processor continues with 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 inbridge mode: the origin syntax tree is kept after retext is done; whereasremark-rehype is used in mutate mode: it sets a new syntax tree and discardsthe origin tree.

The following plugins lets you combine ecosystems:

API

This package exports the identifierunified (the rootprocessor).There is no default export.

processor()

Create a new processor.

Returns

Newunfrozen processor (processor).

This processor is configured to work the same as its ancestor.When the descendant processor is configured in the future it does not affectthe ancestral processor.

Example

This example shows how a new processor can be created (fromremark) and linkedtostdin(4) andstdout(4).

importprocessfrom'node:process'importconcatStreamfrom'concat-stream'import{remark}from'remark'process.stdin.pipe(concatStream(function(buf){process.stdout.write(String(remark().processSync(buf)))}))

processor.compiler

Compiler to use (Compiler, optional).

processor.data([key[, value]])

Configure the processor with info available to all plugins.Information is stored in an object.

Typically, options can be given to a specific plugin, but sometimes it makessense to have information shared with several plugins.For example, a list of HTML elements that are self-closing, which is neededduring allphases.

👉Note: setting information cannot occur onfrozenprocessors.Call the processor first to create a new unfrozen processor.

👉Note: to register custom data in TypeScript, augment theData interface.

Signatures
  • processor = processor.data(key, value)
  • processor = processor.data(dataset)
  • value = processor.data(key)
  • dataset = processor.data()
Parameters
Returns

The current processor when setting (processor), the value atkey when getting (Data[key]), or the entire dataset whengetting without key (Data).

Example

This example show how to get and set info:

import{unified}from'unified'constprocessor=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.

When 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 automatically when.parse(),.run(),.runSync(),.stringify(),.process(), or.processSync() are called.

Returns

The current processor (processor).

Example

This example,index.js, shows howrehype prevents extensions to itself:

importrehypeParsefrom'rehype-parse'importrehypeStringifyfrom'rehype-stringify'import{unified}from'unified'exportconstrehype=unified().use(rehypeParse).use(rehypeStringify).freeze()

That processor can be used and configured like so:

import{rehype}from'rehype'importrehypeFormatfrom'rehype-format'// …rehype().use(rehypeFormat)// …

A similar looking example is broken as operates on the frozen interface.If this behavior was allowed it would result in unexpected behavior so an erroris thrown.This is not valid:

import{rehype}from'rehype'importrehypeFormatfrom'rehype-format'// …rehype.use(rehypeFormat)// …

Yields:

~/node_modules/unified/index.js:426    throw new Error(^Error: Cannot call `use` on a frozen processor.Create a new processor first, by calling it: use `processor()` instead of `processor`.    at assertUnfrozen (~/node_modules/unified/index.js:426:11)    at Function.use (~/node_modules/unified/index.js:165:5)    …

processor.parse(file)

Parse text to a syntax tree.

👉Note:parse freezes the processor if not alreadyfrozen.

👉Note:parse performs theparse phase, not the run phaseor other phases.

Parameters
  • file (Compatible) — file to parse; typicallystring orVFile; any value accepted asx innew VFile(x)
Returns

Syntax tree representingfile (Node).

Example

This example shows howparse can be used to create a tree from a file.

importremarkParsefrom'remark-parse'import{unified}from'unified'consttree=unified().use(remarkParse).parse('# Hello world!')console.log(tree)

Yields:

{type:'root',children:[{type:'heading',depth:1,children:[Array],position:[Object]}],position:{start:{line:1,column:1,offset:0},end:{line:1,column:15,offset:14}}}

processor.parser

Parser to use (Parser, optional).

processor.process(file[, done])

Process the given file as configured on the processor.

👉Note:process freezes the processor if not alreadyfrozen.

👉Note:process performs theparse, run, and stringifyphases.

Signatures
  • processor.process(file, done)
  • Promise<VFile> = processor.process(file?)
Parameters
Returns

Nothing ifdone is given (undefined).Otherwise a promise, rejected with a fatal error or resolved with theprocessed file (Promise<VFile>).

The parsed, transformed, and compiled value is available atfile.value (seenote).

👉Note: unified typically compiles by serializing: mostcompilers returnstring (orUint8Array).Some compilers, such as the one configured withrehype-react, return other values (in this case, a Reacttree).If you’re using a compiler that doesn’t serialize, expect different resultvalues.

To register custom results in TypeScript, add them toCompileResultMap.

Example

This example shows howprocess can be used to process a file:

importrehypeDocumentfrom'rehype-document'importrehypeFormatfrom'rehype-format'importrehypeStringifyfrom'rehype-stringify'importremarkParsefrom'remark-parse'importremarkRehypefrom'remark-rehype'import{unified}from'unified'constfile=awaitunified().use(remarkParse).use(remarkRehype).use(rehypeDocument,{title:'👋🌍'}).use(rehypeFormat).use(rehypeStringify).process('# Hello world!')console.log(String(file))

Yields:

<!doctype html><htmllang="en"><head><metacharset="utf-8"><title>👋🌍</title><metaname="viewport"content="width=device-width, initial-scale=1"></head><body><h1>Hello world!</h1></body></html>

processor.processSync(file)

Process the given file as configured on the processor.

An error is thrown if asynchronous transforms are configured.

👉Note:processSync freezes the processor if not alreadyfrozen.

👉Note:processSync performs theparse, run, and stringifyphases.

Parameters
  • file (Compatible, optional) — file; typicallystring orVFile; any value accepted asx innew VFile(x)
Returns

The processed file (VFile).

The parsed, transformed, and compiled value is available atfile.value (seenote).

👉Note: unified typically compiles by serializing: mostcompilers returnstring (orUint8Array).Some compilers, such as the one configured withrehype-react, return other values (in this case, a Reacttree).If you’re using a compiler that doesn’t serialize, expect different resultvalues.

To register custom results in TypeScript, add them toCompileResultMap.

Example

This example shows howprocessSync can be used to process a file, if alltransformers are synchronous.

importrehypeDocumentfrom'rehype-document'importrehypeFormatfrom'rehype-format'importrehypeStringifyfrom'rehype-stringify'importremarkParsefrom'remark-parse'importremarkRehypefrom'remark-rehype'import{unified}from'unified'constprocessor=unified().use(remarkParse).use(remarkRehype).use(rehypeDocument,{title:'👋🌍'}).use(rehypeFormat).use(rehypeStringify)console.log(String(processor.processSync('# Hello world!')))

Yields:

<!doctype html><htmllang="en"><head><metacharset="utf-8"><title>👋🌍</title><metaname="viewport"content="width=device-width, initial-scale=1"></head><body><h1>Hello world!</h1></body></html>

processor.run(tree[, file][, done])

Runtransformers on a syntax tree.

👉Note:run freezes the processor if not alreadyfrozen.

👉Note:run performs therun phase, not other phases.

Signatures
  • processor.run(tree, done)
  • processor.run(tree, file, done)
  • Promise<Node> = processor.run(tree, file?)
Parameters
  • tree (Node) — tree to transform and inspect
  • file (Compatible, optional) — file associatedwithnode; any value accepted asx innew VFile(x)
  • done (RunCallback, optional) — callback
Returns

Nothing ifdone is given (undefined).Otherwise, a promise rejected with a fatal error or resolved with thetransformed tree (Promise<Node>).

Example

This example shows howrun can be used to transform a tree:

importremarkReferenceLinksfrom'remark-reference-links'import{unified}from'unified'import{u}from'unist-builder'consttree=u('root',[u('paragraph',[u('link',{href:'https://example.com'},[u('text','Example Domain')])])])constchangedTree=awaitunified().use(remarkReferenceLinks).run(tree)console.log(changedTree)

Yields:

{type:'root',children:[{type:'paragraph',children:[Array]},{type:'definition',identifier:'1',title:'',url:undefined}]}

processor.runSync(tree[, file])

Runtransformers on a syntax tree.

An error is thrown if asynchronous transforms are configured.

👉Note:runSync freezes the processor if not alreadyfrozen.

👉Note:runSync performs therun phase, not other phases.

Parameters
  • tree (Node) — tree to transform and inspect
  • file (Compatible, optional) — file associatedwithnode; any value accepted asx innew VFile(x)
Returns

Transformed tree (Node).

processor.stringify(tree[, file])

Compile a syntax tree.

👉Note:stringify freezes the processor if not alreadyfrozen.

👉Note:stringify performs thestringify phase, not the runphase or other phases.

Parameters
  • tree (Node) — tree to compile
  • file (Compatible, optional) — file associatedwithnode; any value accepted asx innew VFile(x)
Returns

Textual representation of the tree (Uint8Array orstring, see note).

👉Note: unified typically compiles by serializing: most compilersreturnstring (orUint8Array).Some compilers, such as the one configured withrehype-react, return other values (in this case, aReact tree).If you’re using a compiler that doesn’t serialize, expect differentresult values.

To register custom results in TypeScript, add them toCompileResultMap.

Example

This example shows howstringify can be used to serialize a syntax tree:

import{h}from'hastscript'importrehypeStringifyfrom'rehype-stringify'import{unified}from'unified'consttree=h('h1','Hello world!')constdocument=unified().use(rehypeStringify).stringify(tree)console.log(document)

Yields:

<h1>Hello world!</h1>

processor.use(plugin[, options])

Configure the processor to use a plugin, a list of usable values, or a preset.

If the processor is already using a plugin, the previous plugin configurationis changed based on the options that are passed in.In other words, the plugin is not added a second time.

👉Note:use cannot be called onfrozen processors.Call the processor first to create a new unfrozen processor.

Signatures
  • processor.use(preset?)
  • processor.use(list)
  • processor.use(plugin[, ...parameters])
Parameters
  • preset (Preset) — plugins and settings
  • list (PluggableList) — list of usable things
  • plugin (Plugin) — plugin
  • parameters (Array<unknown>) — configuration forplugin, typically asingle options object
Returns

Current processor (processor).

Example

There are many ways to pass plugins to.use().This example gives an overview:

import{unified}from'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}})

CompileResultMap

Interface of known results from compilers (TypeScript type).

Normally, compilers result in text (Value ofvfile).When you compile to something else, such as a React node (as in,rehype-react), you can augment this interface to include that type.

importtype{ReactNode}from'somewhere'declare module'unified'{interfaceCompileResultMap{// Register a new result (value is used, key should match it).ReactNode:ReactNode}}export{}// You may not need this, but it makes sure the file is a module.

UseCompileResults to access the values.

Type
interfaceCompileResultMap{// Note: if `Value` from `VFile` is changed, this should too.Uint8Array:Uint8Arraystring:string}

CompileResults

Acceptable results from compilers (TypeScript type).

To register custom results, add them toCompileResultMap.

Type
typeCompileResults=CompileResultMap[keyofCompileResultMap]

Compiler

Acompiler handles the compiling of a syntax tree to something else(in most cases, text) (TypeScript type).

It is used in the stringify phase and called with aNodeandVFile representation of the document to compile.It should return the textual representation of the given tree (typicallystring).

👉Note: unified typically compiles by serializing: most compilersreturnstring (orUint8Array).Some compilers, such as the one configured withrehype-react, return other values (in this case, aReact tree).If you’re using a compiler that doesn’t serialize, expect differentresult values.

To register custom results in TypeScript, add them toCompileResultMap.

Type
typeCompiler<TreeextendsNode=Node,ResultextendsCompileResults=CompileResults>=(tree:Tree,file:VFile)=>Result

Data

Interface of known data that can be supported by all plugins (TypeScript type).

Typically, options can be given to a specific plugin, but sometimes it makessense to have information shared with several plugins.For example, a list of HTML elements that are self-closing, which is neededduring all phases.

To type this, do something like:

declare module'unified'{interfaceData{htmlVoidElements?:Array<string>|undefined}}export{}// You may not need this, but it makes sure the file is a module.
Type
interfaceData{settings?:Settings|undefined}

SeeSettings for more info.

Parser

Aparser handles the parsing of text to a syntax tree (TypeScript type).

It is used in the parse phase and is called with astring andVFile of the document to parse.It must return the syntax tree representation of the given file(Node).

Type
typeParser<TreeextendsNode=Node>=(document:string,file:VFile)=>Tree

Pluggable

Union of the different ways to add plugins and settings (TypeScript type).

Type
typePluggable=|Plugin<Array<any>,any,any>|PluginTuple<Array<any>,any,any>|Preset

SeePlugin,PluginTuple,andPreset for more info.

PluggableList

List of plugins and presets (TypeScript type).

Type
typePluggableList=Array<Pluggable>

SeePluggable for more info.

Plugin

Single plugin (TypeScript type).

Plugins configure the processors they are applied on in the following ways:

  • they change the processor, such as the parser, the compiler, or byconfiguring data
  • they specify how to handle trees and files

In practice, they are functions that can receive options and configure theprocessor (this).

👉Note: plugins are called when the processor isfrozen, not when theyare applied.

Type
typePlugin<PluginParametersextendsunknown[]=[],InputextendsNode|string|undefined=Node,Output=Input>=(this:Processor,  ...parameters:PluginParameters)=>Inputextendsstring// Parser.  ?OutputextendsNode|undefined    ?undefined|void    :never  :OutputextendsCompileResults// Compiler.  ?InputextendsNode|undefined    ?undefined|void    :never  :// Inspect/transform.|Transformer<InputextendsNode ?Input :Node,OutputextendsNode ?Output :Node>|undefined|void

SeeTransformer for more info.

Example

move.js:

/** *@import {Plugin} from 'unified' *//** *@typedef Options *   Configuration (required). *@property {string} extname *   File extension to use (must start with `.`). *//**@type {Plugin<[Options]>} */exportfunctionmove(options){if(!options||!options.extname){thrownewError('Missing `options.extname`')}returnfunction(_,file){if(file.extname&&file.extname!==options.extname){file.extname=options.extname}}}

example.md:

#Hello, world!

example.js:

importrehypeStringifyfrom'rehype-stringify'importremarkParsefrom'remark-parse'importremarkRehypefrom'remark-rehype'import{read,write}from'to-vfile'import{unified}from'unified'import{reporter}from'vfile-reporter'import{move}from'./move.js'constfile=awaitunified().use(remarkParse).use(remarkRehype).use(move,{extname:'.html'}).use(rehypeStringify).process(awaitread('example.md'))console.error(reporter(file))awaitwrite(file)// Written to `example.html`.

Yields:

example.md: no issues found

…and inexample.html:

<h1>Hello, world!</h1>

PluginTuple

Tuple of a plugin and its configuration (TypeScript type).

The first item is a plugin, the rest are its parameters.

Type
typePluginTuple<TupleParametersextendsunknown[]=[],InputextendsNode|string|undefined=undefined,Output=undefined>=[plugin:Plugin<TupleParameters,Input,Output>,  ...parameters:TupleParameters]

SeePlugin for more info.

Preset

Sharable configuration (TypeScript type).

They can contain plugins and settings.

Fields
  • plugins (PluggableList, optional)— list of plugins and presets
  • settings (Data, optional)— shared settings for parsers and compilers
Example

preset.js:

/** *@import {Preset} from 'unified' */importremarkCommentConfigfrom'remark-comment-config'importremarkLicensefrom'remark-license'importremarkPresetLintConsistentfrom'remark-preset-lint-consistent'importremarkPresetLintRecommendedfrom'remark-preset-lint-recommended'importremarkTocfrom'remark-toc'/**@type {Preset} */constpreset={plugins:[remarkPresetLintRecommended,remarkPresetLintConsistent,remarkCommentConfig,[remarkToc,{maxDepth:3,tight:true}],remarkLicense],settings:{bullet:'*',emphasis:'*',fences:true},}exportdefaultpreset

example.md:

#Hello, world!_Emphasis_ and**importance**.##Table of contents##API##License

example.js:

import{remark}from'remark'import{read,write}from'to-vfile'import{reporter}from'vfile-reporter'importpresetfrom'./preset.js'constfile=awaitremark().use(preset).process(awaitread('example.md'))console.error(reporter(file))awaitwrite(file)

Yields:

example.md: no issues found

example.md now contains:

#Hello, world!*Emphasis* and**importance**.##Table of contents*[API](#api)*[License](#license)##API##License[MIT](license) ©[Titus Wormer](https://wooorm.com)

ProcessCallback

Callback called when the process is done (TypeScript type).

Called with either an error or a result.

Parameters
  • error (Error, optional)— fatal error
  • file (VFile, optional)— processed file
Returns

Nothing (undefined).

Example

This example shows howprocess can be used to process a file with a callback.

importremarkGithubfrom'remark-github'importremarkParsefrom'remark-parse'importremarkStringifyfrom'remark-stringify'import{unified}from'unified'import{reporter}from'vfile-reporter'unified().use(remarkParse).use(remarkGithub).use(remarkStringify).process('@unifiedjs',function(error,file){if(error)throwerrorif(file){console.error(reporter(file))console.log(String(file))}})

Yields:

no issues found
[**@unifiedjs**](https://github.com/unifiedjs)

Processor

Type of aprocessor (TypeScript type).

RunCallback

Callback called when transformers are done (TypeScript type).

Called with either an error or results.

Parameters
  • error (Error, optional)— fatal error
  • tree (Node, optional)— transformed tree
  • file (VFile, optional)— file
Returns

Nothing (undefined).

Settings

Interface of known extra options, that can be supported by parser andcompilers.

This exists so that users can use packages such asremark, which configureboth parsers and compilers (in this caseremark-parse andremark-stringify), and still provide options for them.

When you make parsers or compilers, that could be packaged up together, youshould supportthis.data('settings') as input and merge it with explicitlypassedoptions.Then, to type it, usingremark-stringify as an example, do something like:

declare module'unified'{interfaceSettings{bullet:'*'|'+'|'-'// …}}export{}// You may not need this, but it makes sure the file is a module.
Type
interfaceSettings{}

TransformCallback

Callback passed to transforms (TypeScript type).

If the signature of atransformer accepts a third argument, the transformermay perform asynchronous operations, and must call it.

Parameters
  • error (Error, optional)— fatal error to stop the process
  • tree (Node, optional)— new, changed, tree
  • file (VFile, optional)— new, changed, file
Returns

Nothing (undefined).

Transformer

Transformers handle syntax trees and files (TypeScript type).

They are functions that are called each time a syntax tree and file arepassed through the run phase.When an error occurs in them (either because it’s thrown, returned,rejected, or passed tonext), the process stops.

The run phase is handled bytrough, see its documentation forthe exact semantics of these functions.

👉Note: you should likely ignorenext: don’t accept it.it supports callback-style async work.But promises are likely easier to reason about.

Type
typeTransformer<InputextendsNode=Node,OutputextendsNode=Input>=(tree:Input,file:VFile,next:TransformCallback<Output>)=>|Promise<Output|undefined>|Output|Error|undefined

Types

This package is fully typed withTypeScript.It exports the additional typesCompileResultMap,CompileResults,Compiler,Data,Parser,Pluggable,PluggableList,Plugin,PluginTuple,Preset,ProcessCallback,Processor,RunCallback,Settings,TransformCallback,andTransformer

For TypeScript to work, it is particularly important to type your pluginscorrectly.We strongly recommend using thePlugin type with its generics and to use thenode types for the syntax trees provided by our packages (as in,@types/hast,@types/mdast,@types/nlcst).

/** *@import {Root as HastRoot} from 'hast' *@import {Root as MdastRoot} from 'mdast' *@import {Plugin} from 'unified' *//** *@typedef Options *   Configuration (optional). *@property {boolean | null | undefined} [someField] *   Some option (optional). */// To type options:/**@type {Plugin<[(Options | null | undefined)?]>} */exportfunctionmyPluginAcceptingOptions(options){constsettings=options||{}// `settings` is now `Options`.}// To type a plugin that works on a certain tree, without options:/**@type {Plugin<[], MdastRoot>} */exportfunctionmyRemarkPlugin(){returnfunction(tree,file){// `tree` is `MdastRoot`.}}// To type a plugin that transforms one tree into another:/**@type {Plugin<[], MdastRoot, HastRoot>} */exportfunctionremarkRehype(){returnfunction(tree){// `tree` is `MdastRoot`.// Result must be `HastRoot`.}}// To type a plugin that defines a parser:/**@type {Plugin<[], string, MdastRoot>} */exportfunctionremarkParse(options){}// To type a plugin that defines a compiler:/**@type {Plugin<[], HastRoot, string>} */exportfunctionrehypeStringify(options){}

Compatibility

Projects maintained by the unified collective are compatible with maintainedversions of Node.js.

When we cut a new major release, we drop support for unmaintained versions ofNode.This means we try to keep the current release line,unified@^11, compatiblewith Node.js 16.

Contribute

Seecontributing.md inunifiedjs/.github for waysto get started.Seesupport.md for ways to get help.

This project has acode of conduct.By interacting with this repository, organization, or community you agree toabide by its terms.

For info on how to submit a security report, see oursecurity policy.

Sponsor

Support this effort and give back by sponsoring onOpenCollective!

Vercel

Motif

HashiCorp

American Express

GitBook

Gatsby

Netlify

Coinbase

ThemeIsle

Expo

Boost Note

Markdown Space

Holloway


You?

Acknowledgments

Preliminary work for unified was donein 2014 forretext and inspired byware.Further incubation happened inremark.The project was finallyexternalised in 2015 andpublished asunified.The project was authored by@wooorm.

Althoughunified since moved its plugin architecture totrough,thanks to@calvinfo,@ianstormtaylor, and others for theirwork onware, as it was a huge initial inspiration.

License

MIT ©Titus Wormer


[8]ページ先頭

©2009-2025 Movatter.jp