В библиотеке Marked обработка Markdown начинается с этапа токенизации, когда исходный текст преобразуется в последовательность логических единиц — токенов. Токен представляет собой объект, описывающий конкретный элемент Markdown: заголовок, параграф, список, ссылку, изображение и т.д. Такой подход позволяет разделить парсинг текста на независимые этапы: сначала формируется структура токенов, затем из них строится HTML.
Токенизация в Marked выполняется с помощью функции
lexer, которая принимает строку Markdown и возвращает
массив токенов:
import { marked } from 'marked';
const markdownText = `
# Заголовок уровня 1
Это абзац текста с **жирным** выделением.
- Пункт списка 1
- Пункт списка 2
`;
const tokens = marked.lexer(markdownText);
console.log(tokens);
Результат будет массивом объектов с ключевыми свойствами, описывающими тип токена, его содержимое и дополнительные параметры.
Каждый токен имеет свой type, определяющий его роль.
Основные типы:
#,
##, ### и т.д.)Каждый токен имеет дополнительные свойства. Например, для заголовка:
{
"type": "heading",
"depth": 2,
"text": "Подзаголовок второго уровня"
}
depth показывает уровень заголовка (от 1 до 6), а
text — содержимое заголовка без Markdown-разметки.
Некоторые токены содержат вложенные токены,
отражающие структуру документа. Например, элемент списка
(list_item) может содержать абзацы, код, ссылки и другие
элементы. Это позволяет библиотеке строить дерево документа, которое
потом удобно рендерить в HTML:
{
"type": "list_item",
"tokens": [
{ "type": "paragraph", "text": "Первый пункт списка" }
]
}
Таким образом, каждый элемент списка может включать несколько токенов, а каждый параграф внутри списка — свои собственные вложенные элементы.
Marked разделяет block-токены и inline-токены:
Lexer сначала формирует block-токены, затем при необходимости
анализирует их содержимое с помощью inline-лексера, чтобы получить
вложенные inline-токены. Например, для параграфа с текстом
Это **важно** будет создан блок:
{
"type": "paragraph",
"tokens": [
{ "type": "text", "text": "Это " },
{ "type": "strong", "text": "важно" }
]
}
Некоторые токены имеют дополнительные свойства, которые управляют их поведением при рендеринге:
list:
ordered — true, если список
нумерованный.start — стартовое число для нумерованного списка.loose — true, если элементы списка
разделены пустыми строками.code:
lang — язык программирования для подсветки.text — содержимое кода.link:
href — URL ссылки.title — текст всплывающей подсказки.text — видимый текст ссылки.image:
href — URL изображения.title — текст подсказки.text — альтернативный текст.Marked позволяет изменять поведение токенизации через options:
gfm — включение расширений GitHub Flavored
Markdown.breaks — переводы строк в параграфах становятся
<br>.smartLists — улучшенная обработка списков.smartypants — замена типографских символов
(" → “/”, -- →
—).Пример:
const tokens = marked.lexer(markdownText, {
gfm: true,
breaks: true
});
После получения массива токенов можно обходить его для анализа или модификации содержимого, что часто используют для создания кастомных рендереров:
tokens.forEach(token => {
if (token.type === 'heading' && token.depth === 1) {
token.text = token.text.toUpperCase();
}
});
Такой подход позволяет строить динамическую обработку Markdown перед преобразованием в HTML.
Токены в Marked создают мощный каркас для последующей генерации HTML, анализа структуры документа и внедрения кастомной логики рендеринга, делая библиотеку гибкой и эффективной для любых задач работы с Markdown.