Для подсветки синтаксиса кода в Markdown с помощью библиотеки Marked часто используется интеграция с библиотекой Prism. Prism предоставляет готовые темы и поддержку множества языков программирования, что позволяет легко стилизовать блоки кода.
Основная идея интеграции заключается в переопределении функции
рендеринга блоков кода (renderer.code) в Marked, чтобы она
использовала Prism для подсветки.
import { marked } from 'marked';
import Prism from 'prismjs';
// Подключение языков по необходимости
import 'prismjs/components/prism-javascript';
import 'prismjs/components/prism-css';
import 'prismjs/components/prism-html';
// Настройка рендерера
const renderer = new marked.Renderer();
renderer.code = (code, language) => {
const validLang = Prism.languages[language] ? language : 'markup';
const highlighted = Prism.highlight(code, Prism.languages[validLang], validLang);
return `<pre class="language-${validLang}"><code class="language-${validLang}">${highlighted}</code></pre>`;
};
marked.setOptions({
renderer,
gfm: true,
breaks: true,
});
Prism поддерживает большое количество языков, но для корректной
работы необходимо убедиться, что соответствующие компоненты подключены.
Если язык не подключен или не распознан, рекомендуется использовать
markup (HTML) как язык по умолчанию.
const validLang = Prism.languages[language] ? language : 'markup';
Это предотвращает ошибки и сохраняет корректное форматирование блока кода.
Prism поставляется с набором CSS-тем. Для отображения подсветки нужно подключить одну из тем:
<link rel="stylesheet" href="prism.css">
В зависимости от выбранной темы будут меняться цвета ключевых слов, комментариев и других элементов кода.
Для специфичных языков, не включённых в стандартный пакет Prism, можно подключать отдельные компоненты:
import 'prismjs/components/prism-python';
import 'prismjs/components/prism-ruby';
Это позволяет расширять функциональность подсветки без изменения кода Marked.
При рендеринге Markdown, полученного динамически (например, с
сервера), важно применять marked() и сразу передавать
результат в DOM. Prism подсветит код только после того, как HTML уже
вставлен в документ:
const markdown = `
\`\`\`javascript
console.log("Hello, world!");
\`\`\`
`;
const container = document.getElementById('content');
container.innerHTML = marked(markdown);
Блок кода будет обернут в pre и code с
классом language-javascript, и Prism применит стили
подсветки.
При больших объемах Markdown или множестве блоков кода может быть полезно:
const cache = new Map();
renderer.code = (code, language) => {
const key = language + code;
if (cache.has(key)) return cache.get(key);
const validLang = Prism.languages[language] ? language : 'markup';
const highlighted = Prism.highlight(code, Prism.languages[validLang], validLang);
const result = `<pre class="language-${validLang}"><code class="language-${validLang}">${highlighted}</code></pre>`;
cache.set(key, result);
return result;
};
Marked позволяет использовать расширенные синтаксические возможности Markdown, такие как таблицы, списки и ссылки. Prism не влияет на их работу, но важно учитывать, что подсветка применяется только к блокам кода.
# Пример таблицы
| Язык | Код |
|------|-----|
| JS | console.log('test'); |
При рендеринге с Marked таблицы и текст будут форматироваться
стандартными средствами, а блоки кода внутри таблиц также могут
подсвечиваться при правильном указании language.
При использовании Marked и Prism в React, Vue или других фреймворках:
componentDidMount / onMounted), чтобы
DOM был готов.dangerouslySetInnerHTML, при этом необходимо тщательно
фильтровать ввод, чтобы предотвратить XSS.<div dangerouslySetInnerHTML={{ __html: marked(markdown) }} />
Эта связка Marked + Prism позволяет создавать красивый, читаемый и наглядный Markdown-контент с подсветкой кода любого объема и сложности.