static AnsiTextStyle() { Empty = new AnsiTextStyle(); Empty.Fg = -1; Empty.Bg = -1; Empty.IsBold = false; Empty.IsInverse = false; }
public static ColorMessage CreateFromAnsi(string str, AnsiTextStyle lastStyle) { ColorMessage colorMsg = Ansi.ParseAnsi(str, ref lastStyle); return(colorMsg); }
public static ColorMessage ParseAnsi(string text, ref AnsiTextStyle currentStyle) { StringBuilder stringBuilder = new StringBuilder(text.Length); List <ColorMessage.MetaData> metaData = new List <ColorMessage.MetaData>(); int pos = 0; int oldPos = 0; AnsiTextStyle previousStyle = currentStyle; if (!currentStyle.IsEmpty) { ColorMessage.MetaData md = new ColorMessage.MetaData(stringBuilder.Length, currentStyle.ToTextStyle()); metaData.Add(md); } while (pos < text.Length) { if (text[pos] == '\t') { stringBuilder.Append(' ', 4); pos++; continue; } if (text[pos] != ESC) { stringBuilder.Append(text[pos]); pos++; continue; } oldPos = pos; pos++; // skip ESC if (pos >= text.Length) { stringBuilder.Append(text.Substring(oldPos, pos - oldPos)); continue; } if (text[pos] == '[') { pos++; // skip [ if (pos >= text.Length) { ChiConsole.WriteLineLow("Incomplete ansi sequence"); stringBuilder.Append(text.Substring(oldPos, pos - oldPos)); continue; } int seqStart = pos; while (pos < text.Length && ((text[pos] >= '0' && text[pos] <= '9') || text[pos] == ';')) { pos++; } if (pos == text.Length) { ChiConsole.WriteLineLow("Incomplete ansi sequence"); stringBuilder.Append(text.Substring(oldPos, pos - oldPos)); continue; } if (text[pos] == 'm') { int seqEnd = pos; pos++; // skip m string str2 = text.Substring(seqStart, seqEnd - seqStart); string[] arr = str2.Split(';'); if (str2.Length == 0) { arr = new string[] { "0" } } ; for (int i = 0; i < arr.Length; i++) { int num = System.Int16.Parse(arr[i]); switch (num) { case 0: // normal currentStyle.Fg = -1; currentStyle.Bg = -1; currentStyle.IsBold = false; currentStyle.IsInverse = false; break; case 1: // bold currentStyle.IsBold = true; break; case 7: // inverse currentStyle.IsInverse = true; break; case 30: case 31: case 32: case 33: case 34: case 35: case 36: case 37: currentStyle.Fg = num - 30; break; case 38: if (arr.Length != 3 || i != 0 || arr[1] != "5") { ChiConsole.WriteLineLow("Illegal 256 color ansi code: {0}", str2); break; } currentStyle.Fg = byte.Parse(arr[2]); i += 3; break; case 39: // default color currentStyle.Fg = -1; break; case 40: case 41: case 42: case 43: case 44: case 45: case 46: case 47: currentStyle.Bg = num - 40; break; case 48: if (arr.Length != 3 || i != 0 || arr[1] != "5") { ChiConsole.WriteLineLow("Illegal 256 color ansi code: {0}", str2); break; } currentStyle.Bg = byte.Parse(arr[2]); i += 3; break; case 49: // default color currentStyle.Bg = -1; break; default: ChiConsole.WriteLineLow("Unknown ansi code {0}", num); break; } } if (!previousStyle.IsSame(currentStyle)) { ColorMessage.MetaData md = new ColorMessage.MetaData(stringBuilder.Length, currentStyle.ToTextStyle()); metaData.Add(md); } previousStyle = currentStyle; } else if (text[pos] == 'H') { pos++; } else if (text[pos] == 'J') { pos++; } else { ChiConsole.WriteLine("Unknown ansi command: {0}", text[pos]); } } } return(new ColorMessage(stringBuilder.ToString(), metaData)); }
public bool IsSame(AnsiTextStyle style) { return(Fg == style.Fg && Bg == style.Bg && IsBold == style.IsBold && IsInverse == style.IsInverse); }