Для начала работы с библиотекой Marked необходимо установить её через npm:
npm install marked
Импорт в проект JavaScript осуществляется следующим образом:
import { marked } from 'marked';
Базовое использование заключается в преобразовании Markdown в HTML:
const markdown = "# Заголовок\n\nТекст с **жирным** выделением.";
const html = marked(markdown);
console.log(html);
Результатом будет:
<h1>Заголовок</h1>
<p>Текст с <strong>жирным</strong> выделением.</p>
Marked позволяет глубоко кастомизировать процесс парсинга Markdown через Lexer, Parser и собственные рендереры.
Создание собственного рендерера позволяет изменять поведение стандартного HTML-вывода:
const renderer = {
heading(text, level) {
return `<h${level} class="custom-heading">${text}</h${level}>`;
},
link(href, title, text) {
return `<a href="${href}" title="${title || ''}" target="_blank">${text}</a>`;
}
};
marked.use({ renderer });
Теперь все заголовки будут иметь класс custom-heading, а
ссылки открываться в новом окне.
Расширения в Marked — это объектные конфигурации, которые позволяют добавлять новые правила токенизации, парсинга или рендеринга. Для их отладки важно понимать последовательность этапов обработки Markdown:
Простейшее расширение может добавлять поддержку нестандартного синтаксиса:
const highlightExtension = {
name: 'highlight',
level: 'inline',
start(src) { return src.indexOf('=='); },
tokenizer(src) {
const match = src.match(/^==(.+?)==/);
if (match) return { type: 'highlight', raw: match[0], text: match[1] };
},
renderer(token) {
return `<mark>${token.text}</mark>`;
}
};
marked.use({ extensions: [highlightExtension] });
Теперь текст ==важное== будет преобразован в
<mark>важное</mark>.
Для отладки расширений часто полезно увидеть, какие токены создаются на этапе лексинга:
const tokens = marked.lexer("Текст с ==выделением==");
console.log(tokens);
Вывод покажет массив объектов токенов, включая созданный тип
highlight, что облегчает поиск ошибок.
Расширения могут генерировать некорректные токены или падать при
парсинге. Marked предоставляет возможность безопасной обработки ошибок
через try/catch и кастомные функции рендеринга ошибок:
const safeRenderer = {
highlight(token) {
try {
if (!token.text) throw new Error("Пустой токен");
return `<mark>${token.text}</mark>`;
} catch (err) {
console.error(err);
return `<span class="error">Ошибка выделения</span>`;
}
}
};
marked.use({ renderer: safeRenderer });
console.log(marked.lexer("## Тест"));
const tokens = marked.lexer("Тестовый текст");
const html = marked.parser(tokens);
console.log(html);
marked.use({
walkTokens(token) {
console.log("Обрабатывается токен:", token);
}
});
walkTokens для логирования всех
промежуточных токенов.level: 'inline' и
level: 'block' при создании расширений, иначе токены могут
не распознаваться.Добавление пользовательского блока заметки с логированием:
const noteExtension = {
name: 'note',
level: 'block',
start(src) { return src.indexOf(':::note'); },
tokenizer(src) {
const match = src.match(/^:::note\n([\s\S]+?)\n:::/);
if (match) return { type: 'note', raw: match[0], text: match[1] };
},
renderer(token) {
console.log("Рендеринг токена заметки:", token);
return `<div class="note">${token.text}</div>`;
}
};
marked.use({ extensions: [noteExtension] });
console.log(marked(":::note\nСодержимое заметки\n:::"));
Консоль покажет все этапы обработки токена, а результат будет
корректно обёрнут в HTML <div>.
Эти методы позволяют детально контролировать работу Marked, выявлять ошибки на любом этапе обработки Markdown и безопасно разрабатывать сложные пользовательские расширения.