Markdown-it — это высокопроизводительный Markdown-парсер для JavaScript, который предоставляет гибкую архитектуру для обработки текста. Основой этой архитектуры являются блочные (block) и инлайн (inline) парсеры, обеспечивающие разделение текста на смысловые уровни и их корректное преобразование в HTML.
Блочные парсеры отвечают за разбиение текста на структурные
элементы документа, такие как заголовки, списки, цитаты, блоки
кода и параграфы. В Markdown-it каждый блочный элемент представлен
объектом Token с типом (type), уровнем
вложенности (level) и дополнительными свойствами.
fence
используется для многострочного кода с поддержкой языка,
code_block — для простого.Блочные парсеры вызываются один раз для каждой строки или группы строк и определяют структуру документа до того, как начнётся инлайн-парсинг.
Инлайн-парсеры отвечают за обработку текста внутри блочных элементов. Они распознают ссылки, эмфазис, изображения, код, автолинки и другие конструкции, которые находятся внутри параграфов, заголовков или блоков цитат.
href и title.src и
alt.Инлайн-парсер работает на уровне токена блочного элемента:
Markdown-it поддерживает плагины и правила, позволяющие модифицировать как блочные, так и инлайн-парсеры.
const md = require('markdown-it')();
md.block.ruler.before('paragraph', 'custom_block', (state, startLine, endLine, silent) => {
const lineText = state.getLines(startLine, startLine + 1, 0, false);
if (!lineText.startsWith('::custom')) return false;
if (!silent) {
const token = state.push('custom_block_open', 'div', 1);
token.attrs = [['class', 'custom-block']];
state.push('inline', '', 0).content = lineText.slice(8).trim();
state.push('custom_block_close', 'div', -1);
}
state.line = startLine + 1;
return true;
});
ruler.before — добавляет правило перед
существующим.state.push — создаёт новый токен.inline — используется для инлайн-парсинга содержимого
блока.md.inline.ruler.after('emphasis', 'highlight', (state, silent) => {
const pos = state.pos;
if (state.src.charCodeAt(pos) !== 0x7E) return false; // символ ~
if (!silent) {
const token = state.push('highlight_open', 'mark', 1);
state.push('text', '', 0).content = 'выделенный текст';
state.push('highlight_close', 'mark', -1);
}
state.pos += 1;
return true;
});
inline.ruler.after позволяет вставить правило после
существующего.state.src и state.pos управляют текущей
позицией в тексте.highlight_open/close создают новый тип
инлайн-токена.inline передаётся в
инлайн-парсер.Эта архитектура обеспечивает максимальную гибкость при обработке Markdown, позволяя точно контролировать парсинг и расширять синтаксис без изменения ядра библиотеки. Блочные и инлайн-парсеры работают в тандеме, создавая структурированный и форматированный вывод.