Вложенность токенов

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

Основы структуры токенов

Парсер Markdown-it разбивает текст на массив токенов. Каждый токен имеет следующие ключевые свойства:

  • type — строка, указывающая тип токена, например, paragraph_open, inline, strong_open.

  • tag — HTML-тег, который будет использован при рендеринге (p, strong, em и т.д.).

  • nesting — число, указывающее уровень вложенности:

    • 1 — открывающий токен (например, <p>),
    • 0 — самозакрывающийся или одиночный токен (например, текст внутри параграфа),
    • -1 — закрывающий токен (например, </p>).
  • children — массив дочерних токенов для inline-элементов.

  • level — числовой показатель глубины вложенности в общем массиве токенов.

  • content — текстовое содержимое токена, актуально для токенов с nesting = 0.

Вложенность реализуется через комбинацию nesting и children. Inline-токены (type = "inline") содержат массив children, где находятся текстовые и форматирующие токены.

Пример структуры вложенности

Рассмотрим Markdown:

**Жирный текст с _курсивом_ внутри**

После парсинга Markdown-it создаёт следующие токены:

1. strong_open, tag: "strong", nesting: 1
2. inline, content: "Жирный текст с _курсивом_ внутри", children: [
       2.1 text: "Жирный текст с ", nesting: 0
       2.2 em_open, tag: "em", nesting: 1
       2.3 text: "курсивом", nesting: 0
       2.4 em_close, tag: "em", nesting: -1
       2.5 text: " внутри", nesting: 0
   ]
3. strong_close, tag: "strong", nesting: -1

Здесь видно, что inline токен является контейнером для вложенных токенов, а каждый открывающий/закрывающий токен поддерживает правильную структуру HTML.

Работа с уровнем вложенности

Свойство level помогает определять текущую глубину. Пример использования:

const md = require('markdown-it')();
const tokens = md.parse('**Текст с _вложенным_ элементом**', {});

tokens.forEach(token => {
    console.log(`${' '.repeat(token.level * 2)}${token.type} (${token.nesting})`);
});

Вывод покажет визуально, как каждый токен находится на разных уровнях. Это особенно полезно при создании собственных рендереров, чтобы корректно обрабатывать вложенные структуры.

Inline-токены и их особенность

Inline-токены часто содержат текстовые узлы и другие inline-токены. Пример:

const inlineToken = tokens[1]; // inline токен
inlineToken.children.forEach(child => {
    console.log(child.type, child.content);
});

При работе с children можно реализовать трансформации текста, вставку HTML, замену элементов или анализ сложных Markdown-конструкций без нарушения структуры.

Практическая обработка вложенности

  1. Плагины для Markdown-it используют вложенность для добавления новых правил рендеринга. Например, плагин для подчеркивания текста может вставлять u_open и u_close токены внутрь inline.children.
  2. Манипуляции с массивом токенов требуют сохранения правильной последовательности open → inline → close.
  3. Сложные структуры вроде списков с вложенными параграфами, цитатами и код-блоками используют level и nesting для построения корректного DOM при рендеринге.

Важные особенности

  • Вложенность inline-токенов всегда находится внутри одного родительского inline-токена.
  • Токены с nesting = 0 не имеют дочерних токенов, но могут содержать текст в content.
  • Для глубоких структур рекомендуется использовать рекурсивные функции при обходе children.

Рекурсивный обход токенов

Пример обхода токенов с учётом вложенности:

function printTokens(tokens, indent = 0) {
    tokens.forEach(token => {
        console.log(`${' '.repeat(indent)}${token.type} (${token.nesting})`);
        if (token.children) {
            printTokens(token.children, indent + 2);
        }
    });
}

printTokens(tokens);

Этот подход позволяет наглядно увидеть всю иерархию элементов Markdown, что критично при написании кастомных парсеров и обработчиков.

Влияние вложенности на рендеринг

Markdown-it строит HTML на основе вложенных токенов:

  • Открывающий токен создаёт начальный тег.
  • Inline-токены обрабатываются рекурсивно, формируя содержимое.
  • Закрывающий токен завершает элемент.

Поддержание корректной вложенности гарантирует валидный HTML, правильное оформление и отсутствие конфликтов между стилями.


Вложенность токенов в Markdown-it — это фундаментальный механизм, обеспечивающий точное преобразование Markdown в HTML. Понимание nesting, children и level позволяет реализовывать сложные расширения и контролировать внутреннюю структуру документа на уровне токенов.