Хелперы utils

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


Основные функции модуля utils

1. isSpace(code)

Функция проверяет, является ли переданный символ пробельным. Принимает числовой код символа (charCode) и возвращает логическое значение. Используется для:

  • Игнорирования пробелов в начале и конце строк.
  • Правильного разбиения текста на токены.

Пример использования внутри кастомного рендера:

const { isSpace } = require('markdown-it/lib/common/utils');

if (isSpace(str.charCodeAt(pos))) {
    // обрабатываем пробел
}

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


2. isAlpha(code)

Определяет, является ли символ латинской буквой. Возвращает true для кодов A-Z и a-z. Используется при:

  • Разборе ссылок с именами.
  • Валидации идентификаторов токенов.

3. isPunct(code)

Возвращает true, если символ относится к знакам препинания. В Markdown это критично для:

  • Определения границ токенов.
  • Разделения текста на блоки и inline-элементы.

4. escapeHtml(str)

Экранирует HTML-символы (<, >, &, ", ') в строке. Часто применяется при:

  • Выводе текста, содержащего HTML-код, чтобы предотвратить XSS.
  • Создании безопасного рендера токенов inline.

Пример:

const escaped = escapeHtml('<div>Test</div>');
console.log(escaped); // &lt;div&gt;Test&lt;/div&gt;

5. unescapeAll(str)

Противоположная функция escapeHtml. Преобразует HTML-энкодинг обратно в обычный текст. Используется при:

  • Обработке уже экранированного контента.
  • Создании кастомных inline-парсеров, где нужно получить исходный текст.

6. replaceEntities(str, keepEscaped)

Позволяет заменить HTML-сущности на соответствующие символы. Параметр keepEscaped управляет сохранением уже экранированных последовательностей. Полезно для:

  • Превращения &amp; в &.
  • Обработки символов Unicode в Markdown.

7. normalizeReference(str)

Нормализует ссылки и идентификаторы для внутреннего хранилища ссылок Markdown. Выполняет следующие действия:

  • Приведение к нижнему регистру.
  • Удаление лишних пробелов.
  • Эскейп специальных символов.

Пример:

const { normalizeReference } = require('markdown-it/lib/common/utils');

console.log(normalizeReference(' Example-Link ')); // example-link

Это гарантирует одинаковое представление ссылок, независимо от формы написания в исходном тексте.


Работа с массивами и объектами

utils включает функции для безопасного доступа и манипуляций с коллекциями:

  • arrayReplaceAt(arr, index, newElements) — заменяет элемент массива на новый набор элементов.
  • assign(obj, ...sources) — аналог Object.assign, объединяет объекты.
  • has(obj, key) — проверяет наличие свойства в объекте без риска затронуть прототип.

Эти функции обеспечивают однородное поведение при создании плагинов и расширений Markdown-it.


Применение в кастомных плагинах

  1. Парсинг inline-токенов: Использование isSpace, isAlpha и isPunct позволяет точно определять границы слов, ссылок и эмодзи.

  2. Рендер HTML: escapeHtml и unescapeAll гарантируют безопасный вывод контента, предотвращая случайные вставки вредоносного кода.

  3. Управление ссылками: normalizeReference используется для хранения ссылок в объекте env.references, обеспечивая корректное сопоставление [text][id].

  4. Манипуляция массивами токенов: arrayReplaceAt позволяет изменять последовательности токенов без создания новых массивов с нуля.


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

  • Все функции utils не изменяют исходные строки, а возвращают новые значения.
  • Они ориентированы на высокую производительность, что критично для больших Markdown-документов.
  • Использование этих хелперов делает код плагинов кратким, безопасным и переносимым между версиями Markdown-it.

Практический пример: создание безопасного inline-плагина

const MarkdownIt = require('markdown-it');
const { isSpace, escapeHtml } = require('markdown-it/lib/common/utils');

function customPlugin(md) {
    md.inline.ruler.after('text', 'highlight', (state, silent) => {
        const pos = state.pos;
        const src = state.src;

        if (src[pos] !== '^') return false;

        let start = pos + 1;
        while (start < src.length && !isSpace(src.charCodeAt(start))) {
            start++;
        }

        if (!silent) {
            const token = state.push('text', '', 0);
            token.content = escapeHtml(src.slice(pos + 1, start));
        }

        state.pos = start;
        return true;
    });
}

const md = new MarkdownIt().use(customPlugin);
console.log(md.render('This is a ^highlighted word.'));

В этом примере функции isSpace и escapeHtml обеспечивают корректное выделение текста и безопасный вывод, не требуя написания сложного кода парсера с нуля.


Хотите, я могу подготовить отдельную таблицу всех функций utils с описанием, аргументами и примерами их применения? Это сделает статью ещё более наглядной и учебной.