Remark и Rehype — это мощные экосистемы для обработки Markdown и HTML в экосистеме JavaScript. Они оперируют абстракциями AST (Abstract Syntax Tree), где каждый узел имеет свои типы и свойства. Пространства имен в этих библиотеках помогают управлять контекстом элементов, определять, какие свойства допустимы для конкретного типа узла, и обеспечивать корректное взаимодействие между плагинами.
В контексте AST пространства имен (namespace) — это логическая группа или область, которая определяет, как интерпретировать и валидировать узлы. Они позволяют различать узлы, которые могут иметь одинаковое имя, но разное поведение, в зависимости от контекста.
md.html.Пространства имен позволяют избежать конфликтов между плагинами и поддерживать строгую типизацию узлов.
В Remark и Rehype пространство имен
чаще всего задается через тип узла и его свойства. Для Markdown узлов
используется поле type:
const paragraphNode = {
type: 'paragraph', // пространство имен md
children: [
{ type: 'text', value: 'Пример текста' }
]
};
Для HTML-узлов:
const divNode = {
type: 'element', // пространство имен html
tagName: 'div',
properties: { className: ['container'] },
children: []
};
Отличие заключается в том, что md-узлы ориентированы на
структурную разметку Markdown, а html-узлы — на синтаксис
HTML и атрибуты элементов.
Частая задача — преобразовать Markdown в HTML, сохраняя контекст и
корректно распределяя пространства имен. Это делается через
унифицированный конвейер unified, который
объединяет парсеры, плагины и транспилеры.
import { unified } from 'unified';
import remarkParse from 'remark-parse';
import remarkRehype from 'remark-rehype';
import rehypeStringify from 'rehype-stringify';
const processor = unified()
.use(remarkParse) // md пространство
.use(remarkRehype) // конвертация в html пространство
.use(rehypeStringify); // генерация HTML
const markdown = '# Заголовок\n\nПараграф текста';
const html = await processor.process(markdown);
console.log(String(html));
remarkRehype отвечает за трансляцию узлов из
Markdown-пространства (md) в HTML-пространство
(html). Важно понимать, что при этом сохраняются данные
узлов, такие как текст, ссылки, атрибуты, но структура меняется.
Плагины Remark/Rehype могут определять свои пространства имен для внутренних целей. Это полезно, если нужно обрабатывать специфические типы узлов:
function remarkCustomNamespace() {
return (tree) => {
visit(tree, 'paragraph', (node) => {
node.namespace = 'custom-md';
});
};
}
В этом примере каждому узлу параграфа присваивается пространство имен
custom-md. Оно позволяет другим плагинам идентифицировать
эти узлы и применять особую логику обработки, например, специфическую
генерацию HTML-классов или метаданных.
При обработке дерева часто возникает необходимость отбирать узлы по их пространству имен:
import { visit } from 'unist-util-visit';
function filterHtmlElements(tree) {
const elements = [];
visit(tree, (node) => {
if (node.type === 'element' && node.namespace === 'html') {
elements.push(node);
}
});
return elements;
}
Такой подход позволяет разделять обработку Markdown и HTML узлов, не смешивая их логику и предотвращая неожиданные ошибки при генерации или трансформации.
В больших проектах с несколькими плагинами пространства имен позволяют:
custom-md, а другой — с
html.import remarkFrontmatter from 'remark-frontmatter';
import remarkCustomNamespace from './remarkCustomNamespace';
const pipeline = unified()
.use(remarkParse)
.use(remarkFrontmatter)
.use(remarkCustomNamespace)
.use(remarkRehype)
.use(rehypeStringify);
В этом конвейере фронтматтер обрабатывается в
md-пространстве, пользовательские узлы получают собственное
пространство, а финальный HTML генерируется уже в
html-пространстве.
namespace как свойство узла только при
необходимости, так как стандартные плагины ориентируются на поля
type, tagName и properties.Пространства имен — это фундаментальный инструмент для управления деревьями AST в Remark и Rehype. Они упрощают создание надежных, масштабируемых конвейеров обработки Markdown и HTML, обеспечивая четкую структуру и предсказуемость поведения узлов.