Метод marked.use с хуками

Библиотека Marked предоставляет мощный инструмент для работы с Markdown в JavaScript. Одной из ключевых возможностей является метод marked.use, который позволяет модифицировать поведение парсера и рендерера с помощью хуков. Этот механизм обеспечивает гибкость при обработке Markdown, позволяя добавлять собственные правила или изменять существующие.


Основы метода marked.use

Метод marked.use принимает один объект с опциями, которые могут включать следующие ключи:

  • renderer — объект для переопределения методов рендерера.
  • walkTokens — функция для обхода и изменения токенов.
  • tokenizer — объект с функциями, определяющими, как парсить текст в токены.
  • extensions — массив расширений, включающих renderer, tokenizer и дополнительные поля.
  • mangle — настройка маскировки e-mail адресов.
  • headerIds — генерация идентификаторов для заголовков.
  • langPrefix — префикс для блоков кода с указанием языка.

Пример базового вызова:

marked.use({
  renderer: {
    link(href, title, text) {
      return `<a href="${href}" title="${title || ''}" target="_blank">${text}</a>`;
    }
  }
});

В этом примере метод link стандартного рендерера переопределяется так, чтобы все ссылки открывались в новом окне.


Хуки для обхода токенов: walkTokens

Функция walkTokens вызывается для каждого токена Markdown, позволяя изменять их перед рендерингом.

Пример:

marked.use({
  walkTokens(token) {
    if (token.type === 'text') {
      token.text = token.text.toUpperCase();
    }
  }
});

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

Особенности работы с токенами:

  • Токены содержат поля type, raw и специфические свойства, например, text, href, depth.
  • Хук walkTokens вызывается рекурсивно для всех вложенных токенов.
  • Можно добавлять новые свойства к токену, которые потом можно использовать в рендерере.

Расширение функционала через renderer

renderer позволяет полностью контролировать HTML-вывод Markdown. Можно переопределять методы для всех типов токенов: paragraph, heading, list, listitem, link, code, image и др.

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

marked.use({
  renderer: {
    heading(text, level, raw, slugger) {
      const id = slugger.slug(raw);
      return `<h${level} id="${id}" class="custom-heading">${text}</h${level}>`;
    }
  }
});

Здесь создается уникальный идентификатор с помощью slugger, добавляется CSS-класс, а сам текст сохраняется.


Кастомные токенизаторы

Хуки tokenizer позволяют создавать новые синтаксические конструкции Markdown или изменять стандартные.

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

const emojiTokenizer = {
  name: 'emoji',
  level: 'inline',
  start(src) {
    return src.indexOf(':');
  },
  tokenizer(src, tokens) {
    const match = /^:([a-z_]+):/.exec(src);
    if (match) {
      return {
        type: 'emoji',
        raw: match[0],
        text: match[1]
      };
    }
  },
  renderer(token) {
    return `<span class="emoji">${token.text}</span>`;
  }
};

marked.use({ extensions: [emojiTokenizer] });

Теперь любой текст вида :smile: будет преобразован в <span class="emoji">smile</span>.


Использование нескольких расширений

marked.use поддерживает массив расширений и комбинированное использование хуков.

Пример:

marked.use({
  extensions: [
    {
      name: 'highlight',
      renderer: {
        code(code, lang) {
          return `<pre class="highlighted"><code>${code}</code></pre>`;
        }
      }
    },
    {
      name: 'customLink',
      renderer: {
        link(href, title, text) {
          return `<a href="${href}" rel="nofollow">${text}</a>`;
        }
      }
    }
  ]
});

Метод объединяет все переданные расширения и переопределяет стандартные методы рендерера, применяя их по очереди.


Применение marked.use для глобальных настроек

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

marked.use({
  mangle: false,
  headerIds: true,
  langPrefix: 'language-'
});
  • mangle: false отключает маскировку e-mail адресов.
  • headerIds: true включает автоматическую генерацию идентификаторов для заголовков.
  • langPrefix: 'language-' задает префикс для блоков кода с подсветкой синтаксиса.

Эти параметры действуют на весь процесс преобразования Markdown в HTML после вызова marked.use.


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

Часто применяют комбинацию walkTokens и кастомного renderer для сложных преобразований.

Пример: подсветка ключевых слов в тексте заголовков:

marked.use({
  walkTokens(token) {
    if (token.type === 'heading') {
      token.text = token.text.replace(/JavaScript/g, '<strong>JavaScript</strong>');
    }
  },
  renderer: {
    heading(text, level) {
      return `<h${level}>${text}</h${level}>`;
    }
  }
});

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


Итоговые рекомендации по marked.use

  • Использовать walkTokens для изменений содержимого без вмешательства в HTML.
  • Переопределять методы рендерера для контроля финального HTML.
  • Применять кастомные токенизаторы для расширения синтаксиса Markdown.
  • Группировать расширения и хуки для масштабируемой архитектуры парсинга.
  • Настраивать глобальные параметры через объект опций для единообразного поведения парсера.

Метод marked.use делает библиотеку Marked гибкой и мощной, позволяя создавать сложные и кастомные решения для обработки Markdown.