Работа в Node.js окружении

Для работы с Remark и Rehype в Node.js необходимо установить соответствующие пакеты через npm или yarn:

npm install remark remark-html rehype rehype-stringify unified

или

yarn add remark remark-html rehype rehype-stringify unified
  • unified — основной процессор, объединяющий плагины.
  • remark — парсер Markdown.
  • rehype — парсер/трансформер HTML.
  • remark-html — преобразует Markdown в HTML.
  • rehype-stringify — сериализует дерево HTML обратно в строку.

После установки создаётся база для построения пайплайнов обработки текста.


Создание процессора Markdown

Для обработки Markdown в Node.js используется цепочка unified() с подключением нужных плагинов:

import { unified } from 'unified';
import remarkParse from 'remark-parse';
import remarkHtml from 'remark-html';

const processor = unified()
  .use(remarkParse)
  .use(remarkHtml);

remarkParse превращает Markdown в AST (Abstract Syntax Tree), называемое MDAST, которое представляет структуру документа. remarkHtml преобразует MDAST в HTML, используя внутреннее представление Rehype (HAST — HTML AST).


Обработка Markdown в строку HTML

После настройки процессора можно обрабатывать Markdown-текст:

const markdown = `
# Заголовок уровня 1

Текст с **жирным выделением** и [ссылкой](https://example.com).
`;

async function convertMarkdown() {
  const file = await processor.process(markdown);
  console.log(String(file));
}

convertMarkdown();
  • Результат будет готовым HTML-кодом.
  • Метод process возвращает объект типа VFile, который содержит содержимое, метаданные и информацию о возможных ошибках.

Использование Rehype для дальнейшей обработки

Rehype позволяет работать с HTML-представлением AST:

import rehypeParse from 'rehype-parse';
import rehypeStringify from 'rehype-stringify';

const htmlProcessor = unified()
  .use(rehypeParse, { fragment: true }) // парсит HTML-фрагменты
  .use(rehypeStringify); // сериализует обратно в HTML

Преимущество использования Rehype заключается в возможности добавлять плагины для модификации HTML:

  • Добавление классов к тегам
  • Преобразование ссылок
  • Обработка изображений и таблиц
  • Оптимизация HTML-структуры

Пример модификации ссылок:

import rehypeVisit from 'unist-util-visit';

function addTargetBlank() {
  return (tree) => {
    rehypeVisit(tree, 'element', (node) => {
      if (node.tagName === 'a') {
        node.properties = node.properties || {};
        node.properties.target = '_blank';
      }
    });
  };
}

const enhancedProcessor = unified()
  .use(rehypeParse, { fragment: true })
  .use(addTargetBlank)
  .use(rehypeStringify);

Интеграция Remark и Rehype

Remark и Rehype можно объединять в единый процессор, используя remark-rehype:

import remarkRehype from 'remark-rehype';

const fullProcessor = unified()
  .use(remarkParse)
  .use(remarkRehype)      // конвертирует MDAST в HAST
  .use(rehypeStringify);   // преобразует HAST в HTML

Цепочка выполняет:

  1. Парсинг Markdown → MDAST
  2. Преобразование MDAST → HAST
  3. Сериализация HAST → HTML

Это позволяет подключать плагины как на этапе Markdown, так и на этапе HTML.


Работа с плагинами

Remark и Rehype используют плагины для расширения функциональности. Плагины бывают двух типов:

  • Пресетные: remark-gfm, rehype-highlight
  • Пользовательские функции: функции, принимающие AST и модифицирующие его

Пример добавления поддержки GitHub Flavored Markdown и подсветки синтаксиса:

import remarkGfm from 'remark-gfm';
import rehypeHighlight from 'rehype-highlight';

const processor = unified()
  .use(remarkParse)
  .use(remarkGfm)
  .use(remarkRehype)
  .use(rehypeHighlight)
  .use(rehypeStringify);
  • remark-gfm добавляет таблицы, списки с чекбоксами, авто-ссылки.
  • rehype-highlight подсвечивает синтаксис внутри блоков кода.

Асинхронная обработка и VFile

Все плагины Remark и Rehype поддерживают асинхронную работу. Для обработки файлов можно использовать VFile напрямую:

import { readFile } from 'fs/promises';
import { VFile } from 'vfile';

async function processFile(path) {
  const content = await readFile(path, 'utf-8');
  const file = new VFile({ path, value: content });
  const result = await processor.process(file);
  console.log(String(result));
}
  • VFile хранит путь, содержимое и метаданные.
  • Позволяет безопасно передавать файлы через цепочку плагинов.

Расширенные возможности

  1. Обратное преобразование HTML → Markdown Можно использовать rehype-remark, чтобы HAST обратно преобразовать в MDAST, затем в Markdown.

  2. Использование с потоками (Streams) Remark/Rehype поддерживают работу с потоками для больших файлов и интеграции с Node.js потоковой системой.

  3. Настройка обработки AST Возможность полностью контролировать структуру документа через функции-плагины на любом этапе: MDAST → HAST → HTML.

  4. Поддержка TypeScript Все библиотеки имеют типы для TypeScript, обеспечивая автодополнение и строгую проверку типов.


Практические советы

  • Всегда использовать fragment: true при работе с фрагментами HTML, чтобы избежать ошибок парсинга.
  • Для производительности сложные цепочки плагинов лучше строить один раз и переиспользовать.
  • Проверять выходной HTML через rehype-validate для соблюдения стандартов.
  • Пользовательские плагины писать через чистые функции без побочных эффектов, изменяя AST напрямую.

Remark и Rehype в Node.js обеспечивают гибкую, расширяемую систему для работы с Markdown и HTML, предоставляя полный контроль над обработкой документов на уровне AST с поддержкой плагинов, асинхронной работы и TypeScript.