Переводчик кода 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' | \
...

что является частью быстрого теста, который я провел наИрссизапись.

Но интересно, есть ли какие-то существующие инструменты для этой работы.

В качестве примечания у нас есть aha,Адаптер HTML Ansi, который преобразует ANSI в HTML. Но это не тот адаптер, который я ищу.


решение1

Кто-то может предложить программу. Это не тривиальная задача сделатьхорошо:

  • «Последовательности ANSI» стандартизированы в ECMA-48,
  • некоторые из ваших примеров (например, внешний вид курсора ивведите_ca_mode) не входят в стандарт,
  • некоторые, такие каквведите_ca_mode 1049код имеет вариации ( \E7\E[?47h). Если программа опирается на описание терминала, будет распознана только одна из вариаций,
  • некоторые последовательности параметризованы, что означает, что программа должна либо иметь встроенные правила, либо иметь возможность преобразовывать возможности терминала, например, \E[%i%p1%d;%p2%dHв регулярное выражение, которое можно сопоставлять с входными данными.

Учитывая все это, если кто-то предложит программу, она, скорее всего, не решит эти аспекты, а будет просто эмулятором терминала без дисплея.

решение2

Если вам нужно только перемещение курсора ANSI, вы можете легко создать интерпретатор с помощью модуля NPM.узел-ансипарсер. Я использовал тот же модуль для своей библиотеки JavaScript:jQuery-терминал, где я анализирую и обрабатываю экранированные последовательности ANSI и перезаписываемые символы (вывод команды man).

Вы можете посмотреть, как я использовал парсер на GitHub.unix_formatting.js(файл включает в себя ansi-parser). Вы можете попробовать изменить код так, чтобы он обрабатывал только текст и игнорировал цвета (синтаксис форматирования jQuery Terminal). Это не должно быть так уж сложно.

Если вам нужно что-то быстрое, вы можете создать скрипт, который просто обработает файл и удалит форматирование, используемое jQuery Terminal. Вот быстрый хак, который делает это (но вам, вероятно, лучше будет изменить файл unix_formatting.js и удалить все, что не нужно).

Для начала работы с jQuery Terminal используйте следующее:

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, а это и есть основная цель функции.

Связанный контент