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で標準化されており、
  • いくつかの例(カーソルの外観やカナダモードに入る)は標準には含まれていないが、
  • 例えば、カナダモードに入る 1049コードにはバリエーション(\E7\E[?47h)があります。プログラムが端末記述に依存している場合、バリエーションの1つだけが認識されます。
  • 一部のシーケンスはパラメータ化されており、プログラムにはルールが組み込まれているか、端末機能を\E[%i%p1%d;%p2%dH入力と照合できる正規表現に変換できる必要があります。

これらすべてを考慮すると、誰かがプログラムを提案したとしても、それらの側面は解決されず、単にディスプレイのない端末エミュレーターになる可能性が高くなります。

答え2

ANSIカーソル移動だけが必要な場合は、NPMモジュールを使用して簡単にインタープリターを作成できます。ノード-ansiparser私はJavaScriptライブラリに同じモジュールを使用しました:jQueryターミナルここでは、ANSI エスケープとオーバータイプ (man コマンドの出力) を解析して処理します。

パーサーの使い方はGitHubで確認できます。unix_formatting.js(ファイルには ansi-parser が含まれています)。コードを変更して、テキストのみを処理し、色を無視することもできます (jQuery ターミナルの書式設定構文)。それほど難しいことではありません。

手っ取り早く済ませたい場合は、ファイルを処理して jQuery Terminal で使用される書式設定を削除するだけのスクリプトを作成できます。ここでは、この問題を解決する簡単なハックを紹介します (ただし、unix_formatting.js ファイルを変更して、不要なものをすべて削除したほうがよいでしょう)。

jQuery ターミナルを開始するには、これを使用します。

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

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

テキスト

#!/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 ターミナルの書式設定を処理する必要がないため、おそらくもっと単純なものを使用できるでしょう。これがこの関数の主な目的です。

関連情報