# tools/core/readers/token.reader.ts

> 64 lines of code and 17 definitions.

Tree: Coordination tree
Language: typescript
Canonical: https://banes-lab.com/anatomy/coordination#file-coordination-tools-core-readers-token-reader-ts
Source text: https://banes-lab.com/assets/sources/source.dc3cf41baac08cbc5dd8d62490b31b798dd159e82b93e18240eb9595ee076f36.generated.txt

## Definitions

- `enclosedStep` (lexical_declaration, line 26)
- `importStep` (lexical_declaration, line 41)
- `stepAt` (lexical_declaration, line 50)
- `LineContext` (interface_declaration, line 3)
- `Step` (interface_declaration, line 9)
- `IMPORT_STOPS` (lexical_declaration, line 14)
- `inlineOf` (lexical_declaration, line 16)
- `close` (lexical_declaration, line 33)
- `cursor` (lexical_declaration, line 42)
- `inline` (lexical_declaration, line 46)
- `char` (lexical_declaration, line 51)
- `opensImport` (lexical_declaration, line 58)
- `inlinesOf` (lexical_declaration, line 62, exported)
- `context` (lexical_declaration, line 63, exported)
- `out` (lexical_declaration, line 64, exported)
- `index` (lexical_declaration, line 65, exported)
- `step` (lexical_declaration, line 68, exported)

## Source

```typescript
import type { Inline, InlineKind } from "../types/segment.types.ts";

interface LineContext {
    readonly line: string;
    readonly start: number;
    readonly number: number;
}

interface Step {
    readonly inlines: readonly Inline[];
    readonly next: number;
}

const IMPORT_STOPS = new Set([" ", "`", ")"]);

const inlineOf = function inlineOf(context: LineContext, kind: InlineKind, from: number, to: number): Inline {
    return {
        end: context.start + to,
        kind,
        line: context.number,
        start: context.start + from,
        value: context.line.slice(from, to),
    };
};

const enclosedStep = function enclosedStep(
    context: LineContext,
    at: number,
    width: number,
    closer: string,
    kind: InlineKind,
): Step {
    const close = context.line.indexOf(closer, at + width);
    if (close === -1) {
        return { inlines: [], next: at + 1 };
    }
    const inline = inlineOf(context, kind, at + width, close);
    return { inlines: inline.value.length > 0 ? [inline] : [], next: close + 1 };
};

const importStep = function importStep(context: LineContext, at: number): Step {
    let cursor = at + 1;
    while (cursor < context.line.length && !IMPORT_STOPS.has(context.line.charAt(cursor))) {
        cursor += 1;
    }
    const inline = inlineOf(context, "import-path", at + 1, cursor);
    return { inlines: inline.value.includes("/") ? [inline] : [], next: cursor };
};

const stepAt = function stepAt(context: LineContext, at: number): Step {
    const char = context.line.charAt(at);
    if (char === "`") {
        return enclosedStep(context, at, 1, "`", "inline-code");
    }
    if (char === "]" && context.line.charAt(at + 1) === "(") {
        return enclosedStep(context, at, 2, ")", "link-target");
    }
    const opensImport = char === "@" && (at === 0 || context.line.charAt(at - 1) === " ");
    return opensImport ? importStep(context, at) : { inlines: [], next: at + 1 };
};

export const inlinesOf = function inlinesOf(line: string, lineStart: number, lineNumber: number): Inline[] {
    const context: LineContext = { line, number: lineNumber, start: lineStart };
    const out: Inline[] = [];
    let index = 0;

    while (index < line.length) {
        const step = stepAt(context, index);
        out.push(...step.inlines);
        index = step.next;
    }

    return out;
};
```
