tools/core/readers/token.reader.ts

tools/core/readers/token.reader.ts is a file in Coordination Surface. 64 lines of code and 17 definitions.

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;
};