UNPKG

sgr-parser

Version:

Parse escape sequence for console. (Especially for SGR)

298 lines (297 loc) 11.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var CODE_LF = 0x0a; var CODE_CR = 0x0d; var CODE_ESC = 0x1b; var CODE_0 = 0x30; var CODE_9 = 0x39; var CODE_SEMI = 0x3b; var CODE_A = 0x41; var CODE_K = 0x4b; var CODE_S = 0x53; var CODE_f = 0x66; var CODE_m = 0x6d; function isValidEscapeChar(c) { // A-H if (c >= CODE_A && c <= CODE_A + 7) return true; // J,K if (c === CODE_A + 9 || c === CODE_A + 10) return true; // S,T if (c === CODE_S || c === CODE_S + 1) return true; // f,m if (c === CODE_f || c == CODE_m) return true; return false; } var TokenType; (function (TokenType) { TokenType[TokenType["Escape"] = 0] = "Escape"; TokenType[TokenType["String"] = 1] = "String"; TokenType[TokenType["Error"] = 2] = "Error"; })(TokenType = exports.TokenType || (exports.TokenType = {})); var TokenState; (function (TokenState) { TokenState[TokenState["Normal"] = 0] = "Normal"; TokenState[TokenState["Escape"] = 1] = "Escape"; })(TokenState || (TokenState = {})); var EscapeToken = /** @class */ (function () { function EscapeToken(_options, _code) { this._options = _options; this._code = _code; } Object.defineProperty(EscapeToken.prototype, "tokenType", { get: function () { return TokenType.Escape; }, enumerable: true, configurable: true }); Object.defineProperty(EscapeToken.prototype, "options", { get: function () { return this._options; }, enumerable: true, configurable: true }); Object.defineProperty(EscapeToken.prototype, "code", { get: function () { return this._code; }, enumerable: true, configurable: true }); return EscapeToken; }()); exports.EscapeToken = EscapeToken; var StringToken = /** @class */ (function () { function StringToken(_str) { this._str = _str; } Object.defineProperty(StringToken.prototype, "tokenType", { get: function () { return TokenType.String; }, enumerable: true, configurable: true }); Object.defineProperty(StringToken.prototype, "str", { get: function () { return this._str; }, enumerable: true, configurable: true }); return StringToken; }()); exports.StringToken = StringToken; var ErrorToken = /** @class */ (function () { function ErrorToken(_str) { this._str = _str; } Object.defineProperty(ErrorToken.prototype, "tokenType", { get: function () { return TokenType.Error; }, enumerable: true, configurable: true }); Object.defineProperty(ErrorToken.prototype, "str", { get: function () { return this._str; }, enumerable: true, configurable: true }); return ErrorToken; }()); exports.ErrorToken = ErrorToken; var Line = /** @class */ (function () { function Line(_str, _classname, _newLine, _removeLine) { this._str = _str; this._classname = _classname; this._newLine = _newLine; this._removeLine = _removeLine; } Object.defineProperty(Line.prototype, "str", { get: function () { return this._str; }, enumerable: true, configurable: true }); Object.defineProperty(Line.prototype, "classname", { get: function () { return this._classname; }, enumerable: true, configurable: true }); Object.defineProperty(Line.prototype, "newLine", { get: function () { return this._newLine; }, enumerable: true, configurable: true }); Object.defineProperty(Line.prototype, "removeLine", { get: function () { return this._removeLine; }, enumerable: true, configurable: true }); return Line; }()); exports.Line = Line; var SGRParser = /** @class */ (function () { function SGRParser(keepState, handleCR) { this.keepState = keepState; this.handleCR = handleCR; this.classes = []; this.newLine = false; this.state = TokenState.Normal; this.options = []; } SGRParser.prototype.parse = function (line) { var _this = this; var classes = this.classes.concat([]); var newLine = this.newLine; var ret = []; this.tokenize(line).forEach(function (token) { switch (token.tokenType) { case TokenType.String: case TokenType.Error: var nextNewLine = false; var lines = token.str.split("\n"); if (lines.length > 1 && lines[lines.length - 1].length === 0) { lines.pop(); nextNewLine = true; } lines.forEach(function (str, index) { ret.push(new Line(str, classes.join(" "), newLine, false)); newLine = true; }); newLine = nextNewLine; break; case TokenType.Escape: var escapeToken = token; switch (escapeToken.code) { case CODE_K: if (escapeToken.options.length === 1 && escapeToken.options[0] === 2) { ret.push(new Line("", "", newLine, !newLine)); newLine = false; } break; case CODE_m: if (escapeToken.options.length > 0) { switch (escapeToken.options[0]) { case 0: classes = []; break; case 39: classes = classes.filter(function (v) { return v.indexOf("sgr-3") === 0 && v !== "sgr-3-m"; }); break; case 49: classes = _this.classes.filter(function (v) { return v.indexOf("sgr-4") === 0 && v !== "sgr-4-m"; }); break; case 38: case 48: classes.push("sgr-" + escapeToken.options.join("-") + "-m"); break; default: escapeToken.options.forEach(function (n) { classes.push("sgr-" + n + "-m"); }); break; } } break; } break; } }); if (this.keepState) { this.classes = classes; this.newLine = newLine; } return ret; }; SGRParser.prototype.tokenize = function (line) { if (!line || line.length === 0) { return []; } var state = this.state; var options = this.options.concat([]); var index = 0; var spos = 0; var ret = []; while (index < line.length) { var c = line.charCodeAt(index++); switch (state) { case TokenState.Normal: switch (c) { case CODE_ESC: if (spos !== index - 1) { ret.push(new StringToken(line.substring(spos, index - 1))); } if (line.charAt(index) === '[') { index++; state = TokenState.Escape; options = []; } else { ret.push(new ErrorToken("")); spos = index; } break; case CODE_CR: if (this.handleCR) { if (spos !== index - 1) { ret.push(new StringToken(line.substring(spos, index - 1))); } ret.push(new EscapeToken([2], CODE_K)); spos = index; } break; default: break; } break; case TokenState.Escape: if (c >= 0x30 && c <= 0x39) { if (options.length === 0) { options.push(c - 0x30); } else { var n = options[options.length - 1]; if (n === -1) { options[options.length - 1] = c - 0x30; } else { options[options.length - 1] = n * 10 + (c - 0x30); } } } else if (c === CODE_SEMI) { if (options.length === 0) { ret.push(new ErrorToken("[;")); state = TokenState.Normal; } else { options.push(-1); } } else if (isValidEscapeChar(c)) { ret.push(new EscapeToken(options.filter(function (n) { return n >= 0; }), c)); state = TokenState.Normal; } else { ret.push(new ErrorToken("[" + options.filter(function (n) { return n >= 0; }).join(";") + line.charAt(index - 1))); state = TokenState.Normal; } if (state === TokenState.Normal) { spos = index; } break; } } if (state === TokenState.Normal && spos < line.length) { ret.push(new StringToken(line.substring(spos, line.length))); } else if (!this.keepState) { ret.push(new ErrorToken("[" + options.filter(function (n) { return n >= 0; }).join(";"))); } if (this.keepState) { this.state = state; this.options = options; } return ret; }; return SGRParser; }()); exports.SGRParser = SGRParser;