├── .github └── workflows │ ├── bb.yml │ └── main.yml ├── .gitignore ├── .npmrc ├── logo.svg ├── package.json └── readme.md /.github/workflows/bb.yml: -------------------------------------------------------------------------------- 1 | jobs: 2 | main: 3 | runs-on: ubuntu-latest 4 | steps: 5 | - uses: unifiedjs/beep-boop-beta@main 6 | with: 7 | repo-token: ${{secrets.GITHUB_TOKEN}} 8 | name: bb 9 | on: 10 | issues: 11 | types: [closed, edited, labeled, opened, reopened, unlabeled] 12 | pull_request_target: 13 | types: [closed, edited, labeled, opened, reopened, unlabeled] 14 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | jobs: 2 | main: 3 | runs-on: ubuntu-latest 4 | steps: 5 | - uses: actions/checkout@v4 6 | - uses: actions/setup-node@v4 7 | with: 8 | node-version: node 9 | - run: npm install 10 | - run: npm test 11 | name: main 12 | on: 13 | - pull_request 14 | - push 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.log 3 | node_modules/ 4 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | ignore-scripts=true 2 | package-lock=false 3 | -------------------------------------------------------------------------------- /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/hast/issues", 4 | "contributors": [ 5 | "Titus Wormer (wooorm.com)" 6 | ], 7 | "description": "hypertext abstract syntax tree", 8 | "devDependencies": { 9 | "remark-cli": "^12.0.0", 10 | "remark-preset-wooorm": "^11.0.0" 11 | }, 12 | "keywords": [], 13 | "license": "MIT", 14 | "private": true, 15 | "repository": "syntax-tree/hast", 16 | "scripts": { 17 | "format": "remark --frail --output --quiet -- .", 18 | "test": "npm run format" 19 | }, 20 | "remarkConfig": { 21 | "plugins": [ 22 | "remark-preset-wooorm" 23 | ] 24 | }, 25 | "version": "0.0.0" 26 | } 27 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # ![hast][github-hast-logo] 4 | 5 | **H**ypertext **A**bstract **S**yntax **T**ree format. 6 | 7 | *** 8 | 9 | **hast** is a specification for representing [HTML][whatwg-html] 10 | (and embedded [SVG][w3c-svg] or [MathML][w3c-mathml]) 11 | as an abstract syntax tree. 12 | It implements the **[unist][github-unist]** spec. 13 | 14 | This document may not be released. 15 | See [releases][github-hast-releases] for released documents. 16 | The latest released version is [`2.4.0`][github-hast-release]. 17 | 18 | ## Contents 19 | 20 | * [Introduction](#introduction) 21 | * [Where this specification fits](#where-this-specification-fits) 22 | * [Virtual DOM](#virtual-dom) 23 | * [Types](#types) 24 | * [Nodes (abstract)](#nodes-abstract) 25 | * [`Literal`](#literal) 26 | * [`Parent`](#parent) 27 | * [Nodes](#nodes) 28 | * [`Comment`](#comment) 29 | * [`Doctype`](#doctype) 30 | * [`Element`](#element) 31 | * [`Root`](#root) 32 | * [`Text`](#text) 33 | * [Other types](#other-types) 34 | * [`Properties`](#properties) 35 | * [`PropertyName`](#propertyname) 36 | * [`PropertyValue`](#propertyvalue) 37 | * [Glossary](#glossary) 38 | * [List of utilities](#list-of-utilities) 39 | * [Related HTML utilities](#related-html-utilities) 40 | * [References](#references) 41 | * [Security](#security) 42 | * [Related](#related) 43 | * [Contribute](#contribute) 44 | * [Acknowledgments](#acknowledgments) 45 | * [License](#license) 46 | 47 | ## Introduction 48 | 49 | This document defines a format for representing hypertext as an 50 | [abstract syntax tree][github-unist-syntax-tree]. 51 | Development of hast started in April 2016 for [rehype][github-rehype]. 52 | This specification is written in a [Web IDL][whatwg-webidl]-like grammar. 53 | 54 | ### Where this specification fits 55 | 56 | hast extends [unist][github-unist], 57 | a format for syntax trees, 58 | to benefit from its [ecosystem of utilities][github-unist-utilities]. 59 | 60 | hast relates to [JavaScript][ecma-javascript] in that it has an 61 | [ecosystem of utilities][section-utilities] 62 | for working with compliant syntax trees in JavaScript. 63 | However, 64 | hast is not limited to JavaScript and can be used in other programming 65 | languages. 66 | 67 | hast relates to the [unified][github-unified] and [rehype][github-rehype] 68 | projects in that hast syntax trees are used throughout their ecosystems. 69 | 70 | ### Virtual DOM 71 | 72 | The reason for introducing a new “virtual” DOM is primarily: 73 | 74 | * The [DOM][whatwg-dom] is very heavy to implement outside of the browser, 75 | a lean and stripped down virtual DOM can be used everywhere 76 | * Most virtual DOMs do not focus on ease of use in transformations 77 | * Other virtual DOMs cannot represent the syntax of HTML in its entirety 78 | (think comments and document types) 79 | * Neither the DOM nor virtual DOMs focus on positional information 80 | 81 | ## Types 82 | 83 | If you are using TypeScript, 84 | you can use the hast types by installing them with npm: 85 | 86 | ```sh 87 | npm install @types/hast 88 | ``` 89 | 90 | ## Nodes (abstract) 91 | 92 | ### `Literal` 93 | 94 | ```idl 95 | interface Literal <: UnistLiteral { 96 | value: string 97 | } 98 | ``` 99 | 100 | **Literal** (**[UnistLiteral][dfn-unist-literal]**) represents a node in hast 101 | containing a value. 102 | 103 | ### `Parent` 104 | 105 | ```idl 106 | interface Parent <: UnistParent { 107 | children: [Comment | Doctype | Element | Text] 108 | } 109 | ``` 110 | 111 | **Parent** (**[UnistParent][dfn-unist-parent]**) represents a node in hast 112 | containing other nodes (said to be *[children][term-child]*). 113 | 114 | Its content is limited to only other hast content. 115 | 116 | ## Nodes 117 | 118 | ### `Comment` 119 | 120 | ```idl 121 | interface Comment <: Literal { 122 | type: 'comment' 123 | } 124 | ``` 125 | 126 | **Comment** (**[Literal][dfn-literal]**) represents a [Comment][concept-comment] 127 | ([\[DOM\]][whatwg-dom]). 128 | 129 | For example, 130 | the following HTML: 131 | 132 | ```html 133 | 134 | ``` 135 | 136 | Yields: 137 | 138 | ```js 139 | {type: 'comment', value: 'Charlie'} 140 | ``` 141 | 142 | ### `Doctype` 143 | 144 | ```idl 145 | interface Doctype <: Node { 146 | type: 'doctype' 147 | } 148 | ``` 149 | 150 | **Doctype** (**[Node][dfn-unist-node]**) represents a 151 | [DocumentType][concept-documenttype] ([\[DOM\]][whatwg-dom]). 152 | 153 | For example, 154 | the following HTML: 155 | 156 | ```html 157 | 158 | ``` 159 | 160 | Yields: 161 | 162 | ```js 163 | {type: 'doctype'} 164 | ``` 165 | 166 | ### `Element` 167 | 168 | ```idl 169 | interface Element <: Parent { 170 | type: 'element' 171 | tagName: string 172 | properties: Properties 173 | content: Root? 174 | children: [Comment | Element | Text] 175 | } 176 | ``` 177 | 178 | **Element** (**[Parent][dfn-parent]**) represents an [Element][concept-element] 179 | ([\[DOM\]][whatwg-dom]). 180 | 181 | A `tagName` field must be present. 182 | It represents the element’s [local name][concept-local-name] 183 | ([\[DOM\]][whatwg-dom]). 184 | 185 | The `properties` field represents information associated with the element. 186 | The value of the `properties` field implements the 187 | **[Properties][dfn-properties]** interface. 188 | 189 | If the `tagName` field is `'template'`, 190 | a `content` field can be present. 191 | The value of the `content` field implements the **[Root][dfn-root]** interface. 192 | 193 | If the `tagName` field is `'template'`, 194 | the element must be a *[leaf][term-leaf]*. 195 | 196 | If the `tagName` field is `'noscript'`, 197 | its *[children][term-child]* should be represented as if 198 | *[scripting is disabled][concept-scripting]* ([\[HTML\]][whatwg-html]). 199 | 200 | For example, 201 | the following HTML: 202 | 203 | ```html 204 | 205 | ``` 206 | 207 | Yields: 208 | 209 | ```js 210 | { 211 | type: 'element', 212 | tagName: 'a', 213 | properties: { 214 | href: 'https://alpha.com', 215 | className: ['bravo'], 216 | download: true 217 | }, 218 | children: [] 219 | } 220 | ``` 221 | 222 | ### `Root` 223 | 224 | ```idl 225 | interface Root <: Parent { 226 | type: 'root' 227 | } 228 | ``` 229 | 230 | **Root** (**[Parent][dfn-parent]**) represents a document. 231 | 232 | **Root** can be used as the *[root][term-root]* of a *[tree][term-tree]*, 233 | or as a value of the `content` field on a `'template'` 234 | **[Element][dfn-element]**, 235 | never as a *[child][term-child]*. 236 | 237 | ### `Text` 238 | 239 | ```idl 240 | interface Text <: Literal { 241 | type: 'text' 242 | } 243 | ``` 244 | 245 | **Text** (**[Literal][dfn-literal]**) represents a [Text][concept-text] 246 | ([\[DOM\]][whatwg-dom]). 247 | 248 | For example, 249 | the following HTML: 250 | 251 | ```html 252 | Foxtrot 253 | ``` 254 | 255 | Yields: 256 | 257 | ```js 258 | { 259 | type: 'element', 260 | tagName: 'span', 261 | properties: {}, 262 | children: [{type: 'text', value: 'Foxtrot'}] 263 | } 264 | ``` 265 | 266 | ## Other types 267 | 268 | ### `Properties` 269 | 270 | ```idl 271 | interface Properties {} 272 | ``` 273 | 274 | **Properties** represents information associated with an element. 275 | 276 | Every field must be a **[PropertyName][dfn-property-name]** and every value a 277 | **[PropertyValue][dfn-property-value]**. 278 | 279 | ### `PropertyName` 280 | 281 | ```idl 282 | typedef string PropertyName 283 | ``` 284 | 285 | Property names are keys on **[Properties][dfn-properties]** objects and reflect 286 | HTML, 287 | SVG, 288 | ARIA, 289 | XML, 290 | XMLNS, 291 | or XLink attribute names. 292 | Often, 293 | they have the same value as the corresponding attribute 294 | (for example, 295 | `id` is a property name reflecting the `id` attribute name), 296 | but there are some notable differences. 297 | 298 | > These rules aren’t simple. 299 | > Use [`hastscript`][github-hastscript] 300 | > (or [`property-information`][github-property-information] directly) 301 | > to help. 302 | 303 | The following rules are used to transform HTML attribute names to property 304 | names. 305 | These rules are based on 306 | [how ARIA is reflected in the DOM][concept-aria-reflection] 307 | ([\[ARIA\]][w3c-aria]), 308 | and differs from how some 309 | (older) 310 | HTML attributes are reflected in the DOM. 311 | 312 | 1. any name referencing a combinations of multiple words 313 | (such as “stroke miter limit”) becomes a camelcased property name 314 | capitalizing each word boundary; 315 | this includes combinations that are sometimes written as several words; 316 | for example, 317 | `stroke-miterlimit` becomes `strokeMiterLimit`, 318 | `autocorrect` becomes `autoCorrect`, 319 | and `allowfullscreen` becomes `allowFullScreen` 320 | 2. any name that can be hyphenated, 321 | becomes a camelcased property name capitalizing each boundary; 322 | for example, 323 | “read-only” becomes `readOnly` 324 | 3. compound words that are not used with spaces or hyphens are treated as a 325 | normal word and the previous rules apply; 326 | for example, 327 | “placeholder”, 328 | “strikethrough”, 329 | and “playback” stay the same 330 | 4. acronyms in names are treated as a normal word and the previous rules apply; 331 | for example, 332 | `itemid` become `itemId` and `bgcolor` becomes `bgColor` 333 | 334 | ###### Exceptions 335 | 336 | Some jargon is seen as one word even though it may not be seen as such by 337 | dictionaries. 338 | For example, 339 | `nohref` becomes `noHref`, 340 | `playsinline` becomes `playsInline`, 341 | and `accept-charset` becomes `acceptCharset`. 342 | 343 | The HTML attributes `class` and `for` respectively become `className` and 344 | `htmlFor` in alignment with the DOM. 345 | No other attributes gain different names as properties, 346 | other than a change in casing. 347 | 348 | ###### Notes 349 | 350 | [`property-information`][github-property-information] lists all property names. 351 | 352 | The property name rules differ from how HTML is reflected in the DOM for the 353 | following attributes: 354 | 355 |
356 | View list of differences 357 | 358 | * `charoff` becomes `charOff` (not `chOff`) 359 | * `char` stays `char` (does not become `ch`) 360 | * `rel` stays `rel` (does not become `relList`) 361 | * `checked` stays `checked` (does not become `defaultChecked`) 362 | * `muted` stays `muted` (does not become `defaultMuted`) 363 | * `value` stays `value` (does not become `defaultValue`) 364 | * `selected` stays `selected` (does not become `defaultSelected`) 365 | * `allowfullscreen` becomes `allowFullScreen` (not `allowFullscreen`) 366 | * `hreflang` becomes `hrefLang`, not `hreflang` 367 | * `autoplay` becomes `autoPlay`, not `autoplay` 368 | * `autocomplete` becomes `autoComplete` (not `autocomplete`) 369 | * `autofocus` becomes `autoFocus`, not `autofocus` 370 | * `enctype` becomes `encType`, not `enctype` 371 | * `formenctype` becomes `formEncType` (not `formEnctype`) 372 | * `vspace` becomes `vSpace`, not `vspace` 373 | * `hspace` becomes `hSpace`, not `hspace` 374 | * `lowsrc` becomes `lowSrc`, not `lowsrc` 375 | 376 |
377 | 378 | ### `PropertyValue` 379 | 380 | ```idl 381 | typedef any PropertyValue 382 | ``` 383 | 384 | Property values should reflect the data type determined by their property name. 385 | For example, 386 | the HTML `` has a `hidden` attribute, 387 | which is reflected as a `hidden` property name set to the property value `true`, 388 | and ``, 389 | which has a `minlength` attribute, 390 | is reflected as a `minLength` property name set to the property value `5`. 391 | 392 | > In [JSON][ietf-json], 393 | > the value `null` must be treated as if the property was not included. 394 | > In [JavaScript][ecma-javascript], 395 | > both `null` and `undefined` must be similarly ignored. 396 | 397 | The DOM has strict rules on how it coerces HTML to expected values, 398 | whereas hast is more lenient in how it reflects the source. 399 | Where the DOM treats `` as having a value of `true` and 400 | `` as having a value of `0`, 401 | these should be reflected as `'no'` and `'yes'`, 402 | respectively, 403 | in hast. 404 | 405 | > The reason for this is to allow plugins and utilities to inspect these 406 | > non-standard values. 407 | 408 | The DOM also specifies comma separated and space separated lists attribute 409 | values. 410 | In hast, these should be treated as ordered lists. 411 | For example, 412 | `
` is represented as `['alpha', 'bravo']`. 413 | 414 | > There’s no special format for the property value of the `style` property name. 415 | 416 | ## Glossary 417 | 418 | See [§ *Glossary* in `syntax-tree/unist`][github-unist-glossary]. 419 | 420 | ## List of utilities 421 | 422 | See [§ *List of utilities* in `syntax-tree/unist`][github-unist-utilities] 423 | for more utilities. 424 | 425 | 426 | 427 | 432 | 433 | * [`hastscript`](https://github.com/syntax-tree/hastscript) 434 | — create trees 435 | * [`hast-util-assert`](https://github.com/syntax-tree/hast-util-assert) 436 | — assert nodes 437 | * [`hast-util-class-list`](https://github.com/shredsnews/hast-util-class-list) 438 | — simulate the browser’s `classList` API for hast nodes 439 | * [`hast-util-classnames`](https://github.com/syntax-tree/hast-util-classnames) 440 | — merge class names together 441 | * [`hast-util-embedded`](https://github.com/syntax-tree/hast-util-embedded) 442 | — check if a node is an embedded element 443 | * [`hast-util-excerpt`](https://github.com/syntax-tree/hast-util-excerpt) 444 | — truncate the tree to a comment 445 | * [`hast-util-find-and-replace`](https://github.com/syntax-tree/hast-util-find-and-replace) 446 | — find and replace text in a tree 447 | * [`hast-util-format`](https://github.com/syntax-tree/hast-util-format) 448 | — format whitespace 449 | * [`hast-util-from-dom`](https://github.com/syntax-tree/hast-util-from-dom) 450 | — transform from DOM tree 451 | * [`hast-util-from-html`](https://github.com/syntax-tree/hast-util-from-html) 452 | — parse from HTML 453 | * [`hast-util-from-parse5`](https://github.com/syntax-tree/hast-util-from-parse5) 454 | — transform from Parse5’s AST 455 | * [`hast-util-from-selector`](https://github.com/syntax-tree/hast-util-from-selector) 456 | — parse CSS selectors to nodes 457 | * [`hast-util-from-string`](https://github.com/rehypejs/rehype-minify/tree/main/packages/hast-util-from-string) 458 | — set the plain-text value of a node (`textContent`) 459 | * [`hast-util-from-text`](https://github.com/syntax-tree/hast-util-from-text) 460 | — set the plain-text value of a node (`innerText`) 461 | * [`hast-util-from-webparser`](https://github.com/Prettyhtml/prettyhtml/tree/HEAD/packages/hast-util-from-webparser) 462 | — transform Webparser’s AST to hast 463 | * [`hast-util-has-property`](https://github.com/syntax-tree/hast-util-has-property) 464 | — check if an element has a certain property 465 | * [`hast-util-heading`](https://github.com/syntax-tree/hast-util-heading) 466 | — check if a node is heading content 467 | * [`hast-util-heading-rank`](https://github.com/syntax-tree/hast-util-heading-rank) 468 | — get the rank (also known as depth or level) of headings 469 | * [`hast-util-interactive`](https://github.com/syntax-tree/hast-util-interactive) 470 | — check if a node is interactive 471 | * [`hast-util-is-body-ok-link`](https://github.com/rehypejs/rehype-minify/tree/main/packages/hast-util-is-body-ok-link) 472 | — check if a `link` element is “Body OK” 473 | * [`hast-util-is-conditional-comment`](https://github.com/rehypejs/rehype-minify/tree/HEAD/packages/hast-util-is-conditional-comment) 474 | — check if `node` is a conditional comment 475 | * [`hast-util-is-css-link`](https://github.com/rehypejs/rehype-minify/tree/main/packages/hast-util-is-css-link) 476 | — check if `node` is a CSS `link` 477 | * [`hast-util-is-css-style`](https://github.com/rehypejs/rehype-minify/tree/main/packages/hast-util-is-css-style) 478 | — check if `node` is a CSS `style` 479 | * [`hast-util-is-element`](https://github.com/syntax-tree/hast-util-is-element) 480 | — check if `node` is a (certain) element 481 | * [`hast-util-is-event-handler`](https://github.com/rehypejs/rehype-minify/tree/main/packages/hast-util-is-event-handler) 482 | — check if `property` is an event handler 483 | * [`hast-util-is-javascript`](https://github.com/rehypejs/rehype-minify/tree/main/packages/hast-util-is-javascript) 484 | — check if `node` is a JavaScript `script` 485 | * [`hast-util-labelable`](https://github.com/syntax-tree/hast-util-labelable) 486 | — check if `node` is labelable 487 | * [`hast-util-minify-whitespace`](https://github.com/rehypejs/rehype-minify/tree/main/packages/hast-util-minify-whitespace) 488 | — minify whitespace between elements 489 | * [`hast-util-parse-selector`](https://github.com/syntax-tree/hast-util-parse-selector) 490 | — create an element from a simple CSS selector 491 | * [`hast-util-phrasing`](https://github.com/syntax-tree/hast-util-phrasing) 492 | — check if a node is phrasing content 493 | * [`hast-util-raw`](https://github.com/syntax-tree/hast-util-raw) 494 | — parse a tree again 495 | * [`hast-util-reading-time`](https://github.com/syntax-tree/hast-util-reading-time) 496 | — estimate the reading time 497 | * [`hast-util-sanitize`](https://github.com/syntax-tree/hast-util-sanitize) 498 | — sanitize nodes 499 | * [`hast-util-script-supporting`](https://github.com/syntax-tree/hast-util-script-supporting) 500 | — check if `node` is script-supporting content 501 | * [`hast-util-select`](https://github.com/syntax-tree/hast-util-select) 502 | — `querySelector`, `querySelectorAll`, and `matches` 503 | * [`hast-util-sectioning`](https://github.com/syntax-tree/hast-util-sectioning) 504 | — check if `node` is sectioning content 505 | * [`hast-util-shift-heading`](https://github.com/syntax-tree/hast-util-shift-heading) 506 | — change heading rank (depth, level) 507 | * [`hast-util-table-cell-style`](https://github.com/mapbox/hast-util-table-cell-style) 508 | — transform deprecated styling attributes on table cells to inline styles 509 | * [`hast-util-to-dom`](https://github.com/syntax-tree/hast-util-to-dom) 510 | — transform to a DOM tree 511 | * [`hast-util-to-estree`](https://github.com/syntax-tree/hast-util-to-estree) 512 | — transform to estree (JavaScript AST) JSX 513 | * [`hast-util-to-html`](https://github.com/syntax-tree/hast-util-to-html) 514 | — serialize as HTML 515 | * [`hast-util-to-jsx`](https://github.com/mapbox/jsxtreme-markdown/tree/HEAD/packages/hast-util-to-jsx) 516 | — transform hast to JSX 517 | * [`hast-util-to-jsx-runtime`](https://github.com/syntax-tree/hast-util-to-jsx-runtime) 518 | — transform to preact, react, solid, svelte, vue, etc 519 | * [`hast-util-to-mdast`](https://github.com/syntax-tree/hast-util-to-mdast) 520 | — transform to mdast (markdown) 521 | * [`hast-util-to-nlcst`](https://github.com/syntax-tree/hast-util-to-nlcst) 522 | — transform to nlcst (natural language) 523 | * [`hast-util-to-parse5`](https://github.com/syntax-tree/hast-util-to-parse5) 524 | — transform to Parse5’s AST 525 | * [`hast-util-to-portable-text`](https://github.com/rexxars/hast-util-to-portable-text) 526 | — transform to portable text 527 | * [`hast-util-to-string`](https://github.com/rehypejs/rehype-minify/tree/HEAD/packages/hast-util-to-string) 528 | — get the plain-text value of a node (`textContent`) 529 | * [`hast-util-to-text`](https://github.com/syntax-tree/hast-util-to-text) 530 | — get the plain-text value of a node (`innerText`) 531 | * [`hast-util-to-xast`](https://github.com/syntax-tree/hast-util-to-xast) 532 | — transform to xast (xml) 533 | * [`hast-util-transparent`](https://github.com/syntax-tree/hast-util-transparent) 534 | — check if `node` is transparent content 535 | * [`hast-util-truncate`](https://github.com/syntax-tree/hast-util-truncate) 536 | — truncate the tree to a certain number of characters 537 | * [`hast-util-whitespace`](https://github.com/syntax-tree/hast-util-whitespace) 538 | — check if `node` is inter-element whitespace 539 | 540 | ## Related HTML utilities 541 | 542 | * [`a-rel`](https://github.com/wooorm/a-rel) 543 | — List of link types for `rel` on `a` / `area` 544 | * [`aria-attributes`](https://github.com/wooorm/aria-attributes) 545 | — List of ARIA attributes 546 | * [`collapse-white-space`](https://github.com/wooorm/collapse-white-space) 547 | — Replace multiple white-space characters with a single space 548 | * [`comma-separated-tokens`](https://github.com/wooorm/comma-separated-tokens) 549 | — Parse/stringify comma separated tokens 550 | * [`html-tag-names`](https://github.com/wooorm/html-tag-names) 551 | — List of HTML tag names 552 | * [`html-dangerous-encodings`](https://github.com/wooorm/html-dangerous-encodings) 553 | — List of dangerous HTML character encoding labels 554 | * [`html-encodings`](https://github.com/wooorm/html-encodings) 555 | — List of HTML character encoding labels 556 | * [`html-element-attributes`](https://github.com/wooorm/html-element-attributes) 557 | — Map of HTML attributes 558 | * [`html-event-attributes`](https://github.com/wooorm/html-event-attributes) 559 | — List of HTML event handler content attributes 560 | * [`html-void-elements`](https://github.com/wooorm/html-void-elements) 561 | — List of void HTML tag names 562 | * [`link-rel`](https://github.com/wooorm/link-rel) 563 | — List of link types for `rel` on `link` 564 | * [`mathml-tag-names`](https://github.com/wooorm/mathml-tag-names) 565 | — List of MathML tag names 566 | * [`meta-name`](https://github.com/wooorm/meta-name) 567 | — List of values for `name` on `meta` 568 | * [`property-information`](https://github.com/wooorm/property-information) 569 | — Information on HTML properties 570 | * [`space-separated-tokens`](https://github.com/wooorm/space-separated-tokens) 571 | — Parse/stringify space separated tokens 572 | * [`svg-tag-names`](https://github.com/wooorm/svg-tag-names) 573 | — List of SVG tag names 574 | * [`svg-element-attributes`](https://github.com/wooorm/svg-element-attributes) 575 | — Map of SVG attributes 576 | * [`svg-event-attributes`](https://github.com/wooorm/svg-event-attributes) 577 | — List of SVG event handler content attributes 578 | * [`web-namespaces`](https://github.com/wooorm/web-namespaces) 579 | — Map of web namespaces 580 | 581 | 582 | 583 | ## References 584 | 585 | * **unist**: 586 | [Universal Syntax Tree][github-unist]. 587 | T. Wormer; et al. 588 | * **JavaScript**: 589 | [ECMAScript Language Specification][ecma-javascript]. 590 | Ecma International. 591 | * **HTML**: 592 | [HTML Standard][whatwg-html], 593 | A. van Kesteren; et al. 594 | WHATWG. 595 | * **DOM**: 596 | [DOM Standard][whatwg-dom], 597 | A. van Kesteren, 598 | A. Gregor, 599 | Ms2ger. 600 | WHATWG. 601 | * **SVG**: 602 | [Scalable Vector Graphics (SVG)][w3c-svg], 603 | N. Andronikos, 604 | R. Atanassov, 605 | T. Bah, 606 | B. Birtles, 607 | B. Brinza, 608 | C. Concolato, 609 | E. Dahlström, 610 | C. Lilley, 611 | C. McCormack, 612 | D. Schepers, 613 | R. Schwerdtfeger, 614 | D. Storey, 615 | S. Takagi, 616 | J. Watt. 617 | W3C. 618 | * **MathML**: 619 | [Mathematical Markup Language Standard][w3c-mathml], 620 | D. Carlisle, 621 | P. Ion, 622 | R. Miner. 623 | W3C. 624 | * **ARIA**: 625 | [Accessible Rich Internet Applications (WAI-ARIA)][w3c-aria], 626 | J. Diggs, 627 | J. Craig, 628 | S. McCarron, 629 | M. Cooper. 630 | W3C. 631 | * **JSON** 632 | [The JavaScript Object Notation (JSON) Data Interchange Format][ietf-json], 633 | T. Bray. 634 | IETF. 635 | * **Web IDL**: 636 | [Web IDL][whatwg-webidl], 637 | C. McCormack. 638 | W3C. 639 | 640 | ## Security 641 | 642 | As hast represents HTML, 643 | and improper use of HTML can open you up to a 644 | [cross-site scripting (XSS)][wikipedia-xss] attack, 645 | improper use of hast is also unsafe. 646 | Always be careful with user input and use 647 | [`hast-util-santize`][github-hast-util-sanitize] to make the hast tree safe. 648 | 649 | ## Related 650 | 651 | * [mdast](https://github.com/syntax-tree/mdast) 652 | — Markdown Abstract Syntax Tree format 653 | * [nlcst](https://github.com/syntax-tree/nlcst) 654 | — Natural Language Concrete Syntax Tree format 655 | * [xast](https://github.com/syntax-tree/xast) 656 | — Extensible Abstract Syntax Tree 657 | 658 | ## Contribute 659 | 660 | See [`contributing.md`][health-contributing] in 661 | [`syntax-tree/.github`][health] for ways to get started. 662 | See [`support.md`][health-support] for ways to get help. 663 | 664 | A curated list of awesome syntax-tree, 665 | unist, 666 | mdast, 667 | hast, 668 | xast, 669 | and nlcst resources can be found in 670 | [awesome syntax-tree][github-syntax-tree-awesome]. 671 | 672 | This project has a [code of conduct][health-coc]. 673 | By interacting with this repository, 674 | organization, 675 | or community you agree to abide by its terms. 676 | 677 | ## Acknowledgments 678 | 679 | The initial release of this project was authored by 680 | [**@wooorm**](https://github.com/wooorm). 681 | 682 | Special thanks to [**@eush77**](https://github.com/eush77) for their work, 683 | ideas, 684 | and incredibly valuable feedback! 685 | 686 | Thanks to 687 | [**@andrewburgess**](https://github.com/andrewburgess), 688 | [**@arobase-che**](https://github.com/arobase-che), 689 | [**@arystan-sw**](https://github.com/arystan-sw), 690 | [**@BarryThePenguin**](https://github.com/BarryThePenguin), 691 | [**@brechtcs**](https://github.com/brechtcs), 692 | [**@ChristianMurphy**](https://github.com/ChristianMurphy), 693 | [**@ChristopherBiscardi**](https://github.com/ChristopherBiscardi), 694 | [**@craftzdog**](https://github.com/craftzdog), 695 | [**@cupojoe**](https://github.com/cupojoe), 696 | [**@davidtheclark**](https://github.com/davidtheclark), 697 | [**@derhuerst**](https://github.com/derhuerst), 698 | [**@detj**](https://github.com/detj), 699 | [**@DxCx**](https://github.com/DxCx), 700 | [**@erquhart**](https://github.com/erquhart), 701 | [**@flurmbo**](https://github.com/flurmbo), 702 | [**@Hamms**](https://github.com/Hamms), 703 | [**@Hypercubed**](https://github.com/Hypercubed), 704 | [**@inklesspen**](https://github.com/inklesspen), 705 | [**@jeffal**](https://github.com/jeffal), 706 | [**@jlevy**](https://github.com/jlevy), 707 | [**@Justineo**](https://github.com/Justineo), 708 | [**@lfittl**](https://github.com/lfittl), 709 | [**@kgryte**](https://github.com/kgryte), 710 | [**@kmck**](https://github.com/kmck), 711 | [**@kthjm**](https://github.com/kthjm), 712 | [**@KyleAMathews**](https://github.com/KyleAMathews), 713 | [**@macklinu**](https://github.com/macklinu), 714 | [**@medfreeman**](https://github.com/medfreeman), 715 | [**@Murderlon**](https://github.com/Murderlon), 716 | [**@nevik**](https://github.com/nevik), 717 | [**@nokome**](https://github.com/nokome), 718 | [**@phiresky**](https://github.com/phiresky), 719 | [**@revolunet**](https://github.com/revolunet), 720 | [**@rhysd**](https://github.com/rhysd), 721 | [**@Rokt33r**](https://github.com/Rokt33r), 722 | [**@rubys**](https://github.com/rubys), 723 | [**@s1n**](https://github.com/s1n), 724 | [**@Sarah-Seo**](https://github.com/Sarah-Seo), 725 | [**@sethvincent**](https://github.com/sethvincent), 726 | [**@simov**](https://github.com/simov), 727 | [**@StarpTech**](https://github.com/StarpTech), 728 | [**@stefanprobst**](https://github.com/stefanprobst), 729 | [**@stuff**](https://github.com/stuff), 730 | [**@subhero24**](https://github.com/subhero24), 731 | [**@tripodsan**](https://github.com/tripodsan), 732 | [**@tunnckoCore**](https://github.com/tunnckoCore), 733 | [**@vhf**](https://github.com/vhf), 734 | [**@voischev**](https://github.com/voischev), and 735 | [**@zjaml**](https://github.com/zjaml), 736 | for contributing to hast and related projects! 737 | 738 | ## License 739 | 740 | [CC-BY-4.0][creativecommons-by-4] © [Titus Wormer][wooorm] 741 | 742 | 743 | 744 | [concept-aria-reflection]: https://w3c.github.io/aria/#idl_attr_disambiguation 745 | 746 | [concept-comment]: https://dom.spec.whatwg.org/#interface-comment 747 | 748 | [concept-documenttype]: https://dom.spec.whatwg.org/#documenttype 749 | 750 | [concept-element]: https://dom.spec.whatwg.org/#interface-element 751 | 752 | [concept-local-name]: https://dom.spec.whatwg.org/#concept-element-local-name 753 | 754 | [concept-scripting]: https://html.spec.whatwg.org/multipage/webappapis.html#enabling-and-disabling-scripting 755 | 756 | [concept-text]: https://dom.spec.whatwg.org/#interface-text 757 | 758 | [creativecommons-by-4]: https://creativecommons.org/licenses/by/4.0/ 759 | 760 | [dfn-element]: #element 761 | 762 | [dfn-literal]: #literal 763 | 764 | [dfn-parent]: #parent 765 | 766 | [dfn-properties]: #properties 767 | 768 | [dfn-property-name]: #propertyname 769 | 770 | [dfn-property-value]: #propertyvalue 771 | 772 | [dfn-root]: #root 773 | 774 | [dfn-unist-literal]: https://github.com/syntax-tree/unist#literal 775 | 776 | [dfn-unist-node]: https://github.com/syntax-tree/unist#node 777 | 778 | [dfn-unist-parent]: https://github.com/syntax-tree/unist#parent 779 | 780 | [ecma-javascript]: https://www.ecma-international.org/ecma-262/9.0/index.html 781 | 782 | [github-hast-logo]: https://raw.githubusercontent.com/syntax-tree/hast/6a36689/logo.svg?sanitize=true 783 | 784 | [github-hast-release]: https://github.com/syntax-tree/hast/releases/tag/2.4.0 785 | 786 | [github-hast-releases]: https://github.com/syntax-tree/hast/releases 787 | 788 | [github-hast-util-sanitize]: https://github.com/syntax-tree/hast-util-sanitize 789 | 790 | [github-hastscript]: https://github.com/syntax-tree/hastscript 791 | 792 | [github-property-information]: https://github.com/wooorm/property-information 793 | 794 | [github-rehype]: https://github.com/rehypejs/rehype 795 | 796 | [github-syntax-tree-awesome]: https://github.com/syntax-tree/awesome-syntax-tree 797 | 798 | [github-unified]: https://github.com/unifiedjs/unified 799 | 800 | [github-unist]: https://github.com/syntax-tree/unist 801 | 802 | [github-unist-glossary]: https://github.com/syntax-tree/unist#glossary 803 | 804 | [github-unist-syntax-tree]: https://github.com/syntax-tree/unist#syntax-tree 805 | 806 | [github-unist-utilities]: https://github.com/syntax-tree/unist#list-of-utilities 807 | 808 | [health]: https://github.com/syntax-tree/.github 809 | 810 | [health-coc]: https://github.com/syntax-tree/.github/blob/HEAD/code-of-conduct.md 811 | 812 | [health-contributing]: https://github.com/syntax-tree/.github/blob/HEAD/contributing.md 813 | 814 | [health-support]: https://github.com/syntax-tree/.github/blob/HEAD/support.md 815 | 816 | [ietf-json]: https://datatracker.ietf.org/doc/html/rfc7159 817 | 818 | [section-utilities]: #list-of-utilities 819 | 820 | [term-child]: https://github.com/syntax-tree/unist#child 821 | 822 | [term-leaf]: https://github.com/syntax-tree/unist#leaf 823 | 824 | [term-root]: https://github.com/syntax-tree/unist#root 825 | 826 | [term-tree]: https://github.com/syntax-tree/unist#tree 827 | 828 | [w3c-aria]: https://www.w3.org/TR/wai-aria-1.3/ 829 | 830 | [w3c-mathml]: https://www.w3.org/TR/mathml4/ 831 | 832 | [w3c-svg]: https://www.w3.org/TR/SVG2/ 833 | 834 | [whatwg-dom]: https://dom.spec.whatwg.org/ 835 | 836 | [whatwg-html]: https://html.spec.whatwg.org/multipage/ 837 | 838 | [whatwg-webidl]: https://webidl.spec.whatwg.org 839 | 840 | [wikipedia-xss]: https://en.wikipedia.org/wiki/Cross-site_scripting 841 | 842 | [wooorm]: https://wooorm.com 843 | --------------------------------------------------------------------------------