unified

Learn/Recipe/Find a node

How to find a node

Contents

What is a node

A node is a single language specific unit inside a syntax tree. For example: a heading in markdown, or anchor element in HTML. In unified, nodes follow the unist specification.

Finding a node

The concept of finding a node involves tree traversal of a syntax tree.

unified compatible utilities should be used for finding a node. Utilities are functions that work with nodes. All specifications that extend unist can use the unist utilities, but they can also have their own utilities for more specific nodes.

To start finding nodes for your input you’ll need:

For this example we use remark and unist-util-find. We want to find the first occurrence of emphasis in our markdown.

/**
 * @import {Root} from 'mdast'
 */

import {remark} from 'remark'
import {find} from 'unist-util-find'

await remark()
  .use(function () {
    /**
     * @param {Root} tree
     * @returns {undefined}
     */
    return function (tree) {
      const node = find(tree, {type: 'emphasis'})
      console.log(node)
    }
  })
  .process('Some _emphasis_, **strongness**, _more emphasis_, and `code`.')
(alias) const remark: Processor<Root, undefined, undefined, Root, string>
import remark

Create a new unified processor that already uses remark-parse and remark-stringify.

(alias) function find<V extends Node>(tree: Node, condition: TestFn | TestObj | TestStr): V | undefined
import find

Find a node in tree matching condition.

  • @template {Node} V Node to search for.
  • @param tree Tree to search in.
  • @param condition Condition used to test each node, which matches V.
  • @returns The first node that matches condition, or undefined if no node matches.
(alias) remark(): Processor<Root, undefined, undefined, Root, string>
import remark

Create a new unified processor that already uses remark-parse and remark-stringify.

(method) Processor<Root, undefined, undefined, Root, string>.use<[], Root, undefined>(plugin: Plugin<[], Root, undefined>, ...parameters: [] | [boolean]): Processor<Root, Root, undefined, Root, string> (+2 overloads)

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 configuration is 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 on frozen processors. Call the processor first to create a new unfrozen 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}})
    
  • @template {Array} [Parameters=[]]
  • @template {Node | string | undefined} [Input=undefined]
  • @template [Output=Input]
  • @overload
  • @overload
  • @overload
  • @param value Usable value.
  • @param parameters Parameters, when a plugin is given as a usable value.
  • @returns Current processor.
(parameter) tree: Root
  • @param tree
const node: Node | undefined
(alias) find<Node>(tree: Node, condition: TestFn | TestObj | TestStr): Node | undefined
import find

Find a node in tree matching condition.

  • @template {Node} V Node to search for.
  • @param tree Tree to search in.
  • @param condition Condition used to test each node, which matches V.
  • @returns The first node that matches condition, or undefined if no node matches.
(parameter) tree: Root
  • @param tree
(property) type: string
var console: Console
(method) console.Console.log(...data: any[]): void
const node: Node | undefined
(method) Processor<Root, Root, undefined, Root, string>.process(file?: Compatible | undefined): Promise<VFile> (+1 overload)

Process the given file as configured on the processor.

Note: process freezes the processor if not already frozen.

Note: process performs the parse, run, and stringify phases.

  • @overload
  • @overload
  • @param file File (optional); typically string or VFile]; any value accepted as x in new VFile(x).
  • @param done Callback (optional).
  • @returns Nothing if done is given. Otherwise a promise, rejected with a fatal error or resolved with the processed file. The parsed, transformed, and compiled value is available at file.value (see note).

    Note: unified typically compiles by serializing: most compilers return string (or Uint8Array). Some compilers, such as the one configured with rehype-react, return other values (in this case, a React tree). If you’re using a compiler that doesn’t serialize, expect different result values.

    To register custom results in TypeScript, add them to {@linkcode CompileResultMap}.

…yields:

{
  type: 'emphasis',
  children: [ { type: 'text', value: 'emphasis', position: [Object] } ],
  position: {
    start: { line: 1, column: 6, offset: 5 },
    end: { line: 1, column: 16, offset: 15 }
  }
}

Read more about unist-util-find in its readme.

The package unist-util-find is rather basic and slow. You likely want to traverse a tree with unist-util-visit