├── .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 | 2 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 12 | 13 | 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 | --------------------------------------------------------------------------------