Библиотека Marked предоставляет мощный инструмент для преобразования Markdown в HTML. Для комплексных приложений, где важно отслеживать каждое преобразование и выявлять ошибки или нестандартные конструкции Markdown, критически важным становится логирование процесса парсинга.
Marked позволяет создавать собственный объект
Renderer, в котором можно переопределять методы для
всех основных элементов Markdown: заголовки, списки, ссылки,
изображения, блоки кода и др. Каждый метод рендерера принимает текстовые
данные и возвращает HTML. Для логирования достаточно добавлять вызовы
console.log или использовать специализированные
логгеры.
const { marked } = require('marked');
const renderer = new marked.Renderer();
renderer.heading = function (text, level, raw, slugger) {
console.log(`[Heading] Уровень: ${level}, Текст: "${text}"`);
return `<h${level}>${text}</h${level}>`;
};
renderer.link = function (href, title, text) {
console.log(`[Link] href: ${href}, text: "${text}", title: "${title}"`);
return `<a href="${href}" title="${title || ''}">${text}</a>`;
};
Ключевой момент: этот подход позволяет контролировать каждый элемент Markdown, фиксировать его исходные данные и результаты преобразования.
Marked разделяет процесс парсинга на два этапа:
лексинг (разбиение текста на токены) и
парсинг (формирование HTML из токенов). Лексер
(marked.Lexer) можно использовать напрямую для детального
логирования.
const lexer = new marked.Lexer();
const tokens = lexer.lex(markdownText);
tokens.forEach((token, index) => {
console.log(`[Token ${index}] Тип: ${token.type}, Содержимое:`, token.text || token.raw);
});
Такой подход позволяет отследить, как именно библиотека интерпретирует различные конструкции Markdown, включая нестандартные или расширенные синтаксисы.
Marked поддерживает флаг debug, который
выводит информацию о процессе парсинга. Он активируется при
конфигурации:
marked.setOptions({
debug: true,
renderer: renderer
});
При включенном debug-параметре библиотека выводит данные о каждом токене и каждом вызове рендерера. Для больших текстов это удобно для пошагового анализа.
Некоторые Markdown-конструкции могут быть некорректными или не поддерживаться полностью. Для их отлавливания стоит использовать try-catch при парсинге и логировать ошибки с указанием контекста.
try {
const html = marked.parse(markdownText, { renderer });
} catch (err) {
console.error('[Parsing Error]', err.message);
}
Для сложных приложений можно создавать отдельные функции, которые собирают информацию о каждом элементе и формируют подробный отчет о процессе конвертации Markdown в HTML.
Marked позволяет создавать пользовательские токены и расширять стандартный синтаксис. Для логирования это дает возможность фиксировать нестандартные элементы:
const myLexer = new marked.Lexer({
extensions: [{
name: 'highlight',
level: 'block',
start(src) { return src.match(/==/)?.index; },
tokenizer(src) {
const rule = /^==(.+?)==/;
const match = rule.exec(src);
if (match) {
return { type: 'highlight', raw: match[0], text: match[1] };
}
},
renderer(token) {
console.log('[Highlight]', token.text);
return `<mark>${token.text}</mark>`;
}
}]
});
Это позволяет интегрировать логирование с кастомной разметкой и анализировать, как библиотека обрабатывает расширенные синтаксические конструкции.
Для крупных проектов целесообразно использовать внешние логгеры вроде Winston или Pino. Преимущество — структурированные логи, возможность сохранять историю и фильтровать по уровням важности.
const winston = require('winston');
const logger = winston.createLogger({
level: 'info',
transports: [
new winston.transports.Console(),
new winston.transports.File({ filename: 'parsing.log' })
]
});
renderer.paragraph = function (text) {
logger.info(`Paragraph: "${text}"`);
return `<p>${text}</p>`;
};
Такой подход позволяет централизованно управлять логированием и собирать статистику по объему и типам Markdown-контента.
Эффективное логирование процесса парсинга в Marked обеспечивает прозрачность работы библиотеки, позволяет выявлять ошибки и нестандартные элементы Markdown, а также дает возможность создавать отчеты для дальнейшего анализа.