delphiansi-escapeansi-colors

Delphi XE3 - Remove Ansi Code / Color from string


I'm struggling with dealing with Ansi code strings. I'm getting the [32m, [37m, [K etc chars.

Is there a quicker way to eliminate/strip the ansi codes from the strings I get rather than doing it with the loop through chars searching for the beginning and end points of the ansi codes?

I know the declaration is something like this: #27'['#x';'#y';'#z'm'; where x, y, z... are the ANSI codes. So I assume I should be searching for #27 until I find "m;"

Are there any already made functions to achieve what I want? My search returned nothing except this article. Thanks


Solution

  • You can treat this protocol very fast with code like this (simplest finite state machine):

    var
      s: AnsiString;
      i: integer;
      InColorCode: Boolean;
    begin
      s := 'test'#27'['#5';'#30';'#47'm colored text';
    
      InColorCode := False;
    
      for i := 1 to Length(s) do
        if InColorCode then
          case s[i] of
              #0: TextAttrib = Normal;
              ...
              #47: TextBG := White;
              'm': InColorCode := false;
            else;
             // I do nothing here for `;`, '[' and other chars.
             // treat them if necessary
    
          end;
         else
           if s[i] = #27 then
             InColorCode := True
           else
             output char with current attributes
    

    Clearing string from ESC-codes:

    procedure StripEscCode(var s: AnsiString);
    const
      StartChar: AnsiChar = #27;
      EndChar: AnsiChar = 'm';
    var
      i, cnt: integer;
      InEsc: Boolean;
    begin
      Cnt := 0;
      InEsc := False;
      for i := 1 to Length(s) do
        if InEsc then begin
          InEsc := s[i] <> EndChar;
          Inc(cnt)
        end
        else begin
          InEsc := s[i] = StartChar;
          if InEsc then
            Inc(cnt)
          else
          s[i - cnt] :=s[i];
        end;
      setLength(s, Length(s) - cnt);
    end;