Back-End

30 jan, 2017

Utilizando o PHP RTF Parser para processar documentos de processamento de documentos – Parte 01

Publicidade

RTF é um formato de arquivo portátil para representar o conteúdo de um documento de processamento, como aqueles gerados por Microsoft Word, OpenOffice e outros.

Leia este artigo para entender o formato RTF, para que você possa entender os próximos artigos nos quais você vai aprender como utilizar os pacotes de PHP RTF Tools para bons propósitos, como utilizar templates RTF, unir múltiplos documentos, ou simplesmente extrair texto de um documento.

Introdução

Este artigo é o primeiro de uma série que vai cobrir o formato de arquivo RTF, e explicar como você pode utilizar o pacote PHP RTF Tools para realizar vários tipos de processamentos de documentos úteis utilizando o PHP.

Um pouco de história

O Rich Text Format (RTF) é um formato de propriedade da Microsoft, e suas especificações foram publicadas pela primeira vez em 1987. Originalmente, ele pretendia facilitar a troca de documentos entre diferentes produtos da Microsoft em diferentes plataformas, mas gradualmente foi ganhando popularidade entre os editores de software.

A razão era simples: as especificações de formato binário .doc do Microsoft Word permaneceram sem ser publicadas até 1997, quando ficaram temporariamente disponíveis sob certas condições.

Essa falta de transparência em relação ao formato de arquivo .doc levou os editores de software a enxergarem o RTF como uma alternativa para suportar os documentos criados com o Microsoft Word e, assim, fornecer uma melhor interoperabilidade para os usuários. O formato RTF evoluiu até sua última versão 1.9.1 em março de 2008.

Por que se preocupar com o formato RTF?

E por que se preocupar em programar em COBOL, Fortran ou RPG? Simplesmente porque existe uma base instalada de empresas que ainda precisam lidar com ele. Isso é parte de sua história e, como um profissional, você pode ter que lidar com tais ambientes.

É claro que escolher o RTF como o principal formato de troca de documentos em vez de outras plataformas e/ou sistemas não seria minha escolha preferida, a menos que eu tivesse que enfrentar fortes restrições técnicas vindas do ambiente de TI, ou de uma forte história da empresa, ou ambos.

Por outro lado, o formato RTF é realmente fácil de ser analisado e pode ser lido por humanos (embora, nesse caso particular, essa “legibilidade por humanos” possa se tornar um tópico altamente subjetivo). De um ponto de vista sintático, ao menos, ele é fácil de ser lido e de ser gerado, então, às vezes, pode ser uma boa escolha.

Além do mais, analisar documentos RTF não requer que você utilize um framework, objeto ou biblioteca complexos em C/C++ (ou suas linguagens favoritas), como é o caso, às vezes, com os arquivos PDF. Criar um RTF parser requer apenas algumas dúzias de linhas de código.

O que você vai encontrar aqui

Esta série de artigos foca na estrutura de documentos RTF.

Eles não explicarão como criar conteúdos RTF, como cabeçalhos, rodapés, tabelas e imagens embutidas, mas focarão no que você precisa saber se um dia você precisar ler documentos em formato RTF e tentar extrair informações úteis deles.

Eles também explicarão como as classes do pacote PHP RTF Tools podem ser utilizadas para resolver algumas de suas necessidades sobre o processamento de arquivos RTF.

Este primeiro artigo também vai te introduzir ao formato RTF, fornecendo as informações básicas que você vai precisar para entender um documento RTF quando visualizar em um editor de texto, ou quando processar através de um script.

O arquivo de formato RTF por exemplo

Talvez a maneira mais fácil de apresentar o formato RTF seja criar o arquivo RTF mais simples possível utilizando o software de processamento de texto mais simples e, então, analisar os dados RTF gerados.

Escolhemos o Microsoft WordPad para isso. Essa pequena aplicação, que vem em todas as versões do Microsoft Windows, tem a grande vantagem de gerar saídas RTF simples. É claro, faltam muitas das funcionalidades mais comuns que os programas de processamento de texto modernos oferecem, mas é ideal para nosso propósito.

A imagem abaixo mostra um documento WordPad contendo um texto muito simples, sem nenhuma formatação:

Para aqueles que estão familiarizados com a API Windows, a aplicação Wordpad utiliza os controles RichTextEdit para todas as suas operações.

Nós utilizamos alguns caracteres comuns, como aspas inclinadas, chaves e barras invertidas. Mais tarde veremos que caracteres tão comuns requerem alguma interpretação quando traduzidos para o formato RTF.

Primeiro, vamos dar uma olhada no arquivo RTF gerado pelo WordPad depois de salvar o documento e reabri-lo utilizando algum editor de texto como o Notepad ou o Notepad++; vamos ter o seguinte retorno. O texto que veio do documento original acima foi destacado em vermelho:

{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1036
{\fonttbl
{\f0\fnil\fcharset0 Arial;}
{\f1\fnil\fcharset0 Calibri;}
}
{\*\generator Riched20 10.0.10586}
\viewkind4\uc1\pard\fs26\'ab\f1\fs22\lang12 Hello world\f0\fs26\lang1036\'bb\par
\f1\fs22\lang12 Special characters : \{ \} \\ \par
}

À primeira vista, podemos notas algumas coisas:

  • Os dados RTF podem estar contidos entre chaves; na verdade, o documento completo está contido entre chaves. Eles são conhecidos como grupos na especificação RTF, e podem ser indefinidamente aninhados.
  • Muitos dados começam com uma barra invertida, seguida por uma palavra-chave (\rtf1, \ansicpg1252 etc.). Todos esses itens são chamados de palavras de controle na especificação RTF. Eles normalmente fornecem informação sobre a formatação do documento, tais como \pard, que redefine os parâmetros de formato de parágrafo para seus valores padrões, ou \ansicpg1252, que define o código de página a ser utilizado no documento. Eles são chamados de tags na documentação do PHP RTF Tools.
  • Nosso texto original ainda aparece aqui, pelo menos uma parte. As aspas de ângulo, por exemplo, foram substituídas pelas construções especiais \’ab e \’bb, que dão seu equivalente hexadecimal para a página de códigos atual. Tais construções são chamadas de símbolos de controle na especificação RTF, e como símbolos scaped character de escape na documentação do PHP RTF Tools.
  • E nossos caracteres especiais (chaves e barras invertidas) são prefixados com uma barra invertida. Eles são scapaded, pois têm um significado especial para os elementos sintáticos do RTF. Tais elementos são chamados de símbolos de controle na especificação RTF, mas o pacote PHP RTF Tools faz uma maior distinção e os chama de Escaped Expressions.

Existem outras noções que não podem ser simplesmente deduzidas da ideia acima: por exemplo, um documento RTF tem uma parte de cabeçalho. Quebras de linha são completamente opcionais, e outras específicas que esta série vai responder com mais detalhes.

Visão geral do formato de arquivo RTF: Elementos de sintaxe

Documentos RTF normalmente contêm dados codificados em ASCII 7-bits, que consiste em grupos, palavras de controle, símbolos de controle e texto. As quebras de linha (CRLFs) podem estar presentes no documento, mas não têm outro propósito além de fornecer uma melhor legibilidade dos dados RTF: eles nunca estarão incluídos no documento de texto.

As seções a seguir descrevem os vários componentes que podem ser encontrados em um documento RTF; elas fornecem os termos oficiais utilizados na especificação RTF da Microsoft, assim como seus equivalentes no pacote PHP RTF Tools, onde distinções mais detalhadas foram feitas para maior clareza.

Palavras de controle

Uma palavra de controle pode ser vista como uma instrução que afeta a maneira que os caracteres são exibidos, ou modifica as configurações de uma página, seção ou parágrafo.

As palavras de controle podem definir os elementos que podem ser referenciados depois dentro do conteúdo do documento. Elas incluem, por exemplo, notas de rodapé, que não são exibidas no lugar em que elas são definidas no documento RTF, mas são geralmente referenciadas de dentro do conteúdo do documento.

Tais palavras de controle são chamadas de Palavras de controle de destino na especificação RTF. O pacote PHP RTF Tools chama ambas as formas simplesmente de palavras de controle.

Uma palavra de controle tem a seguinte sintaxe:

  • Sempre começa com uma barra invertida;
  • É seguida pelo nome do controle, que é um conjunto de caracteres alfabéticos. Note que os nomes são case sensitive.
  • Pode ser seguida por um valor inteiro opcional, que pode ser negativo.

Exemplos:

  • \pard: redefine um parágrafo para seus valores padrões.
  • \ansicpg1252: a palavra ansicpg, seguida pelo parâmetro inteiro 1252 (define o código da página que será utilizado no documento, a menos que haja outra declaração).
  • \margl-200: define a largura da margem esquerda em -200 twips.

 Uma palavra de controle termina quando um caractere que não pode ser parte da palavra de controle em si é encontrado. Tais caracteres são:

  • Barra invertida
  • Abre ou fecha chaves
  • Um espaço ou quebra de linha

Se a palavra de controle for seguida por um espaço, então o espaço é considerado parte da palavra de controle, não parte do conteúdo do documento de texto. Isso pode ser devido a um esforço para melhorar a legibilidade dos conteúdos RTF.

Note, no entanto, que se uma palavra de controle é seguida por dois ou mais espaços, então:

  • O primeiro espaço será parte da palavra de controle;
  • O segundo espaço e os subsequentes serão parte do conteúdo do texto;

As palavras de controle podem ser prefixadas pelos símbolos de controle \*, assim como em :\*background . A especificação RTF diz que isso é utilizado para controles de destino.

O propósito básico de tal construção é dizer ao processador RTF que ele deveria ignorar a palavra de controle se ele não a reconhecer (além disso, a palavra de controle não estará incluída no retorno se o processador RTF for capaz de escrever de volta nos documentos RTF).

A documentação do PHP RTF Tools se refere tanto às palavras de controle quando às palavras de controle de localização como palavras de controle.

Grupos

Os grupos começam em um “abre chaves”({) e terminam em um “fecha chaves”(}). Dentro de um grupo, qualquer propriedade de formato dos caracteres ou parágrafos pode ser especificada, junto com o documento de texto ao qual se aplicam. Os grupos também são utilizados para palavras de controle de destino, como fontes, estilos, cabeçalhos e rodapés.

Os grupos podem ser aninhados. Quando aplicados à formatação de textos, você pode pensar neles como uma maneira de empilhar a seção atual, parágrafo ou opções de formatação de caracteres antes de modificar temporariamente configurações locais. O “abre chaves” de um grupo vai agrupar essas configurações; o conteúdo do grupo aninhado irá definir algumas configurações específicas, como espessura da fonte, tamanho da fonte e cor do texto. Então, fechar chaves vai restaurar as configurações que foram agrupadas quando foi encontrado o abrir chaves.

O exemplo a seguir vai retornar a stringHello” em negrito, “gentle” como texto normal, e “World!” em negrito novamente (a palavra de controle \pard dentro do grupo aninhado redefine as configurações do parágrafo para o padrão):

{\b Hello {\pard gentle } world !}

O próximo artigo vai descrever o significado de cada espaço no conteúdo RTF acima. Os que fazem parte da palavra de controle e os que fazem parte do documento de texto.

Símbolos de controle

Os símbolos de controle, assim como as palavras de controle, começam com uma barra invertida, que é seguida por um caractere não alfanumérico. Ao contrário das palavras de controle, os símbolos de controle nunca são seguidos por espaços opcionais. Se um espaço está presente depois de um símbolo de controle, ele será considerado parte do conteúdo do documento.

Apesar de as especificações da Microsoft sobre o RTF não fazerem nenhuma distinção entre os vários tipos de símbolos de controle, o pacote PHP RTF Tools os divide em três categorias, que estão descritas abaixo.

Escaped Expressions ou Escaped symbol

Os elementos sintáticos básicos de um arquivo RTF consistem em apenas três caracteres: abre chaves({), fecha chaves(}) e barra invertida. Com somente esses três caracteres, você deveria ser capaz de analisar qualquer documento RTF (no caso da barra invertida, é claro, você vai precisar de algum esforço adicional para analisar o que seguir – uma palavra de controle ou um símbolo de controle).

Mas o que acontece se você estiver utilizando esses caracteres no conteúdo do documento? A resposta é simples: eles precisarão ser escaped. Esse processo de escape é tratado automaticamente pelo seu processador de documentos RTF. Lembre-se do nosso exemplo e comentários seguindo na seção RTF por Exemplo.

Normalmente, você deveria encontrar apenas os seguintes escaped symbols em um documento RTF:

  • \{
  • \}
  • \\

No entanto, o pacote PHP RTF Tools vai manusear corretamente esses símbolos onde o caractere seguindo a barra invertida não é aspas (escaped character), nem um símbolo de controle (veja abaixo).

Escaped character

Um escaped character é apresentado com uma barra invertida seguida de um apóstrofo (caractere 0x27 da tabela ASCII) e dois dígitos hexadecimais. Isso permite especificar um caractere de 8 bits utilizando a notação hexadecimal, como no exemplo abaixo, que mapeará o caractere de Euro (€) em  certas páginas de códigos:

\’80

Símbolo de controle

Um símbolo de controle (como o pacote PHP RTF Tools o reconhece) não é uma escaped expression, nem um escaped character, que pode ser manuseado em uma análise de nível lexical.

Os símbolos de controle carregam algumas informações extras endereçadas ao software de leitura de RTF. Eles são, no entanto, tratados separadamente. Você encontrará uma lista abaixo dos símbolos de leitura atualmente reconhecidos.

  • \~ : espaço não separável
  • \- : hífen opcional
  • \_ : hífen não separável
  • \: : especifica um subitem em um índice
  • \| : caractere de fórmula (provavelmente utilizado pelo Word 5.1 para Macintosh como delimitador inicial para uma string de comandos de composição de fórmulas – provavelmente não é mais utilizado)

A especificação RTF também inclui o símbolo de controle \* , que é utilizado para marcar um símbolo de controle de destino cujo texto deve ser ignorado se não compreendido pelo leitor RTF. O pacote PHP RTF Tools, no entanto, entende que uma sequência como:

\*\background

É uma palavra de controle (background) com um atributo especial dizendo que ela é especial, devido à presença do símbolo de controle \* logo antes dela.

Conclusão

Este artigo cobriu uma parte do arquivo de formato RTF, apresentando as noções básicas que permitirão que você se torne familiarizado com os conteúdos do RTF “cru”,  ao menos de um ponto de vista sintático.

Ele também descreveu as entidades básicas que formam o conteúdo RTF: palavras de controle, símbolos de controle, grupos e destinos, junto com seus equivalentes no pacote PHP RTF Tools.

O próximo artigo desta série descreverá como um documento RTF é estruturado: cabeçalho, corpo, fontes, estilos, tabelas de cores, e assim por adiante. Ele também apresentará alguns elementos sintáticos que não foram discutidos aqui e que podem precisar de um pouco mais de “inteligência” de um analista léxico.

Isso inclui os espaços opcionais após as palavras de controle, palavras de controle especiais como \bin ou \pict, que requerem algum processamento específico.

Links úteis

Você vai encontrar abaixo alguns documentos da Microsoft sobre o RTF e alguns links coletados em outros lugares:

  • Guia de Bolso RTF: Um pequeno guia sobre a linguagem RTF, por Sean M. Burke. Não te tornar um especialista, mas vai rapidamente de dar um resumo sobre o que se passa internamente. Sean M Burke é o autor do Guia de Bolso RTF, que é um complemento ideal para as especificações Microsoft, e fornece informações úteis sobre como gerar códigos RTF como tabelas, parágrafos, formatações etc. Se você tem que lidar com a geração de arquivos RTF, então você dever ter esse pequeno livro, pois ele dá exemplos concretos que você nunca vai encontrar na documentação da Microsoft. E você não vai precisar de ferramentas pesadas para testar os exemplos: Notepad para escrever os conteúdos RTF e WordPad para exibir.
  • Rich Text Format: Página do Sean M Burke dando informações adicionais e links sobre o formato de arquivo RTF.
  • Página da Wikipedia: Um artigo compreensível sobre o formato de arquivo RTF.

***

Christian Vigh faz parte do time de colunistas internacionais do iMasters. A tradução do artigo é feita pela redação iMasters, com autorização do autor, e você pode acompanhar o artigo em inglês no link: https://www.phpclasses.org/blog/package/9709/post/1-Using-the-PHP-RTF-Parser-to-Process-Word-Processing-Documents-Part-1-the-RTF-File-Format.html.