eea / odfpy

API for OpenDocument in Python
GNU General Public License v2.0
311 stars 64 forks source link

Libreoffice stylename does not update when adding new lines #134

Open kewapo opened 8 months ago

kewapo commented 8 months ago

I am trying to use Libreoffice to program using 'Literate programming'. To do this, every time I start a programming project I open a writer file in which I type, first the requirements, references and then the programming process. This file serves as both code documentation and to generate the code in python. To do this I use a small Python program, creaCodigo.py, which creates the *.py code files from this libreoffice file:

If I write the code as a “body of text” style and then change the style to ‘code’, the creaCodigo.py program works fine. However, if I add new lines in the middle of the paragraphs with said style, even though LibreOffice shows them as 'code' style, the creaCodigo.py program sees them as normal paragraphs. For it to work I have to apply another style and then the 'code' style.

I use the odfpy library. The file createCodigo.py is the following:

from odf.opendocument import load
from odf import text, teletype
import sys

control_ficheros = dict()

def escribir(fichero, linea):
    with open(fichero,"a", encoding='utf-8') as file:
        file.writelines(linea)
        file.writelines('\n')
    return True

def crear(fichero):
    with open(fichero,"w", encoding='utf-8') as file:
        file.writelines('# Creado automáticamente desde ' + fichero_origen)
        file.writelines('\n')
    return True

def nuevo(fichero):
    if control_ficheros.get(fichero, 0)>0:
        return False
    else:
        return True

def preparar(linea):
    linea = linea.replace('\t', '    ')
    linea = linea.replace('‘', u"'")
    linea = linea.replace('’', u"'")
    return linea

if (len(sys.argv)<2):
    print('No has indicado qué fichero contiene el proyecto')
    exit()
else:
    fichero_origen = sys.argv[1]

# fichero_origen = 'file.odt'
doc = load(fichero_origen)

print('--- BUSCANDO CÓDIGO')

for paragraph in doc.getElementsByType(text.P):
    if paragraph.getAttribute('stylename') == 'código':
        lista = str(paragraph)
        if lista.startswith('Fichero'):
            fichero = lista.split(':')[1].strip()
            if nuevo(fichero):
                crear(fichero)
                print('nuevo fichero: ', fichero)
                control_ficheros.update({fichero: 1})
            else:
                print('fichero', fichero, 'ya existe. Añado líneas')
        else:
            linea = teletype.extractText(paragraph)
            linea = preparar(linea)
            escribir(fichero, linea)

I understand that if lines are written in a writer document among those that have the 'code' style, these lines should not only visually coincide with the format of said style, but also internally they should mark their style name in the 'code' style and Do not leave them with the normal paragraph style name.