Библиотека Marked предназначена для парсинга Markdown в HTML. По умолчанию она выполняет строгий линейный перевод Markdown-разметки в HTML, но при помощи расширяемых функций и кастомизации можно внедрять условный рендеринг элементов. Условный рендеринг позволяет изменять поведение преобразования Markdown в зависимости от контекста, типа контента или внешних условий.
Marked предоставляет два ключевых инструмента для этого: кастомные рендереры (Renderer) и лексеры/парсеры с опциями фильтрации токенов (Tokenizer и WalkTokens).
Каждый элемент Markdown (заголовок, ссылка, список, изображение) в Marked обрабатывается методом рендерера. Для условного рендеринга создается свой объект рендерера с переопределением необходимых методов.
Пример:
const marked = require('marked');
const renderer = new marked.Renderer();
renderer.link = function(href, title, text) {
if (href.startsWith('https://trusted.com')) {
return `<a href="${href}" title="${title || ''}" class="trusted">${text}</a>`;
} else {
return `<a href="${href}" title="${title || ''}" rel="nofollow">${text}</a>`;
}
};
const markdown = '[Ссылка на trusted](https://trusted.com/page) \n[Ссылка на неизвестное](http://malicious.com)';
const html = marked(markdown, { renderer });
console.log(html);
В этом примере ссылки на доверенные домены получают один класс, остальные — другой. Такой подход позволяет применять контекстуальные условия к любому элементу Markdown.
WalkTokens предоставляет более глубокий уровень контроля, позволяя изменять токены перед их рендерингом.
Пример условного скрытия изображений:
const marked = require('marked');
const options = {
walkTokens: (token) => {
if (token.type === 'image' && token.href.includes('ads')) {
token.type = 'text';
token.text = '[Изображение удалено]';
}
}
};
const markdown = '\n';
const html = marked(markdown, options);
console.log(html);
Здесь все изображения с рекламным контентом заменяются текстом, а остальные рендерятся как обычно. WalkTokens подходит для динамического управления содержимым, когда условия сложнее, чем просто проверка URL.
Для условного рендеринга целых блоков Markdown используется комбинация лексера и кастомного рендерера.
Пример скрытия блоков blockquote на основе внешней
переменной:
const marked = require('marked');
const hideQuotes = true;
const renderer = new marked.Renderer();
renderer.blockquote = function(quote) {
if (hideQuotes) {
return '';
}
return `<blockquote>${quote}</blockquote>`;
};
const markdown = '> Этот блок может быть скрыт';
const html = marked(markdown, { renderer });
console.log(html);
Такой подход позволяет внедрять условные правила на уровне блоков, например скрывать цитаты, предупреждения или целые секции документа в зависимости от настроек или среды выполнения.
Marked поддерживает условную обработку элементов списков через
переопределение методов list и listitem:
const renderer = new marked.Renderer();
renderer.listitem = function(text, task, checked) {
if (text.includes('Пропустить')) {
return '';
}
return `<li>${text}</li>`;
};
const markdown = '- Пропустить этот элемент\n- Отобразить этот элемент';
const html = marked(markdown, { renderer });
console.log(html);
В примере элемент списка, содержащий слово «Пропустить», исключается из HTML. Это демонстрирует, что условный рендеринг может применяться не только к отдельным тегам, но и к элементам внутри блоков.
Для больших проектов часто используют комбинацию кастомных рендереров и walkTokens:
Пример интеграции с флагами доступа:
const userSettings = { showImages: false };
const renderer = new marked.Renderer();
renderer.image = (href, title, text) => {
return userSettings.showImages
? `<img src="${href}" alt="${text}" title="${title || ''}"/>`
: `<span>[Изображение скрыто]</span>`;
};
const markdown = '';
const html = marked(markdown, { renderer });
console.log(html);
Условный рендеринг в Marked обеспечивает точное управление преобразованием Markdown в HTML, что важно для создания безопасных и адаптивных документов.