Decoding ANSI escape sequences in Dart

Issue

I’m writing some code for Flutter Desktop targeting linux_x64.
I’m extracting some logs from some applications, these logs presents a syntax like this:

  • Inspecting log file using less logfile

    ESC(BESC[mauthentication-msESC(BESC[m
    
    
  • Inspecting log file using less -r logfile I can see colored text into my terminal.

  • Inspecting log file using cat logfile I can see colored text into my terminal.

  • Inspecting log file using cat -vte logfile I get this:

    ^[(B^[[mauthentication-ms^[(B^[[m$
    
  • In Flutter using this code

    Future<String> readAsString = file.readAsString();
    readAsString.then((String value) => _log = utf8.decode(value.runes.toList()));
    

    I get this output in a SelectableText widget

    (B[mauthentication-ms(B[m
    

I’m really confused about this behaviour so if someone has experience on this suggestions are welcome!

There are 2 options:

  • Cleaning all the logs, visualizing normal text
  • Trying to decode the text just as less -r does, visualizing colored text into Flutter application.

EDIT:
I solved importing tint plugin: tint: ^2.0.0

and changing the Dart code (using the strip() method from tint plugin) as follows:

Future<String> readAsString = file.readAsString();
readAsString.then((String value) => _log = value.strip());

Solution

Those funny characters are called escape sequences, and programs use them to print colours and italics and all of that.

Terminals are designed to decode these escape sequences, but regular programs don’t know what to do with them. less and cat are printing exactly what is in the file, it’s the terminal you run them in that decodes them.

You’ll have to make your program go through and remove all of the escape sequences with a piece of code like this:

m = "h\x1b[34mello\x1b(A.\x1b[H" # Text full of random escape sequences
c = 0 # A count variable
p = True # Are we not in an escape sequence?
o = "" # The output variable
for l in m:
    if l == "\x1b":
        p = False
    elif p:
        o += l
    elif l in "QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm": # Most (maybe all) escape sequences end in letters.
        p = True
    c += 1 # Move on to the next letter in the input string
    
print(o) # Text without escape sequences

Answered By – linux_kettle

Answer Checked By – Jay B. (FlutterFixes Admin)

Leave a Reply

Your email address will not be published.