Markdown-it предоставляет мощный механизм для преобразования Markdown в HTML, используя токенизацию и рендеринг. В основе работы движка лежит генерация токенов для каждого элемента Markdown, после чего каждый токен передается в соответствующую рендер-функцию, которая формирует итоговый HTML. Дефолтные рендер-функции обеспечивают стандартное отображение всех элементов синтаксиса Markdown, от заголовков и параграфов до списков и ссылок.
Каждый токен представляет собой объект с набором полей:
type — тип токена (например,
paragraph_open, link_open,
heading_open).tag — HTML-тег, который будет использован при
рендеринге (p, a, h1 и
т.д.).attrs — массив атрибутов
[ключ, значение].map — массив с указанием начала и конца строки
исходного текста.nesting — уровень вложенности: 1 для
открытия тега, -1 для закрытия, 0 для
самозакрывающихся или текстовых токенов.content — текстовое содержимое для токенов типа
inline.Пример токена заголовка второго уровня:
{
type: 'heading_open',
tag: 'h2',
attrs: null,
map: [0, 1],
nesting: 1,
content: ''
}
Markdown-it использует объект md.renderer.rules для
хранения рендер-функций. Каждая функция принимает параметры:
function(tokens, idx, options, env, self) {
return htmlString;
}
tokens — массив токенов для текущего блока.idx — индекс текущего токена.options — настройки Markdown-it.env — объект окружения, можно использовать для передачи
внешних данных.self — объект рендерера, позволяющий вызвать
стандартный рендеринг для вложенных токенов.Параграфы:
md.renderer.rules.paragraph_open = function(tokens, idx) {
return '';
};
md.renderer.rules.paragraph_close = function(tokens, idx) {
return '
\n';
};
Заголовки:
md.renderer.rules.heading_open = function(tokens, idx) {
return `<${tokens[idx].tag}>`;
};
md.renderer.rules.heading_close = function(tokens, idx) {
return `${tokens[idx].tag}>\n`;
};
Ссылки и изображения:
Для ссылок:
md.renderer.rules.link_open = function(tokens, idx) {
const href = tokens[idx].attrGet('href');
return ``;
};
md.renderer.rules.link_close = function(tokens, idx) {
return '';
};
Для изображений:
md.renderer.rules.image = function(tokens, idx) {
const src = tokens[idx].attrGet('src');
const alt = tokens[idx].content || '';
return `
`;
};
self.renderTokenДля токенов, которые не требуют кастомной обработки, можно вызвать стандартный рендер:
md.renderer.rules.fence = function(tokens, idx, options, env, self) {
const token = tokens[idx];
return `${md.utils.escapeHtml(token.content)}
\n`;
};
Если нужно вызвать встроенный механизм Markdown-it для стандартного рендеринга, используется:
return self.renderToken(tokens, idx, options);
Токены типа inline могут содержать вложенные токены.
Чтобы отрендерить их, используется метод render:
md.renderer.rules.inline = function(tokens, idx, options, env, self) {
return self.render(tokens[idx].children, options, env);
};
Это позволяет рекурсивно обрабатывать текст с форматированием, ссылками, выделением и другими элементами Markdown.
Любую дефолтную рендер-функцию можно заменить или расширить. Например, добавление CSS-класса к заголовкам:
const defaultHeadingOpen = md.renderer.rules.heading_open || function(tokens, idx, options, env, self) {
return self.renderToken(tokens, idx, options);
};
md.renderer.rules.heading_open = function(tokens, idx, options, env, self) {
tokens[idx].attrPush(['class', 'custom-heading']);
return defaultHeadingOpen(tokens, idx, options, env, self);
};
html: true в настройках, HTML из
Markdown вставляется напрямую.env или заранее обрабатывать токены.Эта таблица является ориентиром при кастомизации рендеринга и создании собственных плагинов.