В библиотеках Remark и Rehype
основная единица данных — это узел дерева (Node). Узел
может представлять как структурный элемент документа (заголовок,
параграф, список), так и текст или атрибут. Каждый узел имеет
тип (type), а также дополнительные
свойства, такие как children, value,
position и data.
Пример базовой структуры узла:
{
type: 'paragraph',
children: [
{ type: 'text', value: 'Пример текста.' }
]
}
Ключевые свойства узлов:
type — тип узла (например, 'paragraph',
'heading', 'text').children — массив дочерних узлов. Присутствует у узлов,
которые могут содержать другие узлы.value — текстовое содержимое, используется у листовых
узлов (text, code).data — объект для хранения дополнительных данных или
метаинформации.position — объект с информацией о позиции узла в
исходном документе.Для изменения узлов часто требуется обход дерева. Библиотека unist-util-visit предоставляет удобные функции для рекурсивного обхода.
Пример обхода всех параграфов:
import { visit } from 'unist-util-visit';
visit(tree, 'paragraph', (node, index, parent) => {
node.children.push({ type: 'text', value: ' Добавленный текст.' });
});
Особенности:
node — текущий узел.index — индекс узла в массиве children
родителя.parent — родительский узел.Для модификации текста узла достаточно изменить свойство
value:
visit(tree, 'text', (node) => {
node.value = node.value.toUpperCase();
});
Для структурных узлов с children возможны следующие
операции:
node.children.push({ type: 'text', value: 'Новый текст' });
node.children.splice(index, 1);
node.children[index] = { type: 'emphasis', children: [{ type: 'text', value: 'выделение' }] };
Remark и Rehype поддерживают создание плагинов, которые принимают дерево и могут его изменять. Плагин — это функция, возвращающая функцию обработчика:
function myRemarkPlugin() {
return (tree) => {
visit(tree, 'heading', (node) => {
node.children.push({ type: 'text', value: ' ?' });
});
};
}
Особенности:
unist-util-modifyБиблиотеки семейства unist-util содержат вспомогательные
функции для безопасного изменения дерева:
unist-util-remove — удаляет узлы по критерию.unist-util-find — ищет первый узел определённого
типа.unist-util-visit-parents — обход с доступом ко всем
родителям узла.Пример удаления всех пустых параграфов:
import { remove } from 'unist-util-remove';
remove(tree, (node) => node.type === 'paragraph' && node.children.length === 0);
В HTML-дереве узлы часто содержат атрибуты
(properties). Модификация атрибутов выполняется
через объект properties:
visit(tree, 'element', (node) => {
if (node.tagName === 'img') {
node.properties.alt = 'Описание изображения';
node.properties.loading = 'lazy';
}
});
tagName определяет тип HTML-элемента.properties содержит все атрибуты HTML, включая
className, id, src и др.Новые узлы создаются вручную или с помощью вспомогательных функций:
const newNode = {
type: 'paragraph',
children: [
{ type: 'text', value: 'Новый параграф' }
]
};
parentNode.children.push(newNode);
type и структуру
children.tagName и
properties.visit(tree, 'heading', (node) => {
node.children.unshift({ type: 'text', value: 'Раздел: ' });
});
href:visit(tree, 'link', (node, index, parent) => {
if (!node.url) parent.children.splice(index, 1);
});
<strong> на
<em> в Rehype:visit(tree, 'element', (node) => {
if (node.tagName === 'strong') node.tagName = 'em';
});
children во время обхода
visit без использования индекса.unist-util-visit-parents, чтобы учитывать контекст.children у узла перед обращением к
ним.properties, чтобы не
нарушить структуру HTML.Эти методы позволяют гибко управлять деревом Markdown и HTML, создавать плагины, выполнять массовые трансформации, фильтровать узлы и динамически добавлять или удалять элементы. Мастерство работы с узлами становится ключевым навыком при разработке инструментов для обработки и генерации контента.