В экосистеме Remark и Rehype
свойства узлов (nodes) играют ключевую роль при обработке и
трансформации AST (Abstract Syntax Tree). Каждый узел в дереве имеет
базовую структуру, включающую type, опциональные
children и набор свойств, которые задают
конкретные параметры элемента. Правильная работа с этими свойствами
требует понимания их типов, особенностей нормализации и взаимодействия с
плагинами.
Свойства узлов можно разделить на несколько категорий:
Атрибуты HTML или Markdown Для Rehype узлы
HTML-элементов содержат свойства, соответствующие стандартным атрибутам:
id, className, src,
href и т.д. Remark работает с Markdown-специфичными
свойствами, например, ordered для нумерованных списков или
depth для заголовков.
Метаданные узлов Сюда входят поля, необходимые
для обработки узла внутри AST: position, data,
lang. Поле position содержит объект с
информацией о местоположении узла в исходном тексте (start,
end), что позволяет корректно отображать ошибки или
проводить трансформации.
Служебные поля плагинов Плагины Remark и Rehype
могут добавлять собственные свойства к узлам, например,
hProperties для Rehype, где хранятся атрибуты, специфичные
для обработки HTML. Эти свойства обычно нормализуются для единообразного
взаимодействия с плагинами.
Нормализация свойств — процесс приведения их к единому формату, который гарантирует корректную обработку и совместимость с плагинами и выходными форматами. Основные принципы:
Ключи и регистр Атрибуты HTML должны быть
приведены к нижнему регистру (className →
class), чтобы соответствовать стандарту HTML. Remark
нормализует ключи Markdown-атрибутов по внутренним соглашениям
(ordered всегда булево).
Массивы и строки Некоторые свойства могут быть
заданы как массив или строка. Например, className в Rehype
допускает запись как "foo bar" или
["foo", "bar"]. Нормализация приводит все к массиву для
удобства дальнейшей обработки.
Булевы значения Свойства типа
checked (для чекбоксов) или ordered (для
списков) нормализуются к булевым значениям, даже если исходный синтаксис
допускает альтернативные формы (null,
undefined, "true").
Удаление пустых свойств Для снижения объема AST
и предотвращения ошибок рендеринга свойства с null или
пустыми строками могут быть удалены при нормализации.
При обходе AST и трансформации узлов нормализованные свойства обеспечивают стабильную работу:
Безопасная генерация HTML Rehype при преобразовании AST в HTML ориентируется на нормализованные свойства, что исключает дублирование атрибутов и некорректные значения.
Плагинная совместимость Плагины могут быть уверены в типах и формате свойств, что упрощает фильтрацию и модификацию узлов.
Унификация Markdown-расширений Remark использует нормализацию для того, чтобы расширения, добавляющие собственные свойства к узлам (например, таблицы, footnotes), корректно работали с другими плагинами и парсерами.
import {visit} from 'unist-util-visit';
function normalizeClasses(tree) {
visit(tree, 'element', node => {
if (node.properties?.className) {
if (typeof node.properties.className === 'string') {
node.properties.className = node.properties.className.split(/\s+/);
}
} else {
node.properties = {...node.properties, className: []};
}
});
}
import {visit} from 'unist-util-visit';
function normalizeCheckbox(tree) {
visit(tree, 'listItem', node => {
if (node.checked !== undefined) {
node.checked = Boolean(node.checked);
}
});
}
function removeEmptyProps(tree) {
visit(tree, node => {
for (const key in node) {
if (node[key] === null || node[key] === '') {
delete node[key];
}
}
});
}
hProperties и hChildren В Rehype часто
используются специальные поля hProperties (для атрибутов) и
hChildren (для дочерних узлов HTML). Их нормализация
включает проверку типов и приведение к массиву для
консистентности.
data-поле для Remark Плагины могут записывать
свои данные в node.data. Нормализация предполагает хранение
структурированных объектов и исключение примитивов, которые могут
конфликтовать с внутренней обработкой.
Сериализация и десериализация Нормализованные свойства позволяют безопасно конвертировать AST в JSON и обратно без потери типов и структуры данных.
null свойства перед рендерингом,
чтобы избежать лишнего мусора в HTML.data вместо
добавления нестандартных полей в корень узла.Нормализация свойств в Remark и Rehype не просто упрощает работу с AST, она обеспечивает консистентность, предсказуемость и совместимость с экосистемой плагинов, что особенно важно при масштабных проектах и автоматической генерации контента.