Remark — это экосистема плагинов для обработки Markdown и MDX, предоставляющая гибкий инструмент для трансформации и анализа контента. Основная идея заключается в том, что Markdown-документ преобразуется в абстрактное синтаксическое дерево (AST), которое затем можно изменять с помощью плагинов перед конвертацией в HTML или JSX.
Remark оперирует через цепочку плагинов, каждый из
которых получает на вход дерево Markdown AST (MDAST).
Плагин может:
Результат обработки передается следующему плагину в цепочке.
import {remark} from 'remark';
import remarkHtml from 'remark-html';
remark()
.use(remarkHtml)
.process('# Заголовок')
.then(file => {
console.log(String(file));
});
В примере выше remark-html преобразует Markdown в HTML.
Каждая стадия может быть расширена собственными плагинами.
Parser plugins (Парсеры) Отвечают за чтение
исходного Markdown или MDX и создание MDAST. Пример:
remark-parse — стандартный парсер Markdown.
Transformer plugins (Трансформеры) Манипулируют AST, изменяя узлы документа. Примеры:
remark-slug — добавляет id к
заголовкам.remark-autolink-headings — оборачивает заголовки в
ссылку для быстрого доступа.Compiler plugins (Компиляторы) Преобразуют MDAST
в другой формат: HTML, JSX или MDX. Примеры: remark-html,
remark-mdx.
Remark-плагин — это функция, принимающая AST и опции:
function remarkExample(options = {}) {
return (tree) => {
visit(tree, 'heading', node => {
if (options.prefix) {
node.children.unshift({type: 'text', value: options.prefix});
}
});
};
}
Здесь используется утилита visit из пакета
unist-util-visit, позволяющая обходить дерево. Плагин
модифицирует все заголовки, добавляя префикс.
MDX расширяет Markdown возможностью встраивать JSX-компоненты. Remark-плагины работают с MDX так же, как с Markdown, но могут быть применены до или после обработки JSX, что дает гибкость:
import {remark} from 'remark';
import remarkMdx from 'remark-mdx';
import remarkSlug from 'remark-slug';
remark()
.use(remarkMdx)
.use(remarkSlug)
.processSync('# Заголовок MDX');
remark-mdx превращает MDX в MDAST с поддержкой
JSX-узлов.remark-slug работает только с Markdown-заголовками, JSX
не трогая.Remark часто интегрируют с Rehype, чтобы
конвертировать Markdown/MDX в HTML через промежуточный HAST
(HTML AST):
import {remark} from 'remark';
import remarkHtml from 'remark-html';
import rehypeRaw from 'rehype-raw';
import rehypeSanitize from 'rehype-sanitize';
remark()
.use(remarkHtml)
.use(rehypeRaw)
.use(rehypeSanitize)
.process('# Пример с <b>HTML</b>');
Преимущество такого подхода — возможность безопасной вставки HTML и расширенных трансформаций.
remark-lint — проверка Markdown на соответствие
стилевым правилам.remark-frontmatter — поддержка YAML/JSON
фронтматтеров.remark-gfm — расширения GitHub Flavored Markdown
(таблицы, задачи, зачеркнутый текст).remark-toc — автоматическая генерация оглавления.Каждый плагин можно настраивать через объект options,
передаваемый в use.
remark().use(...).unist-util-visit,
что делает код универсальным и читаемым.@next/mdx или
next-mdx-remote, где Remark-плагины подключаются в
конфигурации.gatsby-plugin-mdx.remark-cli с .remarkrc или программно через
API remark().use(...).Этот подход позволяет создавать мощные и расширяемые конвейеры обработки Markdown/MDX, гибко модифицируя контент, добавляя функциональность и обеспечивая совместимость с различными форматами вывода.