Manipulando Documentos ODF com Python

Num post anterior eu falei sobre padrões abertos e o OpenDocument Format em particular. Depois da conversa filosófica veio a vontade prática, e resolvi escrever alguma coisa para manipular um arquivo ODF. Bem, como todos já sabem o ODF usa XML, na verdade distribuído em vários arquivos, compactados junto com figuras e outras coisas; você pode pode dar um unzip algumdocumento.odt pra ver o conteúdo. O arquivo que interessa para este exemplo é o contents.xml, que é onde está o texto num documento. Criei um documento com um título, alguns subtítulos e um bocado de Lorem Ipsum. Os títulos foram feitos direito, informando que aquele componente era do tipo título (heading; veja o destaque no screenshot abaixo) e não usando a “técnica” ancestral e sebosa de negritar e aumentar a fonte.

OOo Lorem Ipsum

Um trecho do XML em contents.xml (coloquei em negrito os trechos que irão interessar):

<text:h text:style-name=”Heading_20_1″ text:outline-level=”1″>
Título
</text:h>
<text:h text:style-name=”Heading_20_2″ text:outline-level=”2″>
Seção A
</text:h>
<text:p text:style-name=”Standard”>
<text:bookmark text:name=”lipsum1″/>
Lorem ipsum dolor (…)
</text:p>

text.h indica um título (heading), assim como text:p indica um parágrafo, e text:outline-level diz o nível do título. Assim, text:h e text:outline-level=”1″ juntos significam que o texto contido no tag é do tipo “Header 1”.

O objetivo do script é encontrar os títulos contidos no documento e imprimí-los, identando de acordo com o nível do título. Usei a biblioteca zipfile para abrir o odt e minidom para parsear o XML numa árvore. Ambos já vêm numa instalação Python padrão.

import zipfile
from xml.dom.minidom import parseString

def get_titles(odf_filename):

dom = parseString(component)
odf_file = zipfile.ZipFile(odf_filename, 'r')
contents = odf_file.read('content.xml')
odf_file.close()

dom = parseString(component)
title_elements = dom.getElementsByTagName('text:h')
titles = []
for t in title_elements:

level = int(t.attributes['text:outline-level'].value
title = t.childNodes[0].data
titles.append((level, title))

dom.unlink() return titles

if __name__ == '__main__':

titles = get_titles('teste.odt')
for title in titles:

for a in range(title[0] - 1):

print ' ',

print title[1]

A função get_titles extrai o arquivo contents.xml do odt, seu conteúdo é parseado e o método dom.getElementsByTagName('text:h') retorna todos os elementos de título e os adiciona numa lista junto com seu nível no documento. Em seguida, os títulos são escritos na tela com uma identação equivalente ao nível.

O exemplo deu nisso:

Título

Seção A

Subseção A.1
Subseção A.2
Subseção A.3

Seção B
Seção C

Subseção B.1
Subseção B.2

É bem simples, mas é preciso conhecer o formato, o que não é um problema já que este é claro e bem documentado. Contudo, acabei de achar uma biblioteca chamada odfpy, que quando tiver tempo vou dar uma olhada, mas já adianto que tem coisas como

from odf.opendocument import OpenDocumentText
from odf.style import Style, TextProperties
from odf.text import H, P, Span

…o que parece muito promissor.

Uma série de artigos que valem uma olhada é Dr. ODF: Examining OpenDocument Format with Python, na qual este post é inspirado. E qualquer dúvida sobre XML em Python veja o Capítulo 9 de Dive Into Python.

Arquivos:

2 pensamentos sobre “Manipulando Documentos ODF com Python

  1. Pingback: TagGen, Gerador de Personagens para Tagmar 2 (ponto 2) « Head Like a Hole

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s