TOC Service
TOC Service управляет обработкой оглавления (Table of Contents) в Diplodoc.
Этот сервис позволяет модифицировать структуру документации на различных этапах сборки.
Основные возможности
- Загрузка и обработка файлов
toc.yaml
- Управление структурой документации
- Поддержка включателей (includers)
- Поддержка условной логики в TOC
Получение доступа к сервису
export class Extension {
apply(program: Build) {
getBaseHooks(program).BeforeAnyRun.tap('MyExtension', (run) => {
// Получение сервиса из контекста
const {toc} = run;
// Получение hooks сервиса
const tocHooks = getTocHooks(run.toc);
});
}
}
Доступные хуки
Item
Hook для обработки отдельных элементов TOC. Вызывается для каждого элемента в процессе обработки.
tocHooks.Item.tapPromise('MyProcessor', async (item, tocPath) => {
// Скрываем определенные разделы
if (item.name === 'Internal') {
item.hidden = true;
}
// Добавляем метаданные
item.meta = {
...item.meta,
category: 'docs'
};
return item;
});
Includer
Hook для регистрации пользовательских включателей. Позволяет добавлять динамически генерируемые разделы в TOC.
tocHooks.Includer.for('my-includer').tapPromise('MyProcessor', async (toc, options, tocPath) => {
// Генерируем дополнительные элементы
const generatedItems = await generateItems();
return {
...toc,
items: [...(toc.items || []), ...generatedItems]
};
});
Resolved
Hook для работы с полностью разрешенным TOC. На этом этапе TOC уже содержит все включенные элементы и является read-only.
tocHooks.Resolved.tapPromise('MyProcessor', async (toc, tocPath) => {
// Анализируем структуру
validateStructure(toc);
// Собираем статистику
collectMetrics(toc);
});
Included
Hook для обработки TOC после его включения через директиву include.
tocHooks.Included.tapPromise('MyProcessor', async (toc, tocPath, includeInfo) => {
// Модифицируем включенный TOC
return {
...toc,
meta: {
...toc.meta,
includedFrom: includeInfo.source
}
};
});
Dump
Hook для финальной модификации TOC перед сохранением.
tocHooks.Dump.tapPromise('MyProcessor', async (toc, path) => {
// Добавляем общие элементы навигации
return {
...toc,
items: [...(toc.items || []), {
name: 'Support',
href: '/support'
}]
};
});
Loaded
Hook для обработки TOC после его загрузки из файла.
tocHooks.Loaded.tapPromise('MyProcessor', async (toc, path) => {
// Модифицируем загруженный TOC
return {
...toc,
meta: {
...toc.meta,
loadedAt: new Date().toISOString()
}
};
});
API сервиса
Метод init
Инициализирует сервис, загружая TOC из указанных путей.
Параметры:
paths: NormalizedPath[]
- массив путей к файламtoc.yaml
для загрузки
Вызывает хуки:
Loaded
- после загрузки каждого TOC файла
// Инициализация сервиса с указанием путей
await tocService.init(['path/to/toc.yaml']);
Метод for
Возвращает TOC для указанного пути.
Параметры:
path: RelativePath
- относительный путь к файлу, для которого нужно получить TOC
Возвращает:
Toc
- объект TOC, содержащий структуру документации
// Получение TOC для конкретного пути
const toc = tocService.for('path/to/file.md');
Метод dump
Сохраняет TOC в файл.
Параметры:
file: NormalizedPath
- путь к файлу для сохраненияtoc?: Toc
- объект TOC для сохранения (если не указан, используется TOC из кэша)
Возвращает:
Promise<VFile<Toc>>
- промис с виртуальным файлом, содержащим сохраненный TOC
Вызывает хуки:
Dump
- перед сохранением TOC в файл
// Сохранение TOC в файл
await tocService.dump('path/to/toc.yaml', toc);
Метод load
Загружает TOC из файла.
Параметры:
path: NormalizedPath
- путь к файлуtoc.yaml
Возвращает:
Promise<Toc | undefined>
- промис с загруженным TOC или undefined, если файл не найден
Вызывает хуки:
Loaded
- после успешной загрузки TOCItem
- для каждого элемента в загруженном TOC
// Загрузка TOC из файла
const toc = await tocService.load('path/to/toc.yaml');
Метод include
Включает TOC через директиву include.
Параметры:
path: RelativePath
- путь к включаемому файлуtoc.yaml
include: IncludeInfo
- информация о включении:from?: string
- путь к исходному файлуmode?: 'merge' | 'replace'
- режим включенияbase?: string
- базовый путь для относительных ссылокcontent?: string
- содержимое файла (если уже загружено)
Возвращает:
Promise<Toc | undefined>
- промис с включенным TOC или undefined, если файл не найден
Вызывает хуки:
Included
- после включения TOCItem
- для каждого элемента во включенном TOC
// Включение TOC
const includedToc = await tocService.include('path/to/toc.yaml', {
from: 'source/path',
mode: 'merge',
base: 'base/path'
});
Метод setToc
Устанавливает TOC для указанного пути.
Параметры:
toc: Toc
- объект TOC для установки:path: NormalizedPath
- путь к файлуitems?: TocItem[]
- элементы TOChref?: string
- ссылка на страницуmeta?: Record<string, unknown>
- метаданные
Вызывает хуки:
Item
- для каждого элемента в устанавливаемом TOC
// Установка TOC
tocService.setToc({
path: 'path/to/toc.yaml',
items: [...]
});
Свойство entries
Возвращает список всех entry во всех TOC.
Возвращает:
Set<NormalizedPath>
- множество путей к файлам, включенным в TOC
// Получение всех entry
const entries = tocService.entries;
Свойство tocs
Возвращает список всех загруженных TOC.
Возвращает:
Toc[]
- массив загруженных объектов TOC
// Получение всех TOC
const tocs = tocService.tocs;
Свойство copymap
Возвращает карту копирования файлов.
Возвращает:
Record<NormalizedPath, NormalizedPath>
- объект, где ключ - исходный путь, значение - целевой путь
// Получение карты копирования
const copymap = tocService.copymap;
Примеры использования
Добавление метаданных к разделам
export class Extension {
apply(program: Build) {
getBaseHooks(program).BeforeAnyRun.tap('MetadataProcessor', (run) => {
const tocHooks = getTocHooks(run.toc);
tocHooks.Item.tapPromise('MetadataProcessor', async (item) => {
return {
...item,
meta: {
...item.meta,
lastUpdated: new Date().toISOString(),
category: getCategoryFromPath(item.href)
}
};
});
});
}
}
Динамическая генерация разделов
export class Extension {
apply(program: Build) {
getBaseHooks(program).BeforeAnyRun.tap('DynamicSections', (run) => {
const tocHooks = getTocHooks(run.toc);
tocHooks.Includer.for('generated-docs').tapPromise(
'DynamicSections',
async (toc, options) => {
const items = await fetchDocumentationItems();
return {
...toc,
items: [...(toc.items || []), ...items]
};
}
);
});
}
}
Валидация структуры
export class Extension {
apply(program: Build) {
getBaseHooks(program).BeforeAnyRun.tap('StructureValidator', (run) => {
const tocHooks = getTocHooks(run.toc);
tocHooks.Resolved.tapPromise('StructureValidator', async (toc) => {
validateMaxDepth(toc, 3);
validateUniqueUrls(toc);
validateRequiredSections(toc);
});
});
}
}