Парсинг метаданных

Remark и Rehype — это две фундаментальные библиотеки экосистемы Unified, предназначенные для обработки Markdown и HTML в JavaScript. Remark работает с Markdown, Rehype — с HTML. Обе библиотеки строят промежуточное представление документа в виде дерева синтаксических узлов (AST — Abstract Syntax Tree), что позволяет анализировать, модифицировать и обогащать содержимое перед его рендерингом или конвертацией.

Парсинг метаданных в Markdown чаще всего связан с обработкой YAML Front Matter — блока с ключами и значениями, который находится в начале файла и отделён --- сверху и снизу. Пример Front Matter:

---
title: "Пример статьи"
author: "Иван Иванов"
tags:
  - JavaScript
  - Remark
  - Rehype
date: "2026-03-22"
---
Содержание статьи начинается здесь...

Установка зависимостей

Для работы с Remark и метаданными потребуется набор пакетов:

npm install remark remark-parse remark-frontmatter remark-stringify yaml
  • remark — основной процессор Markdown.
  • remark-parse — парсер Markdown.
  • remark-frontmatter — плагин для распознавания Front Matter.
  • remark-stringify — генератор Markdown из AST.
  • yaml — библиотека для парсинга YAML в JavaScript объекты.

Подключение и конфигурация Remark

import { unified } from 'unified';
import remarkParse from 'remark-parse';
import remarkFrontmatter from 'remark-frontmatter';
import { parse } from 'yaml';

const processor = unified()
  .use(remarkParse)
  .use(remarkFrontmatter, ['yaml']); // указываем тип Front Matter, который хотим обрабатывать

Извлечение метаданных

После того как AST создан, можно пройтись по его узлам и найти блоки типа yaml:

const markdownContent = `
---
title: "Пример статьи"
author: "Иван Иванов"
tags:
  - JavaScript
  - Remark
  - Rehype
date: "2026-03-22"
---
Контент Markdown.
`;

const ast = processor.parse(markdownContent);

const metadataNode = ast.children.find(node => node.type === 'yaml');
let metadata = {};

if (metadataNode) {
  metadata = parse(metadataNode.value); // превращаем YAML в JS-объект
}

console.log(metadata);

Вывод:

{
  "title": "Пример статьи",
  "author": "Иван Иванов",
  "tags": ["JavaScript", "Remark", "Rehype"],
  "date": "2026-03-22"
}

Работа с Rehype

Rehype позволяет выполнять аналогичные действия, но с HTML. Для обработки HTML и извлечения данных из атрибутов тегов, мета-тегов и кастомных данных можно использовать плагины и обход дерева узлов:

npm install rehype rehype-parse rehype-stringify

Пример разбора HTML и получения содержимого <meta>:

import { unified } from 'unified';
import rehypeParse from 'rehype-parse';
import { visit } from 'unist-util-visit';

const htmlContent = `
<!DOCTYPE html>
<html>
<head>
  <meta name="description" content="Пример статьи">
  <meta name="author" content="Иван Иванов">
</head>
<body>
  <h1>Заголовок статьи</h1>
</body>
</html>
`;

const htmlAst = unified()
  .use(rehypeParse, { fragment: true })
  .parse(htmlContent);

const metaData = {};

visit(htmlAst, 'element', node => {
  if (node.tagName === 'meta' && node.properties) {
    const { name, content } = node.properties;
    if (name && content) {
      metaData[name] = content;
    }
  }
});

console.log(metaData);

Вывод:

{
  "description": "Пример статьи",
  "author": "Иван Иванов"
}

Принципы работы с AST

  • Типы узлов: для Markdown используются root, heading, paragraph, yaml, text и др.; для HTML — root, element, text, comment.
  • Обход дерева: стандартная библиотека unist-util-visit позволяет рекурсивно проходить все узлы, фильтруя по типу.
  • Модификация узлов: AST можно изменять, добавлять новые узлы или изменять существующие, что упрощает создание динамического контента.
  • Конвертация в другие форматы: после модификации AST можно снова сериализовать его в Markdown, HTML или даже JSON.

Пример объединения Remark и Rehype

В сценариях генерации статических сайтов часто требуется сначала извлечь метаданные из Markdown через Remark, затем конвертировать Markdown в HTML и обработать его через Rehype для дальнейшего анализа или добавления атрибутов.

import remarkRehype from 'remark-rehype';
import rehypeStringify from 'rehype-stringify';

const htmlResult = await unified()
  .use(remarkParse)
  .use(remarkFrontmatter, ['yaml'])
  .use(remarkRehype)
  .use(rehypeStringify)
  .process(markdownContent);

console.log(String(htmlResult));

Этот подход позволяет хранить метаданные в структуре Markdown, а затем работать с HTML через мощные плагины Rehype, включая оптимизацию, добавление классов, атрибутов и обработку ссылок.

Важные аспекты

  • Обработка Front Matter требует парсинга YAML, так как remark-frontmatter только выделяет блоки.
  • Разделение парсинга Markdown и HTML позволяет создавать гибкие конвейеры трансформации данных.
  • AST предоставляет возможность полностью контролировать структуру документа, что важно для генерации сложных сайтов и приложений.

Метаданные становятся доступными как объекты JavaScript, что позволяет интегрировать их с системами шаблонов, CMS и статическими генераторами контента. Такой подход обеспечивает строгую типизацию, предсказуемое поведение и удобство масштабирования проектов, работающих с контентом.