В библиотеке Marked для JavaScript каждый элемент Markdown можно преобразовывать в HTML с использованием рендерера. Рендерер представляет собой объект с набором методов, отвечающих за генерацию HTML для различных типов блоков и inline-элементов: заголовков, параграфов, ссылок, списков, изображений, кода и других.
Для начала создается экземпляр класса Renderer:
const { marked } = require('marked');
const customRenderer = new marked.Renderer();
Каждый метод рендерера можно переопределить. Например, чтобы изменить вывод заголовков:
customRenderer.heading = function(text, level) {
return `<h${level} class="custom-heading">${text}</h${level}>`;
};
Это позволяет индивидуализировать форматирование для конкретных элементов Markdown.
В Marked можно комбинировать поведение нескольких рендереров,
создавая гибридный рендерер, который использует
стандартное поведение для части элементов и кастомное для другой.
Стандартный рендерер доступен через new marked.Renderer()
без изменений.
Пример комбинирования:
const defaultRenderer = new marked.Renderer();
const hybridRenderer = new marked.Renderer();
// Кастомный рендеринг для ссылок
hybridRenderer.link = function(href, title, text) {
return `<a href="${href}" target="_blank" class="external-link">${text}</a>`;
};
// Использование стандартного рендерера для всего остального
Object.keys(defaultRenderer).forEach(key => {
if (!hybridRenderer[key]) {
hybridRenderer[key] = defaultRenderer[key];
}
});
В этом примере ссылки рендерятся с кастомными атрибутами, а все остальные элементы используют стандартный рендеринг Marked.
Выделение элементов для кастомизации Определяется, какие элементы Markdown требуют индивидуального форматирования: заголовки, ссылки, списки, блоки кода, изображения и т.д.
Создание кастомного рендерера Для каждого выбранного элемента создается метод с необходимой логикой HTML.
Интеграция со стандартным рендерером Остальные методы наследуются из стандартного рендерера, чтобы не дублировать код и сохранить совместимость с обновлениями Marked.
Проверка и тестирование Генерируем HTML из Markdown и проверяем, что комбинированный рендеринг работает корректно для всех типов элементов.
const defaultRenderer = new marked.Renderer();
const advancedRenderer = new marked.Renderer();
// Кастомные заголовки
advancedRenderer.heading = (text, level) => {
return `<h${level} class="title-level-${level}">${text}</h${level}>`;
};
// Кастомные ссылки
advancedRenderer.link = (href, title, text) => {
return `<a href="${href}" target="_blank" rel="noopener noreferrer">${text}</a>`;
};
// Кастомные блоки кода с подсветкой
advancedRenderer.code = (code, language) => {
return `<pre class="code-block language-${language}"><code>${code}</code></pre>`;
};
// Остальные методы наследуются из стандартного рендерера
Object.keys(defaultRenderer).forEach(key => {
if (!advancedRenderer[key]) {
advancedRenderer[key] = defaultRenderer[key];
}
});
// Использование
const markdown = `
# Заголовок
Ссылка на [Google](https://google.com)
\`\`\`javascript
console.log("Hello Marked");
\`\`\`
`;
const html = marked(markdown, { renderer: advancedRenderer });
console.log(html);
advancedRenderer.paragraph = function(text) {
const original = defaultRenderer.paragraph(text);
return `<div class="custom-paragraph">${original}</div>`;
};
function mergeRenderers(base, overrides) {
Object.keys(overrides).forEach(key => {
base[key] = overrides[key];
});
return base;
}
Комбинирование рендереров в Marked открывает возможности для тонкой кастомизации Markdown-рендеринга без полной переписи библиотеки. Такой подход облегчает поддержку кода и позволяет создавать богатый HTML с минимальными усилиями.