Locale::Po4a::TransTractor - extrator de tradução
genérico.
O objetivo do projeto po4a (PO for anything, ou PO para qualquer
coisa) é facilitar traduções (e o mais interessante, a
manutenção das traduções) usando as ferramentas
do gettext em áreas em que não se esperava, como
documentação.
Essa classe é o ancestral de todo analisador po4a usado
para analisar um documento, para pesquisar strings traduzíveis, para
extraí-las para um arquivo PO e para substitui-las por suas
traduções no documento de saída.
Mais formalmente, ele leva os seguintes argumentos como
entrada:
- um documento para traduzir;
- um arquivo PO contendo as traduções para usar.
Como saída, ele produz:
- outro arquivo PO, resultando na extração de strings
traduzíveis do documento de entrada;
- um documento traduzido, com a mesma estrutura daquela na entrada, mas com
todas as strings traduzíveis substituídas com as
traduções encontradas no arquivo PO fornecido na
entrada.
Aqui está uma representação gráfica
disso:
Doc. de entrada -\ /---> Doc. de saída
\ / (traduzido)
+---> função parse() -----+
/ \
PO de entrada ---/ \---> PO de saída
(extraído)
FUNÇÕES QUE SEU ANALISADOR DEVERIA
SOBRESCREVER
- parse()
- É aqui onde todo trabalho acontece: o analisador de documentos de
entrada, a geração de saída e a
extração das strings traduzíveis. Isso é bem
simples usando as funções fornecidas apresentadas na
seção FUNÇÕES INTERNAS abaixo. Veja
também a SINOPSE, que apresenta um exemplo.
Essa função é chamada pela
função process() abaixo, mas se você
escolher usar a função new() e adicionar o
conteúdo manualmente a seu documento, você terá que
chamar essa função você mesmo.
- Essa função retorna o cabeçalho que nós
deveríamos adicionar ao documento produzido, coloca apropriadamente
entre aspas para ser um comentário no idioma alvo. Veja a
seção Educando desenvolvedores sobre
tradução, do po4a(7), para o que isso é
bom.
O exemplo a seguir analisa uma linha de parágrafos
começando com "<p>". Em nome da simplicidade,
nós presumimos que o documento está bem formatado, ou seja,
que as marcações "<p>" são as
únicas marcações apresentadas e que essa
marcação está exatamente no começo de cada
parágrafo.
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--; ) {
# Não é a primeira vez que vemos <p>.
# Colocar novamnete a linha atual na entrada,
# e colocar o parágrafo compilado na saída
$self->unshiftline($line,$lref);
# Agora que o documento está formado, traduza-o:
# - Remove a marcação no começo
$paragraph =~ s/^<p>//s;
# - envia para a saída a marcação no começo (não
# traduzida) e o resto do parágrafo (traduzido)
$self->pushline( "<p>"
. $document->translate($paragraph,$pararef)
);
next PARAGRAPH;
} else {
# Anexa ao parágrafo
$paragraph .= $line;
$pararef = $lref unless(length($pararef));
}
# Reinicia o loop
($line,$lref)=$self->shiftline();
}
# Não conseguiu uma linha definida? Termina com o
# arquivo de entrada.
return;
}
}
Uma vez que você tenha implementada a função
de análise, você pode usar sua classe de documento, usando a
interface pública apresentada na seção seguinte.
- process(%)
- Essa função pode fazer tudo que você precisa fazer
com um documento po4a em uma chamada. Seus argumentos devem ser
empacotados como um hash. AÇÕES:
- a.
- Lê todos os arquivos PO especificados em po_in_name
- b.
- Lê todos os documentos originais especificados em file_in_name
- c.
- Analisa o documento
- d.
- Lê e aplica todos os adendos especificados
- e.
- Escreve o documento traduzido para file_out_name (se fornecido)
- f.
- Escreve o arquivo PO extraído para po_out_name (se fornecido)
ARGUMENTOS, além dos aceitos por new() (com o tipo
esperado):
- file_in_name
(@)
- Lista de nomes de arquivos nos quais nós deveríamos ler o
documento de entrada.
- file_in_charset
($)
- Conjunto de caracteres usado no documento de entrada (se esse não
for especificado, será tentado a detecção do
documento de entrada).
- file_out_name
($)
- Nome de arquivo no qual nós deveríamos escrever o documento
de saída.
- file_out_charset
($)
- Conjunto de caracteres usado no documento de saída (se esse
não for especificado, será usado o conjunto de caracteres do
arquivo PO).
- po_in_name
(@)
- Lista de nomes de arquivos dos quais nós deveríamos ler os
arquivos PO de entrada, contendo a tradução que será
usada para traduzir o documento.
- po_out_name
($)
- Nome de arquivo no qual nós deveríamos escrever o arquivo PO
de saída, contendo as strings extraídas do documento de
entrada.
- addendum (@)
- Lista de nomes de arquivos nos quais nós deveríamos ler os
adendos.
- addendum_charset
($)
- Conjunto de caracteres para o adendos.
- new(%)
- Cria um novo documento de po4a. Opções aceitas são
(mas devem estar em um hash):
Manipulação de arquivos de documento
- read($)
- Adiciona dados de outro documento de entrada ao final do vetor
"@{$self->{TT}{doc_in}}" existente. O
argumento é o nome de arquivo para ler.
Esse vetor
"@{$self->{TT}{doc_in}}"
detém os dados desse documento de entrada como um vetor e strings
com significados alternativos.
* A string $textline detendo cada linha de dados
de texto de entrada.
* A string "$filename:$linenum" detendo
sua localização e chamada
como "referência".
Por favor note que ele analisa nada. Você deveria usa a
função parse() quando você acabar de
empacotar os arquivos de entrada no documento.
Note que $linenum inicia como 1.
- write($)
- Escreve o documento traduzido no nome de arquivo fornecido.
Os dados desse documento traduzido são fornecidos por:
* "$self->docheader()" detendo o
texto de cabeçalho para o plugin, e
* "@{$self->{TT}{doc_out}}" detendo
cada linha do principal texto traduzido no vetor.
Manipulação de arquivos PO
- readpo($)
- Adiciona o conteúdo de um arquivo, cujo nome é passado como
argumento, ao PO de entrada existente. O conteúdo antigo é
descartado.
- writepo($)
- Escrever o arquivo PO extraído para o nome de arquivo
fornecido.
- stats()
- Retorna algumas estatísticas sobre a tradução
realizada até o mesmo. Por favor, note que não são as
mesmas estatísticas mostradas pelo "msgfmt --statistic".
Aqui, são as estatísticas sobre uso recente do arquivo PO,
enquanto o msgfmt relata o status do arquivo. Ele é um wrapper da
função Locale::Po4a::Po::stats_get aplicada ao arquivo PO de
entrada. Exemplo de uso:
[uso normal de um documento po4a...]
($percent,$hit,$queries) = $document->stats();
print "Nós encontramos de $percent\% ($hit de $queries) das strings.\n";
- is_po_uptodate()
- Retorna ($uptodate, $diagnostic), sendo que
$uptodate é se o po de entrada e o po de
saída coincidem (se não, significa que o po de entrada deve
ser atualizado) e $diagnostic é uma string
explicando por que o arquivo po não está atualizado, quando
isso acontece.
- addendum($)
- Por favor veja o po4a(7) para mais informações sobre
o que são adendos e como tradutores deveriam escrevê-los.
Para aplicar um adendo ao documento traduzido, simplesmente passe seu nome
de arquivo para essa função e pronto ;)
Essa função retorna um inteiro não nulo
quando há um erro.
FUNÇÕES INTERNAS usadas para escrever analisadores
derivados
Quatro funções são fornecidas para obter
entrada e retornar a saída. Elas são muito parecidas com
shift/unshift e push/pop de Perl.
* Perl shift retorna o primeiro item do vetor e solta-o do vetor.
* Perl unshift preenche um item no vetor como o primeiro item do vetor.
* Perl pop retorna o último item do vetor e solta-o do vetor.
* Perl push acrescenta um item ao vetor como o último item do vetor.
O primeiro par é sobre entrada, enquanto ao segundo
é sobre saída. Mnemônico: na entrada, você
está interessada na primeira linha, que é o que o shift
fornece, e na saída você quer adicionar seu resultado ao
final, como o push faz.
- shiftline()
- Esta função retorna a primeira linha a ser analisada e a sua
referência correspondente (empacotada como um vetor) do vetor
"@{$self->{TT}{doc_in}}" e descarta
estes 2 primeiros itens do vetor. Aqui, a referência é
fornecida por uma string
"$filename:$linenum".
- unshiftline($$)
- Executa unshift a última linha "shiftada" do documento de
entrada e sua referência correspondente de volta para o
cabeçalho de
"{$self->{TT}{doc_in}}".
- pushline($)
- Envia uma nova linha para o fim de
"{$self->{TT}{doc_out}}".
- popline()
- Volta, do fim de
"{$self->{TT}{doc_out}}", a linha
anteriormente enviada.
Uma função é fornecida para manipular o texto
que deveria ser traduzido.
- translate($$$)
- Argumentos obrigatórios:
- Uma string para traduzir
- A referência dessa string (i.e. posição no arquivo de
entrada)
- O tipo dessa string (i.e. a descrição textual de seu papel
estrutural; usado em Locale::Po4a::Po::gettextization(); veja
também po4a(7), seção
Gettextização: como ela funciona?)
Essa função também pode levar alguns
argumentos extras. Eles devem ser organizados como um hash. Por exemplo:
$self->translate("string","ref","type",
'wrap' => 1);
- wrap
- booleano indicando se nós podemos considerar que espaços em
brancos nas strings não são importantes. Se sim, a
função canoniza a string antes de procurar por uma
tradução ou de extrair, e dimensiona a
tradução.
- wrapcol
- a coluna na qual nós deveríamos dimensionar (padrão:
76).
- um comentário extra para adicionar ao registro.
Ações:
- Envia a string, referência e tipo para po_out.
- Retorna a tradução da string (como encontrado em po_in) de
forma que o analisador pode compilar o doc_out.
- Manipula os conjuntos de caracteres para re-codificar as strings antes de
enviá-las para po_out e antes de retornar as
traduções.
- verbose()
- Retorna se a opção de detalhamento foi passada durante a
criação do TransTractor.
- debug()
- Retorna se a opção de depuração foi passada
durante a criação do TransTractor.
- detected_charset($)
- Isso fala para o TransTractor que um novo conjunto de caracteres (o
primeiro argumento) foi detectado no documento de entrada. Ele normalmente
pode ser lido do cabeçalho do documento. Apenas o primeiro conjunto
de caracteres restará, vindo com os argumentos de process()
ou detectado do documento.
- get_out_charset()
- Essa função vai retornar o conjunto de caracteres que
deveria ser usado no documento do entrada (normalmente útil para
substituir o conjunto de caracteres detectado no documento de entrada,
onde ele foi encontrado).
Ele vai usar o conjunto de caracteres de saída
especificado na linha de comando. Se não tiver sido especificado,
ele vai usar o conjunto de caracteres do PO de entrada, e se o PO de
entrada possuir o "CHARSET" padrão, ele vai retornar o
conjunto de caracteres do documento de entrada, de forma que nenhuma
codificação é realizada.
- recode_skipped_text($)
- Essa função retorna o texto re-codificado passado como
argumento, do conjunto de caracteres do documento de entrada para o do
documento de saída. Isso não é necessário
quando se está traduzindo uma string (o próprio
translate() re-codifica tudo), mas é necessário
quando você ignora uma string do documento de entrada e você
deseja que o documento de saída seja consistente com a
codificação global.
Um problema do atual TransTractor é que ele não
consegue manipular documento traduzido contendo todos idiomas, como modelos
de debconf, ou arquivos .desktop.
Para resolver esse problema, as únicas
alterações necessárias na interface são:
Veremos se isso é o suficiente ;)
Denis Barbier <barbier@linuxfr.org>
Martin Quinson (mquinson#debian.org)
Jordi Vilalta <jvprat@gmail.com>