Использование в Node.js

Для работы с библиотекой Marked в Node.js требуется предварительно установить пакет через npm:

npm install marked

После установки подключение осуществляется стандартным способом:

const { marked } = require('marked');

Важно учитывать, что начиная с версии 4.x, Marked экспортирует объект marked, который содержит все методы и настройки.


Основные функции

Преобразование Markdown в HTML

Базовый способ использования — функция marked() для преобразования текста в HTML:

const markdown = `
# Заголовок 1
Это пример **жирного текста** и *курсива*.
`;

const html = marked(markdown);
console.log(html);

Результат автоматически включает разметку HTML, что позволяет интегрировать её в веб-страницы или серверные ответы.


Настройки и опции

Marked поддерживает конфигурацию через объект настроек:

marked.setOptions({
  gfm: true,          // Поддержка GitHub Flavored Markdown
  breaks: true,       // Перевод строки превращается в <br>
  smartLists: true,   // Умные списки
  smartypants: true,  // Типографские замены
  headerIds: true,    // Генерация ID для заголовков
  mangle: false       // Отключение изменения email адресов
});

Каждая опция имеет прямое влияние на результат рендеринга. Например, gfm позволяет использовать списки с чекбоксами и таблицы.


Использование кастомных рендереров

Marked позволяет полностью контролировать вывод через объект Renderer. Это полезно для интеграции с собственными шаблонами HTML или добавления дополнительных атрибутов.

const renderer = new marked.Renderer();

renderer.heading = (text, level) => {
  return `<h${level} class="custom-heading">${text}</h${level}>`;
};

renderer.link = (href, title, text) => {
  return `<a href="${href}" title="${title || ''}" target="_blank">${text}</a>`;
};

const customHtml = marked('# Пример заголовка', { renderer });
console.log(customHtml);

Через кастомный рендерер можно переопределять вывод для заголовков, ссылок, изображений, списков, цитат и других элементов Markdown.


Асинхронный рендеринг с поддержкой токенизации

Marked поддерживает раздельную обработку текста: сначала парсинг в токены, затем генерацию HTML. Это повышает гибкость и позволяет использовать асинхронные обработчики, например, для подстановки данных из базы.

const markdownText = 'Пример с [ссылкой](https://example.com)';

const tokens = marked.lexer(markdownText); // Генерация токенов
const htmlFromTokens = marked.parser(tokens); // Преобразование токенов в HTML

console.log(htmlFromTokens);

Такой подход полезен при необходимости анализа или модификации Markdown перед рендерингом.


Работа с безопасностью

При использовании Marked на сервере важно учитывать уязвимости, связанные с XSS. По умолчанию библиотека не экранирует HTML внутри Markdown. Для безопасного отображения можно использовать комбинацию с библиотеками типа DOMPurify или sanitize-html:

const sanitizeHtml = require('sanitize-html');

const unsafeHtml = marked('<script>alert("XSS")</script>');
const safeHtml = sanitizeHtml(unsafeHtml);

console.log(safeHtml); // <p></p>

Это предотвращает выполнение вредоносного кода, встроенного в Markdown.


Интеграция с потоками Node.js

Marked можно использовать с потоками для обработки больших файлов Markdown без загрузки их целиком в память:

const fs = require('fs');
const { Transform } = require('stream');

const readStream = fs.createReadStream('example.md', 'utf-8');
const writeStream = fs.createWriteStream('example.html');

const transformStream = new Transform({
  transform(chunk, encoding, callback) {
    const htmlChunk = marked(chunk.toString());
    callback(null, htmlChunk);
  }
});

readStream.pipe(transformStream).pipe(writeStream);

Такой подход позволяет эффективно конвертировать большие Markdown-файлы на сервере.


Использование с шаблонизаторами

Marked удобно интегрировать с шаблонизаторами Node.js, например, EJS или Handlebars. Пример с EJS:

const ejs = require('ejs');
const markdownContent = '# Заголовок EJS\nКонтент с **жирным текстом**';

const html = ejs.render('<div class="content"><%- content %></div>', {
  content: marked(markdownContent)
});

console.log(html);

Использование <%- %> позволяет вставлять HTML без экранирования, сохраняя форматирование Markdown.


Примеры расширенного применения

  1. Поддержка таблиц и чекбоксов:

    marked.setOptions({ gfm: true });
    const md = `
    - [x] Задача выполнена
    - [ ] Задача в процессе
    `;
    console.log(marked(md));
  2. Создание динамических ID для заголовков:

    marked.use({
      headerIds: true,
      mangle: false
    });
  3. Комбинация с внешними плагинами: Можно расширять функционал Marked через плагины, например, для подсветки синтаксиса в коде или генерации оглавления.


Эти возможности делают Marked универсальным инструментом для обработки Markdown в среде Node.js, обеспечивая гибкость как для серверных приложений, так и для генерации статического HTML-контента.