PO4A.7(1)

NOMBRE
po4a - Un marco de trabajo para traducir documentación y otro material

Introducción
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.

¿Por qué po4a?
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.

  Formatos compatibles
Actualmente se han implementado satisfactoriamente algunos tipos de formato de texto:

man (intérprete maduro)
    El clásico formato de las páginas de manual, usado por muchos programas fuera de allí. La compatibilidad con po4a es bienvenida ya que el formato es algo difícil de usar, y no muy amistoso para los principiantes.

    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).

AsciiDoc (intérprete maduro)
    Este formato es un formato de margen ligero entendido para facilitar la autoría de documentación. Es utilizado por ejemplo para documentación del sistema git. Esas páginas man son traducidas utilizando po4a.

    Vea Locale::Po4a::AsciiDoc para detalles.

pod (intérprete maduro)
    Este es el formato «Perl Online Documentation» (Documentación en línea de Perl). El lenguaje y sus mismas extensiones están documentados utilizando este formato junto la suma de muchos guiones Perl existentes. Hace muy fácil mantener la documentación cerca del código al integrarlos en el mismo fichero. Facilita la vida del programador, pero por desgracia, no la del traductor, hasta que utilice po4a.

    Vea Locale::Po4a::Pod para detalles.

sgml (intérprete maduro)
    Aunque hoy en día XML lo haya sustituido, este formato aún se usa para documentos más extensos que unas pocas pantallas. Incluso se puede utilizar para libros completos. Actualizar documentos de esta longitud puede convertirse en un reto enorme. A menudo diff se vuelve inútil cuando se ha sangrado («indented») otra vez el texto original tras una actualización. Afortunadamente, po4a le puede ayudar tras ese proceso.

    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.

TeX / LaTeX (intérprete maduro)
    El formato LaTeX es un formato de documentación usado principalmente en el mundo del Software Libre y para publicaciones.

    Se probó el módulo Locale::Po4a::LaTeX(3pm) con la documentación de Python, un libro y algunas presentaciones.

texto (intérprete maduro)
    El formato Texto es el formato base para muchos formatos que incluyen bloques grandes de texto, incluyendo Markdown, fortunes, sección matter de frente YAML, debian/changelog, y debian/control.

    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.

xml y XHML (intérprete probablemente maduro)
    El formato XML sirve de base para muchos formatos de documentación.

    Actualmente, el formato DTD de DocBook (vea L>Locale::Po4a::DocBook(3pm)> para detalles) y XHTML están admitidos por po4a.

BibTex (intérprete probablemente maduro)
    El formato BibTex es utilizado a lo largo de LaTeX para listados de formato de referencias (bibliográficos).

    Vea Locale::Po4a::BibTex para detalles.

Docbook (intérprete probablemente maduro)
    Un lenguaje añadido basado en XML que utiliza etiquetados semánticos para describir documentos.

    Vea Locale::Po4a:Docbook para detalles mayores.

Guide XML (intérprete probablemente maduro)
    Un formato de documentación XML. Este módulo fue desarrollado específicamente para ayudar con apoyo y mantenimiento de traducciones de documentación de Linux Gentoo hasta al menos en marzo de 2016 (basado en la Máquina Wayback). Gentoo desde entonces se ha migrado al formato XML DevBook.

    Vea Locale::Po4a:Guide para detalles mayores.

Wml (probablemente intérprete maduro)
    El XML (Web Markup Language), no mezcla WML con la materia WAP utilizada en celdas de teléfonos. Este módulo depende del módulo XHTML, el mismo que dependo del módulo XML.

    Véase Locale::Po4a::Wml para más detalles.

Yaml (probablemente un analizador completo)
    Un superconjunto estricto de JSON. YAML se utiliza a menudo como sistemas o proyectos de configuración. YAML está en el núcleo de Ansible de Red Hat.

    Vea Locale::Po4a::Yaml para más detalles.

RubyDoc (probablemente analizador estable)
    El formato Ruby Document (RD), originalmente el formato de documentación por defecto para Ruby y los proyectos Ruby antes de convertirse a RDoc en 2002. Aunque aparentemente la versión japonesa del Manual de Referencia de Ruby todavía usa RD.

    Véase Locale::Po4a::RubyDoc para más detalles.

Halibut (analizador sintáctico probablemente experimental)
    Un sistema de producción de documentación, con elementos similares a TeX, debiandoc-sgml, TeXinfo, y otros, desarrollados por Simon Tatham, el desarrollador de PuTTY.

    Vea Locale::Po4a:Halibut para detalles mayores.

Ini (probablemente intérprete experimental)
    Formado del archivo de configuración popularizado por MS-DOS.

    Vea Locale::Po4a::Ini para detalles más grandes.

texinfo (intérprete altamente experimental)
    Toda la documentación de GNU está escrita en este formato (es incluso un requisito para ser un proyecto oficial de GNU). La compatibilidad de Locale::Po4a::Texinfo(3pm) en po4a está en sus inicios. Por favor, remita informes de fallo y peticiones de funcionalidades.

gemtext (analizador sintáctico muy experimental)
    El formato nativo de texto plano del protocolo Gemini. Se usa habitualmente la extensión ".gmi". El soporte para este módulo en po4a aún está en pañales. Si encuentra algo, por favor envíe un error o una petición de funcionalidad.

Otros formatos admitidos
    Po4a también puede tratar algunos formatos raros o específicos, tales como la documentación de las opciones de compilación de núcleos 2.4+ (Locale::Po4a::KernelHelp) o los diagramas producidos por la herramienta (Locale::Po4a:Dia). Añadir un formato nuevo es a menudo una tarea muy sencilla, y la tarea principal es conseguir un intérprete para el formato escogido. Consulte Locale::Po4a::TransTractor(3pm) para más información.

Formatos no compatibles
    Desafortunadamente, po4a aún le falta compatibilidad para formatos de documentación. Muchos de ellos serían sencillos de mantener en po4a. Esto incluye formatos no tan solo utilizados para documentación, como descripciones de paquetes (deb y rpm), guiones de instalación de paquetes , boletines del paquete, y todos los formatos de archivos especializados utilizados por los programas tales como escenarios de juegos o los archivos de recursos de wine.

Cómo utilizar po4a
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.

  Esquema detallado del flujo de trabajo po4a
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.

  Iniciar un nuevo proyecto de traducción
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.

  Actualización de traducciones y documentos
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).

  Al utilizar adenda para agregar texto adicional para traducciones
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

•   Recuerde que se trata de regexp. Por ejemplo, si quiere que coincida con el final de una sección nroff que termina con la línea ".fi", no utilice ".fi" como endboundary, porque esto coincidirá con "el[ fi]chero", que obviamente no es lo que espera. El endboundary correcto en este caso sería: "^\.fi$".

•   Los espacios en blanco SÍ son importantes en el contenido de "position" y los límites. Así que las dos líneas siguientes son diferentes. La segunda sólo se encontrará si hay suficientes espacios finales en el documento traducido.

     PO4A-HEADER: position=Acerca de este documento; mode=after; beginboundary=<section>
     PO4A-HEADER: position=Acerca de este documento; mode=after; beginboundary=<section>

•   Aunque se puede considerar que esta búsqueda de contexto funciona básicamente en cada línea del documento traducido, en realidad funcionan a partir de la cadena de datos interna del documento traducido. Esta cadena de datos interna puede ser un texto que comprende un párrafo de varias líneas, o una etiqueta XML individual. El punto de inserción preciso del apéndice se debe encontrar antes o después de la cadena de datos interna, y no puede encontrarse dentro de la cadena de datos interna.

•   Pase el argumento "-vv" a po4a para entender cómo se añaden las adendas a la traducción. También puede ayudar ejecutar po4a en modo depuración para ver la cadena de datos interna real cuando no se aplica su adenda.

Ejemplos de anexos

•   Si desea añadir algo después de la siguiente sección de nroff:

      .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

•   Si desea añadir algo justo después de una línea concreta (por ejemplo después de «Copyright Big Dude») utilice un "position" que encaje con esta línea, mode=after e introduzca un beginboundary que encaje con cualquier linea.

     PO4A-HEADER:mode=after;position=Copyright Big Dude, 2004;beginboundary=^

•   Si desea añadir algo al final del documento, especifique un position que encaje con cualquier linea del documento (pero sólo una línea. po4a no procederá si no es única), y ponga un endboundary que no encaje con nada. No utilice cadenas simples como "EOF", sino las que tengan menos probabilidad de salir en el documento.

     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

¿Cómo funciona?
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.

  TransTractors y arquitectura de proyectos
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).

  Analizadores sintácticos de formatos específicos
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().

  Objetos Po
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.

  Contribuir a po4a
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.

Proyectos de código abierto que utilizan po4a
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).

•   adduser (man): herramienta de gestión de usuarios y grupos.

•   apt (man, docbook): Gestor de paquetes Debian.

•   aptitude (docbook, svg): gestor de paquetes basado en la terminal para Debian

•   F-Droid website <https://gitlab.com/fdroid/fdroid-website> (markdown): catálogo instalable de aplicaciones FOSS (Software libre y de código abierto) para la plataforma Android.

•   git <https://github.com/jnavila/git-manpages-l10n> (asciidoc): sistema distribuido de control de versiones para el seguimiento de cambios en el código fuente.

•   Linux manpages <https://salsa.debian.org/manpages-l10n-team/manpages-l10n> (man)

    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).

•   Stellarium <https://github.com/Stellarium/stellarium> (HTML): un planetario libre de código abierto para su ordenador. po4a se utiliza para traducir las descripciones de la cultura celeste.

•   Jamulus <https://jamulus.io/> (markdown, yaml, HTML): una aplicación FOSS para interferir en línea en tiempo real. La documentación del sitio web se mantiene en varios idiomas utilizando po4a.

•   Otro tema a solucionar: <https://gitlab.com/fdroid/fdroid-website/> <https://github.com/fsfe/reuse-docs/pull/61>

Preguntas frecuentes

  ¿Cómo se pronuncia po4a?
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 :)

  ¿Por qué están obsoletos los scripts individuales?
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.

  ¿Qué hay de las otras herramientas de traducción de documentación que usan gettext?
Hay unas cuantas. Esta es una lista posiblemente incompleta, y más herramientas se asoman por el horizonte.

poxml
    Esta es la herramienta desarrollada por la gente de KDE para tratar DocBook XML. Me parece que este fue el primer programa que extrajo cadenas de texto a traducir desde la documentación a ficheros PO, e inyectarlas de vuelta después de la traducción.

    Ú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.

po-debiandoc
    Este programa hecho por Denis Barbier es un tipo de precursor del módulo SGML de po4a, que más o menos lo deja obsoleto. Como su nombre indica, únicamente trata el DTD de DebianDoc, que es más o menos un DTD anticuado.

xml2po.py
    Utilizado por el Equipo de Documentación de GIMP desde 2004, funciona bastante bien aunque, como su nombre indica, sólo con archivos XML y necesita makefiles especialmente configurados.

Sphinx
    El Proyecto de Documentación Sphinx también utiliza gettext extensivamente para gestionar sus traducciones. Por desgracia, sólo funciona para unos pocos formatos de texto, rest y markdown, aunque quizá sea la única herramienta que lo hace gestionando todo el proceso de traducción.

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.

  RESUMEN de las ventajas de la metodología basada en gettext

•   Las traducciones no se guardan junto con el original, lo que hace posible la detección de traducciones anticuadas.

•   Las traducciones se guardan en ficheros separados unos de otros, lo que impide que traductores de diferentes idiomas interfieran en su trabajo tanto al enviar parches, como a nivel de codificación de ficheros.

•   Está basado internamente en gettext (pero po4a ofrece una interfaz muy simple de forma que no necesita entender el funcionamiento interno para usarlo). De esa forma no tenemos que reinventar la rueda, y debido a su uso extendido podemos imaginar que estas herramientas están más o menos libres de fallos.

•   Para el usuario final nada ha cambiado (aparte de que, probablemente, las traducciones estarían mejor actualizadas :). El fichero de documentación resultante es exactamente el mismo.

•   No hace falta que los traductores aprendan una nueva sintaxis de fichero, y sus editores favoritos de ficheros PO (como el modo PO de Emacs, Lokalize o Gtranslator) servirán a la perfección.

•   gettext ofrece una manera simple de conseguir estadísticas sobre qué está hecho, qué se debería repasar y actualizar, y lo que queda por hacer. Puede encontrar algunos ejemplos en estas direcciones:

     - 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.

•   Los apéndices son algo extraños a primera vista.

•   No puede adaptar el texto traducido a su gusto, como dividir párrafos por aquí, y juntar esos dos allí. Pero por supuesto, si hay algún problema con el original debería remitir un informe de fallo.

•   Incluso con una interfaz fácil, sigue siendo una nueva herramienta que la gente debe aprender.

    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.

VÉASE TAMBIÉN

•   La documentación de la herramienta todo en uno que debes utilizar: po4a(1).

•   La documentación del script individual po4a: po4a-gettextize(1), po4a-updatepo(1), po4a-translate(1), po4a-normalize(1).

•   Los scripts de ayuda adicionales: msguntypot(1), po4a-display-man(1), po4a-display-pod(1).

•   Loa analizadores de cada formato, en particular para ver las opciones aceptadas por cada uno de ellos: Locale::Po4a::AsciiDoc(3pm) Locale::Po4a::Dia(3pm), Locale::Po4a::Guide(3pm), Locale::Po4a::Ini(3pm), Locale::Po4a::KernelHelp(3pm), Locale::Po4a::Man(3pm), Locale::Po4a::RubyDoc(3pm), Locale::Po4a::Texinfo(3pm), Locale::Po4a::Text(3pm), Locale::Po4a::Xhtml(3pm), Locale::Po4a::Yaml(3pm), Locale::Po4a::BibTeX(3pm), Locale::Po4a::Docbook(3pm), Locale::Po4a::Halibut(3pm), Locale::Po4a::LaTeX(3pm), Locale::Po4a::Pod(3pm), Locale::Po4a::Sgml(3pm), Locale::Po4a::TeX(3pm), Locale::Po4a::Wml(3pm), Locale::Po4a::Xml(3pm).

•   La implementación de la infraestructura central: Locale::Po4a::TransTractor(3pm) (particularmente importante para entender la organización del código), Locale::Po4a::Chooser(3pm), Locale::Po4a::Po(3pm), Locale::Po4a::Common(3pm). Consulte también el archivo CONTRIBUTING.md en el código fuente.

AUTORES
 Denis Barbier <barbier,linuxfr.org>
 Martin Quinson (mquinson#debian.org)

TRADUCCION
 Jordi Vilalta <jvprat@gmail.com>
 Omar Campagne <ocampagne@gmail.com>

POD ERRORS
Hey! The above document had some coding errors, which are explained below:

Around line 263:
    Unknown E content in E<Lokalize>