# tools/core/formatters/board.formatter.ts

> 192 lines of code and 58 definitions.

Tree: Coordination tree
Language: typescript
Canonical: https://banes-lab.com/anatomy/coordination#file-coordination-tools-core-formatters-board-formatter-ts
Source text: https://banes-lab.com/assets/sources/source.e756809827b7fe54897196f29af6f7ec0c965ab540f1d60668eeaac333583620.generated.txt

## Definitions

- `join` (lexical_declaration, line 180)
- `isItemId` (lexical_declaration, line 46, exported)
- `wrapped` (lexical_declaration, line 42)
- `wrappedSegment` (lexical_declaration, line 23)
- `stampedCitations` (lexical_declaration, line 207, exported)
- `nextOrdinal` (lexical_declaration, line 94, exported)
- `fencedItem` (lexical_declaration, line 229, exported)
- `INDENT` (lexical_declaration, line 3)
- `WRAP_WIDTH` (lexical_declaration, line 5)
- `ORDINAL_SEPARATOR` (lexical_declaration, line 7)
- `TO_PREFIX` (lexical_declaration, line 9)
- `KIND_FIELD` (lexical_declaration, line 11, exported)
- `ITEM_KINDS` (lexical_declaration, line 13, exported)
- `AT_FIELD` (lexical_declaration, line 15, exported)
- `TO_FIELD` (lexical_declaration, line 17, exported)
- `READ_FIELD` (lexical_declaration, line 19, exported)
- `ADDRESS_PUNCTUATION` (lexical_declaration, line 21)
- `line` (lexical_declaration, line 25)
- `cut` (lexical_declaration, line 47, exported)
- `i` (lexical_declaration, line 59, exported)
- `highestIn` (lexical_declaration, line 69)
- `prefix` (lexical_declaration, line 70)
- `cursor` (lexical_declaration, line 72)
- `char` (lexical_declaration, line 77, exported)
- `highest` (lexical_declaration, line 95, exported)
- `ordinal` (lexical_declaration, line 103, exported)
- `archived` (lexical_declaration, line 110, exported)
- `ADDRESS_CONNECTORS` (lexical_declaration, line 114)
- `addressToken` (lexical_declaration, line 116)
- `token` (lexical_declaration, line 117)
- `isSeatLetter` (lexical_declaration, line 124)
- `addresseesOf` (lexical_declaration, line 128, exported)
- `tokens` (lexical_declaration, line 132, exported)
- `end` (lexical_declaration, line 133, exported)
- `itemKindOf` (lexical_declaration, line 137, exported)
- `opener` (lexical_declaration, line 138, exported)
- `CITES_FIELD` (lexical_declaration, line 159, exported)
- `stampOf` (lexical_declaration, line 161, exported)
- `REFERENCE_JOIN` (lexical_declaration, line 174)
- `BACKTICK` (lexical_declaration, line 176)
- `citedPathOf` (lexical_declaration, line 178)
- `trimmed` (lexical_declaration, line 179, exported)
- `citedSurfaces` (lexical_declaration, line 188, exported)
- `out` (lexical_declaration, line 189, exported)
- `path` (lexical_declaration, line 191, exported)
- `STAMP_MARK` (lexical_declaration, line 199)
- `citationOf` (lexical_declaration, line 201)
- `mark` (lexical_declaration, line 202)
- `stamp` (lexical_declaration, line 203)
- `at` (lexical_declaration, line 208, exported)
- `rest` (lexical_declaration, line 212, exported)
- `stop` (lexical_declaration, line 213, exported)
- `held` (lexical_declaration, line 214, exported)
- `citation` (lexical_declaration, line 216, exported)
- `stampEntry` (lexical_declaration, line 221)
- `citationStamp` (lexical_declaration, line 225, exported)
- `to` (lexical_declaration, line 236, exported)
- `meta` (lexical_declaration, line 237, exported)

## Uses

- [tools/core/analyzers/board.analyzer.ts](https://banes-lab.com/source/coordination/tools/core/analyzers/board.analyzer.ts.md)

## Used by

- [tools/core/entrypoints/board.entrypoint.ts](https://banes-lab.com/source/coordination/tools/core/entrypoints/board.entrypoint.ts.md)
- [tools/core/entrypoints/corpus.entrypoint.ts](https://banes-lab.com/source/coordination/tools/core/entrypoints/corpus.entrypoint.ts.md)
- [tools/core/registries/claim.registry.ts](https://banes-lab.com/source/coordination/tools/core/registries/claim.registry.ts.md)
- [tools/core/resolvers/reference.resolver.ts](https://banes-lab.com/source/coordination/tools/core/resolvers/reference.resolver.ts.md)
- [tools/core/runners/board.runner.ts](https://banes-lab.com/source/coordination/tools/core/runners/board.runner.ts.md)
- [tools/core/validators/claim.validator.ts](https://banes-lab.com/source/coordination/tools/core/validators/claim.validator.ts.md)

## Source

```typescript
import { delimitersIn } from "../analyzers/board.analyzer.ts";

const INDENT = "           ";

const WRAP_WIDTH = 120;

const ORDINAL_SEPARATOR = "-";

const TO_PREFIX = "To ";

export const KIND_FIELD = "kind:";

export const ITEM_KINDS = ["artifact", "judgement"];

export const AT_FIELD = "at:";

export const TO_FIELD = "to:";

export const READ_FIELD = "read:";

const ADDRESS_PUNCTUATION = new Set([",", ":", ";", "."]);

const wrappedSegment = function wrappedSegment(text: string): string[] {
    const out: string[] = [];
    let line = "";

    for (const word of text.split(" ")) {
        if (line.length > 0 && line.length + word.length + 1 > WRAP_WIDTH) {
            out.push(`${INDENT}${line}`);
            line = word;
        } else {
            line = line.length === 0 ? word : `${line} ${word}`;
        }
    }

    if (line.length > 0) {
        out.push(`${INDENT}${line}`);
    }
    return out;
};

const wrapped = function wrapped(text: string): string[] {
    return text.split("\n").flatMap((segment) => (segment.trim().length === 0 ? [""] : wrappedSegment(segment)));
};

export const isItemId = function isItemId(text: string): boolean {
    const cut = text.indexOf(ORDINAL_SEPARATOR);
    if (cut <= 0 || cut === text.length - 1) {
        return false;
    }

    for (let i = 0; i < cut; i += 1) {
        const char = text.charAt(i);
        if (char < "A" || char > "Z") {
            return false;
        }
    }

    for (let i = cut + 1; i < text.length; i += 1) {
        const char = text.charAt(i);
        if (char < "0" || char > "9") {
            return false;
        }
    }

    return true;
};

const highestIn = function highestIn(text: string, agent: string): number {
    const prefix = `${agent}${ORDINAL_SEPARATOR}`;
    let highest = 0;
    let cursor = text.indexOf(prefix);

    while (cursor !== -1) {
        let end = cursor + prefix.length;
        while (end < text.length) {
            const char = text.charAt(end);
            if (char < "0" || char > "9") {
                break;
            }
            end += 1;
        }

        const ordinal = Number(text.slice(cursor + prefix.length, end));
        if (Number.isFinite(ordinal) && ordinal > highest) {
            highest = ordinal;
        }
        cursor = text.indexOf(prefix, end);
    }

    return highest;
};

export const nextOrdinal = function nextOrdinal(sources: readonly string[], agent: string, archive: string): number {
    let highest = 0;

    for (const source of sources) {
        for (const mark of delimitersIn(source)) {
            if (!mark.agent.startsWith(`${agent}${ORDINAL_SEPARATOR}`)) {
                continue;
            }

            const ordinal = Number(mark.agent.slice(agent.length + 1));
            if (Number.isFinite(ordinal) && ordinal > highest) {
                highest = ordinal;
            }
        }
    }

    const archived = highestIn(archive, agent);
    return (archived > highest ? archived : highest) + 1;
};

const ADDRESS_CONNECTORS: ReadonlySet<string> = new Set(["AND", "and"]);

const addressToken = function addressToken(word: string): string {
    let token = word;
    while (token.length > 0 && ADDRESS_PUNCTUATION.has(token.slice(-1))) {
        token = token.slice(0, -1);
    }
    return token;
};

const isSeatLetter = function isSeatLetter(token: string): boolean {
    return token.length === 1 && token >= "A" && token <= "Z";
};

export const addresseesOf = function addresseesOf(text: string): string[] {
    if (!text.startsWith(TO_PREFIX)) {
        return [];
    }
    const tokens = text.slice(TO_PREFIX.length).split(" ").map(addressToken);
    const end = tokens.findIndex((token) => !isSeatLetter(token) && !ADDRESS_CONNECTORS.has(token));
    return tokens.slice(0, end === -1 ? tokens.length : end).filter(isSeatLetter);
};

export const itemKindOf = function itemKindOf(source: string, key: string): string {
    const opener = `┌─── AGENT ${key} ───`;

    for (const line of source.split("\n")) {
        const trimmed = line.trim();
        if (!trimmed.startsWith(opener)) {
            continue;
        }

        const at = trimmed.indexOf(KIND_FIELD);
        if (at === -1) {
            return "";
        }

        const rest = trimmed.slice(at + KIND_FIELD.length);
        const stop = rest.indexOf(" ");
        return stop === -1 ? rest : rest.slice(0, stop);
    }

    return "";
};

export const CITES_FIELD = "cites:";

export const stampOf = function stampOf(marker: string): number {
    const at = marker.indexOf(AT_FIELD);
    if (at === -1) {
        return 0;
    }

    const rest = marker.slice(at + AT_FIELD.length);
    const stop = rest.indexOf(" ");
    const held = Number((stop === -1 ? rest : rest.slice(0, stop)).trim());

    return Number.isFinite(held) ? held : 0;
};

const REFERENCE_JOIN = "`: `";

const BACKTICK = "`";

const citedPathOf = function citedPathOf(line: string): string | null {
    const trimmed = line.trim();
    const join = trimmed.indexOf(REFERENCE_JOIN);
    if (!trimmed.startsWith(BACKTICK) || !trimmed.endsWith(BACKTICK) || join === -1) {
        return null;
    }
    const path = trimmed.slice(join + REFERENCE_JOIN.length, -1).trim();
    return path.length === 0 || path.includes(" ") || path.includes(",") ? null : path;
};

export const citedSurfaces = function citedSurfaces(text: string): string[] {
    const out: string[] = [];
    for (const line of text.split("\n")) {
        const path = citedPathOf(line);
        if (path !== null && !out.includes(path)) {
            out.push(path);
        }
    }
    return out;
};

const STAMP_MARK = "@";

const citationOf = function citationOf(entry: string): { path: string; at: number } | null {
    const mark = entry.lastIndexOf(STAMP_MARK);
    const stamp = Number(entry.slice(mark + 1));
    return mark <= 0 || !Number.isFinite(stamp) ? null : { at: stamp, path: entry.slice(0, mark) };
};

export const stampedCitations = function stampedCitations(marker: string): { path: string; at: number }[] {
    const at = marker.indexOf(CITES_FIELD);
    if (at === -1) {
        return [];
    }
    const rest = marker.slice(at + CITES_FIELD.length);
    const stop = rest.indexOf(" ");
    const held = stop === -1 ? rest : rest.slice(0, stop);
    return held.split(",").flatMap((entry) => {
        const citation = citationOf(entry);
        return citation === null ? [] : [citation];
    });
};

const stampEntry = function stampEntry(entry: { path: string; at: number }): string {
    return `${entry.path}${STAMP_MARK}${String(entry.at)}`;
};

export const citationStamp = function citationStamp(cited: readonly { path: string; at: number }[]): string {
    return cited.length === 0 ? "" : ` ${CITES_FIELD}${cited.map(stampEntry).join(",")}`;
};

export const fencedItem = function fencedItem(
    key: string,
    text: string,
    at: number,
    kind: string,
    cited: readonly { path: string; at: number }[] = [],
): string[] {
    const to = addresseesOf(text);
    const meta = `${KIND_FIELD}${kind} ${AT_FIELD}${String(at)} ${TO_FIELD}${to.length === 0 ? "*" : to.join(",")}${citationStamp(
        cited,
    )}`;

    return [`${INDENT}┌─── AGENT ${key} ─── ${meta}`, ...wrapped(text), `${INDENT}└─── END AGENT ${key}`];
};
```
