hast (Hypertext Abstract Syntax Tree)

repository·main·Indexed 20 days ago

https://github.com/syntax-tree/hast

A specification for representing HTML, SVG, and MathML as an abstract syntax tree. Designed as a lightweight, transformable 'virtual DOM' compatible with the unist ecosystem, hast provides a language-agnostic format for representing documents, elements, text, comments, and doctypes. It includes rules for property name camelcasing and value type reflection, and is supported by a wide range of utilities for parsing, transformation, and sanitization via the hast-util- ecosystem.

Tokens
1.5K
Snippets
3
Records
10
Agent score
25%

What's inside hast

  1. What is HAST (Hypertext Abstract Syntax Tree)?

    main
    hast is a specification for representing HTML (and embedded SVG or MathML) as an abstract syntax tree. It implements the unist specification, allowing it to benefit from a wide ecosystem of syntax tree utilities. While it has a strong ecosystem in JavaScript (used extensively by unified and rehype), the format is language-agnostic.
  2. Rules for HAST Property Values

    main

    Property values in HAST reflect the data type determined by the property name.

    • Booleans: Attributes like hidden are reflected as hidden: true.
    • Numbers: Attributes like minlength="5" are reflected as minLength: 5.
    • Lists: Comma or space-separated attribute values are represented as ordered arrays. For example, <div class="alpha bravo"> becomes properties: { className: ['alpha', 'bravo'] }.
    • Lenience: Unlike the DOM, HAST is lenient with non-standard values. For example, <div hidden="no"> is reflected as hidden: 'no' rather than being coerced to true.
    • Null/Undefined: In JSON or JavaScript, null or undefined values should be treated as if the property was not included.
  3. How HAST nodes and the Virtual DOM work

    main

    HAST provides a 'virtual' DOM designed to be lean, easy to transform, and capable of representing the entirety of HTML syntax (including comments and doctypes) while providing positional information.

    Abstract Node Types

    • Literal: A node containing a value: string.
    • Parent: A node containing children (which can be Comment, Doctype, Element, or Text).

    Concrete Node Types

    • Root: Represents a document. It can be the root of a tree or the content of a <template> element, but it cannot be a child of another node.
    • Element: Represents an HTML element. It includes a tagName (local name), properties (attributes), and children. If the tagName is 'template', it may also have a content field of type Root.
    • Text: Represents text content.
    • Comment: Represents an HTML comment.
    • Doctype: Represents a <!doctype> declaration.
  4. Rules for HAST Property Names

    main

    HAST transforms HTML attribute names into camelcased property names to align with how attributes are reflected in the DOM.

    Transformation Rules:

    1. Multi-word names: Names referencing combinations of words (e.g., stroke-miterlimit) become camelcased (strokeMiterLimit).
    2. Hyphenated names: Hyphenated attributes (e.g., read-only) become camelcased (readOnly).
    3. Acronyms: Acronyms are treated as normal words (e.g., itemid becomes itemId).

    Notable Exceptions:

    • class becomes className.
    • for becomes htmlFor.
    • allowfullscreen becomes allowFullScreen.
    • autoplay becomes autoPlay.
    • autocomplete becomes autoComplete.

    Note: For a complete list of transformations, use hastscript or the property-information package.

  5. Secure your hast trees against XSS

    main

    Because hast represents HTML, improper use can lead to Cross-Site Scripting (XSS) attacks. When dealing with user-provided input, you must ensure the tree is safe before processing or rendering it.

    Use the hast-util-sanitize utility to sanitize nodes and mitigate security risks.

  6. Representing Text and Comments in HAST

    main

    Text and comments are represented as nodes with a value property.

    Text Example: <span>Foxtrot</span> yields:

    {
      type: 'element',
      tagName: 'span',
      properties: {},
      children: [{type: 'text', value: 'Foxtrot'}]
    }

    Comment Example: <!--Charlie--> yields:

    {type: 'comment', value: 'Charlie'}
  7. Representing HTML Elements as HAST nodes

    main

    When converting HTML to HAST, elements are mapped to objects containing their tag name, properties, and children.

    Example: <a href="https://alpha.com" class="bravo" download></a> becomes:

    {
      type: 'element',
      tagName: 'a',
      properties: {
        href: 'https://alpha.com',
        className: ['bravo'],
        download: true
      },
      children: []
    }
  8. Explore related HTML utilities

    main

    Beyond the core hast-util-* packages, there is a collection of specialized HTML-related utilities for working with specific standards and attributes:

    • Tag Names: html-tag-names, mathml-tag-names, svg-tag-names, html-void-elements.
    • Attributes & Properties: aria-attributes, html-element-attributes, svg-element-attributes, property-information.
    • Parsing Tokens: comma-separated-tokens, space-separated-tokens.
    • Namespaces & Encodings: web-namespaces, html-encodings, html-dangerous-encodings.
    • Link & Meta: a-rel, link-rel, meta-name.
    • Event Handlers: html-event-attributes, svg-event-attributes.
  9. Explore the list of hast utilities

    main

    The hast ecosystem provides a wide range of utilities for manipulating, parsing, and transforming HTML Abstract Syntax Trees. These utilities are typically prefixed with hast-util- (except for hastscript).

    Key categories of utilities include:

    • Creation & Parsing: hastscript (create trees), hast-util-from-html (parse HTML), hast-util-from-selector (parse CSS selectors to nodes).
    • Transformation: hast-util-to-dom (to DOM), hast-util-to-html (to HTML string), hast-util-to-jsx (to JSX), hast-util-to-mdast (to Markdown AST).
    • Validation & Checking: hast-util-is-element (check if node is an element), hast-util-is-javascript (check if node is a script), hast-util-phrasing (check if node is phrasing content).
    • Manipulation: hast-util-class-list (simulate classList), hast-util-find-and-replace (find/replace text), hast-util-sanitize (sanitize nodes).
    • Selection: hast-util-select (provides querySelector, querySelectorAll, and matches).