Xterm.js: RTL-Sprachen unterstützen

Erstellt am 13. Juni 2017  ·  17Kommentare  ·  Quelle: xtermjs/xterm.js

Downstream-Problem: https://github.com/Microsoft/vscode/issues/28571

Als wir die Unicode-Zeichenbreite in https://github.com/sourcelair/xterm.js/issues/467 erzwungen haben, wurden die RTL-Sprachzeichen unterbrochen, da sie jetzt in umgekehrter Reihenfolge (LTR) gerendert werden. Wir könnten dies nur für RTL-Zeichenbereiche rückgängig machen, aber wir sollten die richtige Korrektur vornehmen und die Zeichenfolgen umkehren, damit sie sich tatsächlich im Zeichenraster befinden, da das neue Auswahlmodell darauf beruht, dass alle Zeichen perfekt im Raster https://github ausgerichtet sind. com/sourcelair/xterm.js/pull/670

Idealerweise wird der Zeilenumbruch https://github.com/sourcelair/xterm.js/issues/622 vorher durchgeführt, damit es einfacher ist, den Inhalt mehrerer Zeilen zu ändern.

Terminal.app:

image

VS Code 1.13 (Hinweissätze sind umgekehrt):

image

@mostafa69d @CherryDT ein

  1. Wo sollen die Zeichenfolgen umgedreht werden. Muss ich für Hebräisch/Arabisch/Persisch ganze fortlaufende Zeichenfolgen zwischen ASCII-Zeichen umkehren?
  2. Wie sollen die Zeichen mit Zeichen wie 0-9 oder Satzzeichen interagieren?

Nützliche Referenzen:

arei18n arerenderer typenhancement

Hilfreichster Kommentar

@Tyriar
Zuerst werde ich Ihnen eine sehr kurze Perspektive der arabischen und persischen Sprache geben, vielleicht hilft es Ihnen (ich bin mir nicht sicher, ob das Hebräisch dasselbe ist).
In arabischen und persischen Sprachen sind die Alphabete wie "آ" "ب" "س" und so weiter. Und die Wörter werden von diesen Alphabeten (offensichtlich) mit einer ganz anderen Regel gebildet als zum Beispiel im Englischen.
Der Unterschied besteht darin, dass wir für einige Alphabete wie "س" mehr als eine Form haben. Die erste Form ist "س" und die zweite ist "سـ", die andere ist "ـسـ" und die letzte ist "ـس". Und wozu dienen diese Formen? Je nachdem, wo das Alphabet in einem Wort erscheint, variiert die Form des Alphabets, die wir verwenden. Für das erwähnte Alphabet "س" verwenden wir beispielsweise die Form "سـ", wenn ein Wort mit diesem Alphabet wie "سلام" beginnt. Hier liegt das Problem und eigentlich der Unterschied zwischen einer Sprache wie Englisch und Persisch oder Arabisch. Wir erzeugen Wörter in diesen Sprachen, indem wir die verschiedenen Formen dieser Alphabete verketten (wir kleben sie in einigen Fällen zusammen). Noch einmal hebe ich diese Regel hervor: Wir generieren diese Wörter, indem wir die Formen und nicht die Alphabete verketten (was im Englischen immer Alphabete verkettet). Sie können einige Beispiele unten sehen:
wir haben Alphabete "ک" "ن" "ا" "د" "ی"
Ich bilde diese Wörter durch gerade erwähnte Alphabete: نادان , یاد,
Um es zusammenzufassen und Ihnen den Hinweis zu geben, was in den Screenshots passiert ist, die ich gepostet habe, teilt das Terminal die Wörter in Alphabete auf und kehrt sie um. (Es geht also nicht nur um das Umkehren). Sehen Sie sich Wörter und Alphabete an, die ich zuvor erwähnt habe. Jetzt zeigt das VS-Terminal sie "getrennt" und "umgekehrt" an.

Richtiges Format: نادان Terminal: ن ا د ا ن
Richtiges Format:یاد Terminal: د ا ی
Richtiges Format: دکان Terminal: ن ا ک د

Nun deine Fragen:
Wo sollen die Zeichenfolgen umgedreht werden. Muss ich für Hebräisch/Arabisch/Persisch ganze fortlaufende Zeichenfolgen zwischen ASCII-Zeichen umkehren?
Ich habe keine Ahnung von Hebräisch, aber auf Arabisch und Persisch sollten sich die Zeichenfolgen umdrehen, wenn sie auf ein Leerzeichen treffen (Das Worttrennzeichen ist ein Leerzeichen) wie folgt:" من در حال نوشتن هستم" "Formen" und notwendige Einhaltung.

Wie sollen die Zeichen mit Zeichen wie 0-9 oder Satzzeichen interagieren?
In Bezug auf Zahlen und Satzzeichen sind die Regeln die gleichen wie im Englischen und die Zahlen und Satzzeichen folgen den Zeichen. so was:
?من در "۱۳۶۹" .
"1369" .
Tatsächlich ist eine Sequenz von Charakteren, die RTL- und Nicht-RTL-Charaktere enthalten, eine ganz andere Geschichte und wenn Sie mehr Informationen benötigen, kann ich das ausführen.

PS1:
Dieser Link hier ist ein Quellcode, der geschrieben wurde, um das gleiche Problem in PHP zu lösen (mit Sicherheit alte Versionen), den Sie sich ansehen können
https://github.com/slashmili/php-gd-persian/blob/master/phpgd/fagd.php

PS2:
Hier ist eine Ressource auf Wikipedia über die persischen Schriftzeichen
https://en.wikipedia.org/wiki/Persian_alphabet

PS3:
Auch hier muss ich erwähnen, dass in der vorherigen Version von VS Code alles in Ordnung war.

PS4:
Über das Problem bei der Auswahl eines Wortes mit LTR-Zeichen wie
<p>اینجا را بخوانید</p> die @CherryDT erwähnt hat, es gibt einige kleinere Fehler, mit denen ich kein Problem habe, und ich habe schnelle Lösungen dafür gefunden.

Alle 17 Kommentare

Es ist eigentlich viel komplizierter und beinhaltet Standhaftigkeit und sogar das Spiegeln bestimmter Charaktere. Ich würde sagen, es ist eine eigene Wissenschaft. (Und ich habe den tiefsten Respekt vor den Leuten, die robuste Text-Rendering-Bibliotheken geschrieben haben, die alle BiDi-Probleme richtig handhaben, also muss _ich_ ehrlich gesagt nicht damit herumspielen.)

Siehe auch:
https://en.wikipedia.org/wiki/Bi-directional_text (gute Übersicht)
https://www.w3.org/International/articles/inline-bidi-markup/uba-basics
https://www.w3.org/International/tutorials/svg-tiny-bidi/ (die ursprüngliche Prämisse ist nicht verwandt, erklärt aber einige Dinge besser als der vorherige Link)
https://github.com/fevangelou/doctype-mirror/tree/master/bidihowto/bidi-support-in-a-ui

BEARBEITEN: Ich denke, die Funktionsweise der neuen Auswahl ist möglicherweise unerwartet, da sie sich anders verhalten wird als VSCode selbst. Wenn ich zum Beispiel den Text "Das Lied מדינת קומבינה regt mich zum Nachdenken" gegeben habe, wenn ich mit der Auswahl bei "The" beginne und zwischen den beiden hebräischen Wörtern ende, habe ich "Das Lied מדינת" ausgewählt, während ich in der Konsole ausgewählt habe "Das Lied קומבינה".

Siehe Beispiel:
Image

Es wird jedoch immer noch besser sein, als wie Sublime Text das letzte Mal "funktioniert", da Sie dort eine Sache ausgewählt sehen, aber eine andere kopieren, was sehr ärgerlich ist.

@Tyriar
Zuerst werde ich Ihnen eine sehr kurze Perspektive der arabischen und persischen Sprache geben, vielleicht hilft es Ihnen (ich bin mir nicht sicher, ob das Hebräisch dasselbe ist).
In arabischen und persischen Sprachen sind die Alphabete wie "آ" "ب" "س" und so weiter. Und die Wörter werden von diesen Alphabeten (offensichtlich) mit einer ganz anderen Regel gebildet als zum Beispiel im Englischen.
Der Unterschied besteht darin, dass wir für einige Alphabete wie "س" mehr als eine Form haben. Die erste Form ist "س" und die zweite ist "سـ", die andere ist "ـسـ" und die letzte ist "ـس". Und wozu dienen diese Formen? Je nachdem, wo das Alphabet in einem Wort erscheint, variiert die Form des Alphabets, die wir verwenden. Für das erwähnte Alphabet "س" verwenden wir beispielsweise die Form "سـ", wenn ein Wort mit diesem Alphabet wie "سلام" beginnt. Hier liegt das Problem und eigentlich der Unterschied zwischen einer Sprache wie Englisch und Persisch oder Arabisch. Wir erzeugen Wörter in diesen Sprachen, indem wir die verschiedenen Formen dieser Alphabete verketten (wir kleben sie in einigen Fällen zusammen). Noch einmal hebe ich diese Regel hervor: Wir generieren diese Wörter, indem wir die Formen und nicht die Alphabete verketten (was im Englischen immer Alphabete verkettet). Sie können einige Beispiele unten sehen:
wir haben Alphabete "ک" "ن" "ا" "د" "ی"
Ich bilde diese Wörter durch gerade erwähnte Alphabete: نادان , یاد,
Um es zusammenzufassen und Ihnen den Hinweis zu geben, was in den Screenshots passiert ist, die ich gepostet habe, teilt das Terminal die Wörter in Alphabete auf und kehrt sie um. (Es geht also nicht nur um das Umkehren). Sehen Sie sich Wörter und Alphabete an, die ich zuvor erwähnt habe. Jetzt zeigt das VS-Terminal sie "getrennt" und "umgekehrt" an.

Richtiges Format: نادان Terminal: ن ا د ا ن
Richtiges Format:یاد Terminal: د ا ی
Richtiges Format: دکان Terminal: ن ا ک د

Nun deine Fragen:
Wo sollen die Zeichenfolgen umgedreht werden. Muss ich für Hebräisch/Arabisch/Persisch ganze fortlaufende Zeichenfolgen zwischen ASCII-Zeichen umkehren?
Ich habe keine Ahnung von Hebräisch, aber auf Arabisch und Persisch sollten sich die Zeichenfolgen umdrehen, wenn sie auf ein Leerzeichen treffen (Das Worttrennzeichen ist ein Leerzeichen) wie folgt:" من در حال نوشتن هستم" "Formen" und notwendige Einhaltung.

Wie sollen die Zeichen mit Zeichen wie 0-9 oder Satzzeichen interagieren?
In Bezug auf Zahlen und Satzzeichen sind die Regeln die gleichen wie im Englischen und die Zahlen und Satzzeichen folgen den Zeichen. so was:
?من در "۱۳۶۹" .
"1369" .
Tatsächlich ist eine Sequenz von Charakteren, die RTL- und Nicht-RTL-Charaktere enthalten, eine ganz andere Geschichte und wenn Sie mehr Informationen benötigen, kann ich das ausführen.

PS1:
Dieser Link hier ist ein Quellcode, der geschrieben wurde, um das gleiche Problem in PHP zu lösen (mit Sicherheit alte Versionen), den Sie sich ansehen können
https://github.com/slashmili/php-gd-persian/blob/master/phpgd/fagd.php

PS2:
Hier ist eine Ressource auf Wikipedia über die persischen Schriftzeichen
https://en.wikipedia.org/wiki/Persian_alphabet

PS3:
Auch hier muss ich erwähnen, dass in der vorherigen Version von VS Code alles in Ordnung war.

PS4:
Über das Problem bei der Auswahl eines Wortes mit LTR-Zeichen wie
<p>اینجا را بخوانید</p> die @CherryDT erwähnt hat, es gibt einige kleinere Fehler, mit denen ich kein Problem habe, und ich habe schnelle Lösungen dafür gefunden.

Nach der Aktualisierung meines vscodes ist alles umgekehrt, das ist sehr schlecht, bitte lösen Sie dieses Problem
Ich möchte ein Downgrade durchführen, ist die Hexenversion in Ordnung?

@mostafa69d zum Glück auf Hebräisch, die es kaum gibt. Hebräische Buchstaben bleiben in jeder Position innerhalb eines Wortes meist gleich, abgesehen von wenigen Buchstaben, die כ zu ך werden, dann מ, das zu ם wird, dann נ, das zu ן wird, dann פ, das zu ף wird und schließlich צ, das zu wird . Das macht Hebräisch einfacher zu formatieren, denke ich.

Dies sind jedoch immer noch separate Zeichen (in Bezug auf die Zeichencodierung) und werden immer gleich angezeigt. Sie verändern ihr Aussehen nicht, wenn sie bewegt werden. (Es ist die Aufgabe des Autors, den richtigen Buchstaben - Sofit oder nicht - an der richtigen Stelle zu verwenden.)

Das Problem mit den Aufteilungszeichen besteht darin, dass, wenn sie nacheinander in Spanne eingeschlossen werden, eine Verbindung erforderlich ist und die Form (arabische Buchstaben) nicht dargestellt wird.

Um das Problem zu beheben, müssen sich diese Zeichen innerhalb einer Spanne befinden oder dürfen sie überhaupt nicht umschließen.

Die Liste des Unicodes all diese Buchstaben sind
Arabisch (0600–06FF, 255 Zeichen)
Arabischer Zusatz (0750–077F, 48 Zeichen)
Arabisch Extended-A (08A0–08FF, 73 Zeichen)
Arabische Präsentationsformulare-A (FB50–FDFF, 611 Zeichen)
Arabische Präsentationsformulare-B (FE70–FEFF, 141 Zeichen)
Rumi-Zahlensymbole (10E60–10E7F, 31 Zeichen)
Arabische mathematische alphabetische Symbole (1EE00—1EEFF, 143 Zeichen)
screen shot 2017-11-29 at 11 45 00 pm

Pflichtlektüre: https://opensource.com/life/16/3/twisted-road-right-left-language-support

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

Haben Sie ein Beispiel für ein anderes Terminal, das dies gut handhabt?

mlterm scheint besser zu sein als das durchschnittliche (nicht webbasierte) Terminal.
2018-11-15-023232_577x981_scrot
Es ist kursiv, aber in einigen Fällen abgeschnitten, ich denke, es kann durch Ändern der Schriftart gelöst werden, dieser Absatz wurde aus Wikipedia kopiert, die blauen Zeichen sind das RTL-Zeichen, so gibt vim sie aus und mlterm rendert sie in Blau.

Die Zeichenverbindungs-API könnte dies möglicherweise lösen, wir könnten wahrscheinlich alle angrenzenden arabischen/hebräischen/etc. Unicode-Zeichen verbinden sich und werden in derselben Glyphe gezeichnet.

Für das, was es wert ist, funktioniert die Debug-Konsole gut mit RTL-Texten. Das habe ich versucht:
code
Und das ist die Ausgabe auf der Debug-Konsole:
debug
Aber das Terminal ist immer noch das gleiche:
terminal

Ich verwende VS Code - Insiders v1.31.0.

@babakks Nur zwei Terminals im Linux-System können RTL korrekt ausgeben, konsole und mlterm , sie sind in allen Distributions-Repos verfügbar.

@elieobeid7 @babakks Mac OS Terminal gibt RTL korrekt aus

Veröffentlichen Sie eine PR, um dies zu beheben, wenn jemand den Zweig testen möchte, der nützlich wäre, da ich diese Sprachen nicht spreche. https://github.com/xtermjs/xterm.js/pull/1899

Zu testen:

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

# another terminals
yarn start

Möglicherweise müssen einige Abhängigkeiten installiert werden https://github.com/Microsoft/node-pty#dependencies

Bitte warten Sie ein bisschen :)

Ich habe vor kurzem daran gearbeitet, bestehende Dokumente und Implementierungen von RTL in Terminals zu studieren, zu bewerten und eine (Entwurfs-)Empfehlung zu erstellen. Ich werde es jetzt ganz bald veröffentlichen.

Es ist viel komplizierter, als man zunächst denkt. Ein bisschen Spoiler: Wenn Sie anfangen, die Zeichen gemäß dem BiDi-Algorithmus herumzumischen, wird es buchstäblich, mathematisch nachweislich unmöglich, auf dieser Plattform eine richtige BiDi-bewusste Textbearbeitungs- und Anzeigeerfahrung (z. B. vim, emacs ...) zu haben . (Und um auf die vorherigen Kommentare zu antworten: nein, konsole, mlterm und macOS Terminal machen es auch nicht richtig.)

@egmontkob berücksichtigt dies die Tatsache, dass wir die Bidi-Unterstützung des Browsers nutzen können? Alles, was meine Änderung bewirkt, ist, dass zusammenhängende Unicode-Sequenzen gezwungen werden, nicht als separate Zeichen zusammengezogen zu werden. Dies ist wahrscheinlich falsch, wenn sich der Cursor über dem Zeichen befindet, aber es scheint anders zu funktionieren.

Die Spezifikation definiert, wie die Leinwand aussehen muss, nachdem einige Daten empfangen wurden. Der Spezifikation ist es egal, was das Backend des Terminalemulators ist (z. B. ein grafischer Canvas oder ein Browser (HTML DOM) oder ein anderer Terminalemulator (tmux)), es ist die Aufgabe des Terminalemulators, das angegebene Verhalten mit welchen Mitteln auch immer zu implementieren .

Und ein Aspekt des spezifizierten Verhaltens ist, dass die Zeichenzellen unter Umständen nach dem BiDi-Algorithmus gemischt werden müssen (nur zu Anzeigezwecken, ohne den tatsächlichen Speicher zu beeinflussen), da dies der einzig vernünftige Weg ist, einfache Dienstprogramme wie "cat " die gewünschte Ausgabe erzeugen; und unter anderen Umständen dürfen die Zellen nicht neu angeordnet werden, denn nur so kann vim/emacs/wer auch immer sein eigenes BiDi machen. Es gibt Escape-Sequenzen, die dieses Verhalten steuern. Und die Geschichte hat noch viel mehr zu bieten.

Bitte beachten Sie den veröffentlichten Entwurf der BiDi-Spezifikation unter https://terminal-wg.pages.freedesktop.org/bidi/ . Kommentare, Verbesserungsvorschläge usw. sind dort im Issue Tracker willkommen.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen