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:
- a processor (such as
remark
) - a utility of choice
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
namespace console
var console: Console
The console
module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.
The module exports two specific components:
- A
Console
class with methods such asconsole.log()
,console.error()
andconsole.warn()
that can be used to write to any Node.js stream. - A global
console
instance configured to write toprocess.stdout
andprocess.stderr
. The globalconsole
can be used without importing thenode:console
module.
Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O
for more information.
Example using the global console
:
console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr
Example using the Console
class:
const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err
- @see source
(method) Console.log(message?: any, ...optionalParams: any[]): void
Prints to stdout
with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3)
(the arguments are all passed to util.format()
).
const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout
See util.format()
for more information.
- @since v0.1.100
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
orVFile
]; any value accepted asx
innew 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 atfile.value
(see note).Note: unified typically compiles by serializing: most compilers return
string
(orUint8Array
). Some compilers, such as the one configured withrehype-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