├── .github
└── workflows
│ └── bb.yml
├── .gitignore
├── .npmrc
├── logo-square.svg
├── logo.svg
├── package.json
└── readme.md
/.github/workflows/bb.yml:
--------------------------------------------------------------------------------
1 | name: bb
2 | on:
3 | issues:
4 | types: [closed, edited, labeled, opened, reopened, unlabeled]
5 | pull_request_target:
6 | types: [closed, edited, labeled, opened, reopened, unlabeled]
7 | jobs:
8 | main:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: unifiedjs/beep-boop-beta@main
12 | with:
13 | repo-token: ${{secrets.GITHUB_TOKEN}}
14 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | *.log
3 | node_modules/
4 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | ignore-scripts=true
2 | package-lock=false
3 |
--------------------------------------------------------------------------------
/logo-square.svg:
--------------------------------------------------------------------------------
1 |
14 |
--------------------------------------------------------------------------------
/logo.svg:
--------------------------------------------------------------------------------
1 |
14 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "author": "Titus Wormer (wooorm.com)",
3 | "bugs": "https://github.com/syntax-tree/unist/issues",
4 | "contributors": [
5 | "Christian Murphy ",
6 | "Eugene Sharygin ",
7 | "Titus Wormer (wooorm.com)"
8 | ],
9 | "devDependencies": {
10 | "remark-cli": "^12.0.0",
11 | "remark-preset-wooorm": "^10.0.0"
12 | },
13 | "description": "universal syntax tree",
14 | "keywords": [],
15 | "license": "CC-BY-4.0",
16 | "private": true,
17 | "remarkConfig": {
18 | "plugins": [
19 | "remark-preset-wooorm"
20 | ]
21 | },
22 | "repository": "syntax-tree/unist",
23 | "scripts": {
24 | "format": "remark --frail --output --quiet -- .",
25 | "test": "npm run format"
26 | },
27 | "version": "0.0.0"
28 | }
29 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # ![unist][logo]
2 |
3 | **Uni**versal **S**yntax **T**ree.
4 |
5 | ***
6 |
7 | **unist** is a specification for syntax trees.
8 | It has a big [ecosystem of utilities][list-of-utilities] in JavaScript for
9 | working with these trees.
10 | It’s implemented by several other specifications.
11 |
12 | This document may not be released.
13 | See [releases][] for released documents.
14 | The latest released version is [`3.0.0`][release].
15 |
16 | ## Contents
17 |
18 | * [Intro](#intro)
19 | * [Syntax tree](#syntax-tree)
20 | * [Where this specification fits](#where-this-specification-fits)
21 | * [Types](#types)
22 | * [Nodes](#nodes)
23 | * [`Node`](#node)
24 | * [`Parent`](#parent)
25 | * [`Literal`](#literal)
26 | * [Glossary](#glossary)
27 | * [Tree traversal](#tree-traversal)
28 | * [Utilities](#utilities)
29 | * [List of utilities](#list-of-utilities)
30 | * [References](#references)
31 | * [Contribute](#contribute)
32 | * [Acknowledgments](#acknowledgments)
33 | * [License](#license)
34 |
35 | ## Intro
36 |
37 | This document defines a general-purpose format for syntax trees.
38 | Development of unist started in July 2015.
39 | This specification is written in a [Web IDL][webidl]-like grammar.
40 |
41 | ### Syntax tree
42 |
43 | Syntax trees are representations of source code or even natural language.
44 | These trees are abstractions that make it possible to analyze, transform, and
45 | generate code.
46 |
47 | Syntax trees [come in two flavors][abstract-vs-concrete-trees]:
48 |
49 | * **concrete syntax trees**: structures that represent every detail (such as
50 | white-space in white-space insensitive languages)
51 | * **abstract syntax trees**: structures that only represent details relating
52 | to the syntactic structure of code (such as ignoring whether a double or
53 | single quote was used in languages that support both, such as JavaScript).
54 |
55 | This specification can express both abstract and concrete syntax trees.
56 |
57 | ### Where this specification fits
58 |
59 | unist is not intended to be self-sufficient.
60 | Instead, it is expected that other specifications implement unist and extend it
61 | to express language specific nodes.
62 | For example, see projects such as **[hast][]** (for HTML), **[nlcst][]** (for
63 | natural language), **[mdast][]** (for Markdown), and **[xast][]** (for XML).
64 |
65 | unist relates to [JSON][] in that compliant syntax trees can be expressed
66 | completely in JSON.
67 | However, unist is not limited to JSON and can be expressed in other data
68 | formats, such as [XML][].
69 |
70 | unist relates to [JavaScript][] in that it has a rich [ecosystem of
71 | utilities][list-of-utilities] for working with compliant syntax trees in
72 | JavaScript.
73 | The five most used utilities combined are downloaded thirty million times each
74 | month.
75 | However, unist is not limited to JavaScript and can be used in other programming
76 | languages.
77 |
78 | unist relates to the [unified][], [remark][], [rehype][], and [retext][]
79 | projects in that unist syntax trees are used throughout their ecosystems.
80 |
81 | unist relates to the [vfile][] project in that it accepts unist nodes for its
82 | message store, and that vfile can be a source *[file][term-file]* of a syntax
83 | tree.
84 |
85 | ## Types
86 |
87 | If you are using TypeScript, you can use the unist types by installing them
88 | with npm:
89 |
90 | ```sh
91 | npm install @types/unist
92 | ```
93 |
94 | ## Nodes
95 |
96 | Syntactic units in unist syntax trees are called nodes, and implement the
97 | **[Node][dfn-node]** interface.
98 |
99 | ### `Node`
100 |
101 | ```idl
102 | interface Node {
103 | type: string
104 | data: Data?
105 | position: Position?
106 | }
107 | ```
108 |
109 | The `type` field is a non-empty string representing the variant of a node.
110 | This field can be used to determine the *[type][term-type]* a node implements.
111 |
112 | The `data` field represents information from the ecosystem.
113 | The value of the `data` field implements the **[Data][dfn-data]** interface.
114 |
115 | The `position` field represents the location of a node in a source document.
116 | The value of the `position` field implements the **[Position][dfn-position]**
117 | interface.
118 | The `position` field must not be present if a node is
119 | *[generated][term-generated]*.
120 |
121 | Specifications implementing unist are encouraged to define more fields.
122 | Ecosystems can define fields on **[Data][dfn-data]**.
123 |
124 | Any value in unist **must** be expressible in JSON values: `string`, `number`,
125 | `object`, `array`, `true`, `false`, or `null`.
126 | This means that the syntax tree should be able to be converted to and from JSON
127 | and produce the same tree.
128 | For example, in JavaScript, a tree can be passed through
129 | `JSON.parse(JSON.stringify(tree))` and result in the same tree.
130 |
131 | #### `Position`
132 |
133 | ```idl
134 | interface Position {
135 | start: Point
136 | end: Point
137 | }
138 | ```
139 |
140 | **Position** represents the location of a node in a source *[file][term-file]*.
141 |
142 | The `start` field of **Position** represents the place of the first character of
143 | the parsed source region.
144 | The `end` field of **Position** represents the place of the first character
145 | after the parsed source region, whether it exists or not.
146 | The value of the `start` and `end` fields implement the **[Point][dfn-point]**
147 | interface.
148 |
149 | If the syntactic unit represented by a node is not present in the source
150 | *[file][term-file]* at the time of parsing, the node is said to be
151 | *[generated][term-generated]* and it must not have positional information.
152 |
153 | For example, if the following value was represented as unist:
154 |
155 | ```markdown
156 | alpha
157 | bravo
158 | ```
159 |
160 | …the first word (`alpha`) would start at line `1`, column `1`, offset `0`, and
161 | end at line `1`, column `6`, offset `5`.
162 | The line feed would start at line `1`, column `6`, offset `5`, and end at line
163 | `2`, column `1`, offset `6`.
164 | The last word (`bravo`) would start at line `2`, column `1`, offset `6`, and end
165 | at line `2`, column `6`, offset `11`.
166 |
167 | #### `Point`
168 |
169 | ```idl
170 | interface Point {
171 | line: number >= 1
172 | column: number >= 1
173 | offset: number >= 0?
174 | }
175 | ```
176 |
177 | **Point** represents one place in a source *[file][term-file]*.
178 |
179 | The `line` field (1-indexed integer) represents a line in a source file.
180 | The `column` field (1-indexed integer) represents a column in a source file.
181 | The `offset` field (0-indexed integer) represents a character in a source file.
182 |
183 | The term character means a (UTF-16) code unit which is defined in the
184 | [Web IDL][webidl] specification.
185 |
186 | #### `Data`
187 |
188 | ```idl
189 | interface Data { }
190 | ```
191 |
192 | **Data** represents information associated by the ecosystem with the node.
193 |
194 | This space is guaranteed to never be specified by unist or specifications
195 | implementing unist.
196 |
197 | ### `Parent`
198 |
199 | ```idl
200 | interface Parent <: Node {
201 | children: [Node]
202 | }
203 | ```
204 |
205 | Nodes containing other nodes (said to be *[children][term-child]*) extend the
206 | abstract interface **Parent** (**[Node][dfn-node]**).
207 |
208 | The `children` field is a list representing the children of a node.
209 |
210 | ### `Literal`
211 |
212 | ```idl
213 | interface Literal <: Node {
214 | value: any
215 | }
216 | ```
217 |
218 | Nodes containing a value extend the abstract interface **Literal**
219 | (**[Node][dfn-node]**).
220 |
221 | The `value` field can contain any value.
222 |
223 | ## Glossary
224 |
225 | ###### Tree
226 |
227 | A **tree** is a node and all of its *[descendants][term-descendant]* (if any).
228 |
229 | ###### Child
230 |
231 | Node X is **child** of node Y, if Y’s `children` include X.
232 |
233 | ###### Parent
234 |
235 | Node X is **parent** of node Y, if Y is a *[child][term-child]* of X.
236 |
237 | ###### Index
238 |
239 | The **index** of a *[child][term-child]* is its number of preceding
240 | *[siblings][term-sibling]*, or `0` if it has none.
241 |
242 | ###### Sibling
243 |
244 | Node X is a **sibling** of node Y, if X and Y have the same
245 | *[parent][term-parent]* (if any).
246 |
247 | The **previous sibling** of a *[child][term-child]* is its **sibling** at its
248 | *[index][term-index]* minus 1.
249 |
250 | The **next sibling** of a *[child][term-child]* is its **sibling** at its
251 | *[index][term-index]* plus 1.
252 |
253 | ###### Root
254 |
255 | The **root** of a node is itself, if without *[parent][term-parent]*, or the
256 | **root** of its *[parent][term-parent]*.
257 |
258 | The **root** of a *[tree][term-tree]* is any node in that *[tree][term-tree]*
259 | without *[parent][term-parent]*.
260 |
261 | ###### Descendant
262 |
263 | Node X is **descendant** of node Y, if X is a *[child][term-child]* of Y, or if
264 | X is a *[child][term-child]* of node Z that is a **descendant** of Y.
265 |
266 | An **inclusive descendant** is a node or one of its **descendants**.
267 |
268 | ###### Ancestor
269 |
270 | Node X is an **ancestor** of node Y, if Y is a *[descendant][term-descendant]*
271 | of X.
272 |
273 | An **inclusive ancestor** is a node or one of its **ancestors**.
274 |
275 | ###### Head
276 |
277 | The **head** of a node is its first *[child][term-child]* (if any).
278 |
279 | ###### Tail
280 |
281 | The **tail** of a node is its last *[child][term-child]* (if any).
282 |
283 | ###### Leaf
284 |
285 | A **leaf** is a node with no *[children][term-child]*.
286 |
287 | ###### Branch
288 |
289 | A **branch** is a node with one or more *[children][term-child]*.
290 |
291 | ###### Generated
292 |
293 | A node is **generated** if it does not have *[positional
294 | information][term-positional-info]*.
295 |
296 | ###### Type
297 |
298 | The **type** of a node is the value of its `type` field.
299 |
300 | ###### Positional information
301 |
302 | The **positional information** of a node is the value of its `position` field.
303 |
304 | ###### File
305 |
306 | A **file** is a source document that represents the original file that was
307 | parsed to produce the syntax tree.
308 | *[Positional information][term-positional-info]* represents the place of a node
309 | in this file.
310 | Files are provided by the host environment and not defined by unist.
311 |
312 | For example, see projects such as **[vfile][]**.
313 |
314 | ###### Preorder
315 |
316 | In **preorder** (**NLR**) is [depth-first][traversal-depth] [tree
317 | traversal][traversal] that performs the following steps for each node *N*:
318 |
319 | 1. **N**: visit *N* itself
320 | 2. **L**: traverse *[head][term-head]* (then its *next sibling*, recursively
321 | moving forward until reaching *tail*)
322 | 3. **R**: traverse *[tail][term-tail]*
323 |
324 | ###### Postorder
325 |
326 | In **postorder** (**LRN**) is [depth-first][traversal-depth] [tree
327 | traversal][traversal] that performs the following steps for each node *N*:
328 |
329 | 1. **L**: traverse *[head][term-head]* (then its *next sibling*, recursively
330 | moving forward until reaching *tail*)
331 | 2. **R**: traverse *[tail][term-tail]*
332 | 3. **N**: visit *N* itself
333 |
334 | ###### Enter
335 |
336 | **Enter** is a step right before other steps performed on a given node *N* when
337 | **[traversing][traversal]** a tree.
338 |
339 | For example, when performing *preorder* traversal, **enter** is the first step
340 | taken, right before visiting *N* itself.
341 |
342 | ###### Exit
343 |
344 | **Exit** is a step right after other steps performed on a given node *N* when
345 | **[traversing][traversal]** a tree.
346 |
347 | For example, when performing *preorder* traversal, **exit** is the last step
348 | taken, right after traversing the *[tail][term-tail]* of *N*.
349 |
350 | ## Tree traversal
351 |
352 | **Tree traversal** is a common task when working with a *[tree][term-tree]* to
353 | search it.
354 | Tree traversal is typically either *breadth-first* or *depth-first*.
355 |
356 | In the following examples, we’ll work with this tree:
357 |
358 | ```mermaid
359 | graph TD
360 | A-->B-->C
361 | B-->D
362 | B-->E
363 | A-->F-->G
364 | ```
365 |
366 | ###### Breadth-first traversal
367 |
368 | **Breadth-first traversal** is visiting a node and all its
369 | *[siblings][term-sibling]* to broaden the search at that level, before
370 | traversing *[children][term-child]*.
371 |
372 | For the syntax tree defined in the diagram, a breadth-first traversal first
373 | searches the root of the tree (**A**), then its children (**B** and **F**), then
374 | their children (**C**, **D**, **E**, and **G**).
375 |
376 | ###### Depth-first traversal
377 |
378 | Alternatively, and more commonly, **depth-first traversal** is used.
379 | The search is first deepened, by traversing *[children][term-child]*, before
380 | traversing *[siblings][term-sibling]*.
381 |
382 | For the syntax tree defined in the diagram, a depth-first traversal first
383 | searches the root of the tree (**A**), then one of its children (**B** or
384 | **F**), then their children (**C**, **D**, and **E**, or **G**).
385 |
386 | For a given node *N* with *[children][term-child]*, a **depth-first traversal**
387 | performs three steps, simplified to only binary trees (every node has
388 | *[head][term-head]* and *[tail][term-tail]*, but no other children):
389 |
390 | * **N**: visit *N* itself
391 | * **L**: traverse *[head][term-head]*
392 | * **R**: traverse *[tail][term-tail]*
393 |
394 | These steps can be done in any order, but for non-binary trees, **L** and **R**
395 | occur together.
396 | If **L** is done before **R**, the traversal is called *left-to-right*
397 | traversal, otherwise it is called *right-to-left* traversal.
398 | In the case of non-binary trees, the other children between *head* and *tail*
399 | are processed in that order as well, so for *left-to-right* traversal, first
400 | *head* is traversed (**L**), then its *next sibling* is traversed, etcetera,
401 | until finally *tail* (**R**) is traversed.
402 |
403 | Because **L** and **R** occur together for non-binary trees, we can produce four
404 | types of orders: NLR, NRL, LRN, RLN.
405 |
406 | NLR and LRN (the two *left-to-right* traversal options) are most commonly used
407 | and respectively named *[preorder][term-preorder]* and
408 | *[postorder][term-postorder]*.
409 |
410 | For the syntax tree defined in the diagram, *preorder* and *postorder* traversal
411 | thus first search the root of the tree (**A**), then its head (**B**), then its
412 | children from left-to-right (**C**, **D**, and then **E**).
413 | After all *[descendants][term-descendant]* of **B** are traversed, its next
414 | sibling (**F**) is traversed and then finally its only child (**G**).
415 |
416 | ## Utilities
417 |
418 | **Utilities** are functions that work with nodes.
419 |
420 | There are several projects that deal with nodes from specifications implementing
421 | unist:
422 |
423 | * [hast utilities](https://github.com/syntax-tree/hast#list-of-utilities)
424 | * [mdast utilities](https://github.com/syntax-tree/mdast#list-of-utilities)
425 | * [nlcst utilities](https://github.com/syntax-tree/nlcst#list-of-utilities)
426 | * [xast utilities](https://github.com/syntax-tree/xast#list-of-utilities)
427 |
428 | ### List of utilities
429 |
430 | * [`unist-util-ancestor`](https://github.com/gorango/unist-util-ancestor)
431 | — get the common ancestor of one or more nodes
432 | * [`unist-util-assert`](https://github.com/syntax-tree/unist-util-assert)
433 | — assert nodes
434 | * [`unist-util-filter`](https://github.com/syntax-tree/unist-util-filter)
435 | — create a new tree with all nodes that pass the given function
436 | * [`unist-util-find`](https://github.com/blahah/unist-util-find)
437 | — find a node by condition
438 | * [`unist-util-find-after`](https://github.com/syntax-tree/unist-util-find-after)
439 | — find a node after another node
440 | * [`unist-util-find-all-after`](https://github.com/syntax-tree/unist-util-find-all-after)
441 | — find nodes after another node or index
442 | * [`unist-util-find-all-before`](https://github.com/syntax-tree/unist-util-find-all-before)
443 | — find nodes before another node or index
444 | * [`unist-util-find-all-between`](https://github.com/mrzmmr/unist-util-find-all-between)
445 | — find nodes between two nodes or positions
446 | * [`unist-util-find-before`](https://github.com/syntax-tree/unist-util-find-before)
447 | — find a node before another node
448 | * [`unist-util-flat-filter`](https://github.com/unicorn-utterances/unist-util-flat-filter)
449 | — flat map version of `unist-util-filter`
450 | * [`unist-util-flatmap`](https://gitlab.com/staltz/unist-util-flatmap)
451 | — create a new tree by expanding a node into many
452 | * [`unist-util-generated`](https://github.com/syntax-tree/unist-util-generated)
453 | — check if a node is generated
454 | * [`unist-util-index`](https://github.com/syntax-tree/unist-util-index)
455 | — index nodes by property or computed key
456 | * [`unist-util-inspect`](https://github.com/syntax-tree/unist-util-inspect)
457 | — node inspector
458 | * [`unist-util-is`](https://github.com/syntax-tree/unist-util-is)
459 | — check if a node passes a test
460 | * [`unist-util-map`](https://github.com/syntax-tree/unist-util-map)
461 | — create a new tree by mapping nodes
462 | * [`unist-util-modify-children`](https://github.com/syntax-tree/unist-util-modify-children)
463 | — modify direct children of a parent
464 | * [`unist-util-parents`](https://github.com/syntax-tree/unist-util-parents)
465 | — `parent` references on nodes
466 | * [`unist-util-position`](https://github.com/syntax-tree/unist-util-position)
467 | — get positional info of nodes
468 | * [`unist-util-reduce`](https://github.com/GenerousLabs/unist-util-reduce)
469 | — recursively reduce a tree
470 | * [`unist-util-remove`](https://github.com/syntax-tree/unist-util-remove)
471 | — remove nodes from trees
472 | * [`unist-util-remove-position`](https://github.com/syntax-tree/unist-util-remove-position)
473 | — remove positional info from trees
474 | * [`unist-util-replace-all-between`](https://github.com/unicorn-utterances/unist-util-replace-all-between)
475 | — replace nodes between two nodes or positions
476 | * [`unist-util-select`](https://github.com/syntax-tree/unist-util-select)
477 | — select nodes with CSS-like selectors
478 | * [`unist-util-size`](https://github.com/syntax-tree/unist-util-size)
479 | — calculate the number of nodes in a tree
480 | * [`unist-util-source`](https://github.com/syntax-tree/unist-util-source)
481 | — get the source of a value (node or position) in a file
482 | * [`unist-util-stringify-position`](https://github.com/syntax-tree/unist-util-stringify-position)
483 | — stringify a node, position, or point
484 | * [`unist-util-visit`](https://github.com/syntax-tree/unist-util-visit)
485 | — recursively walk over nodes
486 | * [`unist-util-visit-parents`](https://github.com/syntax-tree/unist-util-visit-parents)
487 | — recursively walk over nodes, with a stack of parents
488 | * [`unist-util-visit-children`](https://github.com/syntax-tree/unist-util-visit-children)
489 | — visit direct children of a parent
490 | * [`unist-util-visit-all-after`](https://github.com/mrzmmr/unist-util-visit-all-after)
491 | — visit nodes after another node
492 | * [`unist-builder`](https://github.com/syntax-tree/unist-builder)
493 | — helper for creating trees
494 |
495 | ## References
496 |
497 | * **JavaScript**:
498 | [ECMAScript Language Specification][javascript].
499 | Ecma International.
500 | * **JSON**:
501 | [The JavaScript Object Notation (JSON) Data Interchange Format][json],
502 | T. Bray.
503 | IETF.
504 | * **XML**:
505 | [Extensible Markup Language][xml],
506 | T. Bray, J. Paoli, C. Sperberg-McQueen, E. Maler, F. Yergeau.
507 | W3C.
508 | * **Web IDL**:
509 | [Web IDL][webidl],
510 | C. McCormack.
511 | W3C.
512 |
513 | ## Contribute
514 |
515 | See [`contributing.md`][contributing] in [`syntax-tree/.github`][health] for
516 | ways to get started.
517 | See [`support.md`][support] for ways to get help.
518 |
519 | A curated list of awesome syntax-tree, unist, hast, xast, mdast, and nlcst
520 | resources can be found in [awesome syntax-tree][awesome].
521 |
522 | This project has a [code of conduct][coc].
523 | By interacting with this repository, organization, or community you agree to
524 | abide by its terms.
525 |
526 | ## Acknowledgments
527 |
528 | The initial release of this project was authored by
529 | **[@wooorm](https://github.com/wooorm)**.
530 |
531 | Special thanks to **[@eush77](https://github.com/eush77)** for their work,
532 | ideas, and incredibly valuable feedback!
533 | Thanks to **[@anandthakker](https://github.com/anandthakker)**,
534 | **[@anko](https://github.com/anko)**,
535 | **[@arobase-che](https://github.com/arobase-che)**,
536 | **[@azu](https://github.com/azu)**,
537 | **[@BarryThePenguin](https://github.com/BarryThePenguin)**,
538 | **[@ben-eb](https://github.com/ben-eb)**,
539 | **[@blahah](https://github.com/blahah)**,
540 | **[@blakeembrey](https://github.com/blakeembrey)**,
541 | **[@brainkim](https://github.com/brainkim)**,
542 | **[@ChristianMurphy](https://github.com/ChristianMurphy)**,
543 | **[@davidtheclark](https://github.com/davidtheclark)**,
544 | **[@denysdovhan](https://github.com/denysdovhan)**,
545 | **[@derhuerst](https://github.com/derhuerst)**,
546 | **[@dozoisch](https://github.com/dozoisch)**,
547 | **[@fazouane-marouane](https://github.com/fazouane-marouane)**,
548 | **[@gibson042](https://github.com/gibson042)**,
549 | **[@hrajchert](https://github.com/hrajchert)**,
550 | **[@ikatyang](https://github.com/ikatyang)**,
551 | **[@inklesspen](https://github.com/inklesspen)**,
552 | **[@izumin5210](https://github.com/izumin5210)**,
553 | **[@jasonLaster](https://github.com/jasonLaster)**,
554 | **[@JDvorak](https://github.com/JDvorak)**,
555 | **[@jlevy](https://github.com/jlevy)**,
556 | **[@justjake](https://github.com/justjake)**,
557 | **[@kmck](https://github.com/kmck)**,
558 | **[@kt3k](https://github.com/kt3k)**,
559 | **[@KyleAMathews](https://github.com/KyleAMathews)**,
560 | **[@luca3m](https://github.com/luca3m)**,
561 | **[@mattdesl](https://github.com/mattdesl)**,
562 | **[@muraken720](https://github.com/muraken720)**,
563 | **[@mrzmmr](https://github.com/mrzmmr)**,
564 | **[@nwtn](https://github.com/nwtn)**,
565 | **[@rhysd](https://github.com/rhysd)**,
566 | **[@Rokt33r](https://github.com/Rokt33r)**,
567 | **[@Sarah-Seo](https://github.com/Sarah-Seo)**,
568 | **[@sethvincent](https://github.com/sethvincent)**,
569 | **[@shawnbot](https://github.com/shawnbot)**,
570 | **[@simov](https://github.com/simov)**,
571 | **[@staltz](https://github.com/staltz)**,
572 | **[@TitanSnow](https://github.com/TitanSnow)**,
573 | **[@tmcw](https://github.com/tmcw)**,
574 | and
575 | **[@vhf](https://github.com/vhf)**,
576 | for contributing to unist and related projects!
577 |
578 | ## License
579 |
580 | [CC-BY-4.0][license] © [Titus Wormer][author]
581 |
582 |
583 |
584 | [health]: https://github.com/syntax-tree/.github
585 |
586 | [contributing]: https://github.com/syntax-tree/.github/blob/main/contributing.md
587 |
588 | [support]: https://github.com/syntax-tree/.github/blob/main/support.md
589 |
590 | [coc]: https://github.com/syntax-tree/.github/blob/main/code-of-conduct.md
591 |
592 | [awesome]: https://github.com/syntax-tree/awesome-syntax-tree
593 |
594 | [logo]: https://raw.githubusercontent.com/syntax-tree/unist/367da2e/logo.svg?sanitize=true
595 |
596 | [releases]: https://github.com/syntax-tree/unist/releases
597 |
598 | [license]: https://creativecommons.org/licenses/by/4.0/
599 |
600 | [author]: https://wooorm.com
601 |
602 | [release]: https://github.com/syntax-tree/unist/releases/tag/3.0.0
603 |
604 | [abstract-vs-concrete-trees]: https://eli.thegreenplace.net/2009/02/16/abstract-vs-concrete-syntax-trees/
605 |
606 | [dfn-node]: #node
607 |
608 | [dfn-position]: #position
609 |
610 | [dfn-point]: #point
611 |
612 | [dfn-data]: #data
613 |
614 | [term-tree]: #tree
615 |
616 | [term-preorder]: #preorder
617 |
618 | [term-postorder]: #postorder
619 |
620 | [term-child]: #child
621 |
622 | [term-parent]: #parent-1
623 |
624 | [term-index]: #index
625 |
626 | [term-sibling]: #sibling
627 |
628 | [term-descendant]: #descendant
629 |
630 | [term-head]: #head
631 |
632 | [term-tail]: #tail
633 |
634 | [term-generated]: #generated
635 |
636 | [term-type]: #type
637 |
638 | [term-positional-info]: #positional-information
639 |
640 | [term-file]: #file
641 |
642 | [traversal]: #tree-traversal
643 |
644 | [traversal-depth]: #depth-first-traversal
645 |
646 | [list-of-utilities]: #list-of-utilities
647 |
648 | [webidl]: https://webidl.spec.whatwg.org
649 |
650 | [json]: https://datatracker.ietf.org/doc/html/rfc7159
651 |
652 | [xml]: https://www.w3.org/TR/xml/
653 |
654 | [javascript]: https://262.ecma-international.org/9.0/
655 |
656 | [hast]: https://github.com/syntax-tree/hast
657 |
658 | [xast]: https://github.com/syntax-tree/xast
659 |
660 | [nlcst]: https://github.com/syntax-tree/nlcst
661 |
662 | [mdast]: https://github.com/syntax-tree/mdast
663 |
664 | [unified]: https://github.com/unifiedjs/unified
665 |
666 | [remark]: https://github.com/remarkjs/remark
667 |
668 | [rehype]: https://github.com/rehypejs/rehype
669 |
670 | [retext]: https://github.com/retextjs/retext
671 |
672 | [vfile]: https://github.com/vfile/vfile
673 |
--------------------------------------------------------------------------------