Миграция с CommonMark

Marked — это современная библиотека для разбора Markdown в JavaScript, обеспечивающая высокую производительность и гибкость в работе с текстом. Для перехода с CommonMark на Marked важно понимать ключевые различия в синтаксисе и поведении, а также возможности кастомизации парсера.


Парсинг и обработка Markdown

Marked предоставляет функцию marked.parse() для преобразования текста Markdown в HTML. Отличие от CommonMark заключается в следующем:

  • Обработка новых элементов Markdown: Marked поддерживает нестандартные расширения, включая таблицы, задачи (task lists), встроенный HTML.
  • Асинхронный парсинг: для работы с большими документами можно использовать marked.parseAsync(), что позволяет обрабатывать текст без блокировки основного потока выполнения.
  • Интерфейс токенов: библиотека разбивает Markdown на токены, которые можно модифицировать через walkTokens перед рендерингом в HTML.

Пример базового использования:

import { marked } from 'marked';

const markdown = `
# Заголовок
- Элемент списка
`;

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

Настройка рендерера

Marked позволяет полностью контролировать вывод HTML через кастомный рендерер. Создание собственного рендерера выполняется через класс marked.Renderer:

const renderer = new marked.Renderer();

renderer.heading = (text, level) => {
  return `${text}`;
};

const html = marked.parse('# Пример', { renderer });

Ключевые возможности кастомного рендерера:

  • Перехват рендеринга заголовков, ссылок, списков, изображений.
  • Встраивание CSS-классов и дополнительных атрибутов.
  • Генерация специфичной разметки для динамических интерфейсов.

Опции парсера

При миграции важно правильно настроить параметры marked. Основные опции:

  • gfm — включает поддержку GitHub Flavored Markdown (таблицы, списки задач).
  • breaks — конвертирует одиночные переводы строки в
    .
  • sanitize — устаревшая опция, заменяется внешними библиотеками для XSS-защиты.
  • smartLists и smartypants — управление типографикой и списками.

Пример настройки:

marked.setOptions({
  gfm: true,
  breaks: true,
  smartLists: true,
  smartypants: true
});

Использование токенов

Marked позволяет работать с токенами Markdown напрямую через lexer. Это удобно для анализа контента перед рендерингом:

const tokens = marked.lexer(markdown);
tokens.forEach(token => {
  if (token.type === 'heading') {
    token.text = token.text.toUpperCase();
  }
});
const html = marked.parser(tokens);

Преимущества работы с токенами:

  • Манипуляция контентом без прямого редактирования HTML.
  • Возможность внедрять дополнительные элементы на уровне Markdown.
  • Создание динамических генераторов контента с учетом структуры документа.

Расширения и плагины

Marked поддерживает расширения через:

  • walkTokens — позволяет изменять любые токены перед рендерингом.
  • extensions — добавление новых синтаксических конструкций Markdown.

Пример расширения для подчеркивания текста:

marked.use({
  extensions: [{
    name: 'underline',
    level: 'inline',
    start(src) { return src.indexOf('__'); },
    tokenizer(src) {
      const rule = /^__([\s\S]+?)__/;
      const match = rule.exec(src);
      if (match) return { type: 'underline', raw: match[0], text: match[1] };
    },
    renderer(token) {
      return `${token.text}`;
    }
  }]
});

Миграция существующих документов

При переносе проектов с CommonMark на Marked необходимо учесть:

  1. Различия в обработке ссылок и изображений — Marked поддерживает более строгую проверку URL и возможность использования кастомных протоколов.
  2. Таблицы и списки задач — включить gfm: true для полной совместимости.
  3. Inline HTML — Marked позволяет использовать его без ограничений, но при необходимости фильтровать через сторонние средства для безопасности.
  4. Асинхронные расширения — если проект использует генерацию контента из API, marked.parseAsync() обеспечивает корректную обработку промисов.

Интеграция с фреймворками

Marked легко интегрируется с React, Vue и Node.js:

  • React: использование dangerouslySetInnerHTML с результатом marked.parse().
  • Vue: через v-html или создание компонента Markdown.
  • Node.js: серверная генерация HTML, кеширование с токенами и рендерером.