Интеграция с Prism

Библиотеки Remark и Rehype предоставляют мощный инструментарий для работы с Markdown и HTML в экосистеме JavaScript. Одним из частых требований при работе с технической документацией или блогами является подсветка синтаксиса в кодовых блоках. Для этого используется Prism, легковесный и расширяемый синтаксический парсер и подсветчик. Интеграция Remark/Rehype с Prism позволяет получать красивую, семантически правильную и настраиваемую подсветку прямо при преобразовании Markdown в HTML.


Установка необходимых пакетов

Для полноценной работы понадобится несколько модулей:

npm install remark remark-html rehype rehype-stringify rehype-highlight prismjs
  • remark — основной парсер Markdown.
  • remark-html — конвертация Markdown в HTML.
  • rehype — обработка HTML AST.
  • rehype-stringify — преобразование AST HTML обратно в строку.
  • rehype-highlight — готовый плагин для подсветки синтаксиса.
  • prismjs — движок подсветки кода.

Дополнительно можно установить языковые пакеты Prism для нужных языков, например:

npm install prismjs@components/prism-javascript prismjs@components/prism-css

Настройка Remark с Rehype и Prism

Для интеграции необходимо создать конвейер обработки Markdown:

import { remark } from 'remark';
import remarkHtml from 'remark-html';
import { rehype } from 'rehype';
import rehypeStringify from 'rehype-stringify';
import rehypePrism from 'rehype-prism-plus';
import fs from 'fs';

const markdownContent = fs.readFileSync('example.md', 'utf-8');

const processed = await remark()
  .use(remarkHtml)       // Преобразование Markdown в HTML
  .use(() => (tree) => {
    // Встраивание Rehype-процессора для подсветки Prism
    return rehype()
      .data('settings', { fragment: true })
      .use(rehypePrism)
      .process(tree);
  })
  .process(markdownContent);

console.log(String(processed));

Ключевой момент — использование rehype-prism-plus, который обеспечивает корректное применение Prism к HTML AST после того, как Markdown преобразован в HTML. Этот плагин поддерживает большое количество языков и автоматически добавляет CSS-классы для стилизации.


Подключение CSS Prism

Prism предоставляет набор готовых тем для подсветки:

<link href="https://cdn.jsdelivr.net/npm/prismjs/themes/prism-tomorrow.css" rel="stylesheet" />

CSS-файл необходимо подключить в проекте, иначе HTML с классами Prism будет отображаться без подсветки.


Настройка пользовательских языков и плагинов Prism

Примеры дополнительных языков:

import 'prismjs/components/prism-python';
import 'prismjs/components/prism-go';
import 'prismjs/components/prism-rust';

Prism также поддерживает плагины, например:

  • line-numbers — нумерация строк
  • highlight-keywords — подсветка ключевых слов
  • autoloader — динамическая подгрузка языков

Подключение производится через импорт соответствующих модулей:

import 'prismjs/plugins/line-numbers/prism-line-numbers.css';
import 'prismjs/plugins/line-numbers/prism-line-numbers.js';

В HTML необходимо добавить класс line-numbers для <pre>:

<pre class="language-js line-numbers">
<code>const x = 42;</code>
</pre>

Пример расширенного пайплайна Remark + Rehype + Prism

import { remark } from 'remark';
import remarkParse from 'remark-parse';
import remarkRehype from 'remark-rehype';
import rehypeStringify from 'rehype-stringify';
import rehypePrism from 'rehype-prism-plus';

const markdown = `
\`\`\`javascript
function sum(a, b) {
  return a + b;
}
\`\`\`
`;

const html = await remark()
  .use(remarkParse)           // Разбор Markdown
  .use(remarkRehype)          // Конвертация в HTML AST
  .use(rehypePrism)           // Подсветка кода Prism
  .use(rehypeStringify)       // Генерация HTML
  .process(markdown);

console.log(String(html));

Результат — HTML с корректными классами Prism (language-js) и подсветкой синтаксиса.


Особенности работы

  • Простая интеграция: Remark и Rehype позволяют подключать Prism без необходимости ручного обхода DOM.
  • Поддержка множества языков: Через Prism можно подключать любые языки и их комбинации.
  • Плагины и кастомизация: Возможность добавления нумерации строк, темной/светлой темы, подсветки ключевых слов.
  • AST-ориентированный подход: Позволяет модифицировать кодовые блоки до генерации HTML, например, добавлять атрибуты, комментарии или кастомные обертки.

Рекомендации по оптимизации

  1. Подключать только необходимые языки Prism, чтобы не увеличивать размер бандла.
  2. Использовать rehype-prism-plus вместо устаревшего rehype-highlight для полной поддержки новых возможностей Prism.
  3. Встраивать CSS темы Prism локально или через CDN, чтобы избежать ошибок отображения на клиенте.
  4. При большом объеме кода рекомендуется кешировать результаты обработки, особенно для статических сайтов.

Поддержка серверного и клиентского рендеринга

  • На Node.js кодовые блоки можно обрабатывать на сервере, отдавая уже подсвеченный HTML.
  • Для SPA/SSR можно использовать тот же пайплайн, интегрируя его в сборку, например через Vite, Next.js или Astro.
  • Возможность динамического рендеринга: можно хранить исходный Markdown и подсвечивать его на клиенте с помощью PrismJS напрямую, если требуется интерактивность.

Хотите, могу подготовить отдельный подробный пример динамической подсветки с пользовательской темой и нумерацией строк, прямо интегрированный с Remark/Rehype. Это будет максимально полный учебный кейс.