Блочные правила

Блочные правила (block rules) в Markdown-it определяют, как исходный текст разбивается на отдельные блоки, которые затем рендерятся в HTML-элементы. Они формируют основу парсинга Markdown, поскольку именно блочные элементы задают структуру документа: заголовки, списки, блоки кода, цитаты, горизонтальные линии и абзацы.

Основные принципы работы блочных правил

Markdown-it использует двухэтапный процесс обработки текста:

  1. Лексический анализ (tokenization) – исходный текст разбивается на последовательность токенов, каждый из которых представляет отдельный блочный элемент.
  2. Рендеринг – токены преобразуются в HTML через соответствующие рендереры.

Каждое блочное правило описывается функцией, которая:

  • Проверяет, соответствует ли текущая строка конкретному блочному паттерну.
  • При успешном совпадении создает один или несколько токенов.
  • Определяет границы блока (начало и конец).

Блочные правила обрабатываются по порядку, и Markdown-it использует механизм «раннего выхода», останавливая проверку, если правило успешно применено.

Типы блочных правил

  1. Абзацы (paragraph)

    Абзац формируется из последовательных строк текста, разделенных пустой строкой. Markdown-it создает токен paragraph_open в начале и paragraph_close в конце.

    Особенности обработки:

    • Пустая строка сигнализирует о завершении абзаца.
    • Блочные элементы внутри абзаца (например, заголовки или списки) разрывают его.
  2. Заголовки (heading)

    Markdown поддерживает два вида заголовков:

    • ATX-заголовки: строки, начинающиеся с # (от одного до шести символов).
    • Setext-заголовки: текстовая строка, за которой следует линия === (h1) или --- (h2).

    Markdown-it создает токены heading_open и heading_close с атрибутом hLevel, указывающим уровень заголовка.

  3. Блоки цитат (blockquote)

    Начинаются с символа > и продолжаются до пустой строки или другого блочного элемента. Блок цитаты может содержать вложенные абзацы, списки и другие блоки.

    Принципы обработки:

    • Каждый вложенный блок внутри цитаты анализируется рекурсивно.
    • Токены создаются с типами blockquote_open и blockquote_close.
  4. Списки (list)

    Списки бывают маркированные (-, *, +) и нумерованные (1., 2., …). Внутри списка могут быть вложенные списки или другие блочные элементы.

    Важные моменты:

    • Markdown-it различает tight и loose списки. Tight списки не имеют промежуточных абзацев между элементами, loose – имеют.
    • Токены: bullet_list_open, ordered_list_open, list_item_open, list_item_close.
  5. Горизонтальные линии (hr)

    Определяются строками, содержащими как минимум три символа -, * или _, без других символов. Создаются одиночные токены hr.

  6. Блоки кода (fenced code и indented code)

    • Indented code – строки с отступом ≥4 пробела или табуляцией. Создается токен code_block.
    • Fenced code – строки, заключенные в тройные символы ``` или ~~~. Токен fence включает информацию о языке программирования.

Механизм добавления и настройки блочных правил

Markdown-it позволяет добавлять новые или модифицировать существующие блочные правила через плагины. Для этого используется массив md.block.ruler:

md.block.ruler.before('paragraph', 'custom_block', customBlockRule, { alt: [] });

Параметры:

  • before – указывает, перед каким правилом вставить новое.
  • 'custom_block' – уникальный идентификатор правила.
  • customBlockRule – функция, реализующая логику распознавания блока.
  • alt – массив альтернативных правил, которые будут проверяться, если текущее не сработало.

Функция правила получает:

  • state – объект состояния, включающий текущие строки и позицию.
  • startLine и endLine – границы анализируемого блока.
  • silent – режим проверки без генерации токенов (используется для предварительной проверки возможности применения правила).

Принципы рекурсивного анализа

Блочные правила могут содержать вложенные блоки. Например:

> Заголовок
> - Список
> - Элемент

Markdown-it разбивает блок цитаты на отдельные токены:

  1. blockquote_open
  2. heading_open / heading_close
  3. bullet_list_open
  4. list_item_open / list_item_close (для каждого элемента)
  5. bullet_list_close
  6. blockquote_close

Рекурсивный разбор обеспечивает корректное вложение HTML-элементов и сохранение структуры документа.

Оптимизация работы с блочными правилами

  • Сортировка правил: порядок важен, так как первое совпадение блокирует дальнейшую проверку.
  • Использование silent режима для предварительной оценки производительности.
  • Минимизация сложных регулярных выражений, так как они вызывают значительную нагрузку при обработке больших документов.

Структура токена блочного элемента

Каждый блочный токен включает:

  • type – тип блока (paragraph_open, heading_open и др.).
  • tag – соответствующий HTML-тег.
  • map – массив [startLine, endLine] исходного текста.
  • level – глубина вложенности.
  • content – текстовое содержимое (для токенов типа inline или code_block).
  • children – массив токенов для вложенных элементов.

Блочные токены служат основой для дальнейшего анализа inline-правил, которые отвечают за обработку ссылок, эмфазы, изображений и кода внутри текста.

Практическое использование

Блочные правила позволяют создавать:

  • Кастомные цитаты с особыми стилями.
  • Собственные блоки предупреждений или примечаний.
  • Пользовательские списки с необычной нумерацией или маркерами.
  • Расширенные блоки кода с подсветкой синтаксиса.

Эти возможности делают Markdown-it гибким инструментом для генерации HTML из Markdown с полной поддержкой кастомизации структуры документа.