В библиотеке Marked рендерер отвечает за
преобразование элементов Markdown в HTML. При парсинге Markdown строки
библиотека разбивает текст на токены, которые представляют различные
элементы: заголовки, списки, ссылки, изображения, код и так далее.
Каждый тип токена обрабатывается с помощью соответствующего метода
рендерера. По умолчанию используется встроенный рендерер
marked.Renderer, который реализует стандартное
HTML-преобразование.
Ключевые моменты:
Чтобы изменить стандартное поведение, создается объект, наследующий
от marked.Renderer или просто объект с необходимыми
методами. Каждый метод соответствует определенному типу
Markdown-элемента.
Пример структуры метода рендерера:
const customRenderer = {
heading(text, level, raw, slugger) {
return `<h${level} class="custom-heading">${text}</h${level}>`;
},
link(href, title, text) {
return `<a href="${href}" title="${title || ''}" target="_blank">${text}</a>`;
},
list(body, ordered) {
const tag = ordered ? 'ol' : 'ul';
return `<${tag} class="custom-list">${body}</${tag}>`;
}
};
Особенности:
text — уже обработанный текст, который может
содержать вложенные элементы.level для заголовков указывает уровень
(1–6).После определения рендерера его нужно передать в опции Marked при вызове функции:
marked.use({ renderer: customRenderer });
const markdownText = `
# Заголовок первого уровня
- Элемент списка
[Ссылка](https://example.com)
`;
const html = marked.parse(markdownText);
console.log(html);
Результат будет соответствовать кастомным правилам рендерера, а не стандартному HTML.
heading(text, level, raw, slugger)
text — содержимое заголовка с уже обработанными
вложенными элементами.level — уровень заголовка.raw — исходный текст Markdown без обработки.slugger — объект для генерации уникальных
идентификаторов.paragraph(text)
text — текст абзаца. Возвращает HTML-строку
<p>...</p>.link(href, title, text)
href — адрес ссылки.title — атрибут title.text — текст ссылки.list(body, ordered, start)
body — HTML-содержимое списка.ordered — true, если это нумерованный
список.start — начальное число для нумерованного списка.listitem(text, task, checked)
text — содержимое элемента.task — true, если элемент — чекбокс.checked — true, если чекбокс отмечен.code(code, language, isEscaped)
code — текст кода.language — указанная язык разметки.isEscaped — указывает, было ли экранирование HTML.image(href, title, text)
href — путь к изображению.title — атрибут title.text — alt-текст изображения.Можно создать класс, наследующий от marked.Renderer,
чтобы переопределять только нужные методы, сохраняя остальные
стандартные:
class MyRenderer extends marked.Renderer {
heading(text, level) {
return `<h${level} class="my-heading">${text}</h${level}>`;
}
}
marked.use({ renderer: new MyRenderer() });
Это удобно, когда нужно изменить поведение нескольких элементов без полной копии стандартного рендерера.
rel="nofollow" к ссылкам,
предотвращать XSS.Рендереры тесно интегрируются с опциями highlight и
walkTokens:
code.marked.use({
renderer: customRenderer,
highlight: (code, lang) => Prism.highlight(code, Prism.languages[lang] || Prism.languages.javascript, lang),
walkTokens: token => {
if (token.type === 'link') {
token.href = token.href.replace('http:', 'https:');
}
}
});
Рендерер в Marked — это централизованный механизм контроля вывода HTML из Markdown. Он отделяет парсинг от визуального представления, обеспечивает гибкость и безопасность, а также позволяет легко внедрять кастомные правила и расширения. При правильном проектировании рендереры делают Markdown мощным инструментом для динамических веб-приложений и статических сайтов.