Xterm.js: Soporta idiomas RTL

Creado en 13 jun. 2017  ·  17Comentarios  ·  Fuente: xtermjs/xterm.js

Problema posterior: https://github.com/Microsoft/vscode/issues/28571

Cuando aplicamos el ancho de carácter Unicode en https://github.com/sourcelair/xterm.js/issues/467, se rompieron los caracteres del idioma RTL, ya que ahora se representan al revés (LTR). Podríamos revertir eso solo para rangos de caracteres RTL, pero deberíamos hacer la corrección correcta e invertir las cadenas para que estén realmente en la cuadrícula de caracteres, ya que el nuevo modelo de selección se basa en todos los caracteres alineados perfectamente en la cuadrícula https: // github. com / sourcelair / xterm.js / pull / 670

Idealmente, el reflujo de línea https://github.com/sourcelair/xterm.js/issues/622 se haría antes de esto, por lo que es más fácil cambiar el contenido de varias líneas.

Terminal.app:

image

VS Code 1.13 (las oraciones de aviso están invertidas):

image

@ mostafa69d @CherryDT un poco de información sobre los idiomas en cuestión sería útil:

  1. ¿Dónde deben invertirse las cadenas. Para hebreo / árabe / persa, ¿debo invertir secuencias continuas completas de caracteres entre caracteres ascii?
  2. ¿Cómo se supone que los personajes interactúen con caracteres como 0-9 o puntuación?

Referencias útiles:

arei18n arerenderer typenhancement

Comentario más útil

@Tyriar
En primer lugar, les daré una perspectiva muy breve del idioma árabe y persa, tal vez les ayude (no estoy seguro de si el hebreo es el mismo).
En los idiomas árabe y persa, los alfabetos son como "آ" "ب" "س" y así sucesivamente. Y las palabras están hechas por estos alfabetos (obviamente) con una regla muy diferente en comparación con, por ejemplo, el inglés.
La diferencia es que tenemos más de una forma para algún alfabeto como "س". La primera forma es "س" y la segunda es "سـ", la otra es "ـسـ" y la última es "ـس". ¿Y cuál es el uso de estas formas? Según dónde aparezca el alfabeto en una palabra, la forma del alfabeto que usamos varía. Por ejemplo, para el alfabeto mencionado "س" usamos la forma "سـ" cuando una palabra comienza con este alfabeto como "سلام". Aquí está el problema y, en realidad, la diferencia entre un idioma como el inglés y el persa o el árabe. Generamos palabras en estos idiomas concatenando las diferentes formas de estos alfabetos (los unimos en algunos casos). De nuevo resalto esta regla: generamos estas palabras concatenando las formas, no los alfabetos (que siempre es concatenando alfabetos en inglés), puedes ver algunos ejemplos a continuación:
tenemos alfabetos "ک" "ن" "ا" "د" "ی"
Hago estas palabras con los alfabetos que acabo de mencionar: نادان, یاد, دکان
Entonces, para terminar y darte la pista de lo que sucedió en las capturas de pantalla que publiqué, el terminal divide las palabras en alfabetos y las invierte (por lo que no se trata solo de invertir). Eche un vistazo a las palabras que creé y los alfabetos que mencioné antes. Ahora, el terminal VS los muestra "separados" y "invertidos".

Formato correcto: نادان Terminal: ن ا د ا ن
Formato correcto: یاد Terminal: د ا ی
Formato correcto: دکان Terminal: ن ا ک د

Ahora tus preguntas:
¿Dónde deben invertirse las cadenas. Para hebreo / árabe / persa, ¿debo invertir secuencias continuas completas de caracteres entre caracteres ascii?
No tengo ninguna idea sobre el hebreo, pero en árabe y persa las secuencias de caracteres deben cambiar cuando encuentran un carácter de espacio (el separador de palabras es el espacio) como este: "من در حال نوشتن هستم" pero aún así debería mantener el "formas" y adherencia necesaria.

¿Cómo se supone que los personajes interactúen con caracteres como 0-9 o puntuación?
En cuanto a los números y la puntuación, las reglas son las mismas que en inglés y los números y los signos de puntuación siguen a los caracteres. como esto:
? من در سال "۱۳۶۹" به دنیا آمدم.
من در سال "1369" به دنیا آمدم.
En realidad, una secuencia de personajes que contienen personajes RTL y no RTL es una historia completamente diferente y si necesita más información, puedo elaborarla.

PD 1:
Este enlace aquí es un código fuente que está escrito para resolver el mismo problema en PHP (seguro que en versiones antiguas) puedes echar un vistazo
https://github.com/slashmili/php-gd-persian/blob/master/phpgd/fagd.php

PD 2:
Aquí hay un recurso en wikipedia sobre los personajes persas.
https://en.wikipedia.org/wiki/Persian_alphabet

PS 3:
Nuevamente, debo mencionar que en la versión anterior de VS Code, todo estaba bien.

PS 4:
Sobre el problema de seleccionar una palabra que contiene algún carácter LTR como
<p>اینجا را بخوانید</p> que @CherryDT mencionó, hay algunos errores menores con los que no tengo ningún problema y encontré soluciones rápidas para ellos (pero aún así, si necesita algo más de detalle, hágamelo saber)

Todos 17 comentarios

En realidad, es mucho más complicado e incluye estado e incluso reflejar ciertos personajes. Yo diría que es una ciencia en sí misma. (Y tengo el más profundo respeto por aquellas personas que escribieron bibliotecas de representación de texto sólidas que manejan todos los problemas de BiDi correctamente, por lo que _yo_ no tengo que perder el tiempo con eso, para ser honesto).

Ver también:
https://en.wikipedia.org/wiki/Bi-directional_text (buena descripción general)
https://www.w3.org/International/articles/inline-bidi-markup/uba-basics
https://www.w3.org/International/tutorials/svg-tiny-bidi/ (la premisa inicial no está relacionada pero explica algunas cosas mejor que el enlace anterior)
https://github.com/fevangelou/doctype-mirror/tree/master/bidihowto/bidi-support-in-a-ui

EDITAR: Creo que la forma en que funciona la nueva selección puede ser realmente inesperada porque se comportará de manera diferente a VSCode. Por ejemplo, dado el texto "La canción מדינת קומבינה me hace pensar", cuando empiezo a seleccionar en "La" y termino entre las dos palabras hebreas, habré seleccionado "La canción מדינת", mientras que en la consola habré seleccionado "La canción קומבינה".

Ver ejemplo:
Image

Sin embargo, seguirá siendo mejor que cómo "funciona" Sublime Text la última vez que verifiqué, porque allí verás una cosa seleccionada pero copiarás otra, lo cual es muy molesto.

@Tyriar
En primer lugar, les daré una perspectiva muy breve del idioma árabe y persa, tal vez les ayude (no estoy seguro de si el hebreo es el mismo).
En los idiomas árabe y persa, los alfabetos son como "آ" "ب" "س" y así sucesivamente. Y las palabras están hechas por estos alfabetos (obviamente) con una regla muy diferente en comparación con, por ejemplo, el inglés.
La diferencia es que tenemos más de una forma para algún alfabeto como "س". La primera forma es "س" y la segunda es "سـ", la otra es "ـسـ" y la última es "ـس". ¿Y cuál es el uso de estas formas? Según dónde aparezca el alfabeto en una palabra, la forma del alfabeto que usamos varía. Por ejemplo, para el alfabeto mencionado "س" usamos la forma "سـ" cuando una palabra comienza con este alfabeto como "سلام". Aquí está el problema y, en realidad, la diferencia entre un idioma como el inglés y el persa o el árabe. Generamos palabras en estos idiomas concatenando las diferentes formas de estos alfabetos (los unimos en algunos casos). De nuevo resalto esta regla: generamos estas palabras concatenando las formas, no los alfabetos (que siempre es concatenando alfabetos en inglés), puedes ver algunos ejemplos a continuación:
tenemos alfabetos "ک" "ن" "ا" "د" "ی"
Hago estas palabras con los alfabetos que acabo de mencionar: نادان, یاد, دکان
Entonces, para terminar y darte la pista de lo que sucedió en las capturas de pantalla que publiqué, el terminal divide las palabras en alfabetos y las invierte (por lo que no se trata solo de invertir). Eche un vistazo a las palabras que creé y los alfabetos que mencioné antes. Ahora, el terminal VS los muestra "separados" y "invertidos".

Formato correcto: نادان Terminal: ن ا د ا ن
Formato correcto: یاد Terminal: د ا ی
Formato correcto: دکان Terminal: ن ا ک د

Ahora tus preguntas:
¿Dónde deben invertirse las cadenas. Para hebreo / árabe / persa, ¿debo invertir secuencias continuas completas de caracteres entre caracteres ascii?
No tengo ninguna idea sobre el hebreo, pero en árabe y persa las secuencias de caracteres deben cambiar cuando encuentran un carácter de espacio (el separador de palabras es el espacio) como este: "من در حال نوشتن هستم" pero aún así debería mantener el "formas" y adherencia necesaria.

¿Cómo se supone que los personajes interactúen con caracteres como 0-9 o puntuación?
En cuanto a los números y la puntuación, las reglas son las mismas que en inglés y los números y los signos de puntuación siguen a los caracteres. como esto:
? من در سال "۱۳۶۹" به دنیا آمدم.
من در سال "1369" به دنیا آمدم.
En realidad, una secuencia de personajes que contienen personajes RTL y no RTL es una historia completamente diferente y si necesita más información, puedo elaborarla.

PD 1:
Este enlace aquí es un código fuente que está escrito para resolver el mismo problema en PHP (seguro que en versiones antiguas) puedes echar un vistazo
https://github.com/slashmili/php-gd-persian/blob/master/phpgd/fagd.php

PD 2:
Aquí hay un recurso en wikipedia sobre los personajes persas.
https://en.wikipedia.org/wiki/Persian_alphabet

PS 3:
Nuevamente, debo mencionar que en la versión anterior de VS Code, todo estaba bien.

PS 4:
Sobre el problema de seleccionar una palabra que contiene algún carácter LTR como
<p>اینجا را بخوانید</p> que @CherryDT mencionó, hay algunos errores menores con los que no tengo ningún problema y encontré soluciones rápidas para ellos (pero aún así, si necesita algo más de detalle, hágamelo saber)

Después de actualizar mi vscode, todo al revés, eso es muy malo, resuelva este problema
Quiero bajar de categoría, ¿la versión de Witch está bien?

@ mostafa69d afortunadamente en hebreo que apenas existe. Las letras hebreas permanecen casi iguales en cualquier posición dentro de una palabra, además de algunas letras que son כ que se convierte en ך, luego מ que se convierte en ם, luego נ que se convierte en ן, luego פ que se convierte en ף y finalmente צ que se convierte en ץ. Esto hace que el hebreo sea más fácil de formatear, supongo.

Sin embargo, estos siguen siendo caracteres separados (en términos de codificación de caracteres) y siempre muestran lo mismo. No cambian de apariencia cuando se mueven. (Es trabajo del escritor usar la letra correcta, suave o no, en la posición correcta).

El problema con los caracteres de división es que cuando se envuelven dentro del intervalo uno por uno, requerirá conexión y no representará la forma (letras árabes).

Para solucionar el problema, estos caracteres deben estar dentro de un intervalo o no envolverlos en absoluto.

La lista del Unicode todas estas letras son
Árabe (0600–06FF, 255 caracteres)
Suplemento árabe (0750–077F, 48 caracteres)
Árabe ampliado-A (08A0–08FF, 73 caracteres)
Formularios de presentación en árabe A (FB50 – FDFF, 611 caracteres)
Formularios de presentación en árabe B (FE70 – FEFF, 141 caracteres)
Símbolos numéricos Rumi (10E60–10E7F, 31 caracteres)
Símbolos alfabéticos matemáticos árabes (1EE00—1EEFF, 143 caracteres)
screen shot 2017-11-29 at 11 45 00 pm

lectura obligatoria: https://opensource.com/life/16/3/twisted-road-right-left-language-support

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

¿tienes un ejemplo de otro terminal que maneje esto bien?

mlterm parece ser mejor que el terminal promedio (no basado en web).
2018-11-15-023232_577x981_scrot
Es cursiva pero en algunos casos cortada, creo que se puede resolver cambiando la fuente, este párrafo fue copiado de Wikipedia, los caracteres azules son la marca RTL, así es como vim los está generando y mlterm los está renderizando en azul.

La API de unión de caracteres podría resolver esto, probablemente podríamos hacer todos los arábigos / hebreos / etc. adyacentes. los caracteres unicode se unen y se dibujan en el mismo glifo.

Por lo que vale, la consola de depuración funciona bien con textos RTL. Esto es lo que he probado:
code
Y esta es la salida en la consola de depuración:
debug
Pero el terminal sigue siendo el mismo:
terminal

Estoy usando VS Code - Insiders v1.31.0.

@babakks Solo dos terminales que yo sepa en el sistema Linux pueden generar RTL correctamente, konsole y mlterm , están disponibles en todos los repositorios de distribución.

@ elieobeid7 @babakks Salida RTL del terminal Mac OS correctamente

Publique un PR para solucionar esto, si alguien quiere probar la rama que sería útil ya que no hablo estos idiomas. https://github.com/xtermjs/xterm.js/pull/1899

Probar:

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

# another terminals
yarn start

Es posible que necesite instalar algunas dependencias https://github.com/Microsoft/node-pty#dependencies

Espere un poco :)

Recientemente he estado trabajando en el estudio, la evaluación de los documentos existentes y las implementaciones de RTL en terminales, y se me ocurrió una recomendación (borrador). Lo lanzaré muy pronto ahora.

Es mucho más complicado de lo que uno pensaría en un principio. Un poco de spoiler: si comienzas a barajar los personajes de acuerdo con el algoritmo BiDi, se vuelve literal y matemáticamente imposible tener una experiencia adecuada de visualización y edición de texto compatible con BiDi (por ejemplo, vim, emacs ...) en la parte superior de esa plataforma . (Y para responder a los comentarios anteriores: no, konsole, mlterm y macOS Terminal tampoco lo hacen bien).

@egmontkob, ¿esto tiene en cuenta el hecho de que podemos aprovechar el soporte bidi del navegador? Todo lo que hace mi cambio es forzar que las secuencias Unicode relacionadas se dibujen juntas, no como caracteres separados. Probablemente esto sea incorrecto cuando el cursor está sobre el carácter, pero parece funcionar de otra manera.

@Tyriar Lo siento Tyriar, pero todavía está mal. Comenté en la solicitud de extracción.
https://github.com/xtermjs/xterm.js/pull/1899#issuecomment -455333377

La especificación define cómo debe verse el lienzo, después de recibir algunos datos. A la especificación no le importa cuál es el backend del emulador de terminal (por ejemplo, un lienzo gráfico o un navegador (HTML DOM) u otro emulador de terminal (tmux)), es la tarea del emulador de terminal implementar el comportamiento especificado por cualquier medio .

Y un aspecto del comportamiento especificado es que, en algunas circunstancias, las celdas de caracteres deben mezclarse de acuerdo con el algoritmo BiDi (solo con fines de visualización, sin afectar el almacenamiento real), porque esa es la única forma razonable de obtener utilidades simples como "cat "producir el resultado deseado; y en algunas otras circunstancias, las celdas no deben reorganizarse, porque esa es la única forma en que vim / emacs / quienquiera que pueda hacer su propio BiDi. Hay secuencias de escape que controlan este comportamiento. Y hay mucho más en la historia que esto.

Consulte el borrador de especificación BiDi publicado en https://terminal-wg.pages.freedesktop.org/bidi/ . Los comentarios, las ideas de mejora, etc. son bienvenidos en su rastreador de problemas.

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

Tyriar picture Tyriar  ·  4Comentarios

fabiospampinato picture fabiospampinato  ·  4Comentarios

zhangjie2012 picture zhangjie2012  ·  3Comentarios

parisk picture parisk  ·  3Comentarios

jerch picture jerch  ·  3Comentarios