Хук postprocess

В библиотеке Marked хук postprocess является одним из ключевых механизмов для тонкой настройки результата рендеринга Markdown. Он позволяет модифицировать итоговый HTML после того, как текст был полностью преобразован библиотекой. Этот подход обеспечивает высокий уровень гибкости при интеграции Markdown в веб-приложения, где требуется дополнительная обработка, например, добавление собственных классов, модификация ссылок или внедрение аналитики.


Назначение postprocess

Хук postprocess срабатывает после того, как весь Markdown был преобразован в HTML. Он принимает на вход строку с HTML и должен вернуть строку с модифицированным HTML. Основные задачи:

  • Добавление кастомных атрибутов к тегам.
  • Очистка или фильтрация HTML для безопасности.
  • Внедрение дополнительной разметки, такой как подсветка синтаксиса или ссылки на внешние ресурсы.
  • Преобразование специфических конструкций Markdown, которые Marked обрабатывает стандартно, но требуется изменить под проект.

Синтаксис и использование

import { marked } from 'marked';

marked.use({
  postprocess(html) {
    // Пример: добавление класса к всем <a> тегам
    return html.replace(/<a /g, '<a class="custom-link" ');
  }
});

const markdownText = `[Пример ссылки](https://example.com)`;
const htmlOutput = marked.parse(markdownText);
console.log(htmlOutput);

В этом примере каждый тег <a> получает класс custom-link. Это простая, но наглядная демонстрация того, как можно изменить HTML на лету после рендеринга Markdown.


Взаимодействие с другими хуками

Marked поддерживает цепочку нескольких хуков. postprocess выполняется после всех остальных хуков, таких как:

  • walkTokens — позволяет обходить и модифицировать токены Markdown до генерации HTML.
  • renderer — даёт возможность заменить стандартные методы генерации HTML для отдельных токенов.

Порядок вызова:

  1. Разбор Markdown в токены.
  2. Обработка токенов через walkTokens.
  3. Генерация HTML через renderer.
  4. Финальная обработка HTML через postprocess.

Этот порядок позволяет комбинировать хуки для сложных сценариев, например: сначала модифицировать токены, потом изменить рендер, и в конце добавить глобальные атрибуты или исправления.


Примеры сложной обработки

1. Автоматическая вставка атрибутов target="_blank" для ссылок:

marked.use({
  postprocess(html) {
    return html.replace(/<a /g, '<a target="_blank" rel="noopener noreferrer" ');
  }
});

2. Оборачивание всех заголовков в контейнеры для анимации:

marked.use({
  postprocess(html) {
    return html.replace(/<(h[1-6])>(.*?)<\/\1>/g, '<div class="animated-header"><$1>$2</$1></div>');
  }
});

3. Очистка нежелательных тегов (например, <script>):

marked.use({
  postprocess(html) {
    return html.replace(/<script.*?>.*?<\/script>/gi, '');
  }
});

Эти примеры показывают, что postprocess способен решать как декоративные задачи, так и задачи безопасности.


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

  • Всегда возвращать корректный HTML. Ошибка в строке может нарушить структуру документа.
  • Для больших документов или частого рендеринга рекомендуется использовать регулярные выражения с осторожностью, чтобы не снизить производительность.
  • Если требуется сложная логика, лучше использовать DOM-парсер, например, DOMParser, вместо сложных регулярных выражений.
  • Комбинируя walkTokens и postprocess, можно добиться практически любой трансформации Markdown, сохраняя при этом удобство работы с библиотекой.

Ограничения

  • postprocess работает только с итоговым HTML. Для изменения структуры токенов до генерации HTML необходимо использовать walkTokens.
  • Нельзя изменить сам Markdown на этом этапе — только HTML.
  • Неправильные регулярные выражения или некорректные замены могут приводить к поломке рендеринга, поэтому важно тестировать все изменения.

Вывод

Хук postprocess является мощным инструментом для последней стадии модификации HTML, генерируемого Marked. Его использование позволяет расширять функционал рендеринга Markdown без изменения исходного текста и встроенных методов библиотеки. Этот хук особенно полезен для:

  • кастомизации внешнего вида HTML;
  • внедрения дополнительной логики;
  • обеспечения безопасности выводимого контента.

Он идеально подходит для проектов, где стандартного рендеринга Markdown недостаточно, и требуется точная настройка финального HTML.