Locale::Po4a::TransTractor - Trans(lator ex)tractor genérico (traductor
extractor).
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 ámbitos
dónde no previstos, como la documentación.
Esta clase es la antecesora de todos los analizadores de po4a usados para
analizar un documento buscando cadenas traducibles, extraerlas a un fichero PO
y reemplazarlas por su traducción en el documento de salida.
Más formalmente, toma los siguientes parámetros como entrada:
- -
- un documento a traducir;
- -
- un fichero PO que contiene las traducciones a usar.
Como salida produce:
- -
- otro fichero PO, resultado de la extracción de
cadenas traducibles del documento de entrada;
- -
- un documento traducido, con la misma estructura que el de
la entrada, pero con todas las cadenas traducibles reemplazadas por las
traducciones encontradas en el fichero PO suministrado en la entrada.
Aquí tiene una representación gráfica:
Documento de entrada -\ /---> Documento de salida
\ / (traducido)
+-> función parse() --+
/ \
PO de entrada --------/ \---> PO de salida
(extraído)
- parse()
- Aquí es dónde se hace todo el trabajo: el
análisis de los documentos de entrada, la generación de la
salida, y la extracción de las cadenas traducibles. Es realmente
simple usando las funciones presentadas en la sección FUNCIONES
INTERNAS más abajo. Consulte la SINOPSIS, que presenta
un ejemplo.
Esta función es invocada por la función «
process()» a continuación, pero si elije usar la
función « new()», y añadir contenido
manualmente a su documento, deberá invocar ésta
función manualmente.
- docheader()
- Esta función devuelve la cabecera que
deberíamos añadir al documento creado, tratada de forma que
sea un comentario para el lenguaje destino. Para ver las ventajas de esto,
consulte la sección Educar a los programadores sobre las
traducciones, en po4a(7).
El siguiente ejemplo analiza una lista de párrafos que empiezan con
«<p>». Para simplificar, suponemos que el documento
está correctamente formateado, es decir, que sólo hay presentes
etiquetas '<p>', y que esta etiqueta está justo al principio de
cada párrafo.
sub parse {
my $self = shift;
PARAGRAPH: while (1) {
my ($paragraph,$pararef)=("","");
my $first=1;
my ($line,$lref)=$self->shiftline();
while (defined($line)) {
if ($line =~ m/<p>/ && !$first--; ) {
# No es la primera vez que vemos <p>.
# Devuelve la línea actual a la entrada,
# y pon el párrafo construido en la salida.
$self->unshiftline($line,$lref);
# Ahora que tenemos el documento creado, lo traducimos:
# - Eliminamos la etiqueta inicial
$paragraph =~ s/^<p>//s;
# - Ponemos en la salida la etiqueta inicial (sin traducir) y el
# resto del párrafo (traducido)
$self>pushline( "<p>"
. $self->translate($paragraph,$parraref)
);
next PARAGRAPH;
} else {
# Añadir al párrafo.
$paragraph .= $line;
$pararef = $lref unless(length($pararef));
}
# Reiniciar el bucle
($line,$lref)=$self->shiftline();
}
¿ # ¿No se obtuvo una línea definida? Fin del fichero de entrada.
return;
}
}
Una vez haya implementado la función de análisis, ya puede usar su
clase de documento usando la interfaz pública presentada en la
siguiente sección.
- process(%)
- Esta función puede hacer todo lo que quiera hacer
con un documento po4a en una invocación:. Sus argumentos deben
estar empaquetados como una tabla de elementos asociativos
(«hash»). ACCIONES:
- a.
- Lee todos los ficheros PO especificados en
«po_in_name»
- b.
- Lee todos los documentos originales especificado en
«file_in_name»
- c.
- Analiza el documento
- d.
- Lee y aplica todos los apéndices especificados
- e.
- Escribe el documento traducido en
«file_out_name» (si se da)
- f.
- Escribe el fichero PO extraído en
«po_out_name» (si se da)
ARGUMENTOS, aparte de los aceptados por «
new()» (con el
tipo esperado):
- file_in_name (@)
- Lista de los nombres de ficheros de los que se debe leer el
documento de entrada.
- file_in_charset ($)
- El juego de caracteres usado en el documento de entrada (si
no se especifica, se intentará detectar del documento de
entrada).
- file_out_name ($)
- Nombre del fichero donde se debe escribir el documento de
salida.
- file_out_charset ($)
- El juego de caracteres usado en el documento de salida (si
no se especifica, se usará el juego de caracteres del fichero
PO).
- po_in_name (@)
- Lista de los nombres de ficheros de los que se deben leer
los ficheros PO de entrada, y que contienen la traducción que se
usará para traducir el documento.
- po_out_name ($)
- Nombre de fichero en el que se debe escribir el fichero PO
de salida, el cual contendrá las cadenas extraídas del
documento de entrada.
- addendum (@)
- Lista de los nombres de los ficheros de los que se deben
leer los apéndices.
- addendum_charset ($)
- El juego de caracteres para los apéndices.
- new(%)
- Create a new po4a document. Accepted options (in the hash
passed as a parameter):
- verbose ($)
- Configura el nivel de verbosidad.
- debug ($)
- Configura la depuración.
- read($$)
- Add another input document data at the end of the existing
array "@{$self->{TT}{doc_in}}". The argument is the filename
to read. If a second argument is provided, it is the filename to use in
the references.
This array "@{$self->{TT}{doc_in}}" holds this input document
data as an array of strings with alternating meanings.
* The string $textline holding each line of the input text data.
* The string "$filename:$linenum" holding its location and called
as
"reference" ("linenum" starts with 1).
Cabe destacar que esto no analiza nada. Debe usar la función «
parse()» cuando haya terminado de cargar los ficheros de
entrada en el documento.
- write($)
- Escribe el documento traducido al fichero dado.
Estos datos de documentos traducidos se proporcionan por:
* "$self->docheader()" que contiene el texto de cabecera de la
extensión, y
* "@{$self->{TT}{doc_out}}" que contiene cada línea del
texto traducido principal de la matriz.
- readpo($)
- Añade el contenido de un fichero (cuyo nombre se
introduce como argumento) al PO de entrada existente. El contenido
anterior no se desecha.
- writepo($)
- Escribe el fichero PO extraído al nombre de fichero
dado.
- stats()
- Devuelve algunas estadísticas sobre el punto actual
de la traducción en curso. Estas no son las mismas
estadísticas que las que muestra «msgfmt
--statistic». Aquí las estadísticas son sobre el uso
reciente del fichero PO, mientras que msgfmt informa del estado del
fichero. Esto es un «wrapper» (patrón de
diseño) de la función Locale::Po4a::Po::stats_get aplicada
al fichero PO de entrada. Ejemplo de uso:
[uso normal del documento po4a...]
($porcentaje,$aciertos,$solicitudes) = $documento->stats();
print "Se han encontrado traducciones para el $porcentaje\% ($aciertos de $solicitudes) de cadenas.\n";
- addendum($)
- Consulte po4a(7) para más información
acerca de los apéndices, y cómo los traductores deben
escribirlos. Para aplicar un apéndice a un documento traducido,
simplemente introduzca su nombre de fichero en ésta función
y ya está ;)
Esta función devuelve un entero no nulo en caso de error.
Se proporcionan cuatro funciones para obtener la entrada y salida de vuelta. Son
muy similares a shift/unshift y push/pop de Perl.
* Perl shift devuelve el primer elemento de matriz y lo elimina de la matriz.
* Perl unshift añade un elemento al matriz como el primer elemento del a matriz.
* Perl pop devuelve el último elemento de la matriz y lo elimina de la matriz.
* Perl push añade un elemento a la matriz como el último elemento de la matriz.
El primer par trata la entrada, mientras que el segundo trata la salida. Truco
mnemoténico: en la entrada, está interesado en la primera
línea, lo que ofrece shift, y en la salida desea insertar el resultado
al final, como hace push.
- shiftline()
- Esta función devuelve la primera línea para
su análisis y la referencia correspondiente (en forma de matriz),
de la matriz "@{$self->{TT}{doc_in}}", y elimina estos dos
primeros elementos de matriz. Aquí, la referencia es proporcionada
por la cadena "$filename:$linenum".
- unshiftline($$)
- Devuelve la modificación «shift» de la
última línea «shifted» del documento de
entrada y su referencia a la cabecera de
"{$self->{TT}{doc_in}}".
- pushline($)
- Inserta una línea nueva al final de
"{$self->{TT}{doc_out}}".
- popline()
- Extrae la últma línea insertada al final de
"{$self->{TT}{doc_out}}".
Se proporciona una función para tratar el texto que se debe traducir.
- translate($$$)
- Argumentos obligatorios:
- -
- Una cadena a traducir
- -
- La referencia a esa cadena (por ejemplo, la posición
en el fichero de entrada)
- -
- El tipo de esta cadena (es decir la descripción
textual de su rol estructural; utilizada en
Locale::Po4a::Po::gettextization(); consulte también la
sección Gettextización: ¿cómo funciona?
en po4a(7))
Esta función también puede tomar algunos argumentos adicionales.
Estos deben estar en una tabla de elementos asociativos
(«hash»). Por ejemplo:
$self->translate("string","ref","type",
'wrap' => 1);
- wrap
- Booleano que indica si podemos considerar que los espacios
en blanco de la cadena carecen de importancia. En ese caso, la
función canoniza la cadena antes de buscar su traducción o
extraerla, y justifica la traducción.
- wrapcol
- La columna en la que se debe hacer el salto de línea
(por omisión: 76).
- comment
- Un comentario adicional para añadir a la
entrada.
Acciones:
- -
- Inserta la cadena, referencia y escribe en
«po_out».
- -
- Devuelve la traducción de la cadena (como aparece en
«po_in») de forma que el analizador pueda construir el
fichero «doc_out».
- -
- Trata los juegos de caracteres para recodificar las cadenas
antes de enviarlas a «po_out» y antes de devolver las
traducciones.
- verbose()
- Devuelve si se pasó la opción de verbosidad
durante la creación del TransTractor.
- debug()
- Devuelve si se pasó la opción de
depuración de fallos durante la creación del
TransTractor.
- detected_charset($)
- Esto informa al TransTractor que se ha detectado un nuevo
juego de caracteres (el primer argumento) en el documento de entrada.
Habitualmente se puede encontrar en la cabecera del documento. Solo
permanecerá el primer juego de caracteres, ya venga de los
argumentos de « process()» o si se detectó en
el documento.
- get_out_charset()
- Esta función devuelve el juego de caracteres que se
debe usar en el documento de salida (normalmente es útil para
sustituir el juego de caracteres detectado en el documento de entrada
donde se encontró).
Utilizará el juego de caracteres especificado en la linea de
órdenes. Si no se ha especificado, utilizará el juego de
caracteres del PO de entrada, y si el PO de entrada aún tiene el
«CHARSET» predefinido, devolverá el juego de
caracteres del documento de entrada, para que no se realice ninguna
codificación.
- recode_skipped_text($)
- Esta función devuelve el texto recodificado
introducido como argumento, desde el juego de caracteres del documento de
entrada al del documento de salida. No es necesario cuando se traduzca una
cadena ( translate() ya lo recodifica por su cuenta), pero
sí lo es cuando se salta alguna cadena del documento de entrada y
quiere mantener la consistencia del documento de salida con la
codificación global.
Una deficiencia del TransTractor actual es que no puede tratar documentos
traducidos que contengan todos los idiomas, como las plantillas de debconf, o
en los ficheros «.desktop».
Para tratar este problema, los únicos cambios necesarios en la interfaz
son:
- -
- tomar una tabla «hash» como
«po_in_name» (una lista por idioma)
- -
- añadir un argumento a «translate» para
indicar el idioma de destino
- -
- hacer una función «pushline_all», que
haría un «pushline» de su contenido para todos los
idiomas, usando una sintaxis parecida a «map»:
$self->pushline_all({ "Description[".$langcode."]=".
$self->translate($line,$ref,$langcode)
});
Ya veremos si es suficiente ;)
Denis Barbier <[email protected]>
Martin Quinson (mquinson#debian.org)
Jordi Vilalta <[email protected]>
Jordi Vilalta <[email protected]>
Omar Campagne <[email protected]>