Библиотека Marked — это современный парсер Markdown для JavaScript, позволяющий конвертировать Markdown-текст в HTML с высокой производительностью. Основой работы Marked является концепция токенайзеров, которые разбивают исходный текст на структурные элементы — токены, соответствующие заголовкам, спискам, ссылкам, кодовым блокам и другим конструкциям Markdown.
Каждый токен содержит информацию о типе элемента, его содержимом и дополнительных параметрах. Например, токен для заголовка хранит уровень заголовка и текст, а токен списка — массив элементов списка и информацию о нумерации.
Marked использует два уровня токенизации:
Лексическая токенизация (Lexer) На этом уровне текст разбивается на блоки и строки, формируются базовые токены:
heading)paragraph)list) и элементы списка
(list_item)blockquote)code)hr)Синтаксическая токенизация (Inline Lexer) Каждый блок, полученный на первом этапе, дополнительно обрабатывается на уровне inline-токенов:
link) и изображения (image)strong, em)codespan)del)Разделение на блоки и inline позволяет эффективно управлять разбором сложного текста и применять приоритеты токенов.
Приоритет токенов определяет порядок, в котором Marked проверяет возможность соответствия правилам. Он необходим, чтобы однозначно интерпретировать сложные конструкции Markdown, где один и тот же фрагмент текста может подходить под несколько правил.
Примеры влияния приоритета:
***текст*** могут трактоваться как
жирный и курсив одновременно. Если токен
strong имеет более высокий приоритет, сначала будет найден
жирный текст, а оставшийся символ * обрабатывается как
курсив.> в начале строки может быть как частью
цитаты, так и простой стрелкой. Токен blockquote имеет
приоритет выше, чем обычный текст, поэтому Marked сначала проверяет
возможность создания цитаты.Приоритеты задаются в виде массива правил, где элементы ранжированы сверху вниз. Lexer проверяет текст последовательно по этим правилам, и первый совпавший токен становится активным.
Marked предоставляет возможность определять собственные токены и правила, расширяя стандартный набор. Это особенно важно для специфических Markdown-диалектов:
import { Lexer, Parser } from 'marked';
const customLexer = new Lexer({
// Настройка стандартных правил
gfm: true,
breaks: true,
smartLists: true
});
// Добавление пользовательского токена
customLexer.rules.customTag = /^:::(\w+)\s([\s\S]+?):::/;
const tokens = customLexer.lex(":::note Текст заметки :::");
При добавлении пользовательских токенов важно правильно
позиционировать их в массиве правил, чтобы не нарушить
приоритет стандартных элементов. Например, пользовательский токен,
обрабатывающий блоки с ::: должен проверяться перед
токенами параграфов и списков, иначе текст будет интерпретирован как
обычный параграф.
Правильная настройка приоритета токенов не только обеспечивает корректный разбор текста, но и сокращает время обработки, особенно на больших документах. Если часто встречающийся токен находится ниже по приоритету, Lexer будет проверять все предыдущие правила для каждой строки, что увеличивает нагрузку.
Рекомендации по оптимизации:
g vs y) в регулярных выражениях, чтобы
ускорить поиск совпадений.Lexer генерирует массив токенов, а Parser превращает
их в HTML. Parser также учитывает приоритет, так как
последовательность токенов определяет вложенность
элементов. Например, вложенный список в цитате будет корректно
отрисован только если blockquote обработан раньше
list.
import { marked } from 'marked';
const markdown = "> - Элемент списка в цитате";
const html = marked.parse(markdown);
console.log(html);
// <blockquote><ul><li>Элемент списка в цитате</li></ul></blockquote>
Правильный порядок токенов обеспечивает корректную вложенность и предотвращает неправильное разбиение на блоки.
Приоритет токенов в Marked — это ключевой механизм управления точностью и эффективностью разбора Markdown. Он определяет, какие правила применяются первыми, гарантируя корректное преобразование текста в HTML. Понимание структуры Lexer и Inline Lexer, а также умение настраивать пользовательские токены, позволяет создавать расширяемые и высокопроизводительные Markdown-парсеры в JavaScript.