UNPKG

@taml/encoder

Version:

Convert ANSI escape sequences to TAML (Terminal ANSI Markup Language) tags

284 lines 19.3 kB
import { convert256ToBackgroundColor, convert256ToStandardColor, convertBasicAnsiToBackgroundColor, convertBasicAnsiToStandardColor, convertRGBToBackgroundColor, convertRGBToStandardColor, } from "./color-converter.js"; // biome-ignore lint/suspicious/noControlCharactersInRegex: <explanation> const ANSI_ESCAPE_REGEX = /(\u001b\[[0-9;]*m)/g; /** * Regular expression specifically for SGR (Select Graphic Rendition) sequences * These control text formatting, colors, etc. */ // biome-ignore lint/suspicious/noControlCharactersInRegex: <explanation> const SGR_REGEX = /^(\u001b)\[([0-9;]*)m$/; /** * Create an initial ANSI state with default values */ export function createInitialAnsiState() { return { foreground: null, background: null, bold: false, dim: false, italic: false, underline: false, strikethrough: false, }; } /** * Parse ANSI text into tokens containing text and escape sequences */ export function tokenizeAnsiText(text) { const tokens = []; let lastIndex = 0; const matches = Array.from(text.matchAll(ANSI_ESCAPE_REGEX)); for (const match of matches) { const matchIndex = match.index; if (matchIndex === undefined) continue; const matchText = match[0]; // Add text before this match as a text token if (matchIndex > lastIndex) { const textContent = text.slice(lastIndex, matchIndex); if (textContent) { tokens.push({ type: "text", content: textContent, }); } } // Parse the ANSI sequence const sequence = parseAnsiSequence(matchText); if (sequence) { tokens.push({ type: "sequence", content: matchText, sequence, }); } lastIndex = matchIndex + matchText.length; } // Add remaining text if (lastIndex < text.length) { const textContent = text.slice(lastIndex); if (textContent) { tokens.push({ type: "text", content: textContent, }); } } return tokens; } /** * Parse a single ANSI escape sequence */ function parseAnsiSequence(sequence) { const sgrMatch = sequence.match(SGR_REGEX); if (!sgrMatch) { // Not an SGR sequence, ignore return null; } const params = sgrMatch[2]; if (!params) { // Reset sequence (ESC[m or ESC[0m) return { type: "reset", value: 0, raw: sequence, }; } const codes = params.split(";").map((code) => Number.parseInt(code, 10) || 0); // Handle multiple codes in one sequence for (let i = 0; i < codes.length; i++) { const code = codes[i]; if (code === undefined) continue; // Reset if (code === 0) { return { type: "reset", value: 0, raw: sequence, }; } // Styles if (code === 1) { return { type: "style", value: "bold", raw: sequence }; } if (code === 2) { return { type: "style", value: "dim", raw: sequence }; } if (code === 3) { return { type: "style", value: "italic", raw: sequence }; } if (code === 4) { return { type: "style", value: "underline", raw: sequence }; } if (code === 9) { return { type: "style", value: "strikethrough", raw: sequence }; } // Basic foreground colors (30-37, 90-97) if ((code >= 30 && code <= 37) || (code >= 90 && code <= 97)) { const color = convertBasicAnsiToStandardColor(code); return { type: "color", value: color, raw: sequence, }; } // Foreground color reset (39) if (code === 39) { return { type: "foreground-reset", value: null, raw: sequence, }; } // Basic background colors (40-47, 100-107) if ((code >= 40 && code <= 47) || (code >= 100 && code <= 107)) { const color = convertBasicAnsiToBackgroundColor(code); return { type: "background", value: color, raw: sequence, }; } // Background color reset (49) if (code === 49) { return { type: "background-reset", value: null, raw: sequence, }; } // Extended foreground color (38;5;n or 38;2;r;g;b) if (code === 38 && i + 1 < codes.length) { const mode = codes[i + 1]; if (mode === undefined) continue; if (mode === 5 && i + 2 < codes.length) { // 256-color mode: 38;5;n const colorIndex = codes[i + 2]; if (colorIndex === undefined) continue; const color = convert256ToStandardColor(colorIndex); return { type: "color", value: color, raw: sequence, }; } if (mode === 2 && i + 4 < codes.length) { // RGB mode: 38;2;r;g;b const r = codes[i + 2]; const g = codes[i + 3]; const b = codes[i + 4]; if (r === undefined || g === undefined || b === undefined) continue; const color = convertRGBToStandardColor(r, g, b); return { type: "color", value: color, raw: sequence, }; } } // Extended background color (48;5;n or 48;2;r;g;b) if (code === 48 && i + 1 < codes.length) { const mode = codes[i + 1]; if (mode === undefined) continue; if (mode === 5 && i + 2 < codes.length) { // 256-color mode: 48;5;n const colorIndex = codes[i + 2]; if (colorIndex === undefined) continue; const color = convert256ToBackgroundColor(colorIndex); return { type: "background", value: color, raw: sequence, }; } if (mode === 2 && i + 4 < codes.length) { // RGB mode: 48;2;r;g;b const r = codes[i + 2]; const g = codes[i + 3]; const b = codes[i + 4]; if (r === undefined || g === undefined || b === undefined) continue; const color = convertRGBToBackgroundColor(r, g, b); return { type: "background", value: color, raw: sequence, }; } } } // Unknown sequence, ignore return null; } /** * Apply a parsed ANSI sequence to the current state */ export function applyAnsiSequence(state, sequence) { const newState = { ...state }; switch (sequence.type) { case "reset": return createInitialAnsiState(); case "foreground-reset": newState.foreground = null; break; case "background-reset": newState.background = null; break; case "color": newState.foreground = sequence.value; break; case "background": newState.background = sequence.value; break; case "style": { const styleValue = sequence.value; switch (styleValue) { case "bold": newState.bold = true; break; case "dim": newState.dim = true; break; case "italic": newState.italic = true; break; case "underline": newState.underline = true; break; case "strikethrough": newState.strikethrough = true; break; } break; } } return newState; } /** * Get the active style tags from the current ANSI state */ export function getActiveStyleTags(state) { const tags = []; if (state.bold) tags.push("bold"); if (state.dim) tags.push("dim"); if (state.italic) tags.push("italic"); if (state.underline) tags.push("underline"); if (state.strikethrough) tags.push("strikethrough"); if (state.background) tags.push(state.background); if (state.foreground) tags.push(state.foreground); return tags; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW5zaS1wYXJzZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9hbnNpLXBhcnNlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsMkJBQTJCLEVBQzNCLHlCQUF5QixFQUN6QixpQ0FBaUMsRUFDakMsK0JBQStCLEVBQy9CLDJCQUEyQixFQUMzQix5QkFBeUIsR0FDMUIsTUFBTSxzQkFBc0IsQ0FBQztBQUc5Qix5RUFBeUU7QUFDekUsTUFBTSxpQkFBaUIsR0FBRyxxQkFBcUIsQ0FBQztBQUVoRDs7O0dBR0c7QUFDSCx5RUFBeUU7QUFDekUsTUFBTSxTQUFTLEdBQUcsd0JBQXdCLENBQUM7QUFFM0M7O0dBRUc7QUFDSCxNQUFNLFVBQVUsc0JBQXNCO0lBQ3BDLE9BQU87UUFDTCxVQUFVLEVBQUUsSUFBSTtRQUNoQixVQUFVLEVBQUUsSUFBSTtRQUNoQixJQUFJLEVBQUUsS0FBSztRQUNYLEdBQUcsRUFBRSxLQUFLO1FBQ1YsTUFBTSxFQUFFLEtBQUs7UUFDYixTQUFTLEVBQUUsS0FBSztRQUNoQixhQUFhLEVBQUUsS0FBSztLQUNyQixDQUFDO0FBQ0osQ0FBQztBQUVEOztHQUVHO0FBQ0gsTUFBTSxVQUFVLGdCQUFnQixDQUFDLElBQVk7SUFDM0MsTUFBTSxNQUFNLEdBQWdCLEVBQUUsQ0FBQztJQUMvQixJQUFJLFNBQVMsR0FBRyxDQUFDLENBQUM7SUFFbEIsTUFBTSxPQUFPLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQztJQUU3RCxLQUFLLE1BQU0sS0FBSyxJQUFJLE9BQU8sRUFBRSxDQUFDO1FBQzVCLE1BQU0sVUFBVSxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUM7UUFDL0IsSUFBSSxVQUFVLEtBQUssU0FBUztZQUFFLFNBQVM7UUFDdkMsTUFBTSxTQUFTLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRTNCLDZDQUE2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