Provided by: po4a_0.52-1_all 

NOME
po4a - framework para traduzir documentação e outros materiais
Introdução
A missão do projeto po4a (em inglês, PO for anything) é facilitar as traduções (e o mais interessante, a
manutenção de traduções) usando ferramentas de gettext em áreas onde elas não eram esperadas, como
documentação.
Sumário
Esse documento é organizado da seguinte forma:
1 Por que eu deveria usar po4a? O que tem de bom nele?
Este capítulo introdutório explica a motivação do projeto e sua filosofia. Você deveria ler este
primeiro, se você está em processo de avaliação do po4a para suas próprias traduções.
2 Como usar po4a?
Este capítulo é um tipo de manual de referência, tentando responder as perguntas dos usuários e dar a
você um entendimento melhor do processo como um todo. Ele introduz como fazer coisas com po4a e serve
como uma introdução à documentação das ferramentas específicas.
COMO começar uma nova tradução?
COMO alterar a tradução de volta para um arquivo de documentação?
COMO atualizar uma tradução de po4a?
COMO converter uma tradução pré-existente para po4a?
COMO adicionar um texto extra às traduções (ex.: nome do tradutor)?
COMO fazer tudo isso em uma invocação de programa?
COMO personalizar o po4a?
3 Como ele funciona?
Este capítulo dá a você uma visão geral da parte interna do po4a, de forma que você pode se sentir
mais confiante para nos ajudar a manter e melhorá-lo. ele também pode ajudá-lo a entender o porquê de
ele não funcionar da forma que você esperava, e como resolver seus problemas.
4 FAQ
Este capítulo agrupa as perguntas frequentes (FAQ). Na verdade, a maioria das perguntas até agora
puderam ser formuladas dessa forma: "Porque ele é projetado dessa forma e não dessa outra?" Se você
pensa que po4a não é a resposta correta para tradução de documentação, você deveria considerar ler
esta seção. Se ele não responder suas perguntas, por favor entre em contato conosco na lista de
discussão <po4a-devel@lists.alioth.debian.org>. Nós adoramos feedback.
5 Notas específicas sobre módulos
Este capítulo apresenta as especificidades de cada módulo do ponto de vista do autor original e do
tradutor. Leia isso para aprender a sintaxe que você vai encontrar ao traduzir as coisas neste
módulo, ou as regras que você deveria ser no seu documento original para tornar a vida dos tradutores
mais fácil.
Na verdade, essa seção não é realmente parte desse documento. Ao invés disso, ela é colocada na
documentação de cada módulo. Isso ajuda a assegurar que a informação está atualizada mantendo a
documentação e o código juntos.
Por que eu deveria usar po4a? O que tem de bom nele?
Eu gosto da ideia de software de código aberto, tornando possível para todos acessar o software e seu
código fonte. Mas por ser francês, estou ciente de que a licença não é a única restrição à abertura do
software: um software livre não traduzido é inútil para aqueles que não sabem inglês e, então, nós ainda
temos mais trabalho para disponibilizar para realmente todo mundo por aí.
A percepção dessa situação aos atores do código do aberto tem melhorado drasticamente nos últimos tempos.
Nós, como tradutores, vencemos a primeira batalha e convencemos a todos a importância da tradução. Mas,
infelizmente, essa era uma parte fácil. Agora, nós temos que fazer o trabalho e realmente traduzir todas
essas coisas.
Na verdade, softwares de código aberto se beneficiam de um nível decente de tradução, graças a
maravilhosa suíte de ferramentas do gettext. Ele é capaz de extrair as strings para traduzir a partir do
programa, apresentar um formato uniforme para tradutores e, então, usar o resultado do seus trabalhos em
tempo de execução para exibir mensagens traduzidas para o usuário.
Mas a situação é um pouco diferente quando se trata de documentação. Com muita frequência, a documentação
traduzida não é visível o suficiente (não distribuída como uma parte do programa), apenas parcialmente,
ou não atualizada. Esta última situação é de longe a pior possível. Tradução desatualizada pode se tornar
pior do que nenhuma tradução para os usuários ao descrever comportamento antigo do programa, que não é
mais usado.
O problema para resolver
Tradução de documentação não é muito difícil em si. Textos são bem maiores do que as mensagens do
programa e, portanto, demoram mais para se alcançar, mas nenhuma habilidade técnica é realmente
necessária para isso. A parte difícil aparece quando você tem que manter o seu trabalho. A detecção de
quais partes mudaram e a necessidade de se manter atualizada é muito difícil, propensa a erro e muito
desagradável. Eu acho que isso explica o porquê de várias documentações por aí estão desatualizadas.
As respostas do po4a
Então, a função do po4a é tornar a tradução de documentação manutenível. A ideia é reusar a metodologia
do gettext para esse novo campo. Assim como no gettext, textos são extraídos de suas localizações
originais para estar presente em um formato uniforme para os tradutores. As ferramentas clássicas do
gettext os ajudam a atualizar seus trabalhos quando um novo lançamento do original surge. Mas para
diferenciar do modelo clássico do gettext, as traduções são, então, reinjetadas na estrutura do documento
original de forma que elas podem ser processadas e distribuídas igual como a versão em inglês.
Graças a isso, a descoberta de quais partes do documento foram alteradas e que precisam ser atualizadas
se torna mais fácil. Outra coisa boa é que as ferramentas vão fazer a maior parte do trabalho quando a
estrutura do documento original estiver fundamentalmente reorganizado e quando alguns capítulos tiverem
sido movidos, mesclados ou divididos. Ao extrair o texto para traduzir da estrutura do documento, ele
também afasta você da complexidade da formatação do texto e reduz suas chances de acabar com um documento
quebrado (mesmo que ele não previna completamente você de fazer isso).
Por favor, veja também o FAQ abaixo neste documento para uma lista mais completa de vantagens e
desvantagens desta abordagem.
Formatos suportados
Atualmente, essa abordagem tem sido implementada com sucesso em vários formatos de formatação de texto:
man
O bom e velho formato de páginas de manual, usado por tantos programas por aí. O suporte do po4a é muito
bem-vindo, considerando que esse formato é de certa forma difícil de usar e não exatamente amigável para
novatos. O módulo Locale::Po4a::Man(3pm) também possui suporte ao formato mdoc, usado pelas páginas de
manual do BSD (elas também são bens comuns no Linux).
pod
Esse é o formato da documentação online de Perl, ou Perl Online Documentation. A própria linguagem e
extensões são documentadas dessa forma, assim como a maioria dos scripts Perl existentes. Isso facilita a
manter a documentação ferto do real código embutindo-os no mesmo arquivo. Isso torna a vida dos
programadores mais fácil, mas infelizmente, não a do tradutor.
sgml
Mesmo se de certa forma tenha sido substituído nos dias de hoje pelo XML, esse formato ainda é usado com
certa frequência por documentos que são maiores do algumas telas. Ele permite que você faça livros
completos. Atualizar a tradução de documentos grandes pode se mostrar ser um verdadeiro pesadelo. diff se
mostra frequentemente inútil quando o texto original foi recuado depois da atualização. Por sorte, po4a
pode ajudar você nesse processo.
Atualmente, há suporte apenas ao DebianDoc e o DocBook DTD, mas a adição de suporte a um novo é realmente
fácil. É possível até mesmo usar po4a em um SGML DTD desconhecido sem alterar o código, desde que sejam
fornecidas as informações necessárias na linha de comando. Veja Locale::Po4a::Sgml(3pm) para mais
detalhes.
TeX / LaTeX
O formato LaTeX é um formato de documentação mais usado no mundo de software livre e para publicações. O
módulo Locale::Po4a::LaTeX(3pm) foi testado com a documentação do Python, um livro e algumas
apresentações.
texinfo
Toda a documentação do GNU é escrita neste formato (esse é até mesmo um dos requisitos para se tornar um
projeto GNU oficial). O suporte a Locale::Po4a::Texinfo(3pm) no po4a ainda está nas fases iniciais. Por
favor relate eventuais erros e requisição por recursos.
xml
O formato XML é um formato base para muitos formatos de documentação.
Atualmente, po4a possui suporte a DocBook DTD. Veja Locale::Po4a::Docbook(3pm) para mais detalhes.
outros
Po4a também pode manipular alguns formatos mais raros ou especializados, como a documentação de opções de
compilação dos kernels Linux 2.4+ ou diagramas produzidos pela ferramenta Dia. A adição de um novo
formato é normalmente muito fácil e a tarefa principal é fazer um analisador do seu formato alvo. Veja
Locale::Po4a::TransTractor(3pm) para mais informações sobre isso.
Formatos sem suporte
Infelizmente, po4a ainda não tem suporte a vários formatos de documentação.
Há uma grande quantidade de formatos que nós gostaríamos que po4a tivesse suporte, e não somente de
documentação. Realmente, nós miramos em acertar todos os "furos de mercado" deixados pelas ferramentas
clássicas do gettext. Isos envolve descrições de pacotes (deb e rpm), perguntas de scripts de instalação
de pacotes, changelogs de pacotes e todos formatos de arquivo especializados como cenários de jogos e
arquivos de recursos do wine.
Como usar po4a?
Este capítulo é um tipo de manual de referência, tentando responder as perguntas dos usuários e dar a
você um entendimento melhor do processo como um todo. Ele introduz como fazer coisas com po4a e serve
como uma introdução à documentação das ferramentas específicas.
Visão geral gráfica
O esquema a seguir dá uma visão geral do processo de tradução de documentação usando po4a. Não tenha medo
pela sua complexidade aparente, pois ela vem do fato de que todo o processo está representado aqui. Assim
que você tiver convertido seu projeto para po4a, apenas a parte da direita é relevante.
Note que mestre.doc é tido como um exemplo de documentação a ser traduzida e tradução.doc é o texto
tradução correspondente. O sufixo poderia ser .pod, .xml ou .sgml, dependendo do seu formato. Cada parte
da imagem será detalhada nas próximas seções.
mestre.doc
|
V
+<-----<----+<-----<-----<--------+------->-------->-------+
: | | :
{tradução} | { atualização de mestre.doc } :
: | | :
XX.doc | V V
(opcional) | mestre.doc ->-------->------>+
: | (novo) |
V V | |
[po4a-gettextize] doc.XX.po---->+ | |
| (velho) | | |
| ^ V V |
| | [po4a-updatepo] |
V | | V
tradução.pot ^ V |
| | doc.XX.po |
| | (incerto) |
{ tradução } | | |
| ^ V V
| | {edição manual} |
| | | |
V | V V
doc.XX.po --->---->+<---<-- doc.XX.po adendo mestre.doc
(inicial) (atualizado) (opcional) (atualizado)
: | | |
: V | |
+----->----->----->------> + | |
| | |
V V V
+------>-----+------<------+
|
V
[po4a-translate]
|
V
XX.doc
(atualizado)
Na parte da esquerda, a conversão de uma tradução não usando po4a para esse sistema é mostrada. No topo
da parte da direita, a ação do autor original está descrita (atualização da documentação). O meio da
parte da direita é onde as ações automáticas do po4a estão descritas. Os novos materiais são extraídos e
comparados com a tradução existente. Partes que não foram alteradas são encontradas e a tradução anterior
é usada. Partes que foram parcialmente modificadas também são conectadas à tradução anterior, mas com uma
marcação indicando que a tradução deve ser atualizada. A parte inferior da figura mostra como um
documento formatado é compilado.
Na verdade, como um tradutor, a única operação manual que você tem que fazer é a parte marcada {edição
manual}. Sim, me desculpe, mas o po4a ajuda você a traduzir. Ele não traduz para você...
COMO começar uma nova tradução?
Esta seção apresenta as etapas necessárias para começar uma nova tradução com po4a. Os refinamentos
envolvidos na conversão de um projeto existente para esse sistema estão detalhados na seção relevante.
Para começar uma nova tradução usando po4a, você tem que seguir as etapas a seguir:
- Extraia o texto que você tem que ser traduzido do documento <mestre.doc> original para um arquivo do
novo modelo de tradução <tradução.pot> (o formato gettext). Para isso, use o programa po4a-gettextize
desta forma:
$ po4a-gettextize -f <formato> -m <mestre.doc> -p <tradução.pot>
<formato> normalmente é o formato usado no documento mestre.doc. Como esperado, a saída vai para
tradução.pot. Por favor, veja po4a-gettextize(1) para mais detalhes sobre as opções existentes.
- Realmente traduza o que deveria ser traduzido. Para isso, você tem que renomear o arquivo POT para, por
exemplo, doc.XX.po (sendo XX o código ISO 639-1 do idioma para o qual você está traduzindo, ex.: fr
para francês) e edite o arquivo resultante. Normalmente, é uma boa ideia não nomear o arquivo XX.po
para evitar confusão com a tradução das mensagens do programa, mas a decisão é sua. Não se esqueça de
atualizar os cabeçalhos dos arquivos PO, pois eles são importantes.
A tradução pode ser feita ser feita usando o modo PO do Emacs ou do, Lokalize (baseado no KDE),
Gtranslator (baseado no GNOME) ou qualquer outro programa que você preferir usar para isso (ex.:
Virtaal).
Se você prefere aprender mais sobre isso, você definitivamente precisa ver a documentação do gettext,
disponível no pacote gettext-doc.
COMO alterar a tradução de volta para um arquivo de documentação?
Assim que você finalizar com a tradução, você quer pegar a documentação traduzida e distribuí-la para os
usuários junto com o original. Para isso, use o programa po4a-translate(1) dessa forma (sendo XX o código
do idioma):
$ po4a-translate -f <formato> -m <mestre.doc> -p <doc.XX.po> -l <XX.doc>
Como antes, <formato> é o formato usado no documento mestre.doc. Mas dessa vez, o arquivo PO fornecido
com a opção -p é parte da entrada. Essa é a sua tradução. A saída vai para XX.doc.
Por favor, veja po4a-translate(1) para mais detalhes.
COMO atualizar uma tradução de po4a?
Para atualizar sua tradução quando o arquivo original mestre.doc foi alterado, use o programa
po4a-updatepo(1) dessa forma:
$ po4a-updatepo -f <formato> -m <novo_mestre.doc> -p <doc_antigo.XX.po>
(Por favor, veja po4a-updatepo(1) para mais detalhes)
Normalmente, o novo parágrafo no documento não será traduzido magicamente no arquivo PO com esta operação
e você vai precisar atualizar o arquivo PO manualmente. Da mesma forma, você pode ter que retrabalhar a
tradução por parágrafos que foram um pouco modificados. Para certificar-se de que você vai perder nenhum
deles, eles são marcados como "fuzzy" (aproximado) durante o processo e você tem que remover essa
marcação antes que a tradução possa ser usada por po4a-translate. como a tradução inicial, o melhor a se
fazer é usar aqui o seu editor de PO favorito.
Assim que seu arquivo PO estiver atualizado novamente, sem qualquer string não traduzida ou incerta, você
pode gerar um arquivo de documentação traduzida, como explicado na seção anterior.
COMO converter uma tradução pré-existente para po4a?
Geralmente, você costumava traduzir manualmente a documentação até que uma grande reorganização do
mestre.doc original aconteceu. Então após algumas tentativas desagradáveis com diff ou ferramentas
similares, você quer converter para po4a. Mas, é claro, você não quer perder sua tradução existente no
processo. Não se preocupe, esse caso também é manipulado pelas ferramentas do po4a e é chamado de
gettextização.
A chave aqui é ter a mesma estrutura no documento traduzido e no original, de forma que as ferramentas
possam conferir o conteúdo corretamente.
Se você tiver sorte (isso é, se as estruturas de ambos documentos corresponderem perfeitamente), isso vai
funcionar de forma transparente e você vai estar pronto em poucos segundos. Do contrário, você pode
entender o porquê desse processo ter um nome tão feito, e é bom que você esteja preparado para um
trabalho suado aqui. Em qualquer caso, lembre-se de que o preço a se pagar pelo conforto do po4a
posteriormente. E o lado bom é que você só tem que fazer isso uma vez.
Eu não consigo enfatizar isso muito. Para facilitar o processo, é, então, importante que você localize a
versão exata que foi usada para a tradução. A melhor situação é quando você anotou a revisão no sistema
de controle de versão usada para a tradução e não modificou o seu processo de tradução de forma que você
possa usá-lo.
Vai funcionar melhor quando você usar um texto original atualizado com a tradução antiga. Ainda é
possível, mas é mais difícil e realmente deveria ser evitado, se possível. Na verdade, creio que se você
não conseguir localizar o texto original novamente, a melhor solução é localizar alguém para fazer a
gettextização para você (mas, por favor, não eu ;).
Talvez eu esteja sendo muito dramático. Mesmo quando as coisas dão errado, ainda há formas mais rápidas
do que traduzir tudo de novo. Eu consegui gettextizar a tradução para francês existente da documentação
do Perl em um dia, mesmo as coisas tenham dado errado. Aquilo foi mais do que 2 megabytes de texto, e uma
nova tradução demoraria meses ou mais.
Deixe-me explicar a base do procedimento primeiro e eu vou voltar com dicas para concluir quando o
processo dá errado. Para facilitar a compreensão, vamos usar o exemplo acima novamente.
Assim que você tiver mestre.doc antigo novamente, o qual corresponde com a tradução XX.doc, a
gettextização pode ser feita diretamente ao arquivo PO doc.XX.po sem tradução manual do arquivo
tradução.pot:
$ po4a-gettextize -f <formato> -m <mestre antigo.doc> -l <XX.doc> -p <doc.XX.po>
Quando você tiver sorte, é só isso. Você converteu sua tradução antiga para po4a e pode começar a tarefa
de atualização agora mesmo. Basta seguir o procedimento explicado algumas seções atrás para sincronizar
seu arquivo PO com o documento original mais novo e atualizar a tradução.
Por favor, note que mesmo quando as coisas parecem funcionar adequadamente, ainda há espaços para erros
neste processo. A questão é que po4a não é capaz de entender o texto para certificar-se de que a tradução
corresponde com o original. É por isso que todas as strings serão marcadas como "fuzzy" no processo. Você
deveria verificar cada uma cuidadosamente antes de remover essas marcações.
Com frequência as estruturas do documento não correspondem exatamente, evitando po4a-gettextize de fazer
seu trabalho adequadamente. A essa altura, o jogo em questão é sobre editar os arquivos para fazer com
que suas estruturas correspondam.
Pode ser uma ajuda ler a seção Gettextização: como ela funciona? abaixo. Entender o processo interno
pode ajudar você a fazer o seu trabalho. O lado positivo é que po4a-gettextize é bem detalhista sobre o
que deu errado quando isso acontece. Primeiro, ele indica onde nos documentos há discrepância na
estrutura. Você vai descobrir as strings que não correspondem, suas posições no texto e o tipo de cada
uma delas. Mais ainda, o arquivo PO gerado será despejado para gettextization.failed.po.
- Remove todas as partes extras das traduções, como as seções em que você informa o nome do tradutor e
agradeço a todas as pessoas que contribuíram para a tradução. Adendos, que será descrito na próxima
seção, vai permitir que você adicione-os posteriormente.
- Não hesite em editar ambos o original e a tradução. A coisa mais importante é obter o arquivo PO.
Você poderá atualizá-lo posteriormente. Isto posto, a edição da tradução deveria ser preferida quando
pode-se fazer as duas coisas, pois ela facilita quando a gettextização tiver concluída.
- Se necessário, mate algumas partes do original se elas não tiverem sido traduzidas; Ao se sincronizar
do PO com o documento posteriormente, elas vão voltar por conta própria.
- Se você alterou a estrutura um pouco (para mesclar dois parágrafos ou dividir outro), desfaça aquelas
alterações. Se há problemas no original, você deveria informar o autor original. A correção deles na
sua tradução resolve somente uma parte da comunidade. E além disso, isso é impossível quando se está
usando po4a ;)
- Algumas vezes, o conteúdo do parágrafo não corresponde, mas seus tipos não. Corrigir isso é até
dependente do formato. No POD e man, frequentemente ele vem do fato que um dos dois contém uma linha
começando com espaço em branco, mas a outra não. Naqueles formatos, tal parágrafo não pode ser
dimensionado e, então, se torna um tipo diferente. Basta remover o espaço e está terminado. Pode ser
um erro de escrita no nome da marcação.
Da mesma forma, dois parágrafos podem ser mesclados no POD quando a linha separadora contém alguns
espaços ou quando não há linha vazia entre a linha =item e o conteúdo do item.
- Algumas vezes, há uma dessincronização entre os arquivos e a tradução é anexada ao parágrafo original
incorreto. Isso é um sinal de que o problema real é de antes nestes arquivos. Verifique
gettextization.failed.po para ver quando começa a dessincronização e corrija-a lá.
- Algumas vezes, você tem a sensação de que po4a comeu parte do texto, seja do original seja da
tradução. gettextization.failed.po indica que ambos correspondem gentilmente e, então, a
gettextização falha porque ele tentou corresponder um parágrafo com outro após (ou antes) do correto,
como se o correto tivesse desaparecido. Xingue po4a como eu fiz quando isso aconteceu comigo.
Generosamente.
Essa situação infeliz acontece quando o mesmo parágrafo é repetido no documento. Nesse caso, nenhuma
nova entrada é criada no arquivo PO, mas uma nova referência é adicionada ao já existente.
Então, quando o mesmo parágrafo aparece duas vezes no original, mas ambos não estão traduzidos da
mesma forma cada vez, você terá a sensação de que um parágrafo do original desapareceu. Basta matar a
nova tradução. Se, ao invés disso, você preferir matar a primeira tradução quando a segunda estiver
melhor, substitua a primeira pela segunda.
Do contrário, se dois parágrafos similares, mas diferentes, foram traduzidos na mesma forma, você
terá a sensação de que um parágrafo da tradução desapareceu. Uma solução é adicionar a estúpida da
string ao parágrafo original (do tipo "Sou diferente"). Não tenha medo, aquelas coisas vão
desaparecer durante a sincronização e quando o texto adicionar for curto o suficiente, gettext vai
corresponder sua tradução ao texto existente (marcando-o como incerto, mas você não se importa se
considerar que todas strings estarão marcadas como incertas após a gettextização).
Com muita esperança, essas dicas vão ajudar você a fazer sua gettextização funcionar e obter seu precioso
arquivo PO. Agora você está pronto para sincronizar seu arquivo e começar sua tradução. Por favor, note
que em um texto largo, pode acontecer de a primeira sincronização demorar um bom tempo.
Por exemplo, o primeiro po4a-updatepo da tradução para francês da documentação do Perl (arquivo PO de 5.5
MB) levou cerca de dois dias completos em um computador G5 de 1GHz. Sim, 48 horas. Mas os subsequentes
demora apenas algumas dezenas de segundos no meu laptop antigo. Isso acontece porque na primeira vez, a
maioria do msgid do arquivo PO não corresponde a qualquer dos arquivos POT. Isso força o gettext a
pesquisar pelos mais próximos usando um custoso algoritmo de proximidade de strings.
COMO adicionar um texto extra às traduções (ex.: nome do tradutor)?
Por causa da abordagem do gettext, fazer isso se torna mais difícil em po4a do que era quando simples
edição de um novo arquivo junto com o original, Mas isso ainda é possível, graças aos famosos adendos.
Pode ajudar a compreensão considerar os adendos como uma espécie de patches aplicados ao documento
localizado após processamento. Eles são meio que diferentes dos patches comuns (eles têm apenas uma linha
de contexto, o que pode embutir expressões regulares de Perl, e podem adicionar apenas novos textos sem
remover algum), mas as funcionalidades são as mesmas.
Seu objetivo é permitir que o tradutor adicione conteúdo extra ao documento que não está traduzido a
partir do documento original. O uso mais comum é adicionar uma seção sobre a tradução em si, listando
contribuidores e explicando como relatar um erro da tradução.
Um adendo deve ser fornecido em um arquivo separado. A primeira linha constitui em um cabeçalho indicando
onde no documento produzido ele deveria ser colocado. O resto do arquivo de adendo será adicionado
literalmente à posição determinada do documento resultante.
O cabeçalho possui uma sintaxe bem rígida: ele deve começar com a string PO4A-HEADER:, seguida por um uma
lista separada por ponto-e-vírgula (;) de campos chave=valor. Espaços em branco SÃO importantes. Note que
se você não puder usar o caractere ponto-e-vírgula (;) no valor e colocar entre aspas não vai ajudar.
Novamente, pode soar assustador, mas os exemplos dados abaixo deve ajudar você a descobrir como escrever
a linha de cabeçalho que você precisa. Para ilustrar a discussão, suponha que nós queremos adicionar uma
seção chamada "Sobre esta tradução" após a de "Sobre este documento".
Arqui estão as chaves de cabeçalho possíveis:
position (obrigatório)
uma regexp (expressão regular) Perl. O adendo será colocado perto da linha correspondendo a esta
regexp. Note que estamos falando do documento traduzido aqui, e não do original. Se mais do que uma
linha corresponder a esta expressão (ou nenhuma), a adição vai falhar. É realmente melhor relatar um
erro do que inserir um adendo na localização incorreta.
Esta linha é chamada de ponto de posição a seguir. O ponto onde o adendo é adicionado é chamado de
ponto de inserção. Esses dois pontos estão perto um do outro, mas não são iguais. Por exemplo, se
você quer inserir uma nova seção, é fácil colocar o ponto de posição no título da seção precedente e
explicar para o po4a onde a seção termina (lembre-se de que ponto de posição é dado por uma regexp
que deveria corresponder a uma única linha).
A localização do ponto de inserção no que se refere ao ponto de posição é controlada pelos campos
mode, beginboundary e endboundary, como explicado abaixo.
No nosso caso, não teríamos:
position=<title>Sobre esse documento</title>
mode (obrigatório)
Pode ser tanto a string antes quanto depois, especificando a posição do adendo, relativa ao ponto de
posição. Caso antes seja fornecida, o ponto de inserção será colocado exatamente antes do ponto de
posição. O comportamento depois é detalhado abaixo.
Já que nós queremos que a nova seção seja colocada abaixo daquela que estamos correspondendo, nós
temos:
mode=after
beginboundary (usado somente quando mode=after e obrigatório neste caso)
endboundary (idem)
regexp correspondendo ao fim da seção após a qual o adendo entra.
Quando mode=after, o ponto de inserção está após o ponto de posição, mas não diretamente após! É
colocado no final da seção começando com o ponto de posição, isto é, após ou antes da linha ter
correspondido ao argumento ???boundary, dependendo de se você usou beginboundary ou endboundary.
No nosso caso, nós podemos escolher indicar o fim da seção que nós correspondemos ao adicionar:
endboundary=</section>
ou indicar o começo da próxima seção ao indicar:
beginboundary=<section>
Em ambos casos, nosso adendo vai ser localizado após </section> e antes de <section>. O primeiro é
melhor já que ele vai funcionar mesmo se o documento for reorganizado.
Ambas formas existem porque os formatos de documentação são diferentes. em alguns deles, há uma forma
de marcar o fim da seção (como o </section> que nós usamos), enquanto alguns outros não marcam
explicitamente o fim da seção (como no man). No primeiro caso, nós queremos fazer um boundary
correspondendo ao fim da seção, de forma que o ponto de inserção venha após este. No segundo caso,
nós queremos fazer um boundary correspondendo o começo da próxima seção, de forma que o ponto de
inserção venha logo antes dele.
Isso pode parecer obscuro, mas esperamos que os próximos exemplos sejam mais claros.
Para resumir o exemplo usado até agora, para adicionar uma seção chamada "Sobre esta tradução" após a de
"Sobre esta documentação" em um documento SGML, você pode usar qualquer uma das linhas de cabeçalho:
PO4A-HEADER: mode=after; position=Sobre este documento; endboundary=</section>
PO4A-HEADER: mode=after; position=Sobre este documento; beginboundary=<section>
Se você quiser adicionar alguma coisa após a seção nroff a seguir:
.SH "AUTHORS"
você deveria colocar uma position correspondendo a esta linha e um beginboundary correspondendo ao
começo da próxima seção (isto é,, ^\.SH). O adendo vai, então, ser adicionado após o ponto de posição e
imediatamente antes da primeira linha correspondendo ao beginboundary. Isso é dizer:
PO4A-HEADER:mode=after;position=AUTHORS;beginboundary=\.SH
Se você quiser adicionar alguma coisa a uma seção (como após "Copyright Grande Cara") ao invés de
adicionar uma seção inteira, forneça um position correspondendo a esta linha e forneça um beginboundary
correspondendo a qualquer linha.
PO4A-HEADER:mode=after;position=Copyright Grande Cara, 2004;beginboundary=^
Se você quiser adicionar alguma coisa ao final do documento, forneça um position correspondendo a
qualquer linha do seu documento (mas apenas uma linha. Po4a não vai proceder se ela não for única), e
forneça um endboundary correspondendo a nada. Não use strings simples aqui como "EOF", e sim prefira
aquelas que possuem menos chance de estar no seu documento.
PO4A-HEADER:mode=after;position=<title>Sobre</title>;beginboundary=FakePo4aBoundary
Em qualquer caso, lembre-se que essas são regexp. Por exemplo, se você quiser corresponder o fim de uma
seção de nroff finalizando com a linha
.fi
não use .fi como endboundary porque ele vai corresponder a "the[ fi]le", o que obviamente não é o que
está esperando. O endboundary correto neste caso é: ^\.fi$.
Se o adendo não for onde você esperava, tente passar o argumento -vv para as ferramentas, de forma que
elas expliquem a você o que estão fazendo enquanto inserem o adendo.
Exemplo mais detalhado
Documento original (formatado em POD):
|=head1 NAME
|
|dummy - a dummy program
|
|=head1 AUTHOR
|
|me
Então, o adendo a seguir vai assegurar que a seção (em Francês) sobre o tradutor seja adicionado ao final
do arquivo. (em Francês, "TRADUCTEUR" significa "TRADUTOR", e "moi" significa "eu")
|PO4A-HEADER:mode=after;position=AUTEUR;beginboundary=^=head
|
|=head1 TRADUCTEUR
|
|moi
|
Para colocar seu adendo antes do AUTHOR, use o seguinte cabeçalho:
PO4A-HEADER:mode=after;position=NOM;beginboundary=^=head1
Isso funciona porque a próxima linha correspondendo ao beginboundary /^=head1/ após a seção "NAME"
(traduzido para "NOM" em Francês) é aquela declarando os autores. Então, o adendo será colocado entre as
duas seções. Note que se mais tarde alguma outra seção for adicionada entre NAME e AUTHOR, ele irá
quebrar este exemplo, fazendo com que os adendos sejam adicionados antes desta seção recém adicionada.
Para evitar isto, você pode realizar o mesmo usando modo=depois:
PO4A-HEADER:mode=before;position=^=head1 AUTEUR
COMO fazer tudo isso em uma invocação de programa?
O uso do po4a provou ser um pouco propenso a erros para usuários considerando que você tem que chamar
dois programas diferentes na ordem correta (po4a-updatepo e então po4a-translate), cada um deles
precisando de mais do que 3 argumentos. Além disso, era difícil com este sistema usar apenas um arquivo
PO para todos os seus documentos quando mais de um formato era usado.
O programa po4a(1) foi projetado para resolver essas dificuldades. Assim que seu projeto tiver sido
convertido para o sistema, você escreve um simples arquivo de configuração explicando onde seus arquivos
de tradução estão (PO e POT), onde os documentos originais estão, seus formatos e onde suas traduções
devem ser colocadas.
Então, ao chamar po4a(1) com este arquivo assegura que os arquivos PO são sincronizados com o documento
original e que os documentos traduzidos sejam gerados adequadamente. É claro que você vai querer chamar
este programa duas vezes: uma antes da edição dos arquivos PO para atualizá-los e mais uma vez em seguida
para obter um documento traduzido completamente atualizado. Mas você só precisa se lembrar de uma linha
de comando.
COMO personalizar o po4a?
Módulos do po4a possuem opções (especificadas com a opção -o) que podem ser usadas para alterar o
comportamento do módulo.
Você também pode editar o código fonte dos módulos existentes ou até mesmo escrever seus próprios
módulos. Para torná-los visíveis ao po4a, copie seus módulos para o caminho
"/bli/blah/blu/lib/Locale/Po4a/" e adicione o caminho "/bli/blah/blu" na variável de ambiente "PERLIB" ou
"PERL5LIB". Por exemplo:
PERLLIB=$PWD/lib po4a --previous po4a/po4a.cfg
Nota: o nome real do diretório lib não é importante.
Como ele funciona?
Este capítulo dá a você uma visão geral da parte interna do po4a, de forma que você pode se sentir mais
confiante para nos ajudar a manter e melhorá-lo. ele também pode ajudá-lo a entender o porquê de ele não
funcionar da forma que você esperava, e como resolver seus problemas.
Qual é a jogada aqui?
A arquitetura do po4a é orientada a objeto (em Perl. Isso não é legal?). O antepassado comum para todas
as classes analisadoras é chamado de TransTractor. Esse nome estranho vem do fato que ele é ao mesmo
tempo o encarregado por tradução de documento e extração de strings.
Mais formalmente, ele pega um documento para traduzir mais um arquivo PO contendo as traduções para usar
como entrada, enquanto produz duas saídas separadas: outro arquivo PO (resultante da extração das strings
traduzíveis do documento de entrada) e um documento traduzido (com a mesma estrutura daquele de entrada,
mas com todas as strings traduzíveis substituídas com o conteúdo do PO de entrada). Aqui está uma
representação gráfica disso:
Doc. de entrada --\ /---> Doc. de saída
\ TransTractor:: / (traduzido)
+-->-- parse() --------+
/ \
PO de entrada ----/ \---> PO de saída
(extraído)
Esse pequeno osso é o núcleo de toda arquitetura do po4a. Se você omitir o PO de entrada e o documento de
saída, você obtém po4a-gettextize. Se você fornecer ambos arquivos de entrada e desconsiderar o PO de
saída, você obtém po4a-translate.
TransTractor::parse() é uma função virtual implementada por cada módulo. Aqui está um pequeno exemplo
para mostrar a você como ela funciona. Ela analisa uma lista de parágrafos, um de cada vez com <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; # Não conseguiu uma linha definida? Fim do arquivo de entrada.
19 }
20 }
Na linha 6, nós encontramos <p> pela segunda vez. Esse é o sinal de próximo parágrafo. Nós deveríamos,
então, colocar a linha que acabamos de obter de volta no documento original (linha 7) e jogar o parágrafo
adquirido até agora para as saídas. Após remover o <p> do começo do parágrafo na linha 9, nós realizamos
a concatenação dessa marcação com a tradução do resto do parágrafo.
Essa função translate() é muito legal. Ela joga o argumento para o arquivo PO de saída (extração) e
retorna sua tradução da forma como encontrada no arquivo PO de entrada (tradução). Considerando que é
usada como parte do argumento de pushline(), essa tradução acaba dentro do documento de saída.
Isso não é legal? É possível compilar um módulo po4a completo em menos de 20 segundos quando o formato é
simples o suficiente...
Você pode aprender mais sobre isso en Locale::Po4a::TransTractor(3pm).
Gettextização: como ela funciona?
A ideia aqui é pegar o documento original e sua tradução, e dizer que a enésima string extraída da
tradução é a tradução da enésima string extraída do original. Para que isso funcione, ambos arquivos
devem compartilhar exatamente a mesma estrutura. Por exemplo, se os arquivos possui a estrutura a seguir,
é improvável que a 4ª string na tradução (do tipo "capítulo") seja a tradução da 4ª string no original
(do tipo "parágrafo").
Original Tradução
capítulo capítulo
parágrafo parágrafo
parágrafo parágrafo
parágrafo capítulo
capítulo parágrafo
parágrafo parágrafo
Para isso, analisadores po4a são usados em ambos arquivos original e tradução para extrair arquivos PO e,
então, um terceiro arquivo PO é compilado deles pegando as mensagens do segundo como tradução das strings
do primeiro. Para confirmar que as strings que nós colocamos juntas são realmente as traduções de cada
um, os analisadores de documento no po4a deveria colocar informação sobre o tipo sintático das strings
extraídas do documento (todos existentes fazem isso, os seus devem fazer também). Então, essa informação
é usada para certificar-se de que ambos documentos possuem a mesma sintaxe. O exemplo anterior, ele nos
permitiria detectar que a string 4 é um parágrafo em um caso, e no outro é um título de capítulo e
relatar o problema.
Em teoria, seria possível detectar o problema e sincronizar novamente os arquivos em seguida (assim como
o diff faz). Mas o que nós deveríamos fazer com as poucas strings antes da dessincronização não é muito
claro, e isso poderia produzir resultados indesejáveis em algumas situações. É por isso que a
implementação atual não tenta sincronizar novamente e falha com detalhes quando alguma coisa dá errado,
exigindo modificação manual dos arquivos para corrigir o problema.
Mesmo com essas precauções, coisas podem dar errado facilmente aqui. É por isso que todas as traduções
presumidas dessa forma são marcadas como incertas, para certificar de que o tradutor reveja e verifique-
as.
Adendo: como ele funciona?
Bom, isso é bem simples. O documento traduzido não é escrito diretamente, mas é mantido na memória até
que os adendos são aplicados. Os algoritmos envolvidos são até que simples. Nós procuramos por uma linha
correspondendo a posição da regexp e inserimos o adendo antes, se estivermos em mode=before. Se não, nós
procuramos pela próxima linha correspondendo à fronteira ("boundary") e insere o adendo após a linha, se
ele for um endboundary, ou antes dessa linha, se ele for um beginboundary.
FAQ
Este capítulo agrupa as perguntas frequentes (FAQ). Na verdade, a maioria das perguntas até agora puderam
ser formuladas dessa forma: "Porque ele é projetado dessa forma e não dessa outra?" Se você pensa que
po4a não é a resposta correta para tradução de documentação, você deveria considerar ler esta seção. Se
ele não responder suas perguntas, por favor entre em contato conosco na lista de discussão
<po4a-devel@lists.alioth.debian.org>. Nós adoramos feedback.
Por que traduzir cada parágrafo separadamente?
Sim, no po4a, cada parágrafo é traduzido separadamente (na verdade, cada módulo decide isso, mas todos os
módulos existentes fazem isso, e o seu deveria também). Há muitas vantagens nesta abordagem:
• Quando as partes técnicas do documento estão ocultas da cena, o tradutor não pode bagunçá-las. Quanto
menos marcadores nós mostrarmos para o tradutor, menos erro ele pode criar.
• Cortar o documento ajuda a isolar as alterações do documento original, localizando quais partes da
tradução precisam ser atualizadas para facilitar esse processo.
Mesmo com essas vantagens, algumas pessoas não gostam da ideia de traduzir cada parágrafo separadamente.
Aqui estão algumas respostas que eu posso dar para o seus medo:
• Essa abordagem foi provada com sucesso no projeto KDE e permite que as pessoas produzam o maior corpo
de documentação traduzida e atualizada que eu conheço.
• Os tradutores ainda podem usar o contexto para traduzir, já que as strings no arquivo PO estão na mesma
ordem que no documento original. Traduzir sequencialmente é, então, comparável se você sua po4a ou não.
E, em qualquer caso, a melhor forma de obter o contexto está em converter o documento para um formato
imprimível, já que o formatadores de texto não são realmente legíveis, na minha opinião.
• Essa abordagem é uma das usadas por tradutores profissionais. Nós concordamos que eles têm objetivos
meio diferentes dos tradutores de código aberto. A manutenção é, por exemplo, normalmente menos crítica
para eles, já que o conteúdo raramente é alterado.
Por que não dividir a nível de sentença (ou menor)?
Ferramentas dos tradutores profissionais de alguma forma dividem o documento a nível de sentença para
obter o máximo de reusabilidade das traduções antigas e para agilizar seu processo. O problema é que a
mesma sentença pode ter várias traduções, dependendo do contexto.
Parágrafos são por definição maiores que as sentenças. Isso vai assegurar que mantendo o mesmo parágrafo
em dois documentos vai haver o mesmo sentido (e tradução), independente do contexto de cada caso.
Divisão em partes menores do que a sentença seria muito ruim. Demoraria um pouco explicar o porquê aqui,
mas o leitor interessado pode ver o página de manual do Locale::Maketext::TPJ13(3pm) (a qual vem com a
documentação do Perl), por exemplo. Resumindo, cada idioma tem suas próprias regras sintáticas e não é
possível criar sentenças agregando de partes de sentenças de forma que funcione para todos os idiomas
existentes (ou até mesmo para as 5 das 10 mais falados, ou até menos).
Por que não colocar o original como comentário junto da tradução (ou o contrário)?
À primeira vista, gettext não parece estar adaptado para todos os tipos de traduções. Por exemplo, ele
não parecia adaptado para debconf, a interface que todos os pacotes Debian usamo para sua interação com o
usuário durante a instalação. Neste caso, os textos para traduzir eram bem pequeno (umas dúzias de linhas
para cada pacote) e era difícil colocar a tradução em um arquivo especializado, já que ele tinha que
estar disponível antes da instalação do pacote.
É por isso que o desenvolvedor do debconf decidiu implementar outra solução, na qual traduções estariam
localizadas no mesmo arquivo que o original. Isso até que é atraente. Alguém poderia até querer fazer
isso para XML, por exemplo. Se pareceria essa forma:
<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>
Mas isso era tão problemático que uma abordagem baseada em PO é usada no momento. Apenas o original pode
ser editado no arquivo e as traduções devem ser feitas nos arquivos PO extraídos do modelo mestre (e
colocadas de volta na hora de compilar o pacote). O sistema antigo estava obsoleto porque possuía
diversos problemas:
• problemas de manutenção
Se vários tradutores fornecessem um patch ao mesmo tempo, ficava difícil mesclá-los.
Como você vai detectar alterações no original ao qual precisam ser aplicadas as traduções? Para poder
usar diff, você tem que anotar qual versão do original você traduzido, isto é, você precisa de um
arquivo PO no seu arquivo ;)
• problemas de codificação
Essa solução é viável quando somente idiomas europeus estão envolvidos, mas a tradução de coreano,
russo e/ou árabe realmente complica a situação. UTF seria uma solução, mas ainda haveria problemas
nessa questão.
Além disso, tais problemas são difíceis de detectar (isto é, somente leitores coreanos vão detectar
que a codificação em coreano está quebrada [por causa do tradutor russo])
gettext resolve todos os problemas ao mesmo tempo.
Mas gettext não foi projetado para esse uso!
É verdade, mas até agora ninguém veio com uma solução melhor. E a única alternativa conhecida é a
tradução manual, com todos os problemas de manutenção.
E as outras ferramentas de tradução para documentação usando gettext?
Até onde eu sei, há somente duas:
poxml
Essa é a ferramenta desenvolvida pelo pessoal do KDE para manipular DocBook XML. Até onde eu sei,
esse foi o primeiro programa a extrair strings para traduzir de documentação para arquivos PO, e a
injetá-las de volta após a tradução.
Ela só consegue manipular XML e apenas um DTD em particular. Eu fico, particularmente, não gosto das
listas de manipulação, que acabam com um grande msgid. Quando a lista fica grande, o fragmento se
torna mais difícil de engolir.
po-debiandoc
Esse problema desenvolvido por Denis Barbier é uma espécie de precursor do módulo de SGML do po4a, o
qual meio que torna-o (po-debiandoc) obsoleto. Como o nome já diz, ele linda apenas o DebianDoc DTD,
o qual é meio que um DTD obsoleto.
As principais vantagens do po4a sobre eles é a facilidade de adição de conteúdo extra (o que é bem pior
lá) e a habilidade de alcançar gettextização.
Educando desenvolvedores sobre tradução
Quando você tenta traduzir documentação ou programas, você lida com três tipos de problemas: linguísticas
(nem todo mundo sabe 2 idiomas), técnicos (é por isso que po4a existe) e relacional/humano. Nem todos os
desenvolvedores entendem a necessidade de traduzir as coisas. Mesmo quando estão com boa vontade, eles
podem ignorar como facilitar o trabalho de tradutores. Para ajudar nisso, po4a vem com muita documentação
que pode ser vista.
Outro ponto importante é que cada arquivo traduzido começa com um comentário curto, indicando que arquivo
é e como usá-lo. Isso deve ajudar os coitados dos desenvolvedores mergulhados em toneladas de arquivos em
diferentes idiomas que eles mal conhecem e os ajuda a lidar com isso corretamente.
No projeto po4a, os documentos traduzidos não são mais arquivos fontes, no sentido que estes arquivos não
são da forma preferencial de trabalho para fazer modificações. Já que isto não é convencional, é uma
fonte de erro fácil. É por isso que todos os arquivos possuem esse cabeçalho:
| *****************************************************
| * 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 ;)
Da mesma forma, arquivo PO comuns do gettext apenas precisam ser copiados para o diretório po/. Mas esse
não é o caso daqueles manipulados por po4a. O maior risco aqui é um desenvolvedor apagar a tradução
existente do seu programa com a tradução da sua documentação. (os dois não podem ser armazenados no mesmo
arquivo PO, porque o programa precisa instalar sua tradução em um arquivo MO enquanto a documentação usa
apenas sua tradução em tempo de compilação). É por isso que os arquivos PO produzidos pelo módulo po-
debiandoc contêm o cabeçalho a seguir:
#
# 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
#
RESUMO das vantagens da abordagem baseada em gettext
• As traduções não são armazenadas junto do original, o que possibilita detectar se as traduções estão
desatualizadas.
• As traduções são armazenadas em arquivos separados um dos outros, o que previne tradutores de idiomas
diferentes interferir tanto quando da submissão do patch quanto a nível de codificação do arquivo.
• Ele é internamente baseado no gettext (mas po4a oferece uma interface bem simples, de forma que você
não precisa entender as especificidades para usá-lo). Dessa forma, nós não temos que reinventar a roda
e, por causa do seu amplo uso, nós podemos pensar que essas ferramentas meio que não tem erros.
• Nada mudou para o usuário final (além do fato de traduções estarem melhor mantidas, espero). o arquivo
de documentação resultante distribuído é exatamente o mesmo.
• Não há necessidade de tradutores aprenderem um novo arquivo de sintaxe e seu editor de arquivos PO
(como o modo PO do Emacs, Lokalize ou Gtranslator) vão funcionar muito bem.
• gettext oferece uma forma simples de obter estatísticas sobre o que está feito, o que deveria ser
revisto e atualizado e o que ainda deve ser feito. Alguns exemplos podem ser encontrados nesses
endereços:
- http://kv-53.narod.ru/kaider1.png
- http://www.debian.org/intl/l10n/
Mas tudo tem seu lado negativo, e essa abordagem tem algumas desvantagens com as quais nós temos que
lidar.
• Adendos são... estranhos à primeira vista.
• Você não pode adaptar o texto traduzido às suas preferências, com divisão de um parágrafo aqui e juntar
outros dois ali. Mas de certa forma, se há um problema com o original, isso deveria ser relatado como
um erro.
• Até mesmo com uma interface fácil, ainda é uma nova ferramenta que as pessoas precisam aprender.
Um dos meus sonhos seria integrar de alguma forma po4a ao Gtranslator ou Lokalize. Quando um arquivo de
documento fosse aberto, as strings seriam automaticamente extraídas e um arquivo traduzido + arquivo po
poderia ser gravado no disco. Se nós conseguirmos fazer um módulo para MS Word (TM) (ou pelo menos
RTF), tradutores profissionais podem até mesmo usá-lo.
AUTORES
Denis Barbier <barbier,linuxfr.org>
Martin Quinson (mquinson#debian.org)
Ferramentas do Po4a 2017-08-26 PO4A(7)