Remark и Rehype — это мощные инструменты для работы с Markdown и HTML в экосистеме JavaScript. Один из ключевых сценариев их использования — манипуляция атрибутами элементов, будь то HTML-теги, встроенные изображения или ссылки в Markdown. Атрибуты позволяют контролировать поведение и оформление контента, поэтому умение их изменять является важным навыком при построении парсеров и трансформаций.
Rehype оперирует деревом AST (Abstract Syntax Tree)
для HTML, где каждый узел представляет собой элемент, текст или
комментарий. Атрибуты элемента хранятся в объекте
properties. Для изменения атрибутов используется обход
дерева через плагины или функции трансформации.
Пример базового обхода узлов с модификацией атрибутов:
import { visit } from 'unist-util-visit';
function modifyAttributes() {
return (tree) => {
visit(tree, 'element', (node) => {
if (node.tagName === 'a') {
node.properties = {
...node.properties,
target: '_blank',
rel: 'noopener noreferrer'
};
}
});
};
}
Ключевые моменты:
visit(tree, 'element', callback) — стандартный способ
обхода элементов.node.tagName определяет тип HTML-тега.node.properties — объект, где ключи соответствуют
атрибутам HTML, а значения — их значения....node.properties
сохраняются существующие атрибуты.Для добавления нового атрибута достаточно назначить его в объекте
properties:
node.properties.id = 'unique-id';
node.properties.className = ['highlighted', 'active'];
Для удаления атрибута используется delete:
delete node.properties.style;
Особенности работы с классами и стилями:
className всегда массив строк.style хранится как объект
{property: value} и может быть преобразован в строку при
необходимости.Существуют готовые плагины, облегчающие изменение атрибутов:
import rehypeAddAttributes from 'rehype-add-attributes';
const processor = unified()
.use(rehypeParse)
.use(rehypeAddAttributes, {
selector: 'img',
attributes: { loading: 'lazy', className: 'responsive' }
})
.use(rehypeStringify);
Плагины особенно удобны при работе с большим деревом или при повторяющихся правилах изменения атрибутов.
Remark работает с Markdown и не оперирует HTML напрямую, но
поддерживает расширения через MDX или
remark-directive. Для встроенного HTML и ссылок
используется узлы типа link, image или
html.
Пример изменения атрибутов для ссылок:
import { visit } from 'unist-util-visit';
function modifyLinkAttributes() {
return (tree) => {
visit(tree, 'link', (node) => {
node.data = node.data || {};
node.data.hProperties = {
...node.data.hProperties,
target: '_blank',
rel: 'noopener noreferrer'
};
});
};
}
Важные детали:
node.data.hProperties используется для передачи
атрибутов HTML в процессе конвертации Markdown → HTML.properties напрямую, поэтому
изменения проводятся через hProperties.В типичном пайплайне Remark → Rehype атрибуты можно изменять на двух уровнях:
remark плагины.rehype плагины.Пример пайплайна:
import { unified } from 'unified';
import remarkParse from 'remark-parse';
import remarkRehype from 'remark-rehype';
import rehypeStringify from 'rehype-stringify';
const processor = unified()
.use(remarkParse)
.use(remarkRehype)
.use(modifyAttributes) // Rehype plugin
.use(rehypeStringify);
const html = processor.processSync(markdownContent).toString();
unist-util-visit для обхода и модификации
только нужных узлов.Изменение атрибутов в Remark и Rehype предоставляет полный контроль
над HTML, генерируемым из Markdown. Гибкость AST позволяет как простое
добавление target="_blank" для ссылок, так и сложные
трансформации стилей, классов и других пользовательских атрибутов, что
делает эти библиотеки незаменимыми в современной веб-разработке.