# core/converters/section.segment.converter.ts

> 52 lines of code and 15 definitions.

Tree: Bane's Lab Build Scripts
Language: typescript
Layer: processing
Canonical: https://banes-lab.com/anatomy/build-scripts#file-build-scripts-core-converters-section-segment-converter-ts
Source text: https://banes-lab.com/source/build-scripts/core/converters/section.segment.converter.ts.txt

Listed in [core/converters](https://banes-lab.com/api/source/build-scripts/core/converters.md), after [core/converters/section.page.converter.ts](https://banes-lab.com/source/build-scripts/core/converters/section.page.converter.ts.md) and before [core/converters/site.converter.ts](https://banes-lab.com/source/build-scripts/core/converters/site.converter.ts.md).

## Definitions

- `partedSection` (lexical_declaration, line 39, exported)
- `subsectionPart` (lexical_declaration, line 22)
- `SUBSECTIONS_KEY` (lexical_declaration, line 11)
- `PART_REF_MARK` (lexical_declaration, line 12)
- `subsectionTitle` (lexical_declaration, line 14)
- `withoutSubsections` (lexical_declaration, line 18)
- `title` (lexical_declaration, line 28)
- `ref` (lexical_declaration, line 29)
- `address` (lexical_declaration, line 30)
- `whole` (lexical_declaration, line 31)
- `listed` (lexical_declaration, line 40, exported)
- `parts` (lexical_declaration, line 44, exported)
- `leaves` (lexical_declaration, line 45, exported)
- `summaries` (lexical_declaration, line 48, exported)
- `data` (lexical_declaration, line 55, exported)

## Contained in

- [core/converters](https://banes-lab.com/anatomy/build-scripts/folder-build-scripts-core-converters.md)

## Uses

- [core/formatters/section.formatter.ts](https://banes-lab.com/source/build-scripts/core/formatters/section.formatter.ts.md)
- [core/stores/catalog.store.ts](https://banes-lab.com/source/build-scripts/core/stores/catalog.store.ts.md)

## Used by

- [core/converters/section.converter.ts](https://banes-lab.com/source/build-scripts/core/converters/section.converter.ts.md)

## Linked from

- [core/converters](https://banes-lab.com/anatomy/build-scripts/folder-build-scripts-core-converters.md)
- [core/formatters](https://banes-lab.com/anatomy/build-scripts/folder-build-scripts-core-formatters.md)
- [core/stores](https://banes-lab.com/anatomy/build-scripts/folder-build-scripts-core-stores.md)

## Source

```typescript
import { CATALOG_FILE_BUDGET, INDEX_PART_BUDGET, INDEX_PART_KIND } from "#configuration/constants/catalog.constants";
import type { Identity, Leaf } from "#types/catalog.types";
import type { SectionPartAt, SectionShape } from "#types/section.types";
import { packedParts, serialize } from "#core/stores/catalog.store";
import { Buffer } from "node:buffer";
import { indexPart } from "#core/resolvers/catalog.resolver";
import { indexPartTitle } from "#configuration/strings/catalog.strings";
import { isRecord } from "#core/selectors/base.selector";
import { renderSectionPart } from "#core/formatters/section.formatter";

const SUBSECTIONS_KEY = "subsections";
const PART_REF_MARK = "/";

const subsectionTitle = function subsectionTitle(value: unknown): string {
    return isRecord(value) && typeof value["title"] === "string" ? value["title"] : "";
};

const withoutSubsections = function withoutSubsections(section: SectionShape): object {
    return Object.fromEntries(Object.entries(section).filter(([key]) => key !== SUBSECTIONS_KEY));
};

const subsectionPart = function subsectionPart(
    head: Identity,
    members: readonly object[],
    at: SectionPartAt,
    site: string,
): Leaf {
    const title = indexPartTitle(head.title, at.part, at.total);
    const ref = head.ref + PART_REF_MARK + String(at.part);
    const address = indexPart(head.address, String(at.part));
    const whole = site + (head.address.markdown ?? head.address.json);
    return {
        data: { part: at.part, ref, subsections: members, title, total: at.total },
        identity: { address, href: null, kind: INDEX_PART_KIND, ref, summary: null, title },
        markdown: renderSectionPart(title, site + address.json, whole, members.map(subsectionTitle)),
    };
};

export const partedSection = function partedSection(leaf: Leaf, section: SectionShape, site: string): readonly Leaf[] {
    const listed: unknown = Reflect.get(section, SUBSECTIONS_KEY);
    if (Buffer.byteLength(serialize(leaf.data)) <= CATALOG_FILE_BUDGET || !Array.isArray(listed)) {
        return [leaf];
    }
    const parts = packedParts(listed.filter(isRecord), INDEX_PART_BUDGET);
    const leaves = parts.map((members, index) =>
        subsectionPart(leaf.identity, members, { part: index + 1, total: parts.length }, site),
    );
    const summaries = leaves.map((part, index) => ({
        count: parts[index]?.length ?? 0,
        first: subsectionTitle(parts[index]?.at(0)),
        json: site + part.identity.address.json,
        last: subsectionTitle(parts[index]?.at(-1)),
        markdown: part.identity.address.markdown === null ? null : site + part.identity.address.markdown,
    }));
    const data = { ...leaf.data, content: withoutSubsections(section), parts: summaries };
    return [...leaves, { ...leaf, data }];
};
```
