Xterm.js: RTL 언어 지원

에 만든 2017년 06월 13일  ·  17코멘트  ·  출처: xtermjs/xterm.js

다운스트림 문제: https://github.com/Microsoft/vscode/issues/28571

https://github.com/sourcelair/xterm.js/issues/467 에서 유니코드 문자 너비를 적용했을 때 RTL 언어 문자가 이제 역방향(LTR)으로 렌더링되기 때문에 중단되었습니다. RTL 문자 범위에 대해서만 이를 되돌릴 수 있지만 새 선택 모델이 https://github 그리드에 완벽하게 정렬된 모든 문자에 의존하기 때문에 문자열이 실제로 문자 그리드에 있도록 올바른 수정을 수행하고 문자열을 반대로 해야 합니다

이상적으로는 라인 리플로우 https://github.com/sourcelair/xterm.js/issues/622 가 이 전에 수행되어 여러 라인의 내용을 더 쉽게 변경할 수 있습니다.

터미널.앱:

image

VS Code 1.13(공고문은 반대임):

image

@mostafa69d @CherryDT 해당 언어에 대한 약간의 정보가 도움이 될 것입니다.

  1. 히브리어/아랍어/페르시아어의 경우 문자열을 어디에서 뒤집어야 합니까? ASCII 문자 사이에 있는 전체 연속 문자 시퀀스를 반대로 해야 합니까?
  2. 문자는 0-9 또는 구두점과 같은 문자와 어떻게 상호 작용합니까?

유용한 참조:

arei18n arerenderer typenhancement

가장 유용한 댓글

@티리아르
우선 아랍어와 페르시아어에 대한 아주 간단한 관점을 알려 드리겠습니다. 아마도 도움이 될 것입니다(히브리어가 같은지는 잘 모르겠습니다).
아랍어와 페르시아어에서 알파벳은 "آ" "ب" "س" 등과 같습니다. 그리고 단어는 예를 들어 영어와 비교할 때 매우 다른 규칙으로 이러한 알파벳(분명히)으로 만들어집니다.
차이점은 "س"와 같은 일부 알파벳에 대해 하나 이상의 모양이 있다는 것입니다. 첫 번째 모양은 "س"이고 두 번째 모양은 " سـ"이고 다른 하나는 "ـسـ"이고 마지막 모양은 "ـس"입니다. 그리고 이 모양의 용도는 무엇입니까? 단어에서 알파벳이 나타나는 위치에 따라 우리가 사용하는 알파벳의 모양이 달라집니다. 예를 들어, 언급된 알파벳 "س"의 경우 단어가 "سلام"과 같이 이 알파벳으로 시작할 때 "سـ" 모양을 사용합니다. 여기에 문제가 있고 실제로 영어와 페르시아어 또는 아랍어와 같은 언어의 차이점이 있습니다. 우리는 이러한 알파벳의 다른 모양을 연결하여 이러한 언어로 단어를 생성합니다(경우에 따라 함께 붙임). 다시 한 번 이 규칙을 강조합니다. 알파벳이 아닌 모양을 연결하여 이 단어를 생성합니다(항상 영어로 알파벳을 연결함). 아래에서 몇 가지 예를 볼 수 있습니다.
알파벳 "ک" "ن" "ا" "د" "ی"
나는 방금 언급한 알파벳으로 이 단어들을 만듭니다: نادان , یاد,دکان
그래서, 그것을 마무리하고 내가 게시한 스크린샷에서 무슨 일이 일어났는지에 대한 단서를 제공하기 위해 터미널은 단어를 알파벳으로 나누고 그것을 뒤집습니다. 내가 만든 단어와 전에 언급한 알파벳을 살펴보세요. 이제 VS 터미널은 "분리"와 "반전"으로 표시됩니다.

올바른 형식: نادان 터미널: ن ا د ا ن
올바른 형식:یاد 터미널: د ا ی
올바른 형식: دکان 터미널: ن ا ک د

이제 귀하의 질문:
히브리어/아랍어/페르시아어의 경우 문자열을 어디에서 뒤집어야 합니까? ASCII 문자 사이에 있는 전체 연속 문자 시퀀스를 반대로 해야 합니까?
나는 히브리어에 대해 전혀 모르지만 아랍어와 페르시아어에서 다음과 같이 공백 문자(단어 구분 기호는 공백)를 만나면 문자 시퀀스가 ​​뒤집혀야 합니다. "모양"과 필요한 준수.

문자는 0-9 또는 구두점과 같은 문자와 어떻게 상호 작용합니까?
숫자 및 구두점에 대한 규칙은 영어와 동일하며 숫자와 구두점 기호는 문자 다음에 옵니다. 이와 같이:
?من در سال "۱۳۶۹" به دنیا آمدم.
من در سال "1369" به دنیا آمدم.
실제로 RTL 및 비RTL 문자를 포함하는 일련의 문자는 완전히 다른 이야기이며 추가 정보가 필요하면 자세히 설명할 수 있습니다.

추신 1:
이 링크는 PHP에서 동일한 문제를 해결하기 위해 작성된 소스 코드입니다.
https://github.com/slashmili/php-gd-persian/blob/master/phpgd/fagd.php

추신 2:
다음은 페르시아 문자에 대한 위키피디아의 리소스입니다.
https://en.wikipedia.org/wiki/Persian_alphabet

추신 3:
다시 말하지만 이전 버전의 VS Code에서는 모든 것이 정상이었습니다.

추신 4:
다음과 같은 일부 LTR 문자가 포함된 단어를 선택하는 문제에 대해
<p>اینجا را بخوانید</p> @CherryDT가 언급한 몇 가지 사소한 버그가 있는데 문제가 되지 않으며 빠른 솔루션을 찾았습니다.

모든 17 댓글

실제로는 훨씬 더 복잡하고 상태 유지 및 특정 문자 미러링을 포함합니다. 나는 그것이 그 자체의 과학이라고 말하고 싶습니다. (그리고 저는 모든 BiDi 문제를 적절하게 처리하는 강력한 텍스트 렌더링 라이브러리를 작성한 사람들에 대해 깊은 존경심을 가지고 있습니다. 그래서 솔직히 말해서 _I_ 그것을 엉망으로 만들 필요가 없습니다.)

또한보십시오:
https://en.wikipedia.org/wiki/Bi-directional_text (좋은 개요)
https://www.w3.org/International/articles/inline-bidi-markup/uba-basics
https://www.w3.org/International/tutorials/svg-tiny-bidi/ (초기 전제는 관련이 없지만 이전 링크보다 몇 가지 더 잘 설명합니다)
https://github.com/fevalu/doctype-mirror/tree/master/bidihowto/bidi-support-in-a-ui

편집: 새로운 선택이 작동하는 방식은 VSCode 자체와 다르게 작동하기 때문에 실제로 예상치 못한 것일 수 있다고 생각합니다. 예를 들어 "노래 מדינת קומבינה로 인해 생각하게 됩니다"라는 텍스트가 주어지면 "The"에서 선택을 시작하고 두 히브리어 단어 사이에서 끝날 때 "노래 מדינת"를 선택하고 콘솔에서는 다음을 선택합니다. "노래 קומבינה".

예를 참조하십시오.
Image

그러나 내가 마지막으로 확인했을 때 Sublime Text가 "작동"하는 방식보다 여전히 나을 것입니다. 왜냐하면 거기에서 한 항목이 선택되고 다른 항목을 복사하기 때문입니다. 이는 매우 성가신 일입니다.

@티리아르
우선 아랍어와 페르시아어에 대한 아주 간단한 관점을 알려 드리겠습니다. 아마도 도움이 될 것입니다(히브리어가 같은지는 잘 모르겠습니다).
아랍어와 페르시아어에서 알파벳은 "آ" "ب" "س" 등과 같습니다. 그리고 단어는 예를 들어 영어와 비교할 때 매우 다른 규칙으로 이러한 알파벳(분명히)으로 만들어집니다.
차이점은 "س"와 같은 일부 알파벳에 대해 하나 이상의 모양이 있다는 것입니다. 첫 번째 모양은 "س"이고 두 번째 모양은 " سـ"이고 다른 하나는 "ـسـ"이고 마지막 모양은 "ـس"입니다. 그리고 이 모양의 용도는 무엇입니까? 단어에서 알파벳이 나타나는 위치에 따라 우리가 사용하는 알파벳의 모양이 달라집니다. 예를 들어, 언급된 알파벳 "س"의 경우 단어가 "سلام"과 같이 이 알파벳으로 시작할 때 "سـ" 모양을 사용합니다. 여기에 문제가 있고 실제로 영어와 페르시아어 또는 아랍어와 같은 언어의 차이점이 있습니다. 우리는 이러한 알파벳의 다른 모양을 연결하여 이러한 언어로 단어를 생성합니다(경우에 따라 함께 붙임). 다시 한 번 이 규칙을 강조합니다. 알파벳이 아닌 모양을 연결하여 이 단어를 생성합니다(항상 영어로 알파벳을 연결함). 아래에서 몇 가지 예를 볼 수 있습니다.
알파벳 "ک" "ن" "ا" "د" "ی"
나는 방금 언급한 알파벳으로 이 단어들을 만듭니다: نادان , یاد,دکان
그래서, 그것을 마무리하고 내가 게시한 스크린샷에서 무슨 일이 일어났는지에 대한 단서를 제공하기 위해 터미널은 단어를 알파벳으로 나누고 그것을 뒤집습니다. 내가 만든 단어와 전에 언급한 알파벳을 살펴보세요. 이제 VS 터미널은 "분리"와 "반전"으로 표시됩니다.

올바른 형식: نادان 터미널: ن ا د ا ن
올바른 형식:یاد 터미널: د ا ی
올바른 형식: دکان 터미널: ن ا ک د

이제 귀하의 질문:
히브리어/아랍어/페르시아어의 경우 문자열을 어디에서 뒤집어야 합니까? ASCII 문자 사이에 있는 전체 연속 문자 시퀀스를 반대로 해야 합니까?
나는 히브리어에 대해 전혀 모르지만 아랍어와 페르시아어에서 다음과 같이 공백 문자(단어 구분 기호는 공백)를 만나면 문자 시퀀스가 ​​뒤집혀야 합니다. "모양"과 필요한 준수.

문자는 0-9 또는 구두점과 같은 문자와 어떻게 상호 작용합니까?
숫자 및 구두점에 대한 규칙은 영어와 동일하며 숫자와 구두점 기호는 문자 다음에 옵니다. 이와 같이:
?من در سال "۱۳۶۹" به دنیا آمدم.
من در سال "1369" به دنیا آمدم.
실제로 RTL 및 비RTL 문자를 포함하는 일련의 문자는 완전히 다른 이야기이며 추가 정보가 필요하면 자세히 설명할 수 있습니다.

추신 1:
이 링크는 PHP에서 동일한 문제를 해결하기 위해 작성된 소스 코드입니다.
https://github.com/slashmili/php-gd-persian/blob/master/phpgd/fagd.php

추신 2:
다음은 페르시아 문자에 대한 위키피디아의 리소스입니다.
https://en.wikipedia.org/wiki/Persian_alphabet

추신 3:
다시 말하지만 이전 버전의 VS Code에서는 모든 것이 정상이었습니다.

추신 4:
다음과 같은 일부 LTR 문자가 포함된 단어를 선택하는 문제에 대해
<p>اینجا را بخوانید</p> @CherryDT가 언급한 몇 가지 사소한 버그가 있는데 문제가 되지 않으며 빠른 솔루션을 찾았습니다.

내 vscode를 업데이트한 후 모든 것이 바뀌었습니다. 매우 나쁩니다. 이 문제를 해결하십시오.
다운그레이드 하고싶은데 마녀버전 괜찮나요?

@mostafa69d 다행히 히브리어로는 거의 존재하지 않습니다. 히브리어 문자는 ך으로 변하는 כ, ם으로 변하는 מ, ן으로 변하는 נ, ף으로 변하는 פ, 마지막으로 ㅎㅎ 이것은 히브리어를 형식화하기 쉽게 만듭니다.

그러나 이들은 여전히 ​​별도의 문자(문자 인코딩 측면에서)이며 항상 동일하게 표시됩니다. 이리저리 움직여도 모양이 바뀌지 않습니다. (소핏이든 아니든 올바른 글자를 올바른 위치에 사용하는 것은 작가의 몫입니다.)

분할 문자의 문제는 범위 내에서 하나씩 래핑될 때 연결이 필요하고 모양(아랍 문자)을 나타내지 못한다는 것입니다.

문제를 해결하려면 이러한 문자가 한 범위 내에 있거나 전혀 줄 바꿈하지 않아야 합니다.

이 모든 문자의 유니코드 목록은 다음과 같습니다.
아랍어(0600–06FF, 255자)
아랍어 보충(0750–077F, 48자)
아랍어 확장-A(08A0–08FF, 73자)
아랍어 프레젠테이션 양식-A(FB50–FDFF, 611자)
아랍어 프레젠테이션 양식-B(FE70–FEFF, 141자)
루미 숫자 기호(10E60–10E7F, 31자)
아랍어 수학 알파벳 기호(1EE00-1EEFF, 143자)
screen shot 2017-11-29 at 11 45 00 pm

필수 읽기: https://opensource.com/life/16/3/twisted-road-right-left-language-support

https://github.com/Microsoft/vscode/issues/28571#issuecomment -307991443에서

이것을 잘 처리하는 다른 터미널의 예가 있습니까?

mlterm 은 평균(웹 기반이 아닌) 터미널보다 나은 것 같습니다.
2018-11-15-023232_577x981_scrot
필기체지만 잘리는 경우가 있는데 글꼴을 변경하여 해결할 수 있다고 생각합니다. 이 단락은 Wikipedia에서 복사했으며 파란색 문자는 RTL 표시이므로 vim이 출력하고 mlterm이 파란색으로 렌더링합니다.

Character Joiner API는 이 문제를 해결할 수 있을 것입니다. 우리는 아마도 인접한 모든 아랍어/히브리어/등을 만들 수 있을 것입니다. 유니코드 문자는 결합되어 동일한 글리프로 그려집니다.

그만한 가치가 있기 때문에 디버그 콘솔은 RTL 텍스트와 잘 작동합니다. 이것이 내가 시도한 것입니다.
code
디버그 콘솔의 출력은 다음과 같습니다.
debug
그러나 터미널은 여전히 ​​동일합니다.
terminal

VS Code - Insiders v1.31.0을 사용하고 있습니다.

@babakks 내가 아는 한 Linux 시스템에서 RTL을 올바르게 출력할 수 있는 터미널은 konsolemlterm 이며 모든 배포판 저장소에서 사용할 수 있습니다.

@elieobeid7 @babakks Mac OS 터미널 출력 RTL이 올바르게

내가 이 언어를 구사하지 못하기 때문에 누군가가 유용한 분기를 테스트하고 싶다면 이 문제를 해결하기 위해 PR을 작성하십시오. https://github.com/xtermjs/xterm.js/pull/1899

테스트하려면:

git clone https://github.com/Tyriar/xterm.js
cd xterm.js
git checkout 701_rtl_support
yarn
yarn watch

# another terminals
yarn start

https://github.com/Microsoft/node-pty#dependencies를 설치하려면 일부 종속성이 필요할 수 있습니다.

잠시만 기다려주세요 :)

저는 최근에 터미널에서 RTL 구현 및 기존 문서를 연구하고 평가하고 (초안) 권장 사항을 제시하는 작업을 하고 있습니다. 이제 곧 공개하겠습니다.

처음 생각하는 것보다 훨씬 더 복잡합니다. 약간의 스포일러: BiDi 알고리즘에 따라 문자를 섞기 시작하면 해당 플랫폼에서 적절한 BiDi 인식 텍스트 편집 보기 경험(예: vim, emacs...)을 갖는 것이 문자 그대로 수학적으로 불가능합니다. . (그리고 이전 몇 가지 의견에 대한 답변: 아니요, konsole, mlterm 및 macOS Terminal도 제대로 이해하지 못합니다.)

@egmontkob 이것은 우리가 브라우저의 bidi 지원을 활용한다는 사실을 고려합니까? 내 변경 사항은 관련 유니코드 시퀀스가 ​​별도의 문자가 아닌 함께 그려지도록 강제하는 것뿐입니다. 커서가 문자 위에 있을 때 이것은 아마도 틀릴 수 있지만 그 외에는 작동하는 것 같습니다.

@Tyriar Tyriar에게 미안하지만 여전히 틀렸습니다. 나는 풀 리퀘스트 아래에 댓글을 달았다.
https://github.com/xtermjs/xterm.js/pull/1899#issuecomment -455333377

사양은 일부 데이터를 수신한 후 캔버스가 어떻게 표시되어야 하는지 정의합니다. 사양은 터미널 에뮬레이터의 백엔드가 무엇인지(예: 그래픽 캔버스, 브라우저(HTML DOM) 또는 다른 터미널 에뮬레이터(tmux)) 상관하지 않습니다. 어떤 방법으로든 지정된 동작을 구현하는 것은 터미널 에뮬레이터의 작업입니다. .

그리고 지정된 동작의 한 측면은 "cat " 원하는 출력을 생성합니다. 그리고 일부 다른 상황에서는 셀을 재배열해서는 안 됩니다. 왜냐하면 이것이 vim/emacs/whoever가 자신의 BiDi를 할 수 있는 유일한 방법이기 때문입니다. 이 동작을 제어하는 ​​이스케이프 시퀀스가 ​​있습니다. 그리고 이것보다 훨씬 더 많은 이야기가 있습니다.

https://terminal-wg.pages.freedesktop.org/bidi/ 에서 게시된 BiDi 사양 초안을

이 페이지가 도움이 되었나요?
0 / 5 - 0 등급