Миграция с Showdown

При переходе с Showdown на Marked важно понимать фундаментальные различия в подходах этих библиотек. Showdown изначально ориентирован на полную конвертацию Markdown в HTML с акцентом на совместимость с различными диалектами Markdown. Marked же делает ставку на скорость парсинга, расширяемость и современный API для работы с AST (Abstract Syntax Tree).

Ключевые отличия:

  • API: Showdown использует объект конвертера с методами makeHtml и настройками через setOption. Marked предлагает функции marked.parse, marked.parseInline и возможность настройки рендерера через объект marked.Renderer.
  • Расширяемость: В Marked проще подключать пользовательские токены и парсеры через marked.use, что обеспечивает гибкую интеграцию новых синтаксических конструкций.
  • Производительность: Marked оптимизирован под высокую скорость обработки больших объемов Markdown, особенно в браузере и Node.js.

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

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

npm install marked

Подключение и простой пример использования:

import { marked } from 'marked';

const markdownText = `
# Заголовок 1

Параграф с **жирным текстом** и [ссылкой](https://example.com).
`;

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

Метод marked.parse конвертирует полный документ Markdown в HTML, тогда как marked.parseInline обрабатывает только отдельные строки или фрагменты, исключая блочные элементы вроде заголовков или списков.


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

Marked позволяет полностью кастомизировать HTML, который генерируется из Markdown. Для этого используется объект Renderer:

import { marked } from 'marked';

const renderer = new marked.Renderer();

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

const markdown = `[OpenAI](https://openai.com)`;
const html = marked.parse(markdown, { renderer });
console.log(html);

Особенности кастомизации:

  • Переопределяются методы для заголовков, списков, изображений, ссылок и других элементов.
  • Можно добавлять классы, атрибуты или изменять структуру HTML полностью.
  • В сочетании с marked.use можно расширять функционал без изменения исходного кода рендерера.

Конфигурация и опции

Marked поддерживает обширный набор опций, схожих с настройками Showdown, но с большей точностью:

  • gfm — включение поддержки GitHub Flavored Markdown.
  • breaks — перенос строк при разрыве строки в Markdown.
  • sanitize — очистка HTML от потенциально опасных тегов (устарело, рекомендуется использовать DOMPurify).
  • headerIds — автоматическая генерация ID для заголовков.
  • mangle — предотвращение автоматического кодирования email-адресов.

Пример:

const html = marked.parse(markdownText, {
    gfm: true,
    breaks: true,
    headerIds: true,
    mangle: false
});

Пользовательские токены и расширения

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

Пример добавления токена для заметок:

import { marked } from 'marked';

const noteTokenizer = {
  name: 'note',
  level: 'inline',
  start(src) { return src.indexOf('!!'); },
  tokenizer(src, tokens) {
    const rule = /^!!(.+?)!!/;
    const match = rule.exec(src);
    if (match) return { type: 'note', raw: match[0], text: match[1] };
  },
  renderer(token) {
    return `<span class="note">${token.text}</span>`;
  }
};

marked.use({ extensions: [noteTokenizer] });

console.log(marked.parse('Это !!важная заметка!!'));

Разбор AST и обработка Markdown как структуры

В отличие от Showdown, который сразу генерирует HTML, Marked предоставляет возможность работать с AST через токены. Это открывает доступ к логике обработки Markdown на уровне структуры документа.

import { marked } from 'marked';

const tokens = marked.lexer('# Заголовок\n\nПараграф');
console.log(tokens);

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

  • Фильтрация или модификация элементов перед рендерингом.
  • Генерация других форматов (PDF, LaTeX) без промежуточного HTML.
  • Более точная интеграция в сложные веб-приложения.

Миграция специфичных возможностей Showdown

  1. Конвертация пользовательских расширений: Showdown использует плагины, Marked требует токены и кастомные рендереры.
  2. Безопасность HTML: Showdown имел встроенную опцию sanitize, Marked рекомендует использовать внешние библиотеки вроде DOMPurify.
  3. Обработка ссылок и изображений: Showdown автоматически добавлял атрибуты, Marked предоставляет полный контроль через рендерер.
  4. Совместимость с GitHub Flavored Markdown: Оба поддерживают, но синтаксис опций отличается. В Marked включается через gfm: true.

Практические рекомендации при переходе

  • Переписать все пользовательские плагины Showdown через токены и рендереры Marked.
  • Проверить корректность генерации HTML для всех типов элементов (таблицы, списки, коды).
  • Использовать marked.use для централизованного управления расширениями и рендерером.
  • Рассмотреть работу с AST для сложных трансформаций документа.

Если потребуется, можно добавить подробную таблицу соответствий настроек Showdown → Marked для упрощения процесса миграции и сохранения поведения документов.