| PO4A.7(1) | User Contributed Perl Documentation | PO4A.7(1) |
po4a - Un marco de trabajo para traducir documentación y otro material
po4a (PO para todo) facilita el mantenimiento de traducción de documentación utilizando las clásicas herramientas gettext. La característica de po4a principal es que desacopla la traducción del contenido desde su estructura documental.
Este documento sirve como una introducción para el proyecto po4a con un enfoque en usuarios potenciales considerando si utiliza esta herramienta y en la curioso deseo de entender por qué las cosas son de la manera que son.
La filosofía de Free Software , es hacer que la tecnología está disponible a cada uno. Pero la licencia no es la única consideración: el software libre no traducido es inútil para los hablantes no ingleses. Por lo tanto, aún hay tarea que hacer para crear software disponible para todos.
Esta situación es bien entendida por muchos proyectos y cada uno ahora está convencido de la necesidad de traducir todo. Aún, las traducciones actuales representan un enorme esfuerzo de muchos individuales, heridos por pequeñas dificultades técnicas.
Agradecidamente, el software libre se beneficia de un nivel decente de traducción gracias al maravilloso conjunto de herramientas gettext. Éste puede extraer las cadenas a traducir de un programa, presentarlas en un formato uniforme a los traductores, y luego usar el resultado de su trabajo durante la ejecución para mostrar los mensajes traducidos al usuario.
En cuanto a la documentación, sin embargo, la situación sigue siendo un tanto decepcionante. Al principio, traducir documentación puede parecer más fácil que traducir un programa, ya que parece que basta con copiar el archivo fuente de la documentación y empezar a traducir el contenido. Sin embargo, cuando se modifica la documentación original, hacer un seguimiento de las modificaciones se convierte rápidamente en una pesadilla para los traductores. Si se hace manualmente, esta tarea es desagradable y propensa a errores.
Las traducciones obsoletas suelen ser peores que la ausencia de traducción. Los usuarios finales pueden ser engañados por documentación que describe un comportamiento antiguo del programa. Además, no pueden interactuar directamente con los mantenedores porque no hablan inglés. Asimismo, el mantenedor no puede solucionar el problema porque no conoce todos los idiomas a los que se traduce su documentación. Estas dificultades, a menudo causadas por herramientas deficientes, pueden minar la motivación de los traductores voluntarios, lo que agrava aún más el problema.
La ambición del proyecto po4a es facilitar el trabajo de los traductores de la documentación. En particular, crea traducciones de documentación mantenibles.
La idea es reutilizar y adaptar el enfoque de gettext a este campo. Al igual que con gettext, los textos se extraen de sus ubicaciones originales y se presentan a los traductores como catálogos de traducción PO. Los traductores pueden aprovechar las herramientas clásicas de gettext para controlar el trabajo a realizar, colaborar y organizarse como equipos. po4a inyecta entonces las traducciones directamente en la estructura de la documentación para producir archivos fuente traducidos que pueden procesarse y distribuirse igual que los archivos en inglés. Cualquier párrafo que no se traduzca se deja en inglés en el documento resultante, asegurando que los usuarios finales nunca vean una traducción obsoleta en la documentación.
Esto automatiza la mayor parte del trabajo de mantenimiento de la traducción. Descubrir los párrafos que necesitan una actualización resulta muy fácil, y el proceso se automatiza por completo cuando los elementos se reordenan sin más modificaciones. La verificación específica también puede utilizarse para reducir la posibilidad de errores de formato que darían lugar a un documento roto.
Por favor, lea también las Preguntas frecuentes, más abajo en éste documento, para una lista más completa de las ventajas y desventajas de este enfoque al problema.
Actualmente se han implementado satisfactoriamente algunos tipos de formato de texto:
El módulo Locale::Po4a::Man(3pm) además admite el formato mdoc, utilizado por las páginas man BSD (no son muy comunes en Linux).
Vea Locale::Po4a::AsciiDoc para detalles.
Vea Locale::Po4a::Pod para detalles.
Actualmente, sólo son compatibles los DTD de DebianDoc y de DocBook, pero añadir compatibilidad con uno nuevo es realmente fácil. Incluso es posible usar po4a con un DTD desconocido de SGML sin cambiar el código introduciendo la información necesaria en la línea de órdenes. Consulte Locale::Po4a::Sgml(3pm) para más detalles.
Se probó el módulo Locale::Po4a::LaTeX(3pm) con la documentación de Python, un libro y algunas presentaciones.
Esto admite el formato común utilizado en Generadores de Sitio Estático, README, y otros sistemas de documentación. Vea Locale::Po4a::Text(3pm) para detalles.
Actualmente, el formato DTD de DocBook (vea L>Locale::Po4a::DocBook(3pm)> para detalles) y XHTML están admitidos por po4a.
Vea Locale::Po4a::BibTex para detalles.
Vea Locale::Po4a:Docbook para detalles mayores.
Vea Locale::Po4a:Guide para detalles mayores.
Véase Locale::Po4a::Wml para más detalles.
Vea Locale::Po4a::Yaml para más detalles.
Véase Locale::Po4a::RubyDoc para más detalles.
Vea Locale::Po4a:Halibut para detalles mayores.
Vea Locale::Po4a::Ini para detalles más grandes.
La forma más sencilla de utilizar esta herramienta en su proyecto es escribir un fichero de configuración para el programa po4a, e interactuar únicamente con este programa. Consulte su documentación, en po4a(1). El resto de esta sección proporciona más detalles para los usuarios avanzados de po4a que quieran profundizar en su comprensión.
Asegúrese de leer po4a(1) antes de esta sección excesivamente detallada para obtener una visión simplificada del flujo de trabajo de po4a. Vuelva aquí cuando quiera obtener la imagen completa que asusta, con casi todos los detalles.
En el siguiente esquema, master.doc es un nombre de ejemplo para la documentación a traducir; XX.doc es el mismo documento traducido al idioma XX mientras que doc.XX.po es el catálogo de traducción para ese documento en el idioma XX. Los autores de la documentación se ocuparán principalmente de master.doc (que puede ser una página de manual, un documento XML, un fichero AsciidDoc, etc); los traductores se ocuparán principalmente del fichero PO, mientras que los usuarios finales sólo verán el fichero XX.doc.
Las transiciones con corchetes como "[po4a updates po]" representan la ejecución de una herramienta po4a mientras que las transiciones con corchetes como "{update of master.doc}" representan una modificación manual de los archivos del proyecto.
master.doc
|
V
+<-----<----+<-----<-----<--------+------->-------->-------+
: | | :
{translation} | {update of master.doc} :
: | | :
XX.doc | V V
(optional) | master.doc ->-------->------>+
: | (new) |
V V | |
[po4a-gettextize] doc.XX.po -->+ | |
| (old) | | |
| ^ V V |
| | [po4a updates po] |
V | | V
translation.pot ^ V |
| | doc.XX.po |
| | (fuzzy) |
{translation} | | |
| ^ V V
| | {manual editing} |
| | | |
V | V V
doc.XX.po --->---->+<---<-- doc.XX.po adendos master.doc
(initial) (up-to-date) (optional) (up-to-date)
: | | |
: V | |
+----->----->----->------> + | |
| | |
V V V
+------>-----+------<------+
|
V
[po4a updates translations]
|
V
XX.doc
(up-to-date)
De nuevo, este esquema es excesivamente complicado. Consulta po4a(1) para obtener una visión simplificada.
La parte izquierda muestra cómo se puede usar po4a-gettextize(1) para convertir un proyecto de traducción existente a la infraestructura po4a. Este script toma un documento original y su contrapartida traducida, e intenta construir el archivo PO correspondiente. Esta conversión manual es bastante engorrosa (consulte la documentación de po4a-gettextize(1) para más detalles), pero solo es necesaria una vez para convertir sus traducciones existentes. Si no tiene ninguna traducción que convertir, puede olvidarse de esto y centrarse en la parte derecha del esquema.
En la parte superior derecha se representa la acción del autor original, que actualiza la documentación. La parte central derecha muestra la actualización automática de los archivos de traducción: se extrae el nuevo material y se compara con la traducción existente. La traducción anterior se utiliza para las partes que no han cambiado, mientras que las partes parcialmente modificadas se conectan a la traducción anterior con un marcador "difuso" que indica que la traducción debe actualizarse. El material nuevo o muy modificado se deja sin traducir.
A continuación, el bloque edición manual representa la acción de los traductores, que modifican los ficheros PO para proporcionar traducciones a cada cadena y párrafo originales. Esto se puede hacer usando un editor específico como el GNOME Translation Editor, Lokalize o poedit de KDE, o usando una plataforma de localización online como weblate o pootle. El resultado de la traducción es un conjunto de ficheros PO, uno por idioma. Por favor, consulte la documentación de gettext para más detalles.
La parte inferior de la figura muestra cómo po4a crea un documento fuente traducido a partir del documento original master.doc y el catálogo de traducción doc.XX.po actualizado por los traductores. La estructura del documento se reutiliza, mientras que el contenido original se sustituye por su homólogo traducido. Opcionalmente, se puede utilizar un apéndice para añadir texto adicional a la traducción. Suele utilizarse para añadir el nombre del traductor al documento final. Para más detalles, véase más abajo.
Al invocarlo, po4a actualiza automáticamente tanto los archivos de traducción como los archivos de documentación traducidos.
Si empieza desde cero, sólo tiene que escribir un fichero de configuración para po4a, y listo. Se crearán las plantillas relevantes para los ficheros que falten, permitiendo a sus colaboradores traducir su proyecto a su idioma. Por favor, consulte po4a(1) para un tutorial de inicio rápido y para todos los detalles.
Si tiene una traducción existente, es decir, un fichero de documentación que se tradujo manualmente, puede integrar su contenido en su flujo de trabajo po4a usando po4a-gettextize. Esta tarea es un poco engorrosa (como se describe en la página de manual de la herramienta), pero una vez que su proyecto se convierta al flujo de trabajo po4a, todo se actualizará automáticamente.
Una vez configurado, basta con invocar po4a para actualizar tanto los ficheros PO de traducción como los documentos traducidos. Puede pasar "--no-translations" a po4a para no actualizar las traducciones (actualizando así sólo los ficheros PO) o "--no-update" para no actualizar los ficheros PO (actualizando así sólo las traducciones). Esto corresponde aproximadamente a los scripts individuales po4a-updatepo y po4a-translate que ahora están obsoletos (vea "Por qué están obsoletos los scripts individuales" en las FAQ más abajo).
Agregando texto nuevo para la traducción es probablemente la única cosa que es más fácil en la dirección larga cuando traduzca archivos manualmente :). Esto ocurre cuando desea añadir una sección adicional para el documento traducido, no correspondiente a ningún contenido dentro del documento original. La utilización clásica de caso es dar reconocimientos al equipo de traducción, y para indicar como informar problemas específicos de traducción.
Con po4a, tiene que especificar archivos anexos, que pueden verse conceptualmente como parches aplicados al documento localizado después de procesarlo. Cada anexo debe proporcionarse como un archivo separado, cuyo formato es, sin embargo, muy diferente de los parches clásicos. La primera línea es una línea de encabezamiento, que define el punto de inserción del anexo (con una sintaxis desafortunadamente críptica -- ver más abajo) mientras que el resto del archivo se añade textualmente en la posición determinada.
La línea de encabezado debe comenzar con la cadena PO4A-HEADER:, seguida de una lista de campos clave=valor separados por punto y coma.
Por ejemplo, el siguiente encabezamiento declara un anexo que debe colocarse al final de la traducción.
PO4A-HEADER: mode=eof
Las cosas se complican cuando desea añadir su contenido adicional en medio del documento. La siguiente cabecera declara un anexo que debe colocarse después de la sección XML que contiene la cadena "Acerca de este documento" en la traducción.
PO4A-HEADER: position=Acerca de este documento; mode=after; endboundary=</section>
En la práctica, al intentar aplicar un anexo, po4a busca la primera línea que coincida con el argumento de "posición" (puede ser una regexp). No olvide que po4a considera aquí el documento traducido. Esta documentación está en inglés, pero su línea probablemente debería decir lo siguiente si pretende que su anexo se aplique a la traducción francesa del documento.
PO4A-HEADER: position=À propos de ce document; mode=after; endboundary=</section>
Una vez encontrada la "posición" en el documento destino, po4a busca la siguiente línea después de la "posición" que coincida con el "endboundary" proporcionado. El anexo se añade justo después de esa línea (porque proporcionamos un endboundary, es decir, un límite que termina la sección actual).
Se podría obtener exactamente el mismo efecto con la siguiente cabecera, que es equivalente:
PO4A-HEADER: position=Acerca de este documento; mode=after; beginboundary=<section>
A continuación, el bloque edición manual representa la acción de los traductores, que modifican los ficheros PO para proporcionar traducciones a cada cadena y párrafo originales. Esto puede hacerse usando un editor específico como el GNOME Translation Editor, B o B para KDE<Lokalize><poedit>, o usando una plataforma de localización online como weblate o pootle. El resultado de la traducción es un conjunto de ficheros PO, uno por idioma. Consulte la documentación de gettext para más detalles.
También se puede asignar a la inserción mode el valor "before", con una semántica similar: si se combina "mode=before" con un "endboundary", el apéndice se situará justo after del límite coincidente, es decir, la última línea límite potencial antes de la "position". Si se combina "mode=before" con "beginboundary", el apéndice se situará justo before del límite coincidente, es decir, la última línea límite potencial antes de "position".
Modo | Tipo límite | Límite usado | Punto de inserción relativo al límite ========|===============|========================|========================================= 'before'| 'endboundary' | último antes de 'position' | Justo tras el límite seleccionado 'before'|'beginboundary'| último antes de 'position' | Justo antes del límite seleccionado 'after' | 'endboundary' | primero tras 'position' | Justo tras el límite seleccionado 'after' |'beginboundary'| primero tras 'position' | Justo antes del límite seleccionado 'eof' | (ninguno) | n/a | Fin del archivo
Consejos y trucos sobre los anexos
PO4A-HEADER: position=Acerca de este documento; mode=after; beginboundary=<section>
PO4A-HEADER: position=Acerca de este documento; mode=after; beginboundary=<section>
Ejemplos de anexos
.SH "AUTORES"
Debe seleccionar un enfoque de dos pasos estableciendo mode=after. A continuación, debe limitar la búsqueda a la línea posterior a AUTHORS con el argumento regex position. A continuación, debe hacer coincidir el comienzo de la siguiente sección (es decir, ^\.SH) con el argumento regex beginboundary. Es decir:
PO4A-HEADER:mode=after;position=AUTORES;beginboundary=\.SH
PO4A-HEADER:mode=after;position=Copyright Big Dude, 2004;beginboundary=^
PO4A-HEADER:mode=after;position=Acerca de este documento;beginboundary=FakePo4aBoundary
Ejemplo más detallado
Documento original (en formato POD):
|=head1 NOMBRE | |relleno - un programa de relleno | |=head1 AUTOR | |yo
Luego, el siguiente apéndice asegurará que se añade una sección (en español) sobre el traductor al final del fichero.
|PO4A-HEADER:mode=after;position=AUTOR;beginboundary=^=head | |=head1 TRADUCTOR | |yo |
Para poner su anexo antes del AUTOR, utilice la siguiente cabecera:
PO4A-HEADER:mode=after;position=NOMBRE;beginboundary=^=head1
Esto funciona porque la siguiente línea que coincide con la beginboundary "/^=head1/" después de la sección "NAME" (traducido a "NOM" en francés), es la que declara los autores. Así pues, el addendum se colocará entre ambas secciones. Tenga en cuenta que si más tarde se añade otra sección entre las secciones NOMBRE y AUTOR, po4a pondrá erróneamente la adenda antes de la nueva sección.
Para evitarlo, puede lograr el mismo efecto utilizando mode=before:
PO4A-HEADER:mode=before;position=^=head1 AUTHOR
Este capítulo le da una breve visión general del funcionamiento interno de po4a, para que se sienta más seguro a la hora de ayudarnos a mantenerlo y mejorarlo. También puede ayudarle a entender por qué no hace lo que esperaba, y cómo resolver sus problemas.
En el núcleo del proyecto po4a, la clase Locale::Po4a::TransTractor(3pm) es el ancestro común de todos los analizadores sintácticos de po4a. Este extraño nombre proviene del hecho de que se encarga al mismo tiempo de traducir el documento y de extraer las cadenas.
Más formalmente, toma un documento para traducir más un fichero PO que contiene las traducciones para utilizarlo como entrada, al tiempo que produce dos salidas separadas: Otro fichero PO (resultante de la extracción de cadenas traducibles del documento de entrada), y un documento traducido (con la misma estructura que el de entrada, pero con todas las cadenas traducibles sustituidas por contenido del PO de entrada). He aquí una representación gráfica de esto:
Documento de entrada --\ /---> Documento de salida
\ TransTractor:: / (traducido)
+-->-- parse() --------+
/ \
PO de entrada --------/ \---> PO de salida
(extraído)
Este pequeño hueso es el núcleo de toda la arquitectura po4a. Si proporciona ambos PO de entrada y no tiene en cuenta el PO de salida, obtiene po4a-translate. Si no tiene en cuenta el documento de salida, obtiene po4a-updatepo. po4a utiliza un primer TransTractor para obtener un fichero POT de salida actualizado (sin tener en cuenta los documentos de salida), llama a msgmerge -U para actualizar los ficheros PO de traducción en disco, y construye un segundo TransTractor con estos ficheros PO actualizados para actualizar los documentos de salida. En resumen, po4a proporciona una solución única para actualizar lo que sea necesario, utilizando un único archivo de configuración.
po4a-gettextize también usa dos TransTractores, pero de otra forma: Construye un TransTractor por idioma, y luego construye un nuevo fichero PO usando los msgids del documento original como msgids, y los msgids del documento traducido como msgstrs. Hay que tener mucho cuidado para asegurarse de que las cadenas emparejadas de esta forma realmente coinciden, como se describe en po4a-gettextize(1).
Todos los analizadores de formato po4a se implementan sobre el TransTractor. Algunos son muy simples, como los de Text, Markdown y AsciiDoc. Cargan las líneas una a una usando TransTractor::shiftline(), acumulan el contenido de los párrafos o lo que sea. Una vez que una cadena está completamente analizada, el analizador usa TransTractor::translate() para (1) añadir esta cadena al fichero PO de salida y (2) obtener la traducción del fichero PO de entrada. El parseador entonces empuja el resultado al fichero de salida usando TransTractor::pushline().
Algunos otros analizadores sintácticos son más complejos porque dependen de un analizador sintáctico externo para analizar el documento de entrada. Los analizadores sintácticos Xml, HTML, SGML y Pod están construidos sobre analizadores sintácticos SAX. Declaran retrollamadas a eventos como "He encontrado un nuevo título cuyo contenido es el siguiente" para actualizar el documento de salida y los archivos POT de salida según el contenido de entrada utilizando TransTractor::translate() y TransTractor::pushline(). El analizador Yaml es similar pero diferente: serializa una estructura de datos producida por el analizador YAML::Tiny. Esta es la razón por la que el módulo Yaml de po4a no declara las líneas de referencia: la localización de cada cadena en el fichero de entrada no la guarda el analizador, por lo que sólo podemos proporcionar "$nombredefichero:1" como localización de la cadena. Los analizadores sintácticos orientados a SAX usan globales y otros trucos para guardar el nombre del fichero y los números de línea de las referencias.
Un problema específico surge de las codificaciones de archivos y los marcadores BOM. Los analizadores sintácticos simples pueden olvidarse de este problema, que es manejado por TransTractor::read() (usado internamente para obtener las líneas de un documento de entrada), pero los módulos que dependen de un analizador sintáctico externo deben asegurarse de que todos los ficheros se leen con una capa de decodificación PerlIO apropiada. Lo más fácil es abrir el fichero tú mismo, y proporcionar un filehandle o directamente la cadena completa a tu parser externo. Mira en Pod::read() y Pod::parse() para ver un ejemplo. El contenido leído por el TransTractor se ignora, pero se pasa un nuevo filehandle al analizador externo. La parte importante es el modo "<:encoding($charset)" que se pasa a la función perl open().
La clase Locale::Po4a::Po(3pm) se encarga de cargar y usar ficheros PO y POT. Básicamente, puede leer un fichero, añadir entradas, obtener traducciones con el método gettext(), escribir el PO en un fichero. Funciones más avanzadas como fusionar un fichero PO con un fichero POT o validar un fichero se delegan en msgmerge y msgfmt respectivamente.
Incluso si nunca ha contribuido a ningún proyecto de código abierto en el pasado, es bienvenido: estamos dispuestos a ayudarle y guiarle. po4a es mejor mantenido por sus usuarios hoy en día. Como nos falta mano de obra, intentamos hacer el proyecto acogedor mejorando la documentación y las pruebas automáticas para que tenga confianza en contribuir al proyecto. Por favor, consulte el archivo CONTRIBUTING.md para más detalles.
Aquí hay una lista muy parcial de proyectos que usan po4a en producción para su documentación. Si desea añadir su proyecto a la lista, envíenos un correo electrónico (o una Merge Request).
Este proyecto proporciona una infraestructura para traducir muchas páginas de manual a diferentes idiomas, listas para su integración en varias de las principales distribuciones (Arch Linux, Debian y derivados, Fedora).
Yo personalmente lo pronuncio como pouah <https://en.wiktionary.org/wiki/pouah>, que es una onomatopeya francesa que usamos en lugar de puaj :) Puede que tenga un extraño sentido del humor :)
De hecho, po4a-updatepo y po4a-translate quedan obsoletos en favor de po4a. La razón es que, aunque po4a puede utilizarse como sustituto de estos scripts, hay mucha duplicación de código. Los scripts individuales tienen alrededor de 150 líneas de código mientras que el programa po4a tiene 1200 líneas, por lo que hacen mucho además de las funciones internas comunes. La duplicación de código resulta en errores que ocurren en ambas versiones y necesitan dos correcciones. Un ejemplo de tal duplicación son los errores #1022216 en Debian y el problema #442 en GitHub que tenían exactamente la misma solución, pero uno en po4a y el otro po4a-updatepo.
A largo plazo, me gustaría abandonar los scripts individuales y mantener sólo una versión de este código. Lo seguro es que los scripts individuales no se mejorarán más, por lo que sólo po4a obtendrá las nuevas características. Dicho esto, no hay urgencia de desaprobación. Planeo mantener los scripts individuales tanto como sea posible, y al menos hasta 2030. Si tu proyecto todavía utiliza po4a-updatepo y po4a-translate en 2030, puede que tengas un problema.
También es posible que en algún momento eliminemos la desaprobación de estos scripts, si una refactorización reduce a cero la duplicación de código. Si tienes una idea (o mejor: un parche), tu ayuda será bienvenida.
Hay unas cuantas. Esta es una lista posiblemente incompleta, y más herramientas se asoman por el horizonte.
Únicamente puede tratar XML, y solo un DTD en particular. Estoy bastante insatisfecho con el tratamiento que hacen de las listas, que terminan en un único msgid. Cuando la lista crece, el bloque se hace difícil de tratar.
Las principales ventajas de po4a sobre ellos son la facilidad de adición de contenidos extra (que es aún peor ahí) y la habilidad de realizar la gettextización.
- https://docs.kde.org/stable5/en/kdesdk/lokalize/project-view.html
- http://www.debian.org/intl/l10n/
Pero no todo es bonito, y este enfoque también tiene algunas desventajas con las que debemos lidiar.
Uno de mis sueños es integrar de alguna forma po4a con Gtranslator o Lokalize. Cuando se abra un fichero, se extraen las cadenas automáticamente, y se puede escribir en el disco un fichero traducido y un fichero PO. Si consiguiéramos hacer un módulo para MS Word (TM) (o al menos RTF) incluso podrían usarlo traductores profesionales.
Denis Barbier <barbier,linuxfr.org> Martin Quinson (mquinson#debian.org)
Jordi Vilalta <jvprat@gmail.com> Omar Campagne <ocampagne@gmail.com>
Hey! The above document had some coding errors, which are explained below:
| 2024-08-06 | perl v5.38.2 |