UNPKG

@taml/encoder

Version:

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

89 lines 7.41 kB
import { applyAnsiSequence, createInitialAnsiState, getActiveStyleTags, tokenizeAnsiText, } from "./ansi-parser.js"; /** * Escapes special characters in a string for TAML. * @param text The input string. * @returns The escaped string. */ function escapeText(text) { return text .replace(/&amp;/g, "&amp;amp;") // First escape existing &amp; .replace(/&lt;/g, "&amp;lt;") // Then escape existing &lt; .replace(/</g, "&lt;"); // Finally escape remaining < } /** * Encode ANSI escape sequences to TAML (Terminal ANSI Markup Language) tags * @param ansiText Input text containing ANSI escape sequences * @returns Text with ANSI sequences converted to TAML tags */ export function encode(ansiText) { if (!ansiText) { return ""; } const tokens = tokenizeAnsiText(ansiText); let result = ""; let currentState = createInitialAnsiState(); const tagStack = []; for (const token of tokens) { if (token.type === "text") { // Add text content with current formatting result += escapeText(token.content); } else if (token.type === "sequence" && token.sequence) { const newState = applyAnsiSequence(currentState, token.sequence); // Handle state changes if (token.sequence.type === "reset") { // Close all open tags when reset while (tagStack.length > 0) { const tag = tagStack.pop(); if (tag) { result += `</${tag}>`; } } currentState = newState; } else { // Get the difference between old and new states const oldTags = getActiveStyleTags(currentState); const newTags = getActiveStyleTags(newState); // Close tags that are no longer active const tagsToClose = oldTags.filter((tag) => !newTags.includes(tag)); for (let i = tagStack.length - 1; i >= 0; i--) { const tag = tagStack[i]; if (tag && tagsToClose.includes(tag)) { // Close this tag and all tags after it const closedTags = tagStack.splice(i); for (let j = closedTags.length - 1; j >= 0; j--) { const closedTag = closedTags[j]; if (closedTag) { result += `</${closedTag}>`; } } // Reopen tags that should still be active const tagsToReopen = closedTags.filter((t) => t && newTags.includes(t)); for (const reopenTag of tagsToReopen) { result += `<${reopenTag}>`; tagStack.push(reopenTag); } break; } } // Open new tags const tagsToOpen = newTags.filter((tag) => !oldTags.includes(tag)); for (const tag of tagsToOpen) { result += `<${tag}>`; tagStack.push(tag); } currentState = newState; } } } // Close any remaining open tags at the end while (tagStack.length > 0) { const tag = tagStack.pop(); if (tag) { result += `</${tag}>`; } } return result; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW5jb2Rlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL2VuY29kZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLGlCQUFpQixFQUNqQixzQkFBc0IsRUFDdEIsa0JBQWtCLEVBQ2xCLGdCQUFnQixHQUNqQixNQUFNLGtCQUFrQixDQUFDO0FBRTFCOzs7O0dBSUc7QUFDSCxTQUFTLFVBQVUsQ0FBQyxJQUFZO0lBQzlCLE9BQU8sSUFBSTtTQUNSLE9BQU8sQ0FBQyxRQUFRLEVBQUUsV0FBVyxDQUFDLENBQUMsOEJBQThCO1NBQzdELE9BQU8sQ0FBQyxPQUFPLEVBQUUsVUFBVSxDQUFDLENBQUMsNEJBQTRCO1NBQ3pELE9BQU8sQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyw2QkFBNkI7QUFDekQsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxNQUFNLFVBQVUsTUFBTSxDQUFDLFFBQWdCO0lBQ3JDLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUNkLE9BQU8sRUFBRSxDQUFDO0lBQ1osQ0FBQztJQUVELE1BQU0sTUFBTSxHQUFHLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQzFDLElBQUksTUFBTSxHQUFHLEVBQUUsQ0FBQztJQUNoQixJQUFJLFlBQVksR0FBRyxzQkFBc0IsRUFBRSxDQUFDO0lBQzVDLE1BQU0sUUFBUSxHQUFhLEVBQUUsQ0FBQztJQUU5QixLQUFLLE1BQU0sS0FBSyxJQUFJLE1BQU0sRUFBRSxDQUFDO1FBQzNCLElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxNQUFNLEVBQUUsQ0FBQztZQUMxQiwyQ0FBMkM7WUFDM0MsTUFBTSxJQUFJLFVBQVUsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDdEMsQ0FBQzthQUFNLElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxVQUFVLElBQUksS0FBSyxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQ3ZELE1BQU0sUUFBUSxHQUFH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