Для начала необходимо установить библиотеки marked и highlight.js через npm или yarn:
npm install marked highlight.js
или
yarn add marked highlight.js
После установки можно подключить их в проект:
import { marked } from 'marked';
import hljs from 'highlight.js';
import 'highlight.js/styles/github.css'; // Подключение темы для подсветки
Библиотека marked позволяет кастомизировать процесс
рендеринга через объект renderer. Для интеграции с
highlight.js нужно переопределить метод
code:
const renderer = new marked.Renderer();
renderer.code = (code, language) => {
const validLanguage = hljs.getLanguage(language) ? language : 'plaintext';
const highlighted = hljs.highlight(code, { language: validLanguage }).value;
return `<pre><code class="hljs ${validLanguage}">${highlighted}</code></pre>`;
};
marked.setOptions({
renderer,
gfm: true,
breaks: true,
smartLists: true,
smartypants: false
});
Ключевые моменты:
hljs.getLanguage(language)
предотвращает ошибки при неизвестных языках.gfm: true) и
переносов строк (breaks: true) обеспечивает соответствие
современному Markdown-стандарту.После настройки renderer можно преобразовать Markdown-текст в HTML с подсветкой:
const markdownText = `
# Пример кода
\`\`\`javascript
function hello(name) {
console.log('Привет, ' + name);
}
hello('Мир');
\`\`\`
`;
const html = marked(markdownText);
document.getElementById('content').innerHTML = html;
marked(markdownText) возвращает HTML-строку с уже
подсвеченным кодом.content будет содержать HTML, который
можно стилизовать с помощью CSS темы highlight.js.Для больших блоков кода можно применять асинхронную версию highlight.js, чтобы не блокировать UI:
renderer.code = async (code, language) => {
const validLanguage = hljs.getLanguage(language) ? language : 'plaintext';
const result = await hljs.highlight(code, { language: validLanguage });
return `<pre><code class="hljs ${validLanguage}">${result.value}</code></pre>`;
};
async function renderMarkdown(markdownText) {
const html = await marked.parse(markdownText, { renderer });
document.getElementById('content').innerHTML = html;
}
marked.parse поддерживает асинхронный рендеринг с
промисами.highlight.js поставляется с множеством готовых тем. Для их применения достаточно импортировать соответствующий CSS-файл:
import 'highlight.js/styles/atom-one-dark.css';
Для динамического изменения темы можно менять классы
hljs на уровне <pre> или
<code> или загружать другой CSS-файл через JS.
В стандартной сборке highlight.js не всегда есть все языки. Для добавления нового языка нужно его импортировать:
import javascript from 'highlight.js/lib/languages/javascript';
hljs.registerLanguage('javascript', javascript);
Помимо renderer, marked позволяет
настраивать:
headerIds: true — генерация уникальных id для
заголовков.mangle: false — отключение автоматического
экранирования email-адресов.sanitize: false — отключение удаления HTML-тегов (важно
при вставке кода с HTML внутри).Пример полной конфигурации:
marked.setOptions({
renderer,
gfm: true,
breaks: true,
headerIds: true,
mangle: false,
sanitize: false,
});
Эта интеграция позволяет получить полный контроль над рендерингом Markdown с красивой, точной подсветкой синтаксиса и гибкой настройкой внешнего вида.