Библиотека Marked предоставляет высокопроизводительный парсер Markdown в JavaScript и позволяет мгновенно преобразовывать текст в HTML. В режиме предпросмотра в реальном времени ключевым моментом является обеспечение синхронного рендеринга текста по мере его ввода.
Для базового преобразования используется функция
marked.parse или её сокращённая форма
marked(). Пример минимального использования:
import { marked } from 'marked';
const markdownText = "# Заголовок\n\nЭто пример текста.";
const html = marked(markdownText);
console.log(html);
Результат:
<h1>Заголовок</h1>
<p>Это пример текста.</p>
Marked поддерживает широкие возможности настройки через объект options, который можно передать при инициализации. Ключевые параметры:
true).false по умолчанию).DOMPurify
для безопасного HTML).id для заголовков (true по умолчанию).Пример:
marked.setOptions({
gfm: true,
breaks: true,
headerIds: true,
langPrefix: 'language-'
});
Для реализации живого предпросмотра используется
событие ввода на элементе <textarea> и динамическая
вставка HTML в контейнер:
const textarea = document.getElementById('editor');
const preview = document.getElementById('preview');
textarea.addEventListener('input', () => {
const markdownText = textarea.value;
preview.innerHTML = marked.parse(markdownText);
});
Ключевой момент: каждое изменение текста триггерит пересборку HTML, что обеспечивает мгновенный отклик. Для больших документов рекомендуется добавлять дебаунсинг ввода, чтобы уменьшить нагрузку на парсер:
let debounceTimer;
textarea.addEventListener('input', () => {
clearTimeout(debounceTimer);
debounceTimer = setTimeout(() => {
preview.innerHTML = marked.parse(textarea.value);
}, 200);
});
Marked позволяет переопределять стандартный рендеринг через объект
Renderer. Это особенно полезно для добавления классов CSS
или обработки нестандартных элементов Markdown.
const renderer = new marked.Renderer();
renderer.heading = function(text, level) {
return `<h${level} class="custom-heading">${text}</h${level}>`;
};
renderer.link = function(href, title, text) {
return `<a href="${href}" target="_blank" rel="noopener noreferrer">${text}</a>`;
};
marked.setOptions({ renderer });
Теперь все заголовки и ссылки будут использовать кастомное оформление, сохраняя при этом полное соответствие стандарту Markdown.
Для полноценного предпросмотра важно корректно обрабатывать блоки
кода. Marked поддерживает передачу функции подсветки через
highlight:
import hljs from 'highlight.js';
marked.setOptions({
highlight: function(code, lang) {
if (lang && hljs.getLanguage(lang)) {
return hljs.highlight(code, { language: lang }).value;
}
return hljs.highlightAuto(code).value;
}
});
Блоки кода <pre><code> будут автоматически
подсвечиваться, что делает предпросмотр более информативным и визуально
структурированным.
Для расширенных сценариев можно использовать токены Markdown напрямую. Например, добавление нестандартного блока заметки:
const tokenizer = {
blockquote(src) {
const match = src.match(/^::note\s+([\s\S]+?)::/);
if (match) {
return {
type: 'blockquote',
raw: match[0],
text: match[1].trim(),
tokens: this.lexer.inlineTokens(match[1].trim())
};
}
return false;
}
};
marked.use({ tokenizer });
Такой подход позволяет интегрировать новые синтаксические конструкции без изменения ядра библиотеки.
При работе с большими документами рекомендуется:
marked.parse.Renderer для оптимизированного
HTML, минимизируя лишние вложенные элементы.Renderer.DOMPurify.Такой подход позволяет создавать полноценный режим предпросмотра в реальном времени, сочетающий высокую производительность и гибкость настройки.