Remark и Rehype используют концепцию плагинов для расширения функциональности обработки Markdown и HTML. Плагины в этих библиотеках являются функциями, которые принимают один или несколько аргументов и возвращают функцию-посетитель, изменяющую или анализирующую дерево синтаксического разбора (AST). Это обеспечивает модульность и позволяет строить сложные цепочки обработки текста, применяя несколько плагинов последовательно.
Ключевые моменты архитектуры плагинов:
mdast), Rehype
— с HTML AST (hast).Правильно оформленная документация плагина состоит из нескольких обязательных элементов:
unified().Пример базовой структуры документации плагина:
## my-plugin
### Назначение
Добавляет уникальные идентификаторы для всех заголовков Markdown.
### Установка
```bash
npm install my-plugin
import { unified } from 'unified';
import remarkParse from 'remark-parse';
import remarkStringify from 'remark-stringify';
import myPlugin from 'my-plugin';
const processor = unified()
.use(remarkParse)
.use(myPlugin, { prefix: 'section-' })
.use(remarkStringify);
const output = processor.processSync('# Заголовок').toString();
console.log(output);
| Опция | Тип | По умолчанию | Описание |
|---|---|---|---|
| prefix | string | ‘heading-’ | Префикс для идентификаторов |
### Документирование опций
Каждая опция должна быть описана максимально подробно:
- **Тип**: указывайте точный тип данных (`string`, `number`, `boolean`, `array`, `function`).
- **Значение по умолчанию**: обязательно указывать, чтобы избежать недопонимания.
- **Описание поведения**: как изменение опции влияет на работу плагина.
- **Примеры использования**: несколько примеров, иллюстрирующих эффект изменения опции.
Пример для функции обратного вызова в конфигурации:
```js
{
transform: (node) => {
if (node.type === 'heading') {
node.data = { ...node.data, custom: true };
}
return node;
}
}
Документация должна включать информацию о типичных ошибках и способах их предотвращения:
if (typeof options.prefix !== 'string') {
throw new TypeError('Опция prefix должна быть строкой');
}
Плагины могут быть асинхронными, если требуется взаимодействие с внешними ресурсами или сложные вычисления:
async function asyncPlugin() {
return async (tree) => {
await someAsyncOperation();
visit(tree, 'text', (node) => {
node.value = node.value.toUpperCase();
});
};
}
Документация должна отражать, что обработка может быть асинхронной и
показать, как правильно использовать
await processor.process().
В документации полезно показать цепочки плагинов с разными задачами: обработка ссылок, добавление метаданных, кастомные трансформации AST.
unified()
.use(remarkParse)
.use(remarkAutolinkHeadings)
.use(myPlugin, { prefix: 'section-' })
.use(remarkStringify);
Каждый пример должен демонстрировать реальный сценарий, чтобы разработчики понимали взаимодействие нескольких плагинов и порядок их применения.
Интеграция с инструментами вроде TypeDoc,
JSDoc или remark-docs позволяет автоматически
создавать структурированную документацию на основе JSDoc-комментариев в
коде. Рекомендуется включать:
/**
* Плагин добавляет идентификаторы заголовкам.
* @param {Object} options - Настройки плагина
* @param {string} options.prefix - Префикс идентификатора
* @returns {Function} Посетитель AST
*/
function myPlugin(options = {}) {
...
}
Эта методика обеспечивает, что документация плагина Remark или Rehype будет понятной, структурированной и удобной для интеграции в проекты.