rehype-raw: обработка встроенного HTML

rehype-raw — это плагин для экосистемы Unified, который позволяет обрабатывать встроенный HTML внутри Markdown-документов, преобразуемых через Remark и Rehype. Он особенно полезен, когда необходимо сохранить или модифицировать HTML-теги, присутствующие в исходном Markdown, вместо того чтобы игнорировать или экранировать их.


Основные принципы работы

По умолчанию Markdown-парсеры, такие как remark-parse, воспринимают HTML как обычный текст или экранируют его, чтобы предотвратить прямую вставку в итоговый HTML. rehype-raw решает эту проблему, позволяя:

  1. Парсить HTML-теги в дереве AST (HAST — HTML Abstract Syntax Tree).
  2. Встраивать их в общий поток обработки Rehype.
  3. Применять последующие плагины Rehype к этим элементам.

Важно понимать, что rehype-raw работает только на этапе преобразования Markdown в HAST через remark-rehype. Он не применяется к чистому HTML напрямую.


Установка и подключение

npm install rehype-raw

Пример подключения в цепочке Unified:

import { unified } from 'unified';
import remarkParse from 'remark-parse';
import remarkRehype from 'remark-rehype';
import rehypeStringify from 'rehype-stringify';
import rehypeRaw from 'rehype-raw';

const processor = unified()
  .use(remarkParse)
  .use(remarkRehype, { allowDangerousHtml: true })
  .use(rehypeRaw)
  .use(rehypeStringify);

const markdown = `
# Заголовок

<p style="color:red;">HTML внутри Markdown</p>
`;

const html = processor.processSync(markdown).toString();
console.log(html);

Ключевые моменты подключения:

  • Параметр allowDangerousHtml: true в remark-rehype обязателен для корректной обработки встроенного HTML.
  • Плагин rehype-raw должен использоваться после remarkRehype, но перед rehypeStringify и другими плагинами, которые работают с HAST.

Безопасность

HTML, вставленный напрямую в Markdown, может содержать вредоносный код. Поэтому рекомендуется использовать rehype-sanitize после rehype-raw для фильтрации небезопасных тегов и атрибутов.

Пример безопасной цепочки:

import rehypeSanitize from 'rehype-sanitize';

const processor = unified()
  .use(remarkParse)
  .use(remarkRehype, { allowDangerousHtml: true })
  .use(rehypeRaw)
  .use(rehypeSanitize) // фильтрация потенциально опасного HTML
  .use(rehypeStringify);

Примеры обработки

1. Обработка <div> и <span> внутри Markdown

Исходный Markdown:

# Заголовок

<div class="note">
  Это заметка внутри HTML
</div>

После применения rehype-raw HTML-теги остаются полноценными элементами HAST:

<h1>Заголовок</h1>
<div class="note">Это заметка внутри HTML</div>

2. Интеграция с другими плагинами Rehype

После rehype-raw можно использовать плагины, например, для добавления классов или модификации структуры:

import rehypeAddClasses from 'rehype-add-classes';

processor.use(rehypeAddClasses, { 'div.note': 'highlight' });

Результат:

<h1>Заголовок</h1>
<div class="note highlight">Это заметка внутри HTML</div>

Типичные ошибки и их причины

  1. HTML не преобразуется Причина: отсутствует allowDangerousHtml: true в remarkRehype.

  2. rehype-raw применяется до remarkRehype Ошибка: плагин работает только с HAST, поэтому порядок имеет значение.

  3. Небезопасный HTML приводит к XSS Решение: всегда использовать rehype-sanitize после rehype-raw при обработке пользовательского контента.


Советы по оптимизации

  • Для крупных документов лучше разделять обработку Markdown и встроенного HTML. Например, сначала парсить Markdown, затем отдельно обрабатывать HTML-блоки через rehype-raw, чтобы минимизировать риск XSS.
  • Использовать AST-трансформации для массовой модификации атрибутов или структуры HTML перед рендерингом.
  • При генерации статических сайтов хранить результат работы rehype-raw в промежуточном формате, чтобы ускорить повторную сборку.

rehype-raw обеспечивает гибкость и мощь при работе с встроенным HTML, превращая Markdown-документы в полноценные HTML-структуры без потери информации, при этом требуя аккуратного подхода к безопасности и последовательности обработки.