core/converters/source.segment.converter.ts

core/converters/source.segment.converter.ts is a file in Bane's Lab Build Scripts. 42 lines of code and 13 definitions.

import { partLabel, partTitle, sourcePartDescription } from "#configuration/strings/page.strings";
import type { SourceRoute } from "#types/source.types";

const LINE_BREAK = "\n";
const PART_MARK = "~";

export const partSlicesOf = function partSlicesOf(text: string, limit: number): readonly (readonly [number, number])[] {
    const slices: (readonly [number, number])[] = [];
    let start = 0;
    while (start < text.length) {
        const cut = start + limit;
        const lineEnd = cut >= text.length ? text.length : text.lastIndexOf(LINE_BREAK, cut);
        const end = cut >= text.length ? text.length : lineEnd > start ? lineEnd + 1 : cut;
        slices.push([start, end]);
        start = end;
    }
    return slices;
};

export const partPathOf = function partPathOf(path: string, index: number): string {
    return index === 0 ? path : path + PART_MARK + String(index + 1);
};

export const sourcePartsOf = function sourcePartsOf(route: SourceRoute, text: string, limit: number): readonly SourceRoute[] {
    const slices = partSlicesOf(text, limit);
    if (slices.length < 2) {
        return [route];
    }
    const { subject } = route;
    const count = slices.length;
    const links = slices.map((_, index) => ({
        label: partLabel(index + 1, count),
        path: partPathOf(subject.path, index),
    }));
    return slices.map((slice, index) => ({
        ...route,
        children: links,
        slice,
        subject: {
            ...subject,
            description: index === 0 ? subject.description : sourcePartDescription(subject.name, index + 1, count),
            path: partPathOf(subject.path, index),
            title: index === 0 ? subject.title : partTitle(subject.title, index + 1, count),
        },
    }));
};