Библиотека Marked предоставляет мощный инструмент для работы с Markdown в JavaScript, и одной из её ключевых возможностей является система хуков. Хуки позволяют вмешиваться в процесс парсинга и рендеринга Markdown, модифицировать результат и добавлять собственную логику без изменения исходного кода библиотеки.
Хук — это функция, которая вызывается в определённый момент жизненного цикла Markdown-парсинга. Marked поддерживает несколько типов хуков, каждый из которых отвечает за свою стадию обработки текста:
Использование хуков позволяет изменять как исходный текст, так и промежуточные данные на любом этапе.
Для подключения хуков используется метод Marked.use().
Он принимает объект с ключами, соответствующими типам хуков, и массивами
функций:
import { marked } from 'marked';
marked.use({
hooks: {
beforeParse: [
(markdown) => {
return markdown.replace(/TODO:/g, '<strong>TODO:</strong>');
}
],
afterRender: [
(html) => {
return html + '<!-- Rendered by Marked -->';
}
]
}
});
Хуки выполняются последовательно в порядке регистрации.
beforeParse позволяет вмешиваться в текст до того, как Marked начнёт токенизацию. Это удобно для:
Пример использования:
marked.use({
hooks: {
beforeParse: [
(text) => {
// Автоматически заменяем смайлики на Unicode-символы
return text.replace(/:\)/g, '?').replace(/:\(/g, '?');
}
]
}
});
В этом случае все смайлики в Markdown будут заменены ещё до того, как библиотека начнёт формировать токены.
Хук afterParse позволяет работать с массивом токенов, полученных после парсинга Markdown. Каждый токен представляет отдельный блок или инлайн-элемент.
marked.use({
hooks: {
afterParse: [
(tokens) => {
tokens.forEach(token => {
if (token.type === 'heading') {
token.text = token.text.toUpperCase();
}
});
return tokens;
}
]
}
});
Преимущества работы на этом этапе:
Эти хуки вызываются для каждого токена при рендеринге HTML.
beforeRender может быть использован для:
marked.use({
hooks: {
beforeRender: [
(token) => {
if (token.type === 'link') {
token.href = token.href + '?utm_source=marked';
}
return token;
}
]
}
});
afterRender позволяет модифицировать окончательный HTML. Это полезно для:
marked.use({
hooks: {
afterRender: [
(html) => `<div class="markdown-content">${html}</div>`
]
}
});
Marked поддерживает регистрацию нескольких функций для одного типа хука. Они вызываются последовательно, и результат предыдущей функции передаётся следующей:
marked.use({
hooks: {
beforeParse: [
text => text.replace(/foo/g, 'bar'),
text => text.replace(/baz/g, 'qux')
]
}
});
Это позволяет строить сложные цепочки трансформаций без объединения логики в одну функцию.
Система хуков в Marked открывает широкие возможности для гибкой обработки Markdown на любом этапе его преобразования. Она позволяет не только адаптировать стандартный синтаксис под конкретные задачи, но и внедрять сложную логику генерации контента без модификации ядра библиотеки.