ANSIトランスコーダ

ANSIトランスコーダ

ANSIコードテキストをテキストなどの出力に変換するツールはありますか?tput帽子の名前やそうですか?

尋ねる理由は、script同様の方法を使用してANSIシーケンスを復号化することなく結果ファイルを表示したいからです。すべてではありませんが、一部はテキスト出力が読みやすくなることを知っています。

ほとんどの場合、ANSIテキストを生成するスクリプトやプログラムのソースコードを見ることができますが、「デバッグ」のようなツールがあれば良いでしょう。

一番いいのはおそらくCだろう。変数名、つまり:

^[[K    ->   <clr_eol>

これにスクリプトを書くことができることを知っています。たとえば、次のようになります。

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' | \
...

これは私が行ったクイックテストの一部です。イルシ記録。

しかし、それを行うための既存のツールがあるかどうか疑問に思います。

参考までに、私たちahaAnsi HTMLアダプタ、ANSIをHTMLに変換します。しかし、これは私が探しているアダプタではありません。


答え1

誰かがプログラムを提案するかもしれません。これは小さな問題ではありません。素晴らしい:

  • 「ANSIシーケンス」はECMA-48に標準化されています。
  • カーソル形状と_ca_モードに切り替える)は標準にはありません。
  • たとえば、いくつかは次のとおりです。_ca_モードに切り替える 1049コードが変更されました( \E7\E[?47h)。プログラムが端末記述に依存している場合、バリアントの1つだけが認識されます。
  • 一部のシーケンスはパラメータ化されます。つまり、プログラムには規則が組み込まれているか、端末機能(\E[%i%p1%d;%p2%dH入力に一致する正規表現など)を端末機能に変換できる必要があります。

これらすべてを念頭に置いて、誰かがプログラムを提案した場合、これらの側面を解決することはできず、ディスプレイがないだけの端末エミュレータである可能性が高くなります。

答え2

ANSIカーソルの移動だけが必要な場合は、NPMモジュールを使用してインタプリタを簡単に作成できます。ノードディパーサー。私はJavaScriptライブラリに同じモジュールを使用します。jQuery端末ここでは、ANSIエスケープと書き換え(manコマンドの出力)を解析して処理します。

GitHubでパーサーをどのように使用するかを見ることができます。unix_formatting.js(このファイルにはansi-parserが含まれています)。テキストのみを処理し、色を無視するようにコードを変更することができます(jQuery端末形式の構文)。それほど難しくありません。

すばやく作業したい場合は、ファイルを処理してjQuery端末で使用されている形式を削除するスクリプトを作成できます。これは問題を解決するための簡単な方法です(ただし、unix_formatting.jsファイルを修正し、不要なものを削除する方が良いでしょう)。

jQuery端末の使用を開始するには、次のコマンドを使用します。

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

次に、同じディレクトリにこのファイルを作成します。

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));
        });
    });
}

その後、テストスクリプトを作成できます。

テストファイル

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

次のようにどのように機能するかを確認できます。

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

出力:

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


   HELLO


                    WORLD

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

unbufferはスクリプトがTTY(Expectの一部)だと思うようにします。

JSコードは端末の幅を処理しませんが、ANSIエスケープを変換した後に簡単に追加できます。出力を分割するには、次を使用します。$.terminal.split_equal(string, cols)しかし、この関数の主な目的であるjQuery端末形式を処理する必要はないので、より簡単なものを使用することもできます。

関連情報