ANSI-Code-Konvertierer

ANSI-Code-Konvertierer

Gibt es ein Tool, das Text mit ANSI-Code in eine textähnliche Ausgabe konvertiert? tputGroßbuchstaben oder ähnliches?

Grund der Anfrage ist, dass ich gerne scripto.ä. verwenden und die resultierende Datei anzeigen möchte, ohne ANSI-Sequenzen entziffern zu müssen. Einige kenne ich, aber nicht alle, und eine Textausgabe wäre leichter zu lesen.

In den meisten Fällen kann ich mir den Quellcode des Skripts oder Programms ansehen, das den ANSI-Text erstellt, aber es wäre schön, wenn es ein „Debug“-ähnliches Tool gäbe.

Das Beste wäre wahrscheinlich C?Variablennamen, also:

^[[K    ->   <clr_eol>

Ich weiß, dass ich dafür ein Skript schreiben kann ... zum Beispiel:

sed 's/$/<newline>/' rec001.txt | \
sed 's/\x07/\n<bell>/g' | \
sed 's/\x1b\[K/\n<clr_eol>/g' | \
sed 's/\x1b\[?12l\x1b\[?25h/\n<cursor_normal>/g' | \
sed 's/\x1b\[\([0-9]\+\);\([0-9]\+\)H/\n<cursor_position(\1, \2)>/g' | \
sed 's/\x1b\[?1049h/\n<enter_ca_mode>/g' | \
sed 's/\x1b\[?25l/\n<cursor_invisible>/g' | \
sed 's/\x0d/<CR>/g' | \
...

Das ist Teil eines Schnelltests, den ich an einemIrssiAufzeichnung.

Ich frage mich aber, ob es für diese Aufgabe bereits Werkzeuge gibt.

Als Randbemerkung haben wir aha,Ansi-HTML-Adapter, der ANSI in HTML konvertiert. Aber das ist nicht der Adapter, den ich suche.


Antwort1

Jemand könnte ein Programm vorschlagen. Es ist kein triviales Problem,Also:

  • "ANSI-Sequenzen" sind in ECMA-48 standardisiert,
  • einige Ihrer Beispiele (wie das Aussehen des Cursors undenter_ca_mode) sind nicht im Standard,
  • einige wie dieenter_ca_mode 1049Code haben Variationen ( \E7\E[?47h). Wenn ein Programm auf eine Terminalbeschreibung angewiesen ist, wird nur eine der Variationen erkannt,
  • Einige der Sequenzen sind parametrisiert, was bedeutet, dass ein Programm entweder über integrierte Regeln verfügen oder in der Lage sein muss, Terminalfunktionen \E[%i%p1%d;%p2%dHin einen regulären Ausdruck umzuwandeln, der mit den Eingaben abgeglichen werden kann.

Wenn daher jemand ein Programm vorschlägt, wird es diese Aspekte wahrscheinlich nicht lösen, sondern lediglich ein Terminalemulator ohne Anzeige sein.

Antwort2

Wenn Sie nur die ANSI-Cursorbewegung wünschen, können Sie einfach einen Interpreter mit dem NPM-Modul erstellenKnoten-Ansiparser. Ich habe dasselbe Modul für meine JavaScript-Bibliothek verwendet:jQuery-Terminal, wo ich ANSI-Escapes und Übertypisierungen (Ausgabe des Man-Befehls) analysiere und verarbeite.

Sie können sich auf GitHub ansehen, wie ich den Parser verwendet habe.unix_formatting.js(die Datei enthält den ANSI-Parser). Sie können versuchen, den Code so zu ändern, dass nur Text verarbeitet wird und die Farben ignoriert werden (die Formatierungssyntax des jQuery-Terminals). Das sollte nicht so schwer sein.

Wenn Sie es schnell haben möchten, können Sie ein Skript erstellen, das nur die Datei verarbeitet und die von jQuery Terminal verwendete Formatierung entfernt. Hier ist ein schneller Hack, der das erledigt (aber Sie sollten wahrscheinlich besser die Datei unix_formatting.js ändern und alles entfernen, was nicht benötigt wird).

Um mit jQuery Terminal zu beginnen, verwenden Sie Folgendes:

mkdir ansi-text
cd ansi-text
npm init -y # you need nodeJS installed
npm install jquery.terminal

Erstellen Sie dann diese Datei im selben Verzeichnis:

ansi-text.js

#!/usr/bin/env node
// mock jQuery that is not actually required
const $ = global.$ = global.jQuery = {
    fn: {
        extend: function(obj) {
            Object.assign(global.jQuery.fn, obj);
        }
    },
    extend:  Object.assign
};

global.navigator = {
    userAgent: 'Node'
};

require('jquery.terminal')(global, global.$);
require('jquery.terminal/js/unix_formatting')(global, global.$);

read_stdin().then(function(buff) {
    const str = buff.toString();
    const formatted = $.terminal.apply_formatters(str);
    console.log($.terminal.strip(formatted));
});

function read_stdin() {
    return new Promise((resolve) => {
        const buff = [];

        process.stdin.on('data', data => {
            buff.push(data);
        }).on('end', () => {
            var len = buff.map(x => x.length).reduce((acc, e) => acc + e);
            resolve(Buffer.concat(buff, len));
        });
    });
}

Sie können dann ein Testskript erstellen:

test.sh

tput cup 2 3;
echo HELLO;
tput cup 5 20;
echo WORLD;

Und Sie können sehen, dass es funktioniert, indem Sie Folgendes verwenden:

unbuffer ./test.sh | ./ansi-text.js

Ausgabe:

kuba@jcubic:~/projects/jcubic/ansi-text$ unbuffer test.sh | ./ansi-text.js 


   HELLO


                    WORLD

kuba@jcubic:~/projects/jcubic/ansi-text$ 

Durch unbuffer wird das Skript denken, dass es TTY ist (es ist Teil von expect).

Der JS-Code verarbeitet die Breite des Terminals nicht, kann aber problemlos hinzugefügt werden, nachdem Sie ANSI-Escapes umgewandelt haben. Um die Ausgabe aufzuteilen, verwenden Sie: $.terminal.split_equal(string, cols)Sie können aber wahrscheinlich auch etwas Einfacheres verwenden, da Sie die jQuery-Terminalformatierung nicht verarbeiten müssen, was der Hauptzweck der Funktion ist.

verwandte Informationen