PO4A.7(7)

NOMBRE
po4a - marco de trabajo para traducir documentacion y otro material

Introduccion
El objetivo del proyecto po4a (po para todo) es facilitar la traduccion (y mas interesante, el mantenimiento de las traducciones) usando las herramientas de gettext en areas donde no eran de esperar, como en la documentacion.

Tabla de contenidos
Este documento esta organizado de la siguiente forma:

1 XPorque debo usar po4a? XPara que sirve?
    Este capitulo introductorio explica la motivacion del proyecto y su filosofia. Deberia leerlo primero si esta en el proceso de evaluacion de po4a para sus propias traducciones.

2 XComo usar po4a?
    Este capitulo es como un manual de referencia, donde se intenta contestar las preguntas de los usuarios, y se le ofrece una idea general del proceso. Le introduce al metodo de trabajo con po4a y sirve como documentacion introductoria de las herramientas especificas.

    XComo empezar una nueva traduccion?
    XComo transformar la traduccion de vuelta a un archivo de documentacion?
    XComo actualizar una traduccion con po4a?
    XComo convertir una traduccion ya existente a po4a?
    XComo an~adir texto extra en las traducciones (como el nombre del traductor)?
    XComo hacer todo esto en una sola invocacion a programa?
3 XComo funciona?
    Este capitulo ofrece una breve explicacion del funcionamiento interno de po4a, de forma que se pueda sentir mas seguro para ayudarnos a mantenerlo y mejorarlo. Tambien le puede ayudar a entender porque no hace lo que esperaba, y como solucionar sus problemas.

4 Preguntas Frecuentes
    Este capitulo agrupa las Preguntas Frecuentes. De hecho, la mayoria de preguntas actuales se pueden formular asi: "XPorque se ha disen~ado asi, y no asi?" Si piensa que po4a no es la solucion ideal para la traduccion de documentacion, deberia considerar leer esta seccion. Si no responde su pregunta, contacte con nosotros en la lista de correo <po4a-devel@lists.alioth.debian.org>. Queremos escuchar su opinion.

5 Notas especificas de los modulos
    Este capitulo presenta los puntos especificos de cada modulo desde el punto de vista tanto del traductor como del autor original. Lea esto para aprender la sintaxis que se encontrara cuando traduzca textos con un modulo, o las reglas que debe seguir en el documento original para facilitar la vida del traductor.

    Actualmente esta seccion no forma parte de este documento. En realidad esta en la documentacion de cada modulo. Esto permite asegurar que la informacion esta actualizada al mantener la documentacion y el codigo juntos.

6 Fallos conocidos y caracteristicas solicitadas
    Unos cuantos aun :(

XPorque debo usar po4a? XPara que sirve?
Me gusta la idea del software de codigo abierto, lo que hace posible que todo el mundo pueda acceder al software y a su codigo fuente. Pero al ser frances soy bien consciente de que la licencia no es la unica restriccion de la libertad del software: los programas libres no traducidos son inservibles para gente de habla no inglesa, y todavia queda bastante faena para hacerlos disponibles para todos.

La percepcion de esta situacion por los responsables del software libre ha mejorado drasticamente recientemente. Nosotros, como traductores, hemos ganado la primera batalla y hemos convencido a todo el mundo de la importancia de las traducciones. Pero por desgracia, esta era la parte facil. Ahora tenemos que ponernos en marcha y empezar a traducir.

Actualmente, el software libre se beneficia de un nivel decente de traduccion, gracias al maravilloso paquete de herramientas gettext. Este 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 en tiempo de ejecucion para mostrar los mensajes traducidos al usuario.

Pero la situacion es bastante diferente para la documentacion. Demasiado a menudo, la documentacion traducida no es suficientemente visible (no se distribuye como parte del programa), solo lo esta parcialmente, o no esta actualizada. La ultima situacion es la peor de todas. Para los usuarios, las traducciones anticuadas pueden ser peor que si no existiera la traduccion, si describen viejos comportamientos del programa que ya no se usan.

  El problema a solucionar
Traducir documentacion no es muy dificil por si solo. Los textos son bastante mas largos que los mensajes de programa, y por lo tanto, tardan mas en traducirse, pero no se necesitan conocimientos tecnicos para hacerlo. La parte dificil llega cuando se debe mantener el trabajo. Detectar que partes han cambiado y se necesitan actualizar es muy dificil, lleva a errores y es bastante desagradable. Creo que esto explica porque tantas de las traducciones de documentacion que hay por ahi estan anticuadas.

  Las respuestas de po4a
Luego, el objetivo de po4a es hacer la traduccion de documentacion mantenible. La idea es reusar la metodologia de gettext en este nuevo campo. Como en gettext, los textos se extraen de su localizacion original, para ser presentados en un formato uniforme a los traductores. Las herramientas clasicas de gettext ayudan a actualizar el trabajo cuando aparece una nueva version del original. Pero a diferencia del modelo clasico de gettext, las traducciones son reinyectadas en la estructura del documento original de forma que pueden ser procesadas y distribuidas igual que la version inglesa.

Gracias a esto, descubrir que partes del documento han cambiado y se necesita actualizar se vuelve muy facil. Otro punto fuerte es que las herramientas haran practicamente toda la faena cuando la estructura del documento original se reorganice y cuando algunos capitulos se muevan, se junten o se separen. Al extraer el texto a traducir de la estructura del documento, tambien le mantiene lejos de la complejidad del formateo de texto y reduce las oportunidades de dan~ar el documento (aunque no le prevenga completamente de hacerlo).

Por favor, lea tambien las "Preguntas Frecuentes" mas abajo en este documento para una lista mas completa de ventajas y desventajas de esta solucion.

  Formatos soportados
Actualmente se han implementado satisfactoriamente algunos tipos de formatos de texto:

nroff

El clasico formato de las paginas de manual, usadas por montones de programas. El soporte de po4a es de agradecer, ya que el formato es algo dificil de usar, y no muy amistoso para los novatos.

pod

Este es el formato de Documentacion Online de Perl. El lenguaje y sus mismas extensiones estan documentadas asi, igual que la mayoria de scripts de Perl. Hace muy facil mantener la documentacion cerca del codigo al mezclarlos en el mismo archivo. Facilita la vida del programador, pero por desgracia, no la del traductor.

sgml

Aunque hoy en dia casi haya sido sustituido por XML, este formato aun es usado habitualmente para documentos mas extensos que algunas pantallas. Este permite hacer libros completos. Actualizar una traduccion de documentos tan largos puede ser realmente un infierno. A menudo diff se vuelve inutil cuando se ha reindentado el texto original despues de la actualizacion. Afortunadamente, po4a le puede ayudar en ese proceso.

Actualmente, solo estan soportados los DTDs de debiandoc y de docbook, pero an~adir soporte para uno nuevo es realmente facil. Incluso es posible usar po4a en un dtd desconocido de sgml sin cambiar el codigo, pasando la informacion necesaria en la linea de comandos. Consulte Locale::Po4a::Sgml(3pm) para mas detalles.

otros

Po4a tambien puede tratar algunos formatos raros o especificos, tal como la documentacion de las opciones de compilacion del kernel 2.4.x o los diagramas producidos por la herramienta dia. An~adir uno nuevo acostumbra a ser una tarea muy facil y la tarea principal es conseguir un analizador para su formato. Consulte Locale::Po4a::TransTractor(3pm) para mas informacion.

  Formatos no soportados
Por desgracia, po4a aun carece de soporte para algunos de los formatos de documentacion mas importantes. El mas destacable puede ser XML, ya que cada vez se usa mas y mas en la documentacion de proyectos de codigo abierto. El modulo sgml contiene un soporte limitado para ello (principalmente cuando su documento no usa sintaxis especifica de XML ;). Estamos trabajando en un mejor soporte, y las cosas pueden cambiar en un futuro proximo. Mientras tanto, si po4a no cubre sus necesidades, puede probar el proyecto poxml. Es similar a po4a y trata decentemente la documentacion en docbook xml. Por desgracia, no puede tratar con ningun otro formato por ahora. Y por supuesto, no mola tanto como po4a ;)

TeXinfo es otro de los formatos que hoy en dia se echan en falta en po4a. Toda la documentacion de GNU esta escrita en este formato (incluso es un requisito para llegar a ser un proyecto oficial de GNU). La falta de soporte en po4a deja solos a los traductores de GNU ante las adversidades del mundo. Nos gustaria conseguir una solucion, pero este formato es tan potente/complejo que no vamos tan de prisa como nos gustaria. Si quiere ayudar, su ayuda sera naturalmente bienvenida ;)

A parte de estos dos grandes formatos, hay un monton de otros formatos que nos gustaria soportar en po4a, y no solo de documentacion. De hecho, queremos cubrir todos los "agujeros" dejados por las herramientas clasicas de gettext. Eso incluye la documentacion de python, descripciones de paquetes (deb y rpm), preguntas de los scripts de instalacion de paquetes, registros de cambios de los paquetes, y todos los formatos especificos usados por programas como escenarios de juegos o los ficheros de recursos de wine.

XComo usar po4a?
Este capitulo es como un manual de referencia, donde se intenta contestar las preguntas de los usuarios, y se le ofrece una idea general del proceso. Le introduce al metodo de trabajo con po4a y sirve como documentacion introductoria de las herramientas especificas.

  Vision esquematica
El siguiente esquema le da una vision global del proceso de traduccion de documentacion usando po4a. No se asuste por su aparente complejidad, eso es debido a que aqui se representa el proceso completo. Una vez haya convertido su proyecto a po4a, solo es relevante la parte derecha del grafico. En este ejemplo se habla de sgml, pero es aplicable a todos los modulos. Cada parte del dibujo se detallara en las proximas secciones.

  fr.sgml  original.sgml ---->--------+------>----------->-------+
     |         |                      |                          |
     V         V        { actualizacion del original }           |
     |         |                      |                          |
     +--<---<--+                      V                          |
     |         |              original.new.sgml----->------->----+
     V         V                      |                          |
  [po4a-gettextize]      +--->---->---+                          |
     |         |         |            V                          |
     |         |         |     [po4a-updatepo]                   |
     |         V         ^            |                          V
     V    original.pot   |            V                          |
     |         |         |          fr.po                        |
     |         |         |         (difuso)                      |
     |   { traduccion }  |            |                          |
     |         |         ^            V                          V
     |         |         |     {edicion manual}                  |
     V         V         |            |                          |
     |         |         |            V                          V
     |         |         +--<----   fr.po       apendice   original.sgml
     +---->----+---->------->--->  (al dia)    (opcional)    (al dia)
                                      |            |             |
                                      v            v             v
                                      +------>-----+------<------+
                                                   |
                                                   v
                                           [po4a-translate]
                                                   |
                                                   V
                                                fr.sgml
                                               (al dia)

En la parte izquierda se muestra la conversion de una traduccion que no usa po4a a este sistema. Arriba de la parte derecha se representa la accion del autor original (actualizar la documentacion). En medio de la parte derecha se simbolizan las acciones automaticas de po4a. Se extrae el nuevo material, y se compara con la traduccion existente. Se encuentran las partes que no han cambiado, y se usa la traduccion previa. Las partes parcialmente modificadas tambien se conectan con la traduccion anterior, pero se an~ade un marcador indicando que la traduccion se debe actualizar. La parte de abajo de la figura muestra como se construye el documento formateado.

Actualmente, como traductor, la unica operacion manual que debe hacer es la parte marcada como {edicion manual}. Si, lo siento, pero po4a le ayuda a traducir. No traduce nada solo...

  XComo empezar una nueva traduccion?
Esta seccion presenta los pasos necesarios para iniciar una nueva traduccion con po4a. Los refinamientos involucrados en la conversion de un proyecto existente al este sistema se detallan en la seccion pertinente.

Para iniciar una nueva traduccion utilizando po4a, debe seguir los siguientes pasos:

-   Extraer el texto que se tiene que traducir del documento original a un nuevo archivo pot (el formato de gettext). Para hacerlo puede usar el programa po4a-gettextize asi:

      $ po4a-gettextize -f <formato> -m <principal.doc> -p <traduccion.pot>

    <formato> es naturalmente el formato usado en el documento <principal.doc>. Tal como era de esperar, la salida va a <traduccion.pot>. Consulte po4a-gettextize(1) para mas detalles sobre las opciones existentes.

-   Ahora toca traducir lo que se deba. Para eso, cambie el nombre del fichero pot a doc.XX.po, por ejemplo (donde XX es el codigo ISO639 del idioma al que este traduciendo, por ejemplo "fr" para el frances), y edite el fichero resultante. A menudo es buena idea no llamar al fichero XX.po para evitar confusiones con la traduccion de los mensajes de programa, pero eso es cosa suya. No se olvide de actualizar las cabeceras de los ficheros po, son importantes.

    La traduccion en si misma se puede hacer con el modo po de Emacs o kbabel (basado en KDE) o gtranslator (basado en GNOME), o cualquier programa que prefiera. Incluso el clasico vi puede bastar, aunque no tenga un modo especializado para esta tarea.

    Si quiere aprender mas, definitivamente debe consultar la documentacion de gettext, disponible en el paquete gettext-doc.

  XComo transformar la traduccion de vuelta a un archivo de documentacion?
Una vez haya terminado la traduccion, querra obtener la documentacion traducida para distribuirla a los usuarios junto con el original. Para eso, utilice el programa po4a-translate(1) asi (donde XX es el codigo del idioma):

  $ po4a-translate -f <formato> -m <principal.doc> -p <doc-XX.po> -l <XX.doc>

Igual que antes, <formato> es el formato usado en el documento <principal.doc>. Pero esta vez el fichero po pasado con el parametro -p es parte de la entrada. Esta es su traduccion. La salida va a <XX.doc>

Consulte po4a-translate(1) para mas detalles.

  XComo actualizar una traduccion con po4a?
Para actualizar su traduccion cuando el fichero original cambie, use el programa po4a-updatepo(1) asi:

  $ po4a-updatepo -f <formato> -m <nuevo_original.doc> -p <existente.XX.po>

(Consulte po4a-updatepo(1) para mas detalles)

Naturalmente, los nuevos parrafos del documento no se traduciran magicamente en el fichero "po" con esta operacion, y necesitara actualizar el fichero "po" manualmente. Asimismo, puede tener que rehacer las traducciones de los parrafos que se hayan modificado un poco. Para asegurar que no se olvidara ninguna, se marcan como "difusas" durante el proceso, y debera quitar la marca manualmente antes que se pueda usar la traduccion en po4a-translate. Igual que para la traduccion inicial, aqui lo mejor es usar su editor po favorito.

Una vez su fichero "po" este otra vez actualizado, sin ninguna cadena por traducir ni cadenas difusas, puede generar el fichero de documentacion traducido, tal como se ha explicado en la seccion anterior.

  XComo convertir una traduccion ya existente a po4a?
Seguramente usted acostumbraba a traducir manualmente el documento felizmente hasta que llego una reorganizacion del documento original. Entonces, despues de algunos intentos fracasados con diff o herramientas similares, quiere pasarse a po4a. Pero por supuesto, no quiere perder su proceso de traduccion. No se preocupe, las herramientas po4a tambien tienen en cuenta este caso, se llama gettextizacion.

La condicion mas importante es que tanto el documento traducido como el original tengan la misma estructura de forma que las herramientas puedan encajar los contenidos correctamente.

Si esta de suerte (es decir, si las estructuras de ambos documentos encajan a la perfeccion), todo funcionara a la perfeccion y habra terminado en unos segundos. En caso contrario, debera entender porque este proceso tiene un nombre tan feo, y deberia estar preparado para un poco de faena sucia. De cualquier forma, recuerde que este es el precio a pagar para conseguir luego la comodidad de po4a. Y la mejor parte es que solo debera hacer esto una vez.

No puedo emfatizarlo mas. Para facilitar el proceso, es importante encontrar la version exacta que se uso en la traduccion. La mejor situacion se da cuando se anoto que revision del cvs se uso para la traduccion y no se modifico durante el proceso de traduccion, de forma que pueda usarla.

No funcionara bien si usa el texto original actualizado con una traduccion vieja. Es un proceso posible, pero mas dificil, y realmente se debe evitar en la medida que sea posible. De hecho, imagino que si no consigue encontrar el texto original, la mejor solucion es encontrar a alguien que haga la gettextizacion por usted (pero por favor, que no sea yo ;).

Quiza sea demasiado catastrofico. Aunque las cosas vayan mal, sigue siendo mucho mas rapido que traducirlo todo otra vez. Yo hice la gettextizacion de la traduccion al frances existente de la documentacion de Perl en un dia, a pesar de que las cosas fueron mal. Eran mas de dos megabytes de texto, y una traduccion nueva hubiera podido durar como minimo meses.

Permitame explicar primero las bases del proceso, y luego ya volveremos a los trucos para conseguirlo cuando el proceso vaya mal. Para facilitar la comprension, se toma otra vez como ejemplo el modulo sgml, pero no importa el formato usado:

Una vez haya conseguido el original viejo, la gettextizacion puede ser tan facil como:

 $ po4a-gettextize -f <formato> -m <antiguo.original> -l <antigua.traduccion> -p <doc-XX.po>

Si esta de suerte, eso es todo. Ha convertido su vieja traduccion a po4a y ya puede empezar con la tarea de actualizacion. Simplemente siga el proceso explicado unas secciones antes para sincronizar su fichero po con el documento original mas nuevo, y actualice la traduccion segun convenga.

Tenga en cuenta que aunque parezca que todo ha ido bien, aun queda lugar para los errores en este proceso. El caso es que po4a no es capaz de entender el texto para asegurarse de que la traduccion se refiere al original dado. Es por eso que las cadenas se marcan como "difusas" durante el proceso. Debe comprobar cuidadosamente cada cadena antes de eliminar la marca.

A menudo las estructuras de los documentos no encajan a la perfeccion, impidiendo a po4a-gettextize realizar su tarea. Llegados a este punto, todo el juego se traslada a la edicion de los ficheros para hacer encajar sus malditas estructuras.

Le puede ayudar leer la seccion "Gettextizacion: XComo funciona?" de mas abajo. La comprension del funcionamiento interno del proceso le ayudara a hacerlo funcionar. El punto bueno es que po4a-gettextize da mucha informacion cuando algo no va bien. Primero, apunta donde se encontro la discrepancia de estructuras en los documentos. Luego le mostrara las cadenas que no encajan, su posicion en el texto, y el tipo de cada una. Ademas, el fichero po generado hasta el momento se guardara en /tmp/gettextization.failed.po.

-   Elimine todas las partes extra de las traducciones, como secciones donde se especifique el nombre del traductor, o los agradecimientos de gente que colaboro con la traduccion. Los apendices, descritos en la siguiente seccion, le permitiran volver a an~adir estos contenidos.

-   No dude de editar tanto el original como la traduccion. Lo mas importante es conseguir el fichero po. Ya tendra tiempo de actualizarlo luego. Una vez dicho esto, es preferible editar la traduccion cuando se puedan editar ambos, ya que esto facilita las cosas una vez se termine la gettextizacion.

-   Si es necesario, elimine algunas partes del original si no estaban traducidas. Cuando mas adelante sincronice el po con el documento, volveran por si solas.

-   Si cambio un poco la estructura (para juntar dos parrafos, o partir alguno), deshaga esos cambios. Si se trata de un asunto con el original, debe informar al autor original del texto. Arreglarlo solo en la traduccion solo ofrece la solucion a una parte de la comunidad. Y ademas, es imposible cuando se usa po4a ;)

-   A veces el contenido del parrafo encaja, pero su tipo no. Arreglar eso depende mucho del formato. En pod y nroff, a menudo es culpa de que una de las dos lineas empieza con un espacio y la otra no. En estos formatos, este parrafo no podria justificarse y se volveria de un tipo diferente. Simplemente elimine el espacio y ya esta. Tambien puede tratarse de un error tipografico en el nombre del tag.

    Ademas, dos parrafos pueden juntarse en el pod cuando la linea de separacion contiene algunos espacios, o cuando no hay una linea de separacion antes de la linea =item y del contenido del elemento.

-   A veces, hay una desincronizacion entre archivos, y la traduccion se encaja con un parrafo original equivocado. Este es un signo de que ya habia un problema antes de juntar los ficheros. Compruebe /tmp/gettextization.failed.po para ver cuando empieza la desincronizacion, y arreglelo alli.

-   A veces le puede dar la impresion que po4a se comio algunas partes del texto, ya sea del original o de la traduccion. /tmp/gettextization.failed.po indica que ambos encajaban correctamente, y luego fallo porque intento encajar un parrafo con el anterior o el posterior al correcto, como si el correcto hubiera desaparecido. Maldiga po4a como yo hice la primera vez que me paso. Abundantemente.

    Esta situacion se debe a que el mismo parrafo se repite a lo largo del documento. En ese caso, no se crea una nueva entrada en el fichero po, sino que se le an~ade una nueva referencia a la ya existente.

    Por lo tanto, cuando el mismo parrafo aparece dos veces en el original pero no esta traducido exactamente igual cada vez, tendra esa sensacion de que desaparecio un parrafo del original. Simplemente elimine la nueva traduccion. Si cree que la segunda traduccion es mejor, quitela de donde esta, y sustituya a la primera.

    En el caso contrario, si hay dos parrafos parecidos pero diferentes que se tradujeron de la misma forma, le puede dar la impresion de que desaparecio un parrafo de la traduccion. La solucion es an~adir una cadena estupida al parrafo original (algo como "soy diferente") para solucionarlo. No se asuste. Estas cosas desapareceran durante la sincronizacion, y cuando el texto an~adido sea suficientemente corto, gettext encajara su traduccion con el texto existente (marcandolo como difuso, pero no importa, ya que todas las cadenas se marcan como difusas durante la gettextizacion).

Con un poco de suerte estos trucos le ayudaran a realizar su gettextizacion y a obtener su preciado fichero po. Ahora esta preparado para sincronizar su fichero y empezar la traduccion. Tenga en cuenta que en textos grandes la primera sincronizacion puede tardar mucho tiempo.

Por ejemplo, el primer po4a-updatepo de la traduccion al frances de la documentacion de Perl (un fichero po de 5.5 Mb) tomo alrededor de dos dias enteros en una maquina G5 a 1Ghz. Si, 48 horas. Pero las siguientes veces tan solo tardaba una docena de segundos en mi viejo portatil. Eso es porque la primera vez, la mayoria de msgids del fichero po no encajan con ninguno de los del fichero pot. Eso obliga a gettext a buscar la cadena mas parecida usando un costoso algoritmo de proximidad de cadenas.

  XComo an~adir texto extra en las traducciones (como el nombre del traductor)?
Debido al uso de gettext, esto se vuelve mas dificil en po4a que antes, que simplemente se editaba el nuevo fichero paralelamente al original. Pero sigue siendo posible, gracias a los llamados apendices.

Para ayudar a la comprension, considere los apendices como unos parches aplicados al documento traducido despues del proceso. Son bastante diferentes que los parches habituales (solo tienen una linea de contexto, que puede incluir una expresion regular de perl, y unicamente puede an~adir texto, sin eliminar nada), pero las funcionalidades son las mismas.

Su objetivo es permitir al traductor an~adir contenido extra al documento, que no es traduccion del documento original. El uso mas habitual es an~adir una seccion sobre la traduccion en si misma, listando los colaboradores y explicando como informar de los errores de la traduccion.

Los apendices se deben proporcionar como ficheros a parte. La primera linea forma una cabecera que indica el lugar del documento resultante donde se debe colocar. El resto del fichero de apendice se an~adira tal cual en la posicion determinada del documento resultante.

La cabecera tiene una sintaxis muy rigida: debe empezar con la cadena "PO4A-HEADER:", seguida por una lista de campos "llave=valor" separados por punto y coma (;). Los espacios en blanco SON importantes. Tenga en cuenta que no puede usar el caracter punto y coma (;) en los valores, y que las comillas no ayudan.

Una vez mas, suena espantoso, pero los ejemplos de mas abajo deberian ayudarle a encontrar la forma de escribir la linea de cabecera que necesita. Para ilustrar la discusion, asuma que quiere an~adir una seccion llamada "Sobre esta traduccion" despues de la llamada "Sobre este documento".

Aqui hay las posibles llaves de la cabecera:

position (obligatoria)
    una expresion regular. Se colocara el apendice cerca de la linea que encaje con esta expresion regular. Tenga en cuenta que estamos hablando del documento traducido, no del original. Si hay mas de una linea que encaje (o ninguna), la adicion fallara. Siempre es mejor dar un error que insertar el apendice en el sitio equivocado.

    A continuacion, esta linea se llamara punto de posicion. El punto donde se insertara el apendice se llamara punto de insercion. Estos dos puntos son muy cercanos, pero no iguales. Por ejemplo, si desea insertar una nueva seccion, es mas facil poner el punto de posicion en el titulo de la seccion anterior, y explicarle a po4a donde termina la seccion (recuerde que el punto de posicion viene dado por la expresion regular, que debe encajar una unica linea).

    La localizacion del punto de insercion respecto al punto de posicion esta controlado por los campos "mode", "beginboundary" y "endboundary" que se explican a continuacion.

    En nuestro caso tendriamos:

         position=<title>Sobre este documento</title>

mode (obligatoria)
    Puede valer "before" (antes) o "after" (despues), especificando la posicion del apendice, relativa al punto de posicion.

    Como queremos que la nueva seccion se situe debajo de la que hemos encajado, tenemos:

         mode=after

beginboundary (usada solo cuando mode=after, y obligatoria en este caso)
endboundary (idem)
    Expresion regular que encaje el final de la seccion despues del que va el apendice.

    Cuando mode=after, el punto de insercion esta despues del punto de posicion, pero no justamente despues! Esta situado al final de la seccion que empieza en el punto de posicion, es decir, antes o despues de la linea encajada por el parametro "???boundary", dependiendo de si uso "beginboundary" o "endboundary".

    En nuestro caso, podemos decidirnos por indicar el final de la seccion que encajamos an~adiendo:

       endboundary=</section>

    o indicar el principio de la siguiente seccion indicando:

       beginboundary=<section>

    En ambos casos, se colocara nuestro apendice despues de </section> y antes de <section>. La primera opcion es mejor porque funcionara aunque se reorganice el documento.

    Las dos formas existen debido a que los formatos de documentacion son diferentes. En algunos de ellos, hay una forma de marcar el final de una seccion (tal como el "</section>" que hemos usado), mientras que otros no marcan explicitamente el final de una seccion (como en nroff). En el primer caso, es preferible encajar un boundary con el final de seccion, para que el punto de insercion venga despues. En el segundo caso, debera encajar un boundary con el principio de la siguiente seccion para que el punto de insercion venga justo antes suyo.

Puede parecer oscuro, pero espero que los proximos ejemplos le iluminen.

Para concluir el ejemplo usado hasta el momento, para insertar una seccion llamada "Sobre esta traduccion" despues de la seccion "Sobre este documento" en un documento sgml, debe usar una de estas lineas de cabecera:
     PO4A-HEADER: mode=after; position=Sobre este documento; endboundary=</section>
     PO4A-HEADER: mode=after; position=Sobre este documento; beginboundary=<section>

Si quiere an~adir algo despues de la siguiente seccion de nroff:
      .SH "AUTORES"

    Debe poner un "position" que encaje esta linea, y un "beginboundary" que encaje el principio de la siguiente seccion (es decir "^\.SH"). Entonces el apendice se an~adira despues del punto de posicion e immediatamente antes de la primera linea que encaje el "beginboundary". Asi es:

     PO4A-HEADER:mode=after;position=AUTORES;beginboundary=\.SH

Si desea an~adir algo dentro de una seccion (como despues de "Copyright Big Dude") en vez de an~adir una seccion completa, ponga un "position" que encaje con esta linea, y ponga un "beginboundary" que encaje cualquier linea.
     PO4A-HEADER:mode=after;position=Copyright Big Dude, 2004;beginboundary=^

Si desea an~adir algo al final del documento, especifique un "position" que encaje cualquier linea del documento (pero solo una linea. Po4a no procedera si no es unica), 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=<title>Acerca de</title>;beginboundary=BoundaryFalsoDePo4a

En cualquier caso, recuerde que se trata de expresiones regulares. Por ejemplo, si desea encajar el final de una seccion de nroff que termine con la linea

  .fi

no utilice ".fi" como endboundary, porque esto encajara con "el[ fi]chero", que obviamente no es lo que esperabamos. El endboundary correcto en este caso seria: "^\.fi$".

Si el apendice no va donde esperaba, pruebe pasando el parametro -vv a las herramientas, para que le explique que hace al colocar el apendice.

Ejemplo mas detallado

Documento original (en formato pod):

 |=head1 NAME
 |
 |dummy - a dummy program
 |
 |=head1 AUTHOR
 |
 |me

Luego, el siguiente apendice asegurara que se an~ade una seccion (en espan~ol) sobre el traductor al final del fichero.

 |PO4A-HEADER:mode=after;position=AUTOR;beginboundary=^head
 |
 |=head1 TRADUCTOR
 |
 |yo

Para poner su apendice antes de AUTHOR, utilice la siguiente cabecera:

 PO4A-HEADER:mode=after;position=NOMBRE;beginboundary=^head1

Esto funciona porque la siguiente linea que encaja el beginboundary /^head1/ despues de la seccion "NAME" (traducido a "NOMBRE" en espan~ol), es la que declara los autores. Por lo tanto, se colocara el apendice entre ambas secciones.

  XComo hacer todo esto en una sola invocacion a programa?
El uso de po4a ha demostrado que puede dar lugar a errores ya que se debe llamar a dos programas diferentes en el orden adecuado (po4a-updatepo y luego po4a-translate), y cada uno necesita mas de 3 parametros. Ademas, era dificil con este sistema usar solo un fichero po para todos los documentos cuando se usaba mas de un formato.

El programa po4a(1) se disen~o para solucionar esas dificultades. Una vez su proyecto se haya convertido al sistema, usted escribe un simple fichero de configuracion explicando donde estan los ficheros de traduccion (po y pot), donde estan los documentos originales, sus formatos, y donde se deben guardar las traducciones.

Luego, una simple llamada a po4a(1) con este fichero asegura que los ficheros po se sincronicen con el documento original, y que se generan correctamente los documentos traducidos. Por supuesto, le interesara llamar el programa dos veces: una antes de editar el fichero po para actualizarlo, y otra para actualizar completamente los documentos traducidos. Pero solo necesita recordar una linea de comandos.

XComo funciona?
Este capitulo ofrece una breve explicacion del funcionamiento interno de po4a, de forma que se pueda sentir mas seguro para ayudarnos a mantenerlo y mejorarlo. Tambien le puede ayudar a entender porque no hace lo que esperaba, y como solucionar sus problemas.

  Vision general
La arquitectura de po4a es orientada a objetos (en Perl. Muy pulcro, no?). El antecesor de todas las clases analizadoras se llama TransTractor. Este extran~o nombre viene del hecho de que al mismo tiempo se encarga de traducir el documento (translate) y de extraer las cadenas (extract).

Mas formalmente, toma un documento a traducir ademas del fichero po que contiene las traducciones a usar para producir dos salidas separadas: Otro fichero po (resultante de la extraccion de las cadenas traducibles del documento de entrada), y un documento traducido (con la misma estructura que el de entrada, pero con las cadenas traducibles reemplazadas por el contenido del po de entrada). Aqui hay una representacion grafica:

   Documento de entrada -\                        /---> Documento de salida
                          \    TransTractor::    /         (traducido)
                           +-->--  parse()  ----+
                          /                       \
   po de entrada --------/                         \---> po de salida
                                                           (extraido)

Esta pequen~a estructura es el nucleo de toda la arquitectura de po4a. Si omite el po de entrada y el documento de salida, obtiene po4a-gettextize. Si proporciona ambas entradas y descarta el po de salida, obtiene po4a-translate.

TransTractor::parse() es una funcion virtual implementada por cada modulo. Aqui hay un pequen~o ejemplo que muestra como funciona. Analiza una lista de parrafos, cada uno empezando con <p>

  1 sub parse {
  2   PARRAFO: while (1) {
  3     $my ($parrafo,$parraref,$linea,$lref)=("","","","");
  4     $my $primera=1;
  5     while (($linea,$lref)=$document->shiftline() && defined($linea)) {
  6       if ($line =~ m/<p>/ && !$primera--; ) {
  7         $document->unshiftline($linea,$lref);
  8
  9         $parrafo =~ s/^<p>//s;
 10         $document->pushline("<p>".$document->translate($parrafo,$parraref));
 11
 12         next PARRAFO;
 13       } else {
 14         $parrafo .= $linea;
 15         $parraref = $lref unless(length($parraref));
 16       }
 17     }
 18     return; # No tenemos la linea definida? Final del archivo de entrada.
 19   }
 20 }

En la linea 6, encontramos <p> por segunda vez. Esta es la sen~al de que hemos encontrado el siguiente parrafo. Entonces debemos devolver la linea obtenida de vuelta al documento (linea 7) y enviar el parrafo que hemos construido hacia la salida. Despues de eliminar el <p> inicial, en la linea 9, insertamos la concatenacion del tag con la traduccion del resto del parrafo.

Esta funcion translate() esta muy bien. Envia su parametro hacia el fichero po de salida (extraccion) y devuelve su traduccion como se encuentre en el fichero po de entrada (traduccion). Como es usada como parte del parametro de pushline(), esta traduccion pasa hacia el documento de salida.

Como mola, no? Es posible construir un modulo completo de po4a en menos de 20 lineas si el formato es suficientemente simple...

Encontrara mas sobre esto en Locale::Po4a::TransTractor(3pm).

  Gettextizacion: XComo funciona?
La idea aqui es tomar el documento original y su traduccion, y considerar que la enesima cadena extraida de la traduccion es la traduccion de la enesima cadena extraida del original. Para que funcione, ambos ficheros deben compartir exactamente la misma estructura. Por ejemplo, si los ficheros tienen la siguiente estructura, es muy poco probable que la cuarta cadena de la traduccion (de tipo 'capitulo') sea la traduccion de la cuarta cadena del original (de tipo 'parrafo').

    Original         Traduccion

  capitulo           capitulo
    parrafo            parrafo
    parrafo            parrafo
    parrafo          capitulo
  capitulo             parrafo
    parrafo            parrafo

Para eso, los analizadores de po4a se utilizan tanto para el fichero original como para el traducido para extraer los ficheros po, y luego se construye un tercer fichero po a partir de ellos tomando las cadenas del segundo como traducciones de las del primero. Para comprobar que las cadenas que juntamos se correspondan, los analizadores de documentos de po4a deben dar informacion sobre el tipo sintactico de las cadenas extraidas en el documento (todos los que hay lo hacen, el suyo tambien lo tiene que hacer). Luego se utiliza esa informacion para asegurar que ambos documentos tienen la misma sintaxis. En el ejemplo anterior, nos permitiria detectar que la cuarta cadena es un parrafo en un caso, y un titulo de capitulo en el otro, y tratarlo como un error.

En teoria, la deteccion de este problema seria posible, y se resincronizan los ficheros luego (igual que hace diff). Pero no esta claro que deberiamos hacer con las cadenas antes de las desincronizaciones, y podria producir malos resultados a veces. Es por eso que la implementacion actual no intenta resincronizar nada, e informa extensamente del fallo cuando algo va mal, requiriendo la modificacion manual de los ficheros para arreglar el problema.

Incluso con estas precauciones, las cosas se pueden estropear muy facilmente. Es por eso que todas las traducciones encontradas asi se marcan como difusas, para asegurar que el traductor las repase y las corrija.

  Apendices: XComo funcionan?
Bien, esto es muy simple. El documento traducido no se escribe directamente al disco, sino que se mantiene en memoria hasta que se aplican todos los apendices. Los algoritmos involucrados son sencillos. Buscamos una linea que encaje con la expresion regular de posicion, e insertamos el apendice antes si estaba en mode=before. Sino, buscamos la siguiente linea que encaje en el rango e insertamos el apendice despues de esta linea si es un "endboundary" o antes de esta linea si es un "beginboundary".

Preguntas Frecuentes
Este capitulo agrupa las Preguntas Frecuentes. De hecho, la mayoria de preguntas actuales se pueden formular asi: "XPorque se ha disen~ado asi, y no asi?" Si piensa que po4a no es la solucion ideal para la traduccion de documentacion, deberia considerar leer esta seccion. Si no responde su pregunta, contacte con nosotros en la lista de correo <po4a-devel@lists.alioth.debian.org>. Queremos escuchar su opinion.

  XPorque traducir cada parrafo por separado?
Si, en po4a, cada parrafo se traduce por separado (de hecho, cada modulo lo decide, pero todos los existentes lo hacen, y los suyos deben hacerlo tambien). Hay dos ventajas principales al hacerlo asi:

•   Cuando las partes tecnicas del documento se esconden, el traductor no se puede confundir con ellas. Como menos marcas presentemos al traductor, menos errores podra hacer.

•   El hecho de cortar el documento ayuda a aislar los cambios en el documento original. Cuando se modifica el original, es facil encontrar que partes de la traduccion se necesita actualizar con este proceso.

Incluso con estas ventajas, a alguna gente no le gusta la idea de traducir cada parrafo por separado. Aqui hay algunas respuestas que les puedo dar:

•   Esta idea ha mostrado resultados satisfactorios en el proyecto KDE y permite a la gente producir la cantidad mas grande de documentacion traducida y actualizada que conozco.

•   Los traductores aun pueden usar el contexto para traducir, ya que las cadenas del fichero po estan en el mismo orden que las del documento original. Traducir secuencialmente es comparable a usar po4a o no. Y en cualquier caso, la mejor forma de obtener el contexto sigue siendo el convertir el documento a un formato imprimible, ya que los textos formateados no son leibles, en mi opinion.

•   Los traductores profesionales utilizan esta aproximacion. Estoy de acuerdo en que ellos tienen diferentes objetivos que los traductores de codigo abierto. Por ejemplo, el mantenimiento les es a menudo menos critico, ya que el contenido cambia muy poco.

  XPorque no realizar las divisiones a nivel de frases (o menores)?
A veces las herramientas de traduccion profesionales parten los documentos a nivel de frases para maximizar la reusabilidad de las traducciones previas, y acelerar el proceso. El problema es que la misma frase puede tener varias traducciones, dependiendo del contexto.

Los parrafos son por definicion mas largos que las frases. Con un poco de suerte se podra asegurar que si se tiene el mismo parrafo en dos documentos, tendran el mismo significado (y traduccion), sin importar el contexto de cada caso.

Partirlo en partes mas pequen~as que frases seria muy malo. Podria tomar mucho tiempo explicar el motivo aqui, pero si le interesa puede consultar la pagina de manual de Locale::Maketext::TPJ13(3pm) (que viene con la documentacion de Perl), por ejemplo. Brevemente, cada idioma tiene sus reglas de sintaxis especificas, y no hay forma de construir frases encajando partes de frases para todos los idiomas existentes (incluso para 5 de los 10 idiomas mas hablados, o incluso menos).

  XPorque no se pone el original como comentario junto con la traduccion (o de otra forma)?
A simple vista, gettext no parece estar adaptado a todos los tipos de traducciones. Por ejemplo, no parecia adaptado a debconf, la interfaz que usan todos los paquetes de Debian para sus interacciones con el usuario durante la instalacion. En ese caso, los textos a traducir eran muy cortos (una docena de lineas para cada paquete), y era muy dificil poner las traducciones en un fichero especifico ya que tiene que estar disponible antes de la instalacion del paquete.

Es por eso que los desarrolladores de debconf decidieron implementar otra solucion, donde las traducciones estuvieran situadas en el mismo fichero que el original. Es bastante atractivo. Se podria querer hacerlo en xml, por ejemplo. Tendria esta pinta:

 <section>
  <title lang="en">My title</title>
  <title lang="fr">Mon titre</title>

  <para>
   <text lang="en">My text.</text>
   <text lang="fr">Mon texte.</text>
  </para>
 </section>

Pero fue tan problematico que se termino usando una implementacion basada en po. Solo se puede editar el original en el archivo, y las traducciones se deben hacer en los ficheros po extraidos del patron principal (y vueltos al paquete en tiempo de compilacion). El sistema antiguo se considero obsoleto debido a varios problemas:

•   problemas de mantenimiento

    Si varios traductores envian un parches a la vez, es dificil de juntarlos.

    XComo detectara los cambios en el original, que se deban aplicar a las traducciones? Para poder usar diff, se debe tener en cuenta que version del original se tradujo. Es decir, se necesita un fichero po en su fichero ;)

•   problemas de codificacion

    La solucion es viable cuando solo se utilizan idiomas europeos, pero la introduccion del Koreano, Ruso y/o Arabe complica realmente la cosa. La solucion seria UTF, pero aun hay algunos problemas con el.

    Ademas, estos problemas son dificiles de detectar (es decir, solo los lectores Koreanos detectaran que falla la codificacion del Koreano [por culpa del traductor ruso])

gettext soluciona todos estos problemas a la vez.

  XPero gettext no se disen~o para este uso!
Es cierto, pero hasta el momento nadie ha propuesto una solucion mejor. La unica alternativa conocida es la traduccion manual, con todos los problemas de mantenimiento.

  XQue hay de las otras herramientas de traduccion de documentacion que usan gettext?
Hasta donde yo se, solo hay dos de ellas:

poxml
    Esta es la herramienta desarrollada por la gente de KDE para tratar DocBook XML. Me parecec que este fue el primer programa a extraer cadenas de texto a traducir desde la documentacion a los ficheros po, e inyectarlas de vuelta despues de la traduccion.

    Unicamente puede tratar XML, y solo un DTD particular. Estoy bastante insatisfecho con el trato que hacen de las listas, que terminan en un unico msgid. Cuando la lista crece, el bloque se hace dificil de tratar.

po-debiandoc
    Este programa hecho por Denis Barbier es un tipo de precursor del modulo sgml de po4a, que mas o menos lo deja obsoleto. Como su nombre indica, unicamente trata el dtd de debiandoc, que ademas es un dtd anticuado.

Las principales ventajas de po4a sobre ellos son la facilidad de adicion de contenidos extra (que es aun peor alli) y la habilidad de realizar la gettextizacion.

  Educando a los desarrolladores sobre las traducciones
When you try to translate documentation or programs, you face three kinds of problems; linguistics (not everybody speaks two languages), technical (that's why po4a exists) and relational/human. Not all developers understand the necessity of translating stuff. Even when good willed, they may ignore how to ease the work of translators. To help with that, po4a comes with lot of documentation which can be referred to.

Otro punto importante es que cada fichero traducido empieza con un breve comentario indicando que es el fichero, y como usarlo. Esto deberia ayudar a los pobres desarrolladores avalanchados con montones de ficheros en diferentes idiomas que no entienden, y ayudarles a tratarlos correctamente.

In the po4a project, translated documents are not source files anymore. Since sgml files are habitually source files, it's an easy mistake. That's why all files present this header:

 |       *****************************************************
 |       *           GENERATED FILE, DO NOT EDIT             *
 |       * THIS IS NO SOURCE FILE, BUT RESULT OF COMPILATION *
 |       *****************************************************
 |
 | This file was generated by po4a-translate(1). Do not store it (in cvs,
 | for example), but store the po file used as source file by po4a-translate.
 |
 | In fact, consider this as a binary, and the po file as a regular source file:
 | If the po gets lost, keeping this translation up-to-date will be harder ;)

Likewise, gettext's regular po files only need to be copied to the po/ directory. But this is not the case of the ones manipulated by po4a. The major risk here is that a developer erases the existing translation of his program with the translation of his documentation. (Both of them can't be stored in the same po file, because the program needs to install its translation as an mo file while the documentation only uses its translation at compile time). That's why the po files produced by the po-debiandoc module contain the following header:

 #
 #  ADVISES TO DEVELOPERS:
 #    - you do not need to manually edit POT or PO files.
 #    - this file contains the translation of your debconf templates.
 #      Do not replace the translation of your program with this !!
 #        (or your translators will get very upset)
 #
 #  ADVISES TO TRANSLATORS:
 #    If you are not familiar with the PO format, gettext documentation
 #     is worth reading, especially sections dedicated to this format.
 #    For example, run:
 #         info -n '(gettext)PO Files'
 #         info -n '(gettext)Header Entry'
 #
 #    Some information specific to po-debconf are available at
 #            /usr/share/doc/po-debconf/README-trans
 #         or http://www.debian.org/intl/l10n/po-debconf/README-trans
 #

  RESUMEN de las ventajas de la aproximacion basada en gettext

•   The translations are not stored along with the original, which makes it possible to detect if translations become out of date.

•   The translations are stored in separate files from each other, which prevents translators of different languages from interfering, both when submitting their patch and at the file encoding level.

•   Esta basado internamente en "gettext" (pero "po4a" ofrece una interfaz muy simple de forma que no se necesita entender el funcionamiento interno para usarlo). De esa forma no tenemos que reinventar la rueda, y debido a su extenso uso, podemos imaginar que esas erramientas estan mas o menos libres de fallos.

•   No ha cambiado nada para el usuario final (a parte de que probablemente las traducciones estaran mejor mantenidas :). El fichero de documentacion 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, kbabel o gtranslator) serviran a la perfeccion.

•   Gettext offers a simple way to get statistics about what is done, what should be reviewed and updated, and what is still to do. Some example can be found at those addresses:

     - http://i18n.kde.org/tools/kbabel/img/previewKonq.png
     - http://www.debian.org/intl/l10n

Pero no todo es bonito, y esta aproximacion tambien tiene algunas desventajas con las que debemos cargar.

•   Los apendices son... extran~os a primera vista.

•   No puede adaptar el texto traducido a su gusto, como partir parrafos por aqui, y juntar esos dos alli. Pero segun como, si esta en desacuerdo con el original, deberia informarlo como un bug, de todas formas.

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

    Uno de mis suen~os es integrar de alguna forma po4a con gtranslator o kbabel. Cuando se abra un archivo sgml, se extraen las cadenas automaticamente. Al guardar se guarda un fichero sgml traducido en el disco. Si consiguieramos hacer un modulo para MS Word (TM) (o al menos para RTF) incluso podrian usarlo traductores profesionales.

Fallos conocidos y caracteristicas solicitadas
El asunto mas importante (a parte de los modulos faltantes) es el trato de las codificaciones. La forma de hacerlo es an~adiendo el pragma UTF8 de perl y recodificando las cadenas en la salida, pero aun no esta hecho.

We would also like to factorise some code (about file insertion) of the sgml module back into the TransTractor so that all modules can benefit from this, but this is not user visible.

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

TRADUCCION
 Jordi Vilalta <jvprat@gmail.com>