Применение хуков для валидации

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

Для подключения хуков используется объект hooks, который передается в конфигурацию Marked:

import { marked } from 'marked';

marked.use({
  hooks: {
    beforeParse(text) {
      // Модификация исходного текста перед парсингом
      return text;
    },
    afterParse(tokens) {
      // Изменение токенов после парсинга
      return tokens;
    },
    beforeRender(tokens) {
      // Подготовка токенов перед генерацией HTML
      return tokens;
    },
    afterRender(html) {
      // Финальная обработка HTML перед выводом
      return html;
    }
  }
});

Каждый хук выполняет определенную задачу и позволяет внедрять проверку и валидацию на нужном этапе обработки.


Хук beforeParse

beforeParse вызывается до того, как Marked начнет преобразование текста в токены. Этот хук идеально подходит для предварительной валидации Markdown-контента. Например, можно проверять наличие запрещенных слов, ограничивать длину текста или исправлять синтаксические ошибки.

Пример фильтрации запрещенных слов:

marked.use({
  hooks: {
    beforeParse(text) {
      const forbiddenWords = ['спам', 'реклама'];
      forbiddenWords.forEach(word => {
        if (text.includes(word)) {
          throw new Error(`Недопустимое слово: ${word}`);
        }
      });
      return text;
    }
  }
});

В этом случае Marked прекратит обработку текста и выбросит исключение при обнаружении запрещенного слова. Такой подход позволяет внедрять строгие правила валидации на этапе исходного Markdown.


Хук afterParse

afterParse срабатывает после того, как Markdown преобразован в токены. Токены — это промежуточное представление документа, содержащее типы элементов, их содержимое и атрибуты. Работа с токенами позволяет реализовать детальную проверку структуры документа и корректность вложенности элементов.

Пример проверки заголовков:

marked.use({
  hooks: {
    afterParse(tokens) {
      tokens.forEach(token => {
        if (token.type === 'heading' && token.depth > 3) {
          console.warn(`Заголовок слишком глубокий: ${token.text}`);
        }
      });
      return tokens;
    }
  }
});

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


Хук beforeRender

beforeRender вызывается непосредственно перед генерацией HTML. На этом этапе можно внедрять валидацию содержимого элементов, проверять наличие обязательных атрибутов или корректность ссылок.

Пример проверки ссылок в Markdown:

marked.use({
  hooks: {
    beforeRender(tokens) {
      tokens.forEach(token => {
        if (token.type === 'link' && !/^https?:\/\//.test(token.href)) {
          throw new Error(`Некорректная ссылка: ${token.href}`);
        }
      });
      return tokens;
    }
  }
});

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


Хук afterRender

afterRender срабатывает после генерации HTML. Он подходит для финальной валидации или постобработки документа, например, для удаления нежелательных тегов или внедрения специальных атрибутов.

Пример удаления <script> из HTML:

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

Такой подход позволяет обезопасить вывод HTML, предотвращая выполнение потенциально вредоносного кода.


Практические сценарии применения хуков

  1. Контроль длины текста: до парсинга можно ограничивать размер Markdown-документа.
  2. Фильтрация запрещенного контента: проверка текста и токенов на наличие недопустимых слов или ссылок.
  3. Валидация структуры документа: контроль уровней заголовков, последовательности списков, вложенности блоков.
  4. Безопасность HTML: удаление потенциально опасных тегов и атрибутов после генерации HTML.
  5. Адаптация стиля и форматирования: изменение токенов или HTML для соответствия корпоративным стандартам.

Советы по использованию хуков

  • Всегда возвращать измененный объект (text, tokens или html), иначе Marked не сможет продолжить обработку.
  • Исключения в хуках автоматически останавливают парсинг, что удобно для строгой валидации.
  • Хуки выполняются в порядке их объявления, поэтому можно комбинировать несколько этапов проверки для комплексной валидации.
  • Для больших документов рекомендуется использовать afterParse или beforeRender вместо beforeParse, чтобы избегать лишних операций на исходном тексте.

Хуки в Marked обеспечивают полный контроль над процессом преобразования Markdown в HTML, позволяя внедрять как строгую валидацию, так и динамическую модификацию документа на любом этапе.