Типы для MDAST и HAST узлов

В экосистеме JavaScript для работы с Markdown и HTML существуют два базовых формата представления документа в виде дерева: MDAST (Markdown Abstract Syntax Tree) и HAST (HTML Abstract Syntax Tree). Понимание типов узлов этих деревьев критически важно для эффективной обработки и трансформации контента.


1. Основные понятия MDAST

MDAST используется в библиотеке Remark для представления структуры Markdown-документов. Каждый узел дерева имеет определённый тип и свойства, которые описывают его семантику и содержание.

Типы узлов MDAST:

  • Root – корневой узел документа. Содержит массив дочерних узлов в свойстве children.

  • Paragraph – абзац текста. Содержит children, которые обычно являются узлами типа Text или Emphasis.

  • Heading – заголовок. Имеет свойства:

    • depth – уровень заголовка (1–6),
    • children – массив текстовых узлов или узлов форматирования.
  • Text – текстовый узел, содержит свойство value с текстом.

  • Emphasis – выделение текста курсивом, содержит children.

  • Strong – жирное выделение текста, аналогично Emphasis.

  • Link – гиперссылка. Свойства:

    • url – адрес ссылки,
    • title – заголовок ссылки (необязательный),
    • children – содержимое ссылки.
  • Image – изображение. Свойства:

    • url – адрес изображения,
    • alt – альтернативный текст,
    • title – заголовок (необязательный).

Каждый тип узла может иметь дополнительные свойства, например, position, указывающее диапазон текста в исходном Markdown.


2. Основные понятия HAST

HAST применяется в Rehype для представления HTML-документов в виде дерева. В отличие от MDAST, HAST ориентирован на HTML-структуру и DOM-подобные элементы.

Типы узлов HAST:

  • Root – корневой узел документа. Имеет массив children, содержащий элементы или текст.

  • Element – любой HTML-элемент. Свойства:

    • tagName – название тега (например, div, p, a),
    • properties – объект атрибутов элемента (className, id, href и др.),
    • children – массив дочерних узлов (Element или Text).
  • Text – текстовый узел. Содержит value с текстом.

  • Comment – комментарий HTML. Свойство value содержит текст комментария.

  • Doctype – описание типа документа. Свойства могут включать name, public, system.

HAST-узлы часто используются для трансформаций HTML, добавления атрибутов, генерации контента и интеграции с CSS или JS.


3. Сравнение MDAST и HAST

Характеристика MDAST HAST
Формат Markdown AST HTML AST
Используется в Remark Rehype
Основной узел Root Root
Текстовый узел Text Text
Элементы разметки Heading, Paragraph, Emphasis, Strong, Link, Image Element с tagName и properties
Поддержка атрибутов Ограничена (только ссылки и изображения) Полная поддержка HTML-атрибутов
Сфера применения Обработка Markdown, парсинг контента Преобразование в HTML, модификация DOM

4. Типизация узлов с помощью TypeScript

Для корректной работы с MDAST и HAST рекомендуется использовать строгую типизацию.

Пример типов MDAST-узлов:

interface TextNode {
  type: 'text';
  value: string;
}

interface ParagraphNode {
  type: 'paragraph';
  children: MDASTNode[];
}

interface HeadingNode {
  type: 'heading';
  depth: number;
  children: MDASTNode[];
}

type MDASTNode = TextNode | ParagraphNode | HeadingNode | /* другие узлы */;

Пример типов HAST-узлов:

interface Text {
  type: 'text';
  value: string;
}

interface Element {
  type: 'element';
  tagName: string;
  properties?: { [key: string]: any };
  children: HASTNode[];
}

type HASTNode = Text | Element | /* другие узлы */;

Использование этих типов позволяет избегать ошибок при обходе дерева и облегчает работу с плагинами Remark и Rehype.


5. Практические советы

  • Для преобразования Markdown в HTML сначала строится MDAST через Remark, затем с помощью Rehype MDAST трансформируется в HAST.
  • Для добавления атрибутов HTML или стилизации элементов лучше работать с HAST-узлами, так как MDAST не содержит полноценной поддержки атрибутов.
  • Строгая типизация узлов позволяет безопасно писать плагины, обходить дерево и модифицировать контент без неожиданных ошибок.

Типы MDAST и HAST узлов формируют основу всей экосистемы обработки Markdown и HTML в JavaScript. Понимание их структуры и свойств обеспечивает безопасное и эффективное создание плагинов, трансформаций и генерацию контента на основе дерева документа.