lunes, 21 de diciembre de 2015

Retrocesos en la traducción de un programa, o avances mal documentados

Al lanzarse este año la beta de JAWS 17, el lector de pantalla para Windows de Freedom Scientific, se hablaba de mejoras en el proceso de traducción, y ya en las novedades no sólo se incluía una nota dando cuenta de la imposibilidad de importar automáticamente configuración de versiones anteriores debido a la reestructuración de carpetas producto de estas mejoras, sino también de un modo de compatibilidad para que los scripts compilados en JAWS 17 funcionasen en versiones anteriores. Esos datos eran muy genéricos y todo lo relativo a la traducción de programas informáticos me apasiona, de modo que bajé la beta a fin de echarle un vistazo a este aspecto.
El producto final se lanzó en octubre y en noviembre se publicó una actualización que entre otras cosas resolvió un problema de aceleradores traducidos que con el nuevo sistema de traducción habían dejado de estarlo sin que se diera cuenta de ello en los menús pero, hay interrogantes importantes que todavía el fabricante no se dignó a responder. Aprovechando la última entrada de Pablo Muñoz Sánchez en su blog Algo Más Que Traducir, titulada «Investiga. Experimenta. Traduce. Aprende.», que es precisamente lo que estamos teniendo que hacer los usuarios de comunidades tiflotécnicas involucrados en la traducción de scripts para este lector de pantalla ante la falta de información técnica más allá del mensaje publicitario de las mejoras en el proceso de localización, hoy comparto con ustedes lo que fui encontrándome en esta odisea desde que bajé la beta para un somero vistazo hasta ahora que, salida la versión final, me es importante ir entendiéndola.

Traducción hasta la versión 16 inclusive

Los ejecutables incluían recursos en inglés y, para otros idiomas, en la misma carpeta que los archivos ejecutables había archivos DLL con la extensión de cada idioma que contenían recursos estándar de Windows (dialogs, menus, stringtables etc.), incluso aceleradores traducidos en aras a la coherencia con el material didáctico incluido que enseña a manejar Windows. Había además sendas carpetas Help y Manuals, con subcarpetas para cada idioma y los archivos correspondientes.
Hasta aquí no hay nada que el más aficionado de los traductores no conozca, pues casi cualquier programa dispone de archivos DLL con recursos, algunos manuales en formatos de texto o Word y/o ayuda en HTML compilada con extensión .CHM de esas cuyo visor en Windows muestra el contenido a la izquierda y el tema seleccionado en forma de página web a la derecha.

Lo más interesante en la traducción de este programa son sin embargo los scripts, tanto en el conjunto de archivos Default que controlan el comportamiento del lector en todo el sistema como los específicos de aplicaciones. Y es que además de lo poco estándar del procedimiento de localización, son los que a efectos de traducción contienen los mensajes a verbalizar, explicaciones de las combinaciones de teclas que proporcionan, pronunciaciones específicas por ejemplo de conjuntos de símbolos para leer los emoticonos que representan, y dependiendo de cada caso las asignaciones de teclas de determinados scripts para ejecutar sus funciones, que no siempre se traducen.
Explicar el funcionamiento de JAWS en una entrada de blog sería complejo, pero veamos para ponernos en perspectiva qué pasos se seguirían para traducir un conjunto de scripts para una aplicación específica:

  1. Colocamos los archivos del conjunto de scripts en la carpeta, ya sea de nuestro usuario o compartida, Freedom Scientific\JAWS\Versión —p. ej. 16.0—\Settings\código_de_idioma —p. ej. esn para español—. Se llaman igual que el ejecutable de la aplicación cuyo uso con JAWS mejoran, con una serie de extensiones que empiezan con J; existe un archivo especial llamado ConfigNames.ini para incluir nombres de scripts más significativos que el de los ejecutables (p. ej. para poder llamar a los archivos de un script Microsoft Word en vez de Winword, pero rara vez se utiliza con scripts distintos de los que vienen con JAWS y, por ende, no es menester que lo tratemos aquí.
  2. En el conjunto de archivos que acabamos de copiar, procederemos a ver si hay uno o más con extensión .JSM (JAWS Script Messages), que contienen los mensajes a verbalizar y en ocasiones mostrar en pantalla por los scripts, además de nombres de ventanas o cualquier otra información, visible en pantalla o no, que proveniente de las aplicaciones usen los scripts para comparar cadenas a efectos de funcionalidad que las aplicaciones no permiten de manera programática. Esto puede estar en los mismos archivos .JSS (JAWS Script Source) que constituyen el código fuente, pero que esté separado permite realizar la traducción sin necesidad de modificar el código, referenciando este último en las funciones los identificadores de mensajes del archivo .JSM. Estos archivos estarán asociados al Asistente de Scripts de JAWS, pero se pueden modificar con cualquier editor de texto y de hecho para su edición, a diferencia de lo que ocurre al modificar o crear el código fuente, el Asistente de Scripts de JAWS no proporciona funcionalidad específica relevante para el trabajo con este tipo de archivos. Además de lo puramente necesario (@msg_identificador (a veces seguido de _l o _s para leer un mensaje en versión larga o corta a fin de prever ambas configuraciones sobre los mensajes), salto de línea, cuerpo del mensaje (incluyendo marcadores de posición a reemplazarse en tiempo de ejecución con valores de variables o devueltos por funciones), salto de línea y @@ para cada mensaje, un archivo JSM bien diseñado contiene comentarios (que empiezan con punto y coma) sobre el cometido de los marcadores de posición, ante qué circunstancias se generará un mensaje, qué cadenas deben traducirse exactamente como las muestra la aplicación para no estropear la funcionalidad y, cuando uno se halla ante un archivo de lujo, cadenas on y off distintas para cada opción que permitan hacer honor al género y número de cada configuración. Para poner un ejemplo de cadena que ha de traducirse igual a como está en la aplicación, en Skype la lista de mensajes de una conversación se llama Lista del contenido del chat; aunque Lista de contenidos del chat no sería del todo incorrecto como traducción de Chat content list, si tradujéremos Lista de contenidos del chat las funciones que ejecutan los comandos de estos scripts para leer los últimos mensajes o la opción para leer automáticamente los que van llegando no funcionarían, pues buscarían una lista llamada Lista de contenidos del chat que no existe y, de hecho, los comandos para lectura manual de mensajes dirían el mensaje No estás en una ventana de conversación.
  3. Si lo hay, abrimos el archivo con extensión .JSD (JAWS Script Documentation), que de cada script contiene sinopsis, descripción y a veces el nombre a mostrar en el Buscador de Comandos, una herramienta introducida en JAWS 16 para evitar tener que leer ayudas extensas cuando uno se olvida de la combinación de teclas para alguna operación; la sinopsis y la descripción se emplearán en el modo Ayuda de Teclado, aquel en el que el lector no ejecuta acciones sino que, al pulsar teclas o combinaciones de las mismas, las verbaliza e informa de para qué sirven. En este archivo también se documentan funciones, pero al no verbalizarse salvo que el usuario active herramientas de desarrollo, es costumbre dejar su información sin traducir.
  4. De haber un archivo con extensión .QSM (Quick Settings Messages), lo abriremos y modificaremos con cualquier editor de texto; extrañamente, no está entre los tipos de archivo que el Asistente de Scripts reconoce. Su cometido es que se agreguen al árbol de Configuración Rápida, una utilidad de JAWS 13 y superiores para cambiar ajustes sobre la marcha, las opciones específicas de los scripts que se están traduciendo, además de sus descripciones a mostrarse en el lado derecho de esta ventana. Más allá de su extensión exótica, se trata de un archivo XML estándar sin sorpresa alguna para ningún traductor ni aficionado acostumbrado a estos menesteres. Sí conviene cerciorarse de que la codificación declarada coincida con la real, pues de lo contrario al abrir Configuración Rápida con INSERT+V, se generarán errores al «parsear» aquellos puntos del archivo en que aparezcan caracteres internacionales como pueden ser la ñ o las letras acentuadas.
  5. Si quisiéramos cambiar la tecla o combinación de teclas asignada a alguno de los scripts del conjunto, sea porque en la aplicación para la que son los atajos de teclado están traducidos y/o para tornar más intuitivo algún atajo específico de la «accesibilización» medio difícil de recordar y que en inglés tiene algún componente asociativo, lo haremos en el archivo con extensión .JKM (JAWS Key Map). Si los cambios son complejos será mejor abrirlo en algún editor de texto como el mismo Asistente de Scripts de JAWS, pero si los cambios no involucran secuencias de comandos complicadas será más fácil realizarlos con el Asistente de Teclado de JAWS, un programa para lidiar con estos archivos que para editar las combinaciones de teclas ofrece una interfaz gráfica.
  6. A este punto, estamos en condiciones de compilar los scripts y probar qué tal funcionan. Para ello, abriremos en el Asistente de Scripts el archivo con extensión .JSS y pulsaremos CTRL+G. Si utilizamos otro editor de texto, será menester configurarlo para que el comando de compilación llame a %programfiles%\Freedom Scientific\JAWS\Versión\scompile.exe y le pase el nombre del o los archivos que se van a compilar.
  7. En ocasiones, se puede incluir un archivo con extensión .JDF (JAWS Dictionary File). No hacen al funcionamiento de los scripts, pero estos archivos contienen reglas de pronunciación para palabras o expresiones. ¿Por qué se incluirían de serie con un conjunto de scripts si el usuario suele personalizar la pronunciación de las palabras que le interesan en el diccionario predeterminado? Las causas pueden ser varias, pero el ejemplo más sencillo sería el dirigido a un cliente de mensajería instantánea en aras a que los conjuntos de símbolos relevantes no se lean en sí, diciéndose en su lugar la descripción de los emoticonos que representan, por ejemplo, cara triste o mueca de disgusto. Se pueden modificar con cualquier editor de texto, pero afortunadamente el Asistente de Diccionario de JAWS constituye una interfaz gráfica que minimiza la posibilidad de cometer errores editando a mano, sobre todo ante operaciones avanzadas como incluir en el mismo archivo pronunciaciones para varios idiomas de la voz o crear reglas que distingan entre mayúsculas y minúsculas.
  8. Si miramos nuevamente los archivos de que disponemos, advertiremos que se ha modificado (o creado si no disponíamos de él) un archivo con extensión .JSB (JAWS Script Binary). Es el resultado de compilar el archivo .JSS, que contiene a su vez los .JSM y otros que en el JSS se agreguen con una sentencia include, por supuesto, como su nombre indica, binariamente de forma que se puedan utilizar a nivel máquina.

La desventaja de este enfoque es que debe disponerse de todos los archivos en todas las carpetas de idioma, inclusive de aquellos que no hay necesidad de traducir. Así, por ejemplo, en JAWS en español que también incluye versión en inglés, se tienen las carpetas ESN y ENU con archivos JSS idénticos, que pesan unos 9 MB en cada carpeta. Si a eso sumamos archivos de audio y otros como QS y JCF que tampoco se traducen, no es extraño que los instaladores de versiones de JAWS traducidas doblen en tamaño a los originales en inglés un centenar y algo más de MB.
Para los traductores, por otra parte, el trabajo de tener que ocuparse no sólo de traducir los ejecutables y las ayudas como en cualquier software, sino también de los archivos de scripts mencionados para cada aplicación de la que se prevén adaptaciones específicas, y eso sin contar el conjunto de scripts con nombre Default destinados a funcionar en todo el sistema supletoriamente a los scripts específicos de aplicaciones, sin duda es arduo.

La traducción en JAWS 17: de la irrupción de Gettext

En la carpeta de archivos de programa ya no hay archivos DLL separados para cada idioma, ni carpetas de ayudas y manuales. Todo ello se ha movido a la carpeta de JAWS en Programdata.
Nada cambió en cuanto a manuales y ayudas, pero ya casi nada es igual en cuanto a traducción del programa y los scripts.
La carpeta Settings continúa existiendo, pero en la escena de carpetas compartidas su protagonismo es menor, porque hay una carpeta separada Scripts, que es en la que comienzan las sorpresas.

En la carpeta Scripts hay subcarpetas con cada código de idioma, las cuales de los scripts que vienen con el producto contienen los archivos de asignaciones de teclas que como vimos a veces se traducen, de diccionario que considerando que pueden contener reglas en varios idiomas bien podrían haberse dejado en la carpeta raíz, archivos de documentación y en algunos casos de braille; en la carpeta raíz, de estos mismos conjuntos, están los códigos fuente, los binarios compilados y ¡un momento!, ¿por qué hay aquí archivos JSM y QSM que no están en las carpetas de cada idioma? Si los abrimos descubrimos su contenido en inglés, pero algo tiene que haber pues gran parte de su contenido se nos muestra traducido en tiempo de ejecución. Es aquí donde entra Gettext con los archivos PO y MO, tan comunes en el software libre:
Fuera de la carpeta Scripts, ahora existe una Locale con subcarpetas para cada idioma. En la perteneciente al inglés sólo hallamos Help, Manuals y Resources, esta última con archivos que antes eran recursos de tipo BITMAP y WAVE dentro de los archivos de idioma; no hay aquí archivos que traduzcan la interfaz, naturalmente, por cuanto los recursos para ello están en los propios ejecutables. Para otros idiomas como el español, sin embargo, encontramos además dos carpetas adicionales, a saber:

DialogLayouts
Los diálogos que antes se debían redimensionar en los archivos de recursos de cada idioma, ahora se redimensionan a través de archivos .JSON con información de las medidas de cada diálogo de cada ejecutable que se debe traducir.
LC_MESSAGES
Quien haya colaborado en proyectos de software libre ya habrá adivinado lo que es esta carpeta. Pues sí, contiene archivos jaws.po y el compilado jaws.mo, cuyo papel será el tema central de lo que queda de la entrada.

En este catálogo hay cadenas de (casi) todos los ejecutables para los que antes había DLL de idiomas y, lo más interesante, de los archivos JSM y QSM de todos los scripts de fábrica. A primera vista la ventaja para los traductores parece innegable, pues se reduce considerablemente el trabajo de ocuparse de tantos archivos, y eso sin perjuicio de que todavía no se alcanzó en un grado ideal, pues los archivos JKM y JSD todavía se deben traducir por separado y, los de diccionario donde los haya, también. Para el usuario también es una ventaja el hecho de no tener que volver a compilar los archivos de scripts después de modificar los JSM por ejemplo a efectos de corregir un mensaje, lo que resulta de mucha importancia al editar contenido de Common.jsm al que remite Default.jss, pues antes si se cometía un error y se compilaba Default.jss, la compilación fallaba y dejaba a JAWS inutilizable, mientras que ahora con programas como Poedit uno puede buscar la cadena que le interesa y, tras editada y guardado/compilado el catálogo, cerrar y volver a cargar JAWS para estar surtiendo efecto.
Si hubiera scripts de JAWS para Poedit que permitieran leer las notas para traductores de una cadena sin necesidad de navegar manualmente por la jerarquía de objetos, traducir mensajes de los archivos JSM en Poedit sería casi tan cómodo como hacerlo en el Asistente de Scripts pudiendo ver los comentarios de cada cadena, e incluso de varias líneas antes donde se explica el funcionamiento de una serie de tres o cuatro mensajes que va a comenzar. Más aún, editores especializados como éste son capaces de informar sobre falta de marcadores de posición de variables en las traducciones o traducciones dudosas y, aunque sea comprensible que al ser la primera versión se hayan trasladado automáticamente incluso cadenas con errores de los que comento, por ejemplo una que en la edición traducida le falta un %1 y por lo tanto si uno no la arregla dice menú pero sin anunciar el nombre del menú, es de esperar que su posterior detección y corrección futura sea más sencilla.

El problema realmente gordo aparece con scripts de terceros, porque aparte de que ninguna ayuda da cuenta de la nueva estructura de carpetas ni siquiera en lo atinente a los scripts compartidos que puede agregar el usuario, el material tanto didáctico como de referencia para desarrolladores no se actualizó y en las novedades sólo se nos dice esto:

By default, scripts compiled using the Script Manager or the scompile.exe command line tool in JAWS 17 will not work with prior versions of JAWS. This is due to changes in JAWS 17 to improve the localization process. In order to compile scripts that will work in JAWS 17 as well as prior versions, the following line must be added to the JSS file before compiling your scripts.

;#pragma usePoFile 0

If this line is not included, scripts will be compiled using the new localization model and will only work with JAWS 17 and later.

Ante la falta de más información, y dado que de recompilar scripts para versiones anteriores si uno no agrega esta línea los caracteres internacionales no se procesan correctamente, muchos autores están optando por agregar la línea antedicha y que continuemos traduciendo como hasta ahora, lo cual se sigue admitiendo y no ha dado problemas. Siendo no obstante el nuevo un comportamiento predeterminado, tanta negligencia a la hora de documentar el cambio me parece inadecuado. Por dar algunos ejemplos, estas preguntas que me hice no se responden en ningún lado y los autores de scripts ajenos a Freedom Scientific, pobres, están tan perdidos como yo:

  • ¿Se pueden guardar catálogos modificados en la carpeta del usuario para que surtan efecto? Probé y no se puede, pero no se informa en ninguna documentación.
  • Si uno quisiera traducir scripts de terceros utilizando el nuevo modelo, ¿debe crear catálogos con los nombres de archivo de los scripts y guardarlo en la subcarpeta de cada idioma, o actualizar el integrado jaws.po para que se agreguen las cadenas de los conjuntos de scripts adicionales que se copiaron?
  • Si hay que actualizar el catálogo de JAWS y no pudiéndose guardar catálogos en la carpeta del usuario, ¿no interferiría modificar el catálogo con la instalación de actualizaciones que a fin de evitar descargar un instalador completo sólo se decargan parcialmente y se realiza el parcheo? Y aun si no interfiriera, ¿no se corre al actualizar el producto el riesgo de que las traducciones de los scripts que agregó el usuario desaparezcan de un plumazo?
  • Si como algunos insinúan este modelo de traducción actualmente sólo es compatible con scripts de la propia Freedom Scientific, ¿por qué no programaron el compilador para que de no existir la línea de compatibilidad mencionada se la tome como si tuviese valor 0? ¿No sería más práctico eso si este modelo sólo se va a utilizar en la empresa?

Conclusión

Por años nos hemos quejado de que cada vez más se acumulaban desperfectos en las traducciones de JAWS que, salvo honrosas excepciones, pasaban versiones y seguían sin solucionarse, aun cuando bastantes de ellos los podíamos solucionar los propios usuarios conociendo un poco el funcionamiento de los scripts y en general la arquitectura modular de JAWS. Así, recibí con emoción la noticia de que se estuvieran efectuando cambios para la mejora del proceso de localización y, sin perjuicio de que siempre sea necesaria una buena comunicación entre desarrolladores y equipos de traducción, la materialización de esta declaración en una incipiente transición a un formato como los catálogos Gettext mucho más estándares que el cúmulo de archivos de que les hablaba al explicarles someramente la traducción de scripts para JAWS 16 y anteriores, en la medida que requerirá menos trabajo de familiarización con formatos nuevos y menos archivos separados de que ocuparse, me parece prometedora pues debería redundar en traducciones más cuidadas, amén de que ante la sensación de haber menos material habrá más tiempo de revisión.
Ahora bien: las mejoras para traductores profesionales involucrados en el software en sí no deberían implicar quebraderos de cabeza para los usuarios, máxime cuando el avanzado lenguaje de scripts para personalizar y adaptar el comportamiento del programa fue siempre una de las características de que Freedom Scientific y antaño Henter Joice han hecho gala a la hora de resaltar las virtudes del producto. La introducción allá por 2003 de los archivos JSM en JAWS 4.51 para permitir traducir scripts sin trastear con el código fuente fue un gran avance. La transición a Gettext tiene potencial de serlo, pero mientras no se documente bien su alcance y aprovechamiento por creadores de scripts, en seguida se presenta como un retroceso, amplificado si cabe por la falta de adaptaciones específicas en forma de scripts de JAWS para Poedit que, aun sin ser el único, es el editor especializado en Gettext que más se utiliza en Windows. Mientras no existan scripts para esta pieza de software, a un usuario ciego le seguirá resultando más cómodo la antigua aproximación de trabajar sobre los archivos JSM por ir viendo los comentarios a medida que aparecen, en lugar de explorar manualmente la jerarquía de objetos de la interfaz de PoEdit para encontrar las notas para traductores sobre una cadena, a veces incluso sin una clara idea de en qué sección del archivo al que pertenece está, pues no hay ninguna manera de aprovechar usando el teclado el agrupamiento que Poedit puede hacer de las cadenas según el archivo del que sean. Ojalá Freedom Scientific vuelva paulatinamente a viejas usanzas o, mejor aún, documente con más diligencia las prometedoras que empezó a implementar.

No hay comentarios.:

Publicar un comentario