NOMBRE¶
po4a - Un marco de trabajo para traducir documentación y otro material
Introducción¶
El objetivo del proyecto po4a («PO for anything», PO para todo) es
facilitar la traducción (y más interesante, el mantenimiento de las
traducciones) usando las herramientas de gettext en áreas donde no eran
de esperar, como la documentación.
Tabla de contenidos¶
Este documento está organizado de la siguiente forma:
- 1 ¿Porqué debería usar po4a? ¿Para
qué sirve?
- Este capítulo introductorio explica la motivación
del proyecto y su filosofía. Debería leerlo primero si está
en el proceso de evaluación de po4a para sus propias
traducciones.
- 2 ¿Cómo usar po4a?
- Este capítulo es como un manual de referencia,
dónde se intenta contestar a las preguntas de los usuarios y se
ofrece una idea general del proceso. Le introducirá al método de
trabajo con po4a y sirve como documentación introductoria a las
herramientas específicas.
- ¿Cómo empezar una nueva traducción?
- ¿Cómo transformar la traducción de vuelta a
un fichero de documentación?
- ¿Cómo actualizar una traducción con
po4a?
- ¿Cómo convertir una traducción ya existente
a po4a?
- ¿Cómo añadir texto adicional a las
traducciones (como el nombre del traductor)?
- ¿Cómo hacer todo esto con una sola
invocación al programa?
- ¿Cómo configurar po4a?
- 3 ¿Cómo funciona?
- Este capítulo ofrece una breve explicación del
funcionamiento interno de po4a, de forma que se pueda sentir más
seguro para ayudarnos a desarrollar y mejorar el programa. También le
puede ayudar a entender porqué no hace lo que esperaba, y cómo
solucionar sus problemas.
- 4 Preguntas frecuentes
- Este capítulo agrupa las preguntas frecuentes. De
hecho, la mayoría de preguntas actuales se pueden formular así:
«¿Porqué se ha diseñado de esta manera, y no
otra?» Si piensa que po4a no es la solución ideal para la
traducción de documentación, debería considerar leer
ésta sección. Si no responde a su pregunta, contacte con
nosotros en la lista de correo <po4a-devel@lists.alioth.debian.org>.
Queremos escuchar su opinión.
- 5 Notas específicas acerca de los módulos
- Este capítulo presenta los puntos específicos de
cada módulo desde el punto de vista tanto del traductor como del
autor original. Lea esto para aprender la sintaxis que se encontrará
cuando traduzca textos con un módulo, o las reglas que debe seguir en
el documento original para facilitar la vida del traductor.
Actualmente esta sección no forma parte de este documento. En realidad
está en la documentación de cada módulo. Esto permite
asegurar que la información está actualizada al mantener la
documentación y el código juntos.
¿Porqué debo usar po4a? ¿Para qué sirve?¶
Me gusta la idea del software de código abierto, lo que hace posible que
todo el mundo pueda acceder al software y a su código fuente. Pero al ser
francés soy bien consciente de que la licencia no es la única
restricción a la libertad del software: los programas libres no
traducidos son inservibles para gente de habla no inglesa, y todavía nos
queda bastante tarea para hacerlos disponibles para todos.
La percepción de ésta situación por los responsables del software
libre ha mejorado drásticamente en los últimos tiempos. Nosotros,
como traductores, hemos ganado la primera batalla y hemos convencido a todo el
mundo de la importancia de las traducciones. Pero por desgracia, ésta era
la parte fácil. Ahora tenemos que ponernos a trabajar y empezar a
traducir.
Actualmente, 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.
Pero la situación es bastante diferente para la documentación.
Demasiado a menudo, la documentación traducida no es suficientemente
visible (no se distribuye como parte del programa), sólo lo está
parcialmente, o no está actualizada. La última situación es la
peor de todas. Para los usuarios, las traducciones anticuadas pueden ser peor
que si no existiera la traducción si describen viejos comportamientos del
programa que ya no se usan.
El problema a solucionar¶
Traducir documentación no es muy difícil en si misma. Los textos son
bastante más largos que los mensajes de programa, y por lo tanto tardan
más en traducirse, pero no se necesitan conocimientos técnicos para
hacerlo. La parte difícil llega cuando se debe mantener el trabajo al
día. Detectar qué partes han cambiado y se necesitan actualizar es
muy difícil, conduce a errores y es bastante desagradable. Creo que
ésto explica porqué tantas de las traducciones de documentación
que hay por ahí están anticuadas.
Las respuestas de po4a¶
Por ello, el objetivo de po4a es poder
mantener la traducción de
documentación al día. La idea es reusar la metodología de
gettext en este nuevo campo. Al igual que con gettext, los textos se extraen
de su ubicación original para ser presentados en un formato uniforme a
los traductores. Las herramientas clásicas de gettext ayudan a actualizar
el trabajo cuando aparece una nueva versión del original. Pero a
diferencia del modelo clásico de gettext, las traducciones se devuelven a
la estructura del documento original de forma que se puedan procesar y
distribuir igual que la versión en inglés.
Gracias a esto, descubrir qué partes del documento han cambiado y se
necesitan actualizar se vuelve muy fácil. Otro punto fuerte es que las
herramientas harán prácticamente toda la tarea cuando la estructura
del documento original se reorganice y algunos capítulos se reubiquen,
junten o separen. Al extraer el texto a traducir de la estructura del
documento, también le mantiene lejos de la complejidad del formateo de
texto y reduce las oportunidades de dañar el documento (aunque no le
prevenga completamente de hacerlo).
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:
man
El clásico formato de las páginas de manual, usado por un gran
número de programas. 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) es también
compatible con el formato mdoc, empleado en las páginas de manual BSD
(bastante comunes en Linux).
pod
Este es el formato «Perl Online Documentation» (Documentación en
línea de Perl). El lenguaje y sus mismas extensiones están
documentados así, igual que la mayoría de scripts de Perl. 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.
sgml
Aunque hoy en día XML prácticamente lo haya sustituido, este formato
aún se usa habitualmente para documentos más extensos que algunas
pantallas, y le permite hacer libros completos. Actualizar una traducción
de documentos tan largos puede ser realmente un infierno. A menudo
diff
se vuelve inútil cuando se ha sangrado («indented») otra vez el
texto original después de una actualización. Afortunadamente, po4a
le puede ayudar en 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
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.
texinfo
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.
xml
El formato XML sirve de base para muchos formatos de documentación.
Actualmente, el formato DTD de DocBook es compatible con po4a. Para más
detalles, consulte
Locale::Po4a::Docbook(3pm).
otros
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.x o los diagramas producidos por la herramienta dia. Añadir uno nuevo
es a menudo una tarea muy sencilla, y la tarea principal es conseguir un
analizador para el formato escogido. Consulte
Locale::Po4a::TransTractor(3pm) para más información.
Desafortunadamente, po4a no es compatible con varios formatos de
documentación.
Nos gustaría añadir la compatibilidad de po4a con un grupo de otros
formatos, y no sólo de documentación. De hecho, queremos cubrir
todos los «vacíos del mercado» dejados por las herramientas
clásicas de gettext. Esto incluye descripciones de paquetes (deb y rpm),
preguntas de los scripts de instalación de paquetes, el registro de
cambios de los paquetes, y todos los formatos específicos usados por
programas tales como escenarios de juegos o los ficheros de recursos de wine.
¿Cómo usar po4a?¶
Este capítulo es como un manual de referencia, dónde se intenta
contestar a las preguntas de los usuarios y se ofrece una idea general del
proceso. Le introducirá al método de trabajo con po4a y sirve como
documentación introductoria a las herramientas específicas.
Visión esquemática¶
El siguiente esquema ofrece una visión global del proceso de
traducción de documentación usando po4a. No se asuste por su
aparente complejidad, esto se debe a que aquí se representa el proceso
completo. Una vez que haya convertido su proyecto a po4a sólo
será relevante la parte derecha del gráfico.
Observe que
original.doc se toma como un ejemplo de la documentación
a traducir, y que
traducción.doc es el texto traducido
correspondiente. La extensión podría ser
.pod,
.xml o
.sgml dependiendo del formato. Cada parte del dibujo se explicará
con detalle en las siguientes secciones.
original.doc
|
V
+<-----<----+<-----<-----<--------+------->-------->-------+
: | | :
{traducción} | { actualización de original.doc } :
: | | :
XX.doc | V V
(opcional) | original.doc ->------->----->+
: | (new) |
V V | |
[po4a-gettextize] doc.XX.po--->+ | |
| (antiguo) | | |
| ^ V V |
| | [po4a-updatepo] |
V | | V
traducción.pot ^ V |
| | doc.XX.po |
| | («fuzzy» (difusa)) |
{ traducción } | | |
| ^ V V
| | {edición manual} |
| | | |
V | V V
doc.XX.po --->---->+<---<---- doc.XX.po apéndice original.doc
(inicial) (actualizado) (opcional) (actualizado)
: | | |
: V | |
+----->----->----->------> + | |
| | |
V V V
+------>-----+------<------+
|
V
[po4a-translate]
|
V
XX.doc
(actualizado)
En la parte izquierda se muestra la conversión de una traducción que
no usa po4a a este sistema. En la parte superior derecha se representa la
acción del autor original (actualizar la documentación). En la parte
central derecha se simbolizan las acciones automáticas de po4a. Se extrae
el nuevo material, y se compara con la traducción existente. Se
encuentran las partes que no han cambiado, y se usa la traducción previa.
Las partes parcialmente modificadas también se conectan con la
traducción anterior, pero se añade un marcador indicando que la
traducción se debe actualizar. La parte inferior de la figura muestra
como se construye el documento formateado.
En realidad, como traductor, la única operación manual que debe hacer
es la parte marcada como {edición manual}. Sí, lo siento, pero po4a
le ayuda a traducir. No traduce nada por usted...
¿Cómo empezar una nueva traducción?¶
Esta sección presenta los pasos necesarios para iniciar una nueva
traducción con po4a. Los refinamientos involucrados en la conversión
de un proyecto existente a este sistema se detallan en la sección
pertinente.
Para iniciar una nueva traducción utilizando po4a, debe seguir los
siguientes pasos:
- -
- Extracción del texto que se tiene que traducir del
documento < original.doc> a una nueva plantilla de
traducción < traducción.pot> (el formato de
gettext). Para ello, use el programa po4a-gettextize de la
siguiente manera:
$ po4a-gettextize -f <formato> -m <original.doc> -p <traducción.pot>
Naturalmente, < formato> es el formato usado en el documento
original.doc. Tal como es de esperar, la salida va a
traducción.pot. para más detalles sobre las opciones
existentes consulte po4a-gettextize(1).
- -
- Ahora toca traducir lo que se debe traducir. Para ello,
debe renombrar el fichero POT a doc.XX.po, por ejemplo (dónde
XX es el código ISO639 del idioma al que esté
traduciendo, por ejemplo fr para el francés), y edite el
fichero resultante. A menudo es una buena idea no llamar al fichero
XX.po para evitar confusiones con la traducción de los
mensajes de programa, pero esto depende del usuario. No se olvide de
actualizar las cabeceras de los ficheros PO, son importantes.
La traducción en sí misma se puede hacer con el modo PO de Emacs,
Lokalize (basado en KDE), Gtranslator (basado en GNOME), o cualquier
programa que prefiera (por ejemplo, Virtaal).
Si desea aprender más, definitivamente necesita consultar la
documentación de gettext, disponible en el paquete
gettext-doc.
Una vez que haya terminado la traducción, querrá obtener la
documentación traducida para distribuirla a los usuarios junto con el
original. Para ello, utilice el programa
po4a-translate(1) de la
siguiente manera (
XX es el código del idioma):
$ po4a-translate -f <formato> -m <original.doc> -p <doc-XX.po> -l <XX.doc>
Al igual que antes, <
formato> es el formato usado en el documento
original.doc. Pero esta vez, el fichero PO introducido con el
parámetro
-p es parte de la entrada. Ésta es su
traducción. La salida va a
XX.doc.
Para más detalles consulte
po4a-translate(1) .
¿Cómo actualizar una traducción con po4a?¶
Para actualizar su traducción cuando el fichero de origen
original.doc cambie, use el programa
po4a-updatepo(1) de la
siguiente manera:
$ po4a-updatepo -f <formato> -m <nuevo_original.doc> -p <doc_antiguo.XX.po>
Para más detalles consulte
po4a-updatepo(1).
Naturalmente, los nuevos párrafos del documento no se traducirán
mágicamente en el fichero PO con esta operación, y necesitará
actualizar el fichero PO manualmente. Así mismo, puede que tenga que
rehacer las traducciones de los párrafos que se hayan modificado un poco.
Para asegurar que no pasará ninguna por alto, se marcan como
«fuzzy» (difusas) durante el proceso, y deberá quitar esta
marca manualmente antes de que pueda usar la traducción con
po4a-translate. Al igual que para la traducción inicial, aquí
lo mejor es usar su editor PO favorito.
Una vez su fichero PO esté otra vez actualizado, sin ninguna cadena por
traducir ni cadenas difusas, puede generar el fichero de documentación
traducido, tal y como se explicó en la sección anterior.
¿Cómo convertir una traducción ya existente a
po4a?¶
A menudo, usted acostumbraba a traducir manualmente el documento felizmente
hasta que llegó una reorganización del documento de origen
original.doc. Entonces, después de algunos intentos fracasados con
diff o herramientas similares, desea pasarse a po4a. Pero, por
supuesto, no quiere perder su traducción en el proceso. No se preocupe,
las herramientas de po4a también tienen en cuenta este caso, se llama
«gettextización».
La condición más importante es que tanto el documento traducido como
el original tengan la misma estructura de manera que las herramientas puedan
encajar los contenidos correctamente.
Si está de suerte (es decir, si las estructuras de ambos documentos encajan
a la perfección), todo funcionará a la perfección y habrá
terminado en unos segundos. En caso contrario, deberá entender
porqué este proceso tiene un nombre tan feo, y debería estar
preparado para un poco de trabajo sucio. En cualquier caso, recuerde que
éste es el precio a pagar para obtener luego la comodidad de po4a. Y la
mejor parte es que sólo deberá hacer esto una vez.
No puedo enfatizarlo más. Para facilitar el proceso es importante encontrar
la versión exacta que se usó para la traducción. La mejor
situación se da cuando anotó qué revisión del VCS se
usó para la traducción y que no se modificó durante el proceso
de traducción, de forma que pueda usarla.
No funcionará bien si usa el texto original actualizado con una
traducción vieja. Es un proceso posible, pero más difícil y en
realidad se debe evitar en la medida que sea posible. De hecho, imagino que si
no consigue encontrar el texto original otra vez, la mejor solución es
encontrar a alguien que haga la gettextización por usted (pero por favor,
que no sea yo ;).
Quizá esté siendo demasiado dramático en este punto. Aunque las
cosas vayan mal, sigue siendo mucho más rápido que traducirlo todo
otra vez. Yo hice la gettextización de la traducción al francés
existente de la documentación de Perl en un día, a pesar de que las
cosas fueron
mal. Eran más de dos megabytes de texto, y una
traducción nueva hubiera podido durar como mínimo meses.
Permítame explicar primero las bases del proceso, y luego ya volveremos a
los indicaciones para conseguirlo cuando el proceso vaya mal. Para facilitar
la comprensión usaremos el ejemplo anterior una vez más:
Una vez que tiene el anticuado
original.doc, que encaja con el
XX.doc traducido, puede ejecutar la gettextización directamente
sobre el fichero PO
doc.XX.po sin realizar una traducción manual
del fichero
traducción.pot:
$ po4a-gettextize -f <formato> -m <original_anticuado.doc> -l <XX.doc> -p <doc.XX.po>
Si está de suerte, eso es todo. Ha convertido su vieja traducción a
po4a y ya puede iniciar la tarea de actualización en el momento.
Simplemente siga el proceso explicado unas secciones antes para sincronizar su
fichero PO con el documento original más reciente, y actualizar la
traducción de acuerdo al mismo.
Tenga en cuenta que aunque parezca que todo ha ido bien, aún 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 traducción se refiere al original
dado. Es por ello que las cadenas se marcan como difusas («fuzzy»)
durante el proceso. Debe comprobar cuidadosamente cada cadena antes de
eliminar esas marcas.
A menudo las estructuras de los documentos no encajan a la perfección,
impidiendo que
po4a-gettextize realice su tarea. Llegados a este punto,
todo el proceso se traslada a la edición de los ficheros para hacer
encajar sus malditas estructuras.
Le puede ayudar leer la sección
Gettextización: ¿Cómo
funciona?, más abajo. La comprensión del funcionamiento interno
del proceso le ayudará a hacerlo funcionar. El punto bueno es que
po4a-gettextize da mucha información cuando algo no va bien.
Primero, apunta dónde se encontró la discrepancia de estructuras en
los documentos. Luego le mostrará las cadenas que no encajan, su
posición en el texto, y el tipo de cada una. Además, el fichero PO
generado hasta el momento se guardará en
gettextization.failed.po.
- -
- Elimine todas las partes añadidas de las traducciones,
como secciones donde se especifica el nombre del traductor, o los
agradecimientos de gente que colaboró con la traducción. Los
apéndices, descritos en la siguiente sección, le permitirán
volver a añadir estos contenidos.
- -
- No dude en editar tanto el original como la
traducción. Lo más importante es conseguir el fichero PO. Ya
tendrá tiempo de actualizarlo luego. Dicho esto, es preferible editar
la traducción cuando se pueden editar ambos, ya que facilita las
cosas cuando haya finalizado la gettextización.
- -
- Si es necesario, elimine algunas partes del original si no
estaban traducidas. Cuando más adelante sincronice el PO con el
documento, volverán por si solas.
- -
- Si cambió un poco la estructura (para juntar dos
párrafos, o dividir alguno), deshaga esos cambios. Si hay problemas
con el original, debería informar al autor original del texto.
Arreglarlo sólo en la traducción solo ofrece la solución a
una parte de la comunidad. Y además, es imposible cuando se usa po4a
;)
- -
- A veces el contenido del párrafo encaja, pero su tipo
no. Arreglar eso depende mucho del formato. En POD y man, a menudo es
culpa de que una de las dos líneas empieza con un espacio y la otra
no. En estos formatos, este párrafo no se podría justificar y su
tipo cambiaría. Simplemente elimine el espacio y ya está.
También puede tratarse de un error tipográfico en el nombre de
la etiqueta.
De manera parecida, dos párrafos se podrían fusionar en un POD
cuando la línea de separación contiene algunos espacios, o
cuando no hay una línea de separación antes de la línea
=item y del contenido del elemento («item»).
- -
- A veces, hay un asincronía entre ficheros y la
traducción se empareja con un párrafo original equivocado.
Éste es un signo de que el problema real ya existía en los
ficheros. Compruebe gettextization.failed.po para ver cuando
empieza la asincronismo, y arréglelo ahí.
- -
- A veces le puede dar la impresión de que po4a
omitió algunas partes del texto, ya sea del original o de la
traducción. gettextization.failed.po indica que ambos
encajaban correctamente, y luego falló porque intentó encajar un
párrafo con el anterior (o posterior) con el correcto, como si el
correcto hubiera desaparecido. Maldiga po4a como yo hice la primera vez
que me pasó. Abundantemente.
Esta desafortunada situación se debe a que el mismo párrafo se
repite a lo largo del documento. En ese caso, no se crea una nueva entrada
en el fichero PO, sino que se añade una nueva referencia a la ya
existente.
Por lo tanto, cuando el mismo párrafo aparece dos veces en el original
pero no está traducido exactamente igual en cada aparición,
tendrá la sensación de que desapareció un párrafo del
original. Simplemente elimine la traducción nueva. Si cree que la
segunda traducción es mejor, elimínela de donde está, y
póngala en el lugar de la primera.
En caso contrario, si dos párrafos parecidos pero diferentes se
tradujeron de la misma forma le puede dar la impresión de que
desapareció un párrafo de la traducción. La solución
es añadir una cadena de relleno al párrafo original (algo como
«soy diferente») para solucionarlo. No se asuste. Estas cosas
desaparecerán durante la sincronización, y cuando el texto
añadido sea suficientemente corto, gettext encajara su
traducción con el texto existente (marcándola como difusa, pero
no importa, ya que todas las cadenas se marcan como difusas durante la
gettextización).
Con un poco de suerte estos trucos le ayudarán a realizar su
gettextización y a obtener su preciado fichero PO. Ahora está
preparado para sincronizar su fichero y empezar la traducción. Tenga en
cuenta que en textos grandes la primera sincronización puede tardar mucho
tiempo.
Por ejemplo, el primer
po4a-updatepo de la traducción al
francés de la documentación de Perl (un fichero PO de 5.5 Mb)
tomó alrededor de dos días enteros en una máquina G5 a 1Ghz.
Sí, 48 horas. Pero las siguientes veces tan solo tardaba una docena de
segundos en mi viejo portátil. Esto se debe a que la primera vez la
mayoría de msgid del fichero PO no encajaban con ninguno de los del
fichero POT. Esto obliga a gettext a buscar la cadena más parecida usando
un costoso algoritmo de proximidad de cadenas.
¿Cómo añadir texto adicional a las traducciones
(como el nombre del traductor)?¶
Debido al enfoque de gettext, ésto se vuelve más difícil en po4a
que antes, cuando simplemente se editaba el nuevo fichero paralelamente al
original. Pero sigue siendo posible, gracias a los llamados
apéndices («addenda»).
Para ayudar a la comprensión, considere los apéndices como unos
parches aplicados al documento traducido después del proceso. Son
bastante diferentes que los parches habituales (solo tienen una línea de
contexto, que puede incluir una expresión regular de Perl y
únicamente pueden añadir texto, sin eliminar nada), pero la
funcionalidad es la misma.
Su objetivo es permitir al traductor añadir contenido adicional al
documento que no está traducido a partir documento original. El uso
más habitual es añadir una sección sobre la misma
traducción, listando los colaboradores y explicando cómo informar de
los errores en la traducción.
El apéndice (addendum) se debe proporcionar como un fichero separado. La
primera línea forma una cabecera que indica el lugar del documento
resultante dónde se debe colocar. El resto del contenido del fichero
apéndice se añadirá literalmente cual en la posición
determinada en el documento resultante.
La cabecera tiene una sintaxis muy rígida: debe empezar con la cadena
PO4A-HEADER:, seguida por una lista de campos
llave=valor separados por un punto y coma (
;).
Los espacios en blanco SON importantes. Tenga en cuenta que no puede usar el
carácter de punto y coma (
;) en los valores, y que las comillas
no ayudan en este caso.
Una vez más, suena espantoso, pero los ejemplos proporcionados a
continuación deberían ayudarle a encontrar la forma de escribir la
línea de cabecera que necesita. Para ilustrar la discusión, suponga
que desea añadir una sección llamada «Acerca de esta
traducción» después de la denominada «Acerca de este
documento».
Aquí están las posibles llaves de la cabecera:
- position (obligatoria)
- Una expresión regular. El apéndice se
ubicará cerca de la línea que coincida con esta expresión
regular. Tenga en cuenta que estamos hablando del documento traducido, no
del original. Si hay más de una linea que coincida con esta
expresión (o ninguna), la adición fallará. Siempre es mejor
informar de un error que insertar el apéndice en el sitio equivocado.
Esta línea se llama punto de ubicación
(«position»). El punto donde se insertará el apéndice
se llama punto de inserción («insertion»). Estos dos
puntos están muy próximos, pero no son iguales. Por ejemplo, si
desea una nueva sección, es más fácil definir el punto
de ubicación con el título de la sección anterior, y
explicarle a po4a dónde termina la sección (recuerde que el
punto de ubicación viene dado por la expresión regular,
que debe coincidir con una única linea).
La ubicación del punto de inserción respecto al punto de
ubicación está controlado por los campos mode,
beginboundary y endboundary, explicados a continuación.
En nuestro caso tendríamos:
position=<title>Acerca de este documento</title>
- mode (obligatorio)
- Puede ser tanto before (antes) o after
(después), especificando la posición del apéndice, relativa
al punto de ubicación.
Ya que queremos que la sección nueva se sitúe debajo de la que
hemos emparejado, tenemos:
mode=after
- beginboundary (inicio del límite, usado
sólo con mode=after, y obligatorio en ese caso)
- endboundary (fin del límite, ídem)
- Expresión regular que encaja con el final de la
sección que precede a la posición del apéndice.
Con mode=after, el punto de inserción está
después del punto de ubicación, ¡pero no
justamente después! Está situado al final de la sección que
empieza en el punto de ubicación, es decir, antes o
después de la línea encajada por el argumento
???boundary, dependiendo de si usó beginboundary
o endboundary.
En nuestro caso, podemos decidirnos por indicar el final de la sección
que queremos emparejar añadiendo:
endboundary=</section>
o indicar el principio de la siguiente sección indicando:
beginboundary=<section>
En ambos casos, nuestro apéndice se ubicará después de
</section> y antes de <section>. La primera
opción es mejor ya que funcionará aunque se reorganice el
documento.
Las dos formas existen debido a que los formatos de documentación son
diferentes. En algunos de ellos, hay una forma de marcar el final de una
sección (tal como </section>, que ya hemos usado),
mientras que otros no marcan explícitamente el final de una
sección (como con el formato man). En el primer caso, es preferible
encajar boundary con el final de sección, para
que el punto de inserción venga después. En el segundo
caso, deberá encajar un boundary con el principio de la
siguiente sección para que el punto de
inserción venga justo antes de éste.
Puede parecer críptico, pero espero que los siguientes ejemplos le
iluminen.
- Para resumir el ejemplo usado hasta el momento, si desea
insertar una sección llamada «Acerca de esta traducción»
después de la sección «Acerca de este documento» en un
documento SGML, debe usar una de estas líneas de cabecera:
-
PO4A-HEADER: mode=after; position=Acerca de este documento; endboundary=</section>
PO4A-HEADER: mode=after; position=Acerca de este documento; beginboundary=<section>
- Si desea añadir algo después de la siguiente
sección de nroff:
-
.SH "AUTORES"
debería poner un position que encaje esta linea, y un
beginboundary que encaje con el principio de la siguiente
sección (es decir ^\.SH). El apéndice se
añadiría después del punto de ubicación
e inmediatamente antes de la primera línea que encaje con
beginboundary. Ésto es:
PO4A-HEADER:mode=after;position=AUTORES;beginboundary=\.SH
- Si desea añadir algo dentro de una sección (como
después de «Copyright Big Dude») en vez de añadir una
sección completa, introduzca un "position" que encaje con
esta línea, 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=<title>Acerca de</title>;beginboundary=BoundaryFalsoDePo4a
En cualquier caso, recuerde que se tratan de expresiones regulares. Por ejemplo,
si desea encajar con el final de una sección de nroff que termina con la
línea
.fi
no utilice
.fi como
endboundary, porque esto encajará con
«el[ fi]chero», que obviamente no es lo que espera. El
endboundary correcto en este caso sería:
^\.fi$.
Si el apéndice no se ubica donde esperaba, pruebe introduciendo el
parámetro
-vv a las herramientas para que le expliquen qué
hacen al colocar el apéndice.
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 apéndice antes del AUTOR, utilice la siguiente cabecera:
PO4A-HEADER:mode=after;position=NOMBRE;beginboundary=^=head1
Esto funciona porque la siguiente linea que encaja con
beginboundary
«/^=head1/» después de la sección «NOMBRE», es
la que declara los autores. Por lo tanto, se colocará el apéndice
entre ambas secciones.
¿Cómo hacer todo esto con una sola invocación al
programa?¶
El uso de po4a ha demostrado que puede dar lugar a errores ya que debe invocar
dos programas distinto en el orden adecuado (
po4a-updatepo y luego
po4a-translate), y cada uno necesita más de 3 argumentos.
Además, era difícil con este sistema usar sólo un fichero PO
para todos los documentos cuando se usaba más de un formato.
El programa
po4a(1) se diseñó para solucionar esas
dificultades. Una vez que haya convertido su proyecto a este sistema, puede
escribir un sencillo fichero de configuración explicando dónde
están los ficheros de traducción (PO y POT), dónde están
los documentos originales, sus formatos y dónde se deberían guardar
las traducciones.
Luego, una simple invocación a
po4a(1) con este fichero como
argumento asegura que los ficheros PO se sincronicen con el documento
original, y que los documentos traducidos se generan correctamente. Por
supuesto, le interesará invocar este programa dos veces: una antes de
editar el fichero PO para actualizarlo, y otra para obtener los documentos
traducidos totalmente actualizados. Pero sólo necesita recordar una
orden.
¿Cómo configurar po4a?¶
Los módulos de po4a tienen opciones (especificados con la opción
-o), que se pueden usar para modificar el comportamiento del
módulo.
También es posible configurar un módulo o módulos nuevos,
derivados o modificados mediante la inserción de un módulo en
lib/Locale/Po4a/, y añadiendo
lib a las rutas especificadas
en los entornos PERLLIB o PERL5LIB. Por ejemplo:
PERLLIB=$PWD/lib po4a --previous po4a/po4a.cfg
Nota: el nombre real del directorio «/lib» no es importante.
¿Cómo funciona?¶
Este capítulo ofrece una breve explicación del funcionamiento interno
de po4a, de forma que se pueda sentir más seguro para ayudarnos a
desarrollar y mejorar el programa. También le puede ayudar a entender
porqué no hace lo que esperaba, y cómo solucionar sus problemas.
Visión general¶
La arquitectura de po4a está orientada a objetos (en Perl. Muy pulcro,
¿no?). El antecesor de todas las clases de analizadores se llama
TransTractor. Este extraño nombre viene del hecho de que se encarga al
mismo tiempo de traducir el documento («translate») y de extraer las
cadenas («extract»).
Más formalmente, toma un documento a traducir, además del fichero PO
que contiene las traducciones a usar como entrada mientras produce dos salidas
separadas: Otro fichero PO (resultado de la extracción 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). Esta es una representación
gráfica de este proceso:
Documento de entrada -\ /---> Documento de salida
\ TransTractor:: / (traducido)
+-->-- parse() ------+
/ \
PO de entrada --------/ \---> PO de salida
(extraído)
Esta pequeño hueso es el núcleo 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 función virtual integrada en cada
módulo. Aquí hay un pequeño ejemplo que muestra cómo
funciona. Analiza una lista de párrafos, cada uno empezando con
<p>.
1 sub parse {
2 PARAGRAPH: while (1) {
3 $my ($paragraph,$pararef,$line,$lref)=("","","","");
4 $my $first=1;
5 while (($line,$lref)=$document->shiftline() && defined($line)) {
6 if ($line =~ m/<p>/ && !$first--; ) {
7 $document->unshiftline($line,$lref);
8
9 $paragraph =~ s/^<p>//s;
10 $document->pushline("<p>".$document->translate($paragraph,$pararef));
11
12 next PARAGRAPH;
13 } else {
14 $paragraph .= $line;
15 $pararef = $lref unless(length($pararef));
16 }
17 }
18 return; # ¿No obtuvo una línea definida? Fin del fichero de entrada.
19 }
20 }
En la línea 6, encontramos
<p> por segunda vez. Esta es la
señal de que hemos encontrado el siguiente párrafo. Debemos entonces
devolver la línea obtenida de vuelta al documento (línea 7) y enviar
el párrafo construido hasta el momento a las salidas. Después de
eliminar el
<p> inicial en la línea 9, insertamos la
concatenación de esta etiqueta junto con la traducción del resto del
párrafo.
La función «
translate()» está muy bien. Envía
su argumento al fichero PO de salida (extracción) y devuelve su
traducción tal y como es en el fichero PO de entrada (traducción).
Ya que se usa como parte del argumento de «
pushline()», esta
traducción acaba en el documento de salida.
¿Como mola, no? Es posible construir un módulo completo de po4a en
menos de 20 líneas si el formato es suficientemente simple...
Encontrará más acerca de esto en
Locale::Po4a::TransTractor(3pm).
Gettextización: ¿Cómo funciona?¶
La idea aquí es tomar el documento original y su traducción, y
considerar que la enésima cadena extraída de la traducción es
la traducción de la enésima cadena extraída 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 traducción (de tipo 'capítulo')
sea la traducción de la cuarta cadena del original (de tipo
'párrafo').
Original Traducción
capítulo capítulo
párrafo párrafo
párrafo párrafo
párrafo capítulo
capítulo párrafo
párrafo párrafo
Para ello, los analizadores de po4a se utilizan tanto con el fichero original
como con 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
información sobre el tipo sintáctico de las cadenas extraídas
en el documento (todos los que hay lo hacen, el suyo también lo
debería hacer). Esa información se utiliza después para
asegurar que ambos documentos tienen la misma sintaxis. En el ejemplo
anterior, nos permitiría detectar que la cuarta cadena es un párrafo
en un caso, y el título de un capítulo en el otro e informar del
problema.
En teoría, sería posible detectar el problema, y resincronizar los
ficheros posteriormente (al igual que
diff). Pero no está claro
qué deberíamos hacer con las cadenas antes de las asincronías,
y a veces podría producir malos resultados. Es por ello que la
implementación actual no intenta resincronizar nada, e informa
extensamente del fallo cuando algo va mal, requiriendo la modificación
manual de los ficheros para arreglar el problema.
Incluso con estas precauciones, las cosas se pueden estropear muy
fácilmente. Es por ello que todas las traducciones encontradas así
se marcan como difusas, para asegurar que el traductor las repase y corrija.
Apéndice («Addendum»): ¿Cómo
funciona?¶
Bueno, esto es muy simple. El documento traducido no se escribe directamente al
disco, sino que se mantiene en memoria hasta que se insertan todos los
apéndices. Los algoritmos involucrados son más bien sencillos.
Buscamos una línea que encaje con la expresión regular de la
ubicación, e insertamos el apéndice antes del mismo si estamos en
mode=before. De no ser así, buscamos la siguiente linea que encaje
con el «boundary» (límite) e insertamos el apéndice a
continuación de esta línea si es un
endboundary o antes de
esta línea si es un
beginboundary.
Preguntas frecuentes¶
Este capítulo agrupa las preguntas frecuentes. De hecho, la mayoría de
preguntas actuales se pueden formular así: «¿Porqué se ha
diseñado de esta manera, y no otra?» Si piensa que po4a no es la
solución ideal para la traducción de documentación,
debería considerar leer ésta sección. Si no responde a su
pregunta, contacte con nosotros en la lista de correo
<po4a-devel@lists.alioth.debian.org>. Queremos escuchar su opinión.
¿Porqué traducir cada párrafo por separado?¶
Sí, en po4a, cada párrafo se traduce por separado (de hecho, cada
módulo lo decide, pero todos los existentes lo hacen, y el suyo
también debería hacerlo). Hay dos ventajas principales al hacerlo
así:
- •
- Cuando se ocultan las partes técnicas del documento,
el traductor no puede alterarlas. Cuantas menos marcas presentemos al
traductor, menos errores podrá hacer.
- •
- El hecho de dividir el documento ayuda a aislar los cambios
en el documento original. Este proceso facilita encontrar qué partes
de la traducción se necesitan actualizar cuando se modifica el
documento original.
Incluso con estas ventajas, a algunas personas no les gusta la idea de traducir
cada párrafo por separado. Aquí hay algunas respuestas que les puedo
dar:
- •
- Este enfoque ha demostrado resultados satisfactorios en el
proyecto KDE y permite a sus miembros producir la cantidad más grande
de documentación traducida y actualizada que conozco.
- •
- Los traductores pueden seguir usando el contexto para
traducir, ya que las cadenas del fichero PO están en el mismo orden
que las del documento original. Por ello, traducir secuencialmente
facilita la comparación use o no po4a. Y en cualquier caso, la mejor
forma de obtener el contexto sigue siendo convertir el documento a un
formato imprimible, ya que los textos formateados son, en mi opinión,
ilegibles.
- •
- Este enfoque es el que usan los traductores profesionales.
Estoy de acuerdo en que ellos tienen diferentes objetivos que los
traductores de código abierto. Por ejemplo, la actualización es
habitualmente menos importante para ellos ya que el contenido cambia muy
poco.
¿Porqué no realizar las divisiones a nivel de
oración (o más pequeñas)?¶
A veces las herramientas de traducción profesionales dividen 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 párrafos son por definición más largos que las frases. Con un
poco de suerte se puede asegurar que si se tiene el mismo párrafo en dos
documentos, tendrán el mismo significado (y traducción), sin
importar el contexto en cada caso.
Dividirlo en partes más pequeñas que frases sería
muy
malo. Podría tomar mucho tiempo explicar el motivo aquí, pero si
le interesa puede consultar la página de manual de
Locale::Maketext::TPJ13(3pm) (que viene con la documentación de
Perl), por ejemplo. Brevemente, cada idioma tiene sus reglas de sintaxis
específicas, y no hay forma de construir frases encajando partes de
frases para todos los idiomas existentes (incluso para 5 de los 10 idiomas
más hablados, o incluso menos).
A simple vista, gettext no parece estar adaptado a todos los tipos de
traducciones. Por ejemplo, no parecía adaptado a debconf, la interfaz que
usan todos los paquetes de Debian para sus interacciones con el usuario
durante la instalación. En ese caso, los textos a traducir eran muy
cortos (una docena de lineas para cada paquete) y era muy difícil poner
la traducción en un fichero específico ya que tiene que estar
disponible antes de la instalación del paquete.
Es por ello que el desarrollador de debconf decidió implementar otra
solución, donde las traducciones se situasen en el mismo fichero que el
original. Esto es bastante atractivo. Uno podría incluso desear hacerlo
en XML, por ejemplo. Tendría esta aspecto:
<section>
<title lang="en">My title</title>
<title lang="es">Mi título</title>
<para>
<text lang="en">My text.</text>
<text lang="es">Mi texto.</text>
</para>
</section>
Pero fue tan problemático que se terminó usando una
implementación basada en PO. En el fichero, solo se puede editar el
original, y las traducciones se deben hacer en los ficheros PO extraídos
de la plantilla original (y devueltos al paquete en tiempo de
compilación). El sistema antiguo se consideró obsoleto debido a
varios problemas:
- •
- problemas de mantenimiento
Si varios traductores envían un parche a la vez, fusionarlos es
difícil.
¿Como detectaría los cambios en el original que se deban aplicar a
las traducciones? Para poder usar diff, se debe tener en cuenta qué
versión del original se tradujo. Es decir, necesita un fichero PO en
su fichero ;)
- •
- problemas de codificación
La solución es viable cuando sólo se utilizan idiomas europeos,
pero la introducción del Coreano, Ruso y/o Árabe realmente
complica el asunto. La solución sería UTF, pero aún hay
algunos problemas con él.
Además, estos problemas son difíciles de detectar (es decir, solo
los lectores Coreanos detectarán que falla la codificación del
Coreano [por culpa del traductor ruso])
gettext soluciona todos estos problemas a la vez.
¡Pero gettext no se diseñó para este uso!¶
Es cierto, pero hasta el momento nadie ha propuesto una solución mejor. La
única alternativa conocida es la traducción manual, con todos los
problemas de mantenimiento.
¿Qué hay de las otras herramientas de traducción
de documentación que usan gettext?¶
Hasta donde yo sé, sólo hay dos de ellas:
- 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.
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.
Educar a los desarrolladores sobre la traducción¶
Al intentar traducir documentación o programas, se puede encontrar con tres
tipos de problemas; lingüísticos (no todo el mundo habla dos
lenguas), técnicos (por eso existe po4a) y relacionales/humanos. No todos
los desarrolladores entienden la necesidad de traducir las cosas. Incluso los
concienciados podrían ignorar como se facilita el trabajo a los
traductores. Para ayudar en este tema, po4a trae bastante documentación a
la que se puede acudir.
Otro punto importante es que cada fichero traducido empieza con un breve
comentario que indica qué es el fichero, y como usarlo. Esto debería
ayudar a los pobres desarrolladores que sufren avalanchas de ficheros en
diferentes idiomas que no entienden, y ayudarles a tratarlos correctamente.
En el proyecto po4a, la documentación traducida ya no se considera como
ficheros de fuentes. Como los ficheros SGML son habitualmente ficheros de
fuentes, es un fallo habitual. Es por ello que todos los ficheros presentan
esta cabecera:
| *****************************************************
| * 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 VCS,
| 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 ;)
Así mismo, los ficheros PO regulares de gettext solo necesitan ser copiados
al directorio
po/. Pero
éste no es el caso de los PO tratados
por po4a. Aquí el mayor riesgo es que el desarrollador elimine
las traducciones existentes del programa con la traducción de su
documentación. (Ambos no se pueden almacenar en el mismo fichero PO,
porque el programa necesita instalar su traducción en un fichero mo,
mientras que la documentación solo utiliza su traducción en tiempo
de compilación). Es por esto que los ficheros PO producidos por el
módulo po-debiandoc contienen la siguiente cabecera:
#
# 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 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:
- http://kv-53.narod.ru/kaider1.png
- 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... 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 abre un fichero SGML, se extraen las cadenas
automáticamente. Al guardar se guarda un fichero SGML traducido en el
disco. Si consiguiéramos hacer un módulo para MS Word (TM) (o al
menos RTF) incluso podrían usarlo traductores profesionales.
AUTORES¶
Denis Barbier <barbier,linuxfr.org>
Martin Quinson (mquinson#debian.org)