Remark и Rehype — это две тесно связанные библиотеки для работы с Markdown и HTML в экосистеме JavaScript. Remark занимается разбором и трансформацией Markdown в абстрактное синтаксическое дерево (AST), а Rehype работает с HTML и позволяет модифицировать его через AST, аналогично работе с Remark.
Markdown-текст сначала превращается в дерево через Remark, которое затем можно анализировать, изменять или расширять с помощью плагинов. После этого дерево можно конвертировать обратно в Markdown или преобразовать в HTML через Rehype.
AST — это структура данных, представляющая Markdown-документ в виде
дерева узлов. Каждый узел имеет тип (type) и набор свойств
(data, children и другие), что позволяет точно
описать структуру документа.
Пример основных типов узлов:
root — корень дерева документа.paragraph — абзац.heading — заголовок, с уровнем
(depth).text — текст внутри абзаца или заголовка.link — гиперссылка, со свойствами url и
title.list — маркированный или нумерованный список.listItem — элемент списка.Через AST можно создавать собственные плагины для трансформации документа, добавления новых синтаксических конструкций и расширения стандартного Markdown.
Remark поддерживает подключение плагинов, которые обрабатывают AST. С их помощью можно:
Структура плагина Remark:
function remarkCustomPlugin() {
return (tree) => {
visit(tree, 'paragraph', (node) => {
// пример трансформации текста
node.children.forEach((child) => {
if (child.type === 'text') {
child.value = child.value.replace(/\[important\](.*?)\[\/important\]/g, '**$1**');
}
});
});
};
}
Объяснение:
visit — функция для обхода AST.paragraph и модифицирует
текстовые узлы внутри.[important]...[/important].После обработки AST Remark можно передавать дерево в Rehype для генерации HTML.
import { unified } from 'unified';
import remarkParse from 'remark-parse';
import remarkRehype from 'remark-rehype';
import rehypeStringify from 'rehype-stringify';
const markdown = `
# Заголовок
[important]Важный текст[/important]
`;
unified()
.use(remarkParse)
.use(remarkCustomPlugin)
.use(remarkRehype)
.use(rehypeStringify)
.process(markdown)
.then((file) => {
console.log(String(file));
});
Пояснение:
remarkParse превращает Markdown в AST.remarkCustomPlugin модифицирует дерево, добавляя
поддержку кастомного синтаксиса.remarkRehype конвертирует AST Markdown в AST HTML.rehypeStringify генерирует финальный HTML.Для создания более сложных расширений можно использовать:
Inline и Block синтаксис:
Метаданные узлов: AST узлы могут содержать
объект data, в котором можно хранить дополнительные
свойства для последующего HTML.
node.data = {
hName: 'div',
hProperties: { className: ['callout', 'important'] },
};
Обход и модификация дерева:
unist-util-visit для обхода всех узлов
определённого типа.Remark и Rehype работают как связка: Remark для обработки Markdown, Rehype для генерации HTML.
Преимущества такой связки:
Пример кастомного блока:
{
type: 'customCallout',
title: 'Важно',
children: [{ type: 'text', value: 'Это критическая информация.' }]
}
При передаче в Rehype можно указать, что этот узел преобразуется в
HTML <div class="callout"> с вложенным
содержимым.
Remark и Rehype обладают широкой экосистемой:
remark-gfm — поддержка GitHub Flavored Markdown
(таблицы, чекбоксы, зачеркивания).remark-math и rehype-katex — рендеринг
математических формул.remark-frontmatter — работа с YAML-фронтматтером для
метаданных документа.Каждый плагин можно комбинировать и кастомизировать, создавая собственный пайплайн трансформации Markdown в HTML.
type и data,
чтобы Rehype мог корректно генерировать HTML.Эти подходы позволяют создавать мощные и гибкие системы работы с Markdown, превращая обычный текст в интерактивный и стилизованный HTML-контент.