Форматтеры

MDX — это расширение Markdown, позволяющее внедрять JSX-компоненты в текстовую разметку. Одной из ключевых возможностей MDX является использование форматтеров для управления тем, как содержимое Markdown преобразуется в конечный JSX-вывод. Форматтеры отвечают за парсинг, трансформацию и рендеринг отдельных элементов документа, обеспечивая гибкость и контроль над структурой и стилем.

Основные типы форматтеров

  1. Inline-форматтеры Эти форматтеры работают с встроенным текстом, включая:

    • ссылки ([текст](url)),
    • выделение (**жирный**, _курсив_),
    • inline-код (`код`).

    Inline-форматтеры преобразуют Markdown-разметку в соответствующие React-компоненты, например <strong>, <em> или <code>.

  2. Block-форматтеры Они обрабатывают блочные элементы, такие как:

    • абзацы (<p>),
    • заголовки (<h1>, <h2> и т.д.),
    • списки (<ul>, <ol>),
    • блоки кода (<pre><code>),
    • цитаты (<blockquote>).

    Block-форматтеры позволяют внедрять в документ сложные JSX-компоненты вместо стандартных HTML-тегов, обеспечивая стилизованный вывод.

Принцип работы форматтеров

MDX использует двухступенчатую трансформацию:

  1. Парсинг Markdown в AST (Abstract Syntax Tree) На этом этапе весь текст документа разбивается на дерево узлов:

    • paragraph — абзац,
    • heading — заголовок,
    • link — ссылка,
    • inlineCode — встроенный код и т.д.

    AST хранит как текст, так и метаданные (уровень заголовка, URL ссылки, язык кода).

  2. Трансформация AST в JSX через форматтеры Каждый узел AST обрабатывается соответствующим форматтером. Форматтер:

    • определяет компонент для узла,
    • преобразует внутреннее содержимое,
    • добавляет необходимые props, например className, style или кастомные атрибуты.

    Форматтеры могут быть пользовательскими, что позволяет создавать уникальные компоненты для специфической разметки.

Пользовательские форматтеры

MDX поддерживает подключение своих форматтеров через объект components при использовании MDXProvider:

import { MDXProvider } from '@mdx-js/react';

const components = {
  h1: (props) => <h1 style={{ color: 'darkblue' }} {...props} />,
  code: (props) => <pre className="custom-code" {...props} />,
};

<MDXProvider components={components}>
  <YourMDXContent />
</MDXProvider>

Ключевые моменты при создании кастомных форматтеров:

  • Наследование от стандартных элементов: можно расширять <h1> или <p>, добавляя стили и логику.
  • Использование props: автоматически передаются все свойства AST-узла, включая children и метаданные.
  • Композиция: форматтеры можно комбинировать с другими компонентами, создавая сложные визуальные блоки, например таблицы или интерактивные виджеты.

Работа с блоками кода

Форматтер для блока кода особенно важен в учебниках и документации. Обычно он выполняет три функции:

  1. Подсветка синтаксиса через сторонние библиотеки (Prism, Highlight.js).
  2. Отображение номера строки.
  3. Поддержка кастомных компонентов, например кнопки «Копировать код».

Пример:

const CodeBlock = ({ className, children }) => {
  const language = className?.replace('language-', '');
  return (
    <pre className={`code-block ${language}`}>
      <code>{children}</code>
    </pre>
  );
};

const components = { code: CodeBlock };

Форматтеры и MDX-рамки

MDX можно интегрировать с фреймворками вроде Next.js, Gatsby, React Static. В таких случаях форматтеры:

  • автоматически преобразуют Markdown-файлы в React-компоненты,
  • позволяют подключать стилизованные компоненты,
  • обеспечивают поддержку динамических данных и интерактивных элементов.

Использование форматтеров с такими фреймворками позволяет строить документацию, блоги и учебные материалы с единым подходом к стилям и компонентам.

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

  • Определять форматтеры для каждого типа контента отдельно, чтобы код был модульным.
  • Для блоков кода и таблиц использовать отдельные компоненты, упрощая их повторное использование.
  • Inline-форматтеры лучше минимизировать, оставляя базовые преобразования Markdown, чтобы не усложнять обработку текста.
  • Для больших проектов поддерживать единый объект components, чтобы все MDX-документы использовали одинаковый стиль и логику рендеринга.

Форматтеры — это основа гибкого и мощного отображения Markdown в MDX. Они позволяют не только преобразовывать стандартную разметку, но и внедрять интерактивные компоненты, управлять стилями и расширять возможности документации без изменения исходного Markdown.