Унифицированный процессор: архитектура

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

Абстрактное синтаксическое дерево (AST)

В основе архитектуры лежит дерево узлов, где каждый узел представляет отдельный элемент исходного текста: заголовок, абзац, список, текстовый фрагмент, ссылка или атрибут HTML. AST обеспечивает:

  • Унифицированное представление для разных форматов текста.
  • Легкость трансформации, так как манипуляции происходят на уровне узлов, а не строки текста.
  • Сохранение метаданных, таких как позиции в исходном файле, что критично для генерации отчетов об ошибках и подсветки синтаксиса.

Пример структуры узла Markdown в Remark:

{
  type: 'heading',
  depth: 2,
  children: [
    { type: 'text', value: 'Пример заголовка' }
  ]
}

Модульность и плагины

Архитектура процессора построена вокруг плагинов, которые выполняют три основные функции:

  1. Парсинг (Parser) — преобразует исходный текст в AST. Remark использует remark-parse, Rehype — rehype-parse.
  2. Трансформация (Transformer) — функции, работающие с AST для модификации структуры, добавления или удаления узлов. Трансформеры можно комбинировать в цепочку.
  3. Генерация (Compiler) — преобразует AST обратно в текстовый формат. Remark использует remark-stringify, Rehype — rehype-stringify.

Каждый плагин получает AST и возвращает модифицированное дерево. Такой подход обеспечивает высокую гибкость и возможность создавать кастомные конвейеры обработки текста.

Поток обработки данных

Процесс обработки текста через унифицированный процессор можно представить как тройной конвейер:

  1. Parse Stage: исходный Markdown или HTML → AST.

  2. Transform Stage: модификации AST, добавление плагинов, например:

    • автоматическая нумерация заголовков,
    • проверка орфографии,
    • конвертация ссылок.
  3. Compile Stage: AST → конечный текстовый формат.

Такой поток позволяет создавать цепочки обработки, где каждый этап строго разделен и легко настраивается.

Взаимодействие Remark и Rehype

Remark и Rehype могут работать совместно через унифицированный формат AST unist (Universal Syntax Tree). Использование remark-rehype позволяет преобразовать Markdown AST в HTML AST, после чего его можно обрабатывать через плагины Rehype, а затем сгенерировать HTML.

Пример схемы взаимодействия:

Markdown → Remark Parser → Markdown AST → Remark Plugins → remark-rehype → HTML AST → Rehype Plugins → HTML Compiler → HTML

Ключевые преимущества:

  • Разделение ответственности: Remark отвечает за Markdown, Rehype — за HTML.
  • Возможность многократной трансформации: Markdown можно модифицировать до конвертации в HTML и после.
  • Совместимость с другими инструментами экосистемы unified.

Директивы плагинов и расширяемость

Унифицированная архитектура предусматривает сильную кастомизацию через плагины:

  • Плагины могут быть синхронными или асинхронными.
  • Каждый плагин может добавлять новые узлы или изменять существующие, поддерживая принципы immutability, если это требуется.
  • Возможность комбинировать плагины из разных экосистем, создавая мощные цепочки трансформаций.

Пример использования нескольких плагинов в цепочке:

import { unified } from 'unified'
import remarkParse from 'remark-parse'
import remarkRehype from 'remark-rehype'
import rehypeStringify from 'rehype-stringify'
import remarkSlug from 'remark-slug'
import rehypeAutolinkHeadings from 'rehype-autolink-headings'

const processor = unified()
  .use(remarkParse)
  .use(remarkSlug)
  .use(remarkRehype)
  .use(rehypeAutolinkHeadings)
  .use(rehypeStringify)

В этом примере Markdown сначала парсится, затем заголовки получают уникальные идентификаторы (remark-slug), после чего происходит преобразование в HTML с автоматическими ссылками на заголовки (rehype-autolink-headings).

Контроль качества и устойчивость

Унифицированный процессор строится так, чтобы обеспечить:

  • Предсказуемость трансформаций, благодаря строгой типизации AST.
  • Отладку на уровне AST, что упрощает поиск ошибок.
  • Совместимость между плагинами, предотвращая конфликты, если плагины корректно используют интерфейсы unist.

Итоговая архитектурная концепция

  1. AST как центр всей обработки текста.
  2. Плагинная модульность, позволяющая легко добавлять новые функциональности.
  3. Разделение этапов: парсинг → трансформация → генерация.
  4. Совместимость с другими процессорами, через unist и промежуточные конвертеры.
  5. Расширяемость и гибкость, позволяющая создавать как простые, так и сложные конвейеры обработки Markdown и HTML.

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