Библиотека Marked предоставляет мощный механизм хуков, который позволяет перехватывать процесс разбора Markdown и изменять или расширять его поведение на различных этапах. Хуки представляют собой функции, которые вызываются внутри парсера или рендерера и дают возможность:
Использование хуков особенно важно при создании кастомных решений для преобразования Markdown в HTML с нестандартной логикой форматирования.
Хук в Marked создается путем передачи объекта с именами функций в
метод use. Объект может содержать следующие типы хуков:
walkTokens – вызывается для каждого
токена после его разбора, позволяет модифицировать токены.renderer – предоставляет возможность
переопределять методы рендеринга для конкретных типов токенов.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".
walkTokenswalkTokens позволяет изменять структуру Markdown на
уровне токенов. Токены представляют собой объекты, содержащие тип
(type) и содержимое (text, tokens
и другие свойства).
marked.use({
walkTokens(token) {
if (token.type === 'heading') {
token.text = `? ${token.text}`;
}
}
});
В данном примере к каждому заголовку добавляется эмодзи «огонь» перед текстом. В реальных проектах подобный подход используют для автоматической генерации префиксов, подсветки ключевых слов или добавления ссылок на внешние ресурсы прямо в токенах.
Особенности:
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}${tag}>`;
},
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 — функция, возвращающая промис
с новым текстом. Рендеринг будет ожидать завершения промиса, что делает
процесс полностью управляемым в асинхронной среде.
Хуки обеспечивают гибкость и контроль на каждом этапе конвейера Markdown → HTML, делая Marked удобным инструментом не только для простого рендеринга, но и для интеграции с веб-приложениями, CMS и статическими генераторами сайтов.
Можно одновременно использовать несколько хуков, комбинируя обработку токенов и кастомный рендеринг:
marked.use({
walkTokens(token) {
if (token.type === 'code') {
token.text = highlightCode(token.text);
}
},
renderer: {
heading(text, level) {
return `${text} `;
}
}
});
Такой подход обеспечивает комплексное преобразование Markdown, где логика обработки токенов и визуальная презентация полностью управляются через хуки.