TOC Service
TOC Service manages the processing of the table of contents (Table of Contents, ToC) in Diplodoc. This service allows modifying the documentation structure at various build stages.
Main features
- Loading and processing of
toc.yamlfiles. - Managing the documentation structure.
- Support for includers.
- Support for conditional logic in ToC.
Accessing the service
export class Extension {
apply(program: Build) {
getBaseHooks(program).BeforeAnyRun.tap('MyExtension', (run) => {
// Получение сервиса из контекста
const {toc} = run;
// Получение hooks сервиса
const tocHooks = getTocHooks(run.toc);
});
}
}
Available hooks
Item
Processing individual ToC items. Called for each item during processing.
tocHooks.Item.tapPromise('MyProcessor', async (item, tocPath) => {
// Скрываем определенные разделы
if (item.name === 'Internal') {
item.hidden = true;
}
// Добавляем метаданные
item.meta = {
...item.meta,
category: 'docs'
};
return item;
});
Includer
Hook for registering custom includers. Allows adding dynamically generated sections to the ToC.
tocHooks.Includer.for('my-includer').tapPromise('MyProcessor', async (toc, options, tocPath) => {
// Генерируем дополнительные элементы
const generatedItems = await generateItems();
return {
...toc,
items: [...(toc.items || []), ...generatedItems]
};
});
Resolved
Hook for working with a fully resolved ToC. At this stage, the ToC already contains all included items and is read-only.
tocHooks.Resolved.tapPromise('MyProcessor', async (toc, tocPath) => {
// Анализируем структуру
validateStructure(toc);
// Собираем статистику
collectMetrics(toc);
});
Included
Hook for processing the ToC after it has been included via include.
tocHooks.Included.tapPromise('MyProcessor', async (toc, tocPath, includeInfo) => {
// Модифицируем включенный TOC
return {
...toc,
meta: {
...toc.meta,
includedFrom: includeInfo.source
}
};
});
Dump
Hook for final modification of the ToC before saving.
tocHooks.Dump.tapPromise('MyProcessor', async (toc, path) => {
// Добавляем общие элементы навигации
return {
...toc,
items: [...(toc.items || []), {
name: 'Support',
href: '/support'
}]
};
});
Loaded
Hook for processing the ToC after it has been loaded from a file.
tocHooks.Loaded.tapPromise('MyProcessor', async (toc, path) => {
// Модифицируем загруженный ToC
return {
...toc,
meta: {
...toc.meta,
loadedAt: new Date().toISOString()
}
};
});
Service API
Method init
Initializes the service by loading the ToC from the specified paths.
Parameters:
paths: NormalizedPath[]— an array of paths totoc.yamlfiles to load.
Calls hooks:
Loaded— after loading each ToC file.
// Инициализация сервиса с указанием путей
await tocService.init(['path/to/toc.yaml']);
Method for
Returns the ToC for the specified path.
Parameters:
path: RelativePath— the relative path to the file for which the ToC should be retrieved.
Returns:
Toc— a ToC object containing the documentation structure.
// Получение ToC для конкретного пути
const toc = tocService.for('path/to/file.md');
Method dump
Saves the ToC to a file.
Parameters:
file: NormalizedPath— the path to the file for saving.toc?: Toc— the ToC object to save (if not specified, the ToC from the cache is used).
Returns:
Promise<VFile<Toc>>— a promise with a virtual file containing the saved ToC.
Calls hooks:
Dump— before saving the ToC to a file.
// Сохранение ToC в файл
await tocService.dump('path/to/toc.yaml', toc);
Method load
Loads the ToC from a file.
Parameters:
path: NormalizedPath— the path to thetoc.yamlfile.
Returns:
Promise<Toc | undefined>— a promise with the loaded ToC or undefined if the file is not found.
Calls hooks:
Loaded— after successful loading of the ToC.Item— for each item in the loaded ToC.
// Загрузка ToC из файла
const toc = await tocService.load('path/to/toc.yaml');
Method include
Includes the ToC via the include directive.
Parameters:
path: RelativePath— the path to the includedtoc.yamlfile.include: IncludeInfo— inclusion information:from?: string— the path to the source file.mode?: 'merge' | 'replace'— the inclusion mode.base?: string— the base path for relative links.content?: string— the file content (if already loaded).
Returns:
Promise<Toc | undefined>— a promise with the included ToC or undefined if the file is not found.
Calls hooks:
Included— after including the ToC.Item— for each item in the included ToC.
// Включение ToC
const includedToc = await tocService.include('path/to/toc.yaml', {
from: 'source/path',
mode: 'merge',
base: 'base/path'
});
Method setToc
Sets the ToC for the specified path.
Parameters:
toc: Toc— the ToC object to set:path: NormalizedPath— path to the file.items?: TocItem[]— ToC items.href?: string— link to the page.meta?: Record<string, unknown>— metadata.
Calls hooks:
Item— for each item in the ToC being set.
// Установка ToC
tocService.setToc({
path: 'path/to/toc.yaml',
items: [...]
});
entries property
Returns the list of all entries in all ToCs.
Returns:
Set<NormalizedPath>— a set of paths to files included in the ToC.
// Получение всех entry
const entries = tocService.entries;
tocs property
Returns the list of all loaded ToCs.
Returns:
Toc[]— an array of loaded ToC objects.
// Получение всех ToC
const tocs = tocService.tocs;
copymap property
Returns the file copy map.
Returns:
Record<NormalizedPath, NormalizedPath>— an object where the key is the source path and the value is the target path.
// Получение карты копирования
const copymap = tocService.copymap;
Usage examples
Adding metadata to sections
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)
}
};
});
});
}
}
Dynamic generation of sections
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]
};
}
);
});
}
}
Structure validation
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);
});
});
}
}