Scroll to navigation

Locale::Po4a::TransTractor(3pm) Ferramentas do Po4a Locale::Po4a::TransTractor(3pm)

NOME

Locale::Po4a::TransTractor - extrator de tradução genérico.

DESCRIÇÃO

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

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

SINOPSE

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>"
                             . $self->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.

INTERFACE PÚBLICA para scripts usando seu analisador

Construtor

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:
Lê todos os arquivos PO especificados em po_in_name
Lê todos os documentos originais especificados em file_in_name
Analisa o documento
Lê e aplica todos os adendos especificados
Escreve o documento traduzido para file_out_name (se fornecido)
Escreve o arquivo PO extraído para po_out_name (se fornecido)

ARGUMENTOS, além dos aceitos por new() (com o tipo esperado):

Lista de nomes de arquivos nos quais nós deveríamos ler o documento de entrada.
Conjunto de caracteres usado no documento de entrada (se esse não for especificado, será tentado a detecção do documento de entrada).
Nome de arquivo no qual nós deveríamos escrever o documento de saída.
Conjunto de caracteres usado no documento de saída (se esse não for especificado, será usado o conjunto de caracteres do arquivo PO).
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.
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.
Lista de nomes de arquivos nos quais nós deveríamos ler os adendos.
Conjunto de caracteres para o adendos.
Cria um novo documento de po4a. Opções aceitas são (no hash passado como parâmetro):
Define o detalhamento.
Define a depuração.

Manipulação de arquivos de documento

Adiciona dados de outro documento de entrada ao final do vetor "@{$self->{TT}{doc_in}}" existente. O argumento é o nome de arquivo para ler. Se um segundo argumento é fornecido, ele é o nome de arquivo para usar em referências.

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" ("linenum" inicia com 1).

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.

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

Adiciona o conteúdo de um arquivo, cujo nome é passado como argumento, ao PO de entrada existente. O conteúdo antigo é descartado.
Escrever o arquivo PO extraído para o nome de arquivo fornecido.
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";
    

Manipulando adendos

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

Obtendo a entrada, fornecendo a saída

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.

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".
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}}".
Envia uma nova linha para o fim de "{$self->{TT}{doc_out}}".
Volta, do fim de "{$self->{TT}{doc_out}}", a linha anteriormente enviada.

Marcando strings como traduzíveis

Uma função é fornecida para manipular o texto que deveria ser traduzido.

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

Funções miscelânea

Retorna se a opção de detalhamento foi passada durante a criação do TransTractor.
Retorna se a opção de depuração foi passada durante a criação do TransTractor.
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.
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.

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.

DIREÇÕES FUTURAS

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:

  • pegar um hash como po_in_name (uma lista por idioma)
  • adicionar um argumento para traduzir para indicar o idioma alvo
  • fazer uma função pushline_all, que deveria fazer pushline de seu conteúdo para todos idiomas, usando uma sintaxe tipo mapa:

        $self->pushline_all({ "Description[".$langcode."]=".
                              $self->translate($line,$ref,$langcode)
                            });
        

Veremos se isso é o suficiente ;)

AUTORES

 Denis Barbier <barbier@linuxfr.org>
 Martin Quinson (mquinson#debian.org)
 Jordi Vilalta <jvprat@gmail.com>
2023-01-03 Ferramentas do Po4a