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). 프로그램이 터미널 설명에 의존하는 경우 변형 중 하나만 인식됩니다.
  • 일부 시퀀스는 매개변수화됩니다. 즉, 프로그램에는 규칙이 내장되어 있거나 터미널 기능(예: \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 터미널 형식을 처리할 필요가 없으므로 더 간단한 것을 사용할 수도 있습니다.

관련 정보