# core/formatters/catalog.formatter.ts

> 27 lines of code and 7 definitions.

Tree: GovLab Docs
Language: typescript
Layer: processing
Canonical: https://banes-lab.com/anatomy/docs#file-docs-core-formatters-catalog-formatter-ts
Source text: https://banes-lab.com/source/docs/core/formatters/catalog.formatter.ts.txt

Listed in [core/formatters](https://banes-lab.com/api/source/docs/core/formatters.md), before [core/formatters/coverage.formatter.ts](https://banes-lab.com/source/docs/core/formatters/coverage.formatter.ts.md).

## Definitions

- `sectionLines` (lexical_declaration, line 11)
- `renderConcernBarrel` (lexical_declaration, line 15, exported)
- `LINE_BREAK` (lexical_declaration, line 5)
- `byTypeThenName` (lexical_declaration, line 7)
- `sorted` (lexical_declaration, line 20, exported)
- `lines` (lexical_declaration, line 21, exported)
- `entry` (lexical_declaration, line 22, exported)

## Contained in

- [core/formatters](https://banes-lab.com/anatomy/docs/folder-docs-core-formatters.md)

## Uses

- [configuration/strings/catalog.strings.ts](https://banes-lab.com/source/docs/configuration/strings/catalog.strings.ts.md)
- [core/formatters/markdown.formatter.ts](https://banes-lab.com/source/docs/core/formatters/markdown.formatter.ts.md)

## Linked from

- [configuration/strings](https://banes-lab.com/anatomy/docs/folder-docs-configuration-strings.md)
- [core/formatters](https://banes-lab.com/anatomy/docs/folder-docs-core-formatters.md)

## Source

```typescript
import { SUPERSEDED_MARKER, barrelEntry, barrelHeading, barrelSection } from "#configuration/strings/catalog.strings";
import type { DocNode } from "#types/document.types";
import { titleCase } from "#core/formatters/markdown.formatter";

const LINE_BREAK = "\n";

const byTypeThenName = function byTypeThenName(left: DocNode, right: DocNode): number {
    return left.type.localeCompare(right.type) || left.name.localeCompare(right.name);
};

const sectionLines = function sectionLines(type: string): string[] {
    return ["", barrelSection(titleCase(type)), ""];
};

export const renderConcernBarrel = function renderConcernBarrel(
    concern: string,
    nodes: readonly DocNode[],
    context: { rootPrefix: string; superseded: ReadonlySet<string> },
): string {
    const sorted = nodes.toSorted(byTypeThenName);
    const lines = sorted.flatMap((node, index) => {
        const entry = barrelEntry(
            node.name,
            node.relPath.slice(context.rootPrefix.length),
            node.summary,
            context.superseded.has(node.name) ? SUPERSEDED_MARKER : "",
        );
        return sorted[index - 1]?.type === node.type ? [entry] : [...sectionLines(node.type), entry];
    });
    return [barrelHeading(titleCase(concern)), "", ...lines, ""].join(LINE_BREAK);
};
```
