Библиотека Marked является одним из самых популярных инструментов для парсинга Markdown в JavaScript. Она позволяет конвертировать текст, написанный в Markdown, в HTML с высокой скоростью и гибкостью настройки. Основной принцип работы заключается в разборе исходного Markdown-текста на токены и последующей генерации HTML через встроенный рендерер.
import { marked } from 'marked';
const markdown = '# Заголовок\n\nТекст с **жирным выделением**.';
const html = marked(markdown);
console.log(html);
В этом примере строка Markdown преобразуется в HTML с корректными
тегами и .
Marked позволяет задавать собственные рендереры для управления формированием HTML. Это удобно, когда требуется кастомное отображение элементов.
const renderer = {
heading(text, level) {
return `${text} `;
},
link(href, title, text) {
return `${text}`;
}
};
marked.use({ renderer });
heading – позволяет добавлять классы и атрибуты к
заголовкам.link – позволяет изменять поведение ссылок, например,
открывать их в новом окне.Marked поддерживает множество опций, которые влияют на обработку текста:
.DOMPurify для
очистки HTML.marked.setOptions({
gfm: true,
breaks: true,
smartLists: true
});
Marked разделяет процесс обработки на два этапа:
const lexer = new marked.Lexer();
const tokens = lexer.lex('# Пример\n\nСписок:\n- пункт 1\n- пункт 2');
const parser = new marked.Parser();
const html = parser.parse(tokens);
console.log(html);
Такой подход позволяет производить промежуточную обработку токенов, например, для добавления идентификаторов к заголовкам или для фильтрации определённых элементов.
Marked поддерживает пользовательские плагины для обработки нестандартных синтаксисов. Например, можно реализовать поддержку кастомных блоков:
const tokenizer = {
paragraph(src) {
const match = src.match(/:::(\w+)\n([\s\S]+?)\n:::/);
if (match) {
return {
type: 'customBlock',
name: match[1],
text: match[2],
raw: match[0]
};
}
}
};
const renderer = {
customBlock(token) {
return `${token.text}`;
}
};
marked.use({ tokenizer, renderer });
Такой подход позволяет внедрять собственные синтаксические конструкции без изменения исходного кода библиотеки.
Для предотвращения XSS важно фильтровать результат работы Marked:
import DOMPurify from 'dompurify';
const rawHTML = marked(markdown);
const cleanHTML = DOMPurify.sanitize(rawHTML);
DOMPurify обеспечивает безопасный HTML для вставки в DOM и работает корректно с любыми опциями Marked.
Автосохранение часто требуется при работе с редакторами Markdown.
Простейший подход – сохранять текст в localStorage при
каждом изменении:
const textarea = document.getElementById('editor');
textarea.addEventListener('input', () => {
localStorage.setItem('markdownContent', textarea.value);
});
Для восстановления состояния при перезагрузке:
const saved = localStorage.getItem('markdownContent');
if (saved) {
textarea.value = saved;
}
Для более продвинутого автосохранения можно использовать дебаунс – сохранение каждые несколько секунд, чтобы не перегружать хранилище:
let timeout;
textarea.addEventListener('input', () => {
clearTimeout(timeout);
timeout = setTimeout(() => {
localStorage.setItem('markdownContent', textarea.value);
}, 1000);
});
Markdown можно обновлять в реальном времени, используя
input и динамическое преобразование в HTML:
const preview = document.getElementById('preview');
textarea.addEventListener('input', () => {
const html = marked(textarea.value);
preview.innerHTML = DOMPurify.sanitize(html);
});
Такое решение обеспечивает интерактивный редактор с автосохранением и безопасным отображением контента.