Несовместимость с CommonMark

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


1. Отличия в обработке пробелов и отступов

CommonMark строго определяет правила интерпретации отступов перед списками, блоками кода и цитатами. Markdown-it позволяет некоторую свободу:

  • Списки с нестандартными отступами CommonMark требует ровно четыре пробела или один таб для вложенного списка. Markdown-it допускает вложенность с меньшим количеством пробелов, что может привести к разной визуализации в строгих рендерах.

    - Элемент списка
      - Подэлемент

    В Markdown-it иногда корректно интерпретируется даже при двух пробелах, тогда как CommonMark проигнорирует вложенность.

  • Блоки кода CommonMark требует одинакового количества отступов для всего блока кода. Markdown-it допускает смешанные отступы, что упрощает работу, но снижает совместимость с другими рендерами.


2. Различия в обработке переносов строк

CommonMark использует переносы строк строго: одинарный перенос строки не создает новый параграф, а двойной — создает. Markdown-it расширяет поведение:

  • Разрывы строк (line breaks) В Markdown-it можно настроить автоматическую генерацию <br> при одном переносе строки, что противоречит спецификации CommonMark. Настройка через опцию breaks: true:

    const md = require('markdown-it')({ breaks: true });
    md.render('Строка1\nСтрока2');
    // Вывод: <p>Строка1<br>Строка2</p>
  • Эффект на совместимость Документы, рендеренные с включенным breaks, не будут строго соответствовать CommonMark, что важно учитывать при совместном использовании Markdown в разных системах.


3. Особенности обработки ссылок и изображений

Markdown-it расширяет синтаксис ссылок и изображений, выходя за рамки CommonMark:

  • Автоматическая интерпретация URL без обрамления угловыми скобками В CommonMark прямой URL без < > не превращается в ссылку. Markdown-it может автоматически обрабатывать такие URL при включенном плагине linkify.

    const md = require('markdown-it')().use(require('markdown-it-linkify'));
    md.render('https://example.com');
    // Выводит: <a href="https://example.com">https://example.com</a>
  • Расширенные форматы изображений Markdown-it поддерживает нестандартные атрибуты, такие как классы или ID через синтаксис {.class #id}, чего нет в CommonMark. Такой контент не будет корректно рендериться в строгих CommonMark-парсерах.


4. Различия в обработке HTML-блоков

CommonMark строго ограничивает обработку встроенного HTML: только определенные блоки интерпретируются как HTML, остальное — выводится как текст. Markdown-it более гибок:

  • Поддержка произвольного HTML Markdown-it по умолчанию пропускает HTML как есть, без экранирования. Это может привести к визуальным и функциональным различиям при переносе документа между системами.

  • Фильтрация и безопасность Для безопасного рендеринга HTML в Markdown-it рекомендуется использовать плагин markdown-it-sanitizer или подобные решения, иначе строгие CommonMark-рендереры будут экранировать те же блоки.


5. Поведение с нестандартными символами и спецсимволами

Markdown-it расширяет правила экранирования, позволяя использовать некоторые символы, которые CommonMark интерпретирует иначе:

  • Подчеркивания и звездочки В CommonMark последовательности __ и ** обрабатываются строго для жирного текста, а в Markdown-it можно настроить игнорирование некоторых случаев для более гибкого форматирования.
  • Экранирование символов Markdown-it допускает более свободное использование обратного слэша для экранирования, что приводит к различиям в выводе между стандартными парсерами CommonMark и Markdown-it.

6. Настройка режима совместимости

Markdown-it предоставляет пакет опций для настройки поведения, позволяя приблизиться к стандарту CommonMark:

  • Опции html, xhtmlOut, breaks, linkify, typographer.
  • Использование строгих плагинов, имитирующих поведение CommonMark.
  • Применение markdown-it-regexp для контроля нестандартных расширений.

Пример инициализации с минимальным расширением:

const md = require('markdown-it')({
  html: false,
  breaks: false,
  linkify: false,
  typographer: false
});

Эта конфигурация ближе к строгому CommonMark, но полностью совместимой она не делает — различия в поведении парсера остаются.


Markdown-it предоставляет мощный, расширяемый движок для Markdown с множеством дополнительных функций, однако каждое отклонение от стандарта CommonMark требует внимания, особенно при интеграции с системами, которые строго соблюдают спецификацию. Контроль за опциями рендеринга и знание отличий является ключевым для корректной работы с Markdown в реальных проектах.