Search code examples
pythonunderlineodfodfpy

underline text with odfpy


I'd like to generate an odf file with odfpy, and am stuck on underlining text. Here is a minimal example inspired from official documentation, where i can't find any information about what attributes can be used and where. Any suggestion?

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

textdoc = OpenDocumentText()

ustyle = Style(name="Underline", family="text")
#uprop = TextProperties(fontweight="bold")                  #uncommented, this works well
#uprop = TextProperties(attributes={"fontsize":"26pt"})     #this either
uprop = TextProperties(attributes={"underline":"solid"})    # bad guess, wont work  !!
ustyle.addElement(uprop)
textdoc.automaticstyles.addElement(ustyle)
p = P(text="Hello world. ")
underlinedpart = Span(stylename=ustyle, text="This part would like to be underlined. ")
p.addElement(underlinedpart)
p.addText("This is after the style test.")
textdoc.text.addElement(p)
textdoc.save("myfirstdocument.odt") 

Solution

  • Here is how I finally got it:

    I created a sample document with underlining using libreoffice, and unzipped it. Looking in styles.xml part of the extracted files, I got the part that makes underlining in the document:

    <style:style style:name="Internet_20_link" style:display-name="Internet link" style:family="text">
    <style:text-properties fo:color="#000080" fo:language="zxx" fo:country="none" style:text-underline-style="solid" style:text-underline-width="auto" style:text-underline-color="font-color" style:language-asian="zxx" style:country-asian="none" style:language-complex="zxx" style:country-complex="none"/>
    </style:style>
    

    The interesting style attributes are named: text-underline-style, text-underline-width and text-underline-color.

    To use them in odfpy, '-' characters must be removed, and attributes keys must be used as str (with quotes) like in the following code. A correct style family (text in our case) must be specified in the Style constructor call.

    from odf.opendocument import OpenDocumentText
    from odf.style import Style, TextProperties
    from odf.text import H, P, Span
    
    textdoc = OpenDocumentText()
    
    #underline style
    ustyle = Style(name="Underline", family="text")  #here  style family
    
    uprop = TextProperties(attributes={
        "textunderlinestyle":"solid",
        "textunderlinewidth":"auto",
        "textunderlinecolor":"font-color"
        })
    
    ustyle.addElement(uprop)
    textdoc.automaticstyles.addElement(ustyle)
    p = P(text="Hello world. ")
    underlinedpart = Span(stylename=ustyle, text="This part would like to be underlined. ")
    p.addElement(underlinedpart)
    p.addText("This is after the style test.")
    textdoc.text.addElement(p)
    
    textdoc.save("myfirstdocument.odt")