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

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

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

Использование хуков особенно важно при создании кастомных решений для преобразования Markdown в HTML с нестандартной логикой форматирования.


Регистрация и структура хуков

Хук в Marked создается путем передачи объекта с именами функций в метод use. Объект может содержать следующие типы хуков:

  1. walkTokens – вызывается для каждого токена после его разбора, позволяет модифицировать токены.
  2. renderer – предоставляет возможность переопределять методы рендеринга для конкретных типов токенов.
  3. async – позволяет использовать асинхронные функции в процессе обработки, например, для подгрузки данных.

Пример структуры объекта хуков:

const hooks = {
  walkTokens(token) {
    if (token.type === 'text') {
      token.text = token.text.toUpperCase();
    }
  },
  renderer: {
    link(href, title, text) {
      return `${text}`;
    }
  }
};

marked.use(hooks);

В этом примере каждый текстовый токен преобразуется в верхний регистр, а ссылки автоматически получают атрибут target="_blank".


Хук walkTokens

walkTokens позволяет изменять структуру Markdown на уровне токенов. Токены представляют собой объекты, содержащие тип (type) и содержимое (text, tokens и другие свойства).

Пример использования:

marked.use({
  walkTokens(token) {
    if (token.type === 'heading') {
      token.text = `? ${token.text}`;
    }
  }
});

В данном примере к каждому заголовку добавляется эмодзи «огонь» перед текстом. В реальных проектах подобный подход используют для автоматической генерации префиксов, подсветки ключевых слов или добавления ссылок на внешние ресурсы прямо в токенах.

Особенности:

  • Хук вызывается рекурсивно для всех вложенных токенов.
  • Изменение свойств токена напрямую влияет на итоговый HTML.
  • Можно удалять токены или добавлять новые, изменяя массив tokens у родителя.

Кастомизация рендеринга

Хук renderer позволяет переопределять стандартные методы рендерера Marked, такие как paragraph, heading, link, image и другие. Это дает полное управление тем, как Markdown преобразуется в HTML.

Пример кастомного рендерера для списков:

const renderer = {
  list(body, ordered) {
    const tag = ordered ? 'ol' : 'ul';
    return `<${tag} class="custom-list">${body}`;
  },
  listitem(text) {
    return `
  • ${text}
  • `; } }; marked.use({ renderer });

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

    Примечание: при использовании кастомного рендерера важно помнить, что все стандартные методы Marked остаются доступными через marked.Renderer.prototype.methodName, что позволяет комбинировать кастомизацию и стандартное поведение.


    Асинхронные хуки

    В Marked версии 4+ поддерживаются асинхронные хуки, что позволяет интегрировать внешние API во время рендеринга. Например, можно подгружать данные по ссылкам или заменять ключевые слова на динамический контент.

    marked.use({
      async walkTokens(token) {
        if (token.type === 'text') {
          token.text = await fetchDataAndReplace(token.text);
        }
      }
    });

    Здесь fetchDataAndReplace — функция, возвращающая промис с новым текстом. Рендеринг будет ожидать завершения промиса, что делает процесс полностью управляемым в асинхронной среде.


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

    1. Автоматическое форматирование текста: добавление префиксов, суффиксов, замена ключевых слов.
    2. Кастомные ссылки и изображения: добавление атрибутов, интеграция с системами аналитики.
    3. Динамическое наполнение контента: подгрузка внешних данных прямо во время обработки Markdown.
    4. Фильтрация и контроль: удаление запрещенного контента, обработка пользовательского ввода.
    5. Создание сложных UI компонентов: например, конвертация специальных блоков Markdown в интерактивные элементы.

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


    Комбинирование хуков

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

    marked.use({
      walkTokens(token) {
        if (token.type === 'code') {
          token.text = highlightCode(token.text);
        }
      },
      renderer: {
        heading(text, level) {
          return `${text}`;
        }
      }
    });

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