Automate file insert?

I have a file with a title page and table of contents, plus I have a file with the content itself. I need to merge the files. Actually what I am looking for is the action being signed in menu as Insert → File…, however I’d wanted to automatize the process to use it in script because the second file I am getting from a Markdown.

Any hints? I didn’t find anything relevant in manual. Though I found a page describing scripting but it seems that everything there is a GUI only scripting.

It is also an interesting question in general because I guess that’s not the last thing I’d wanted automatize.

I found some «UNO api». Perhaps if what I’m asking is possible, that have to be done with that. I’ll look at this closer when I happen to be at home.

Omg, that’s not easy… There’s a bunch of documentation, almost no complete examples, and everything needs a good understanding of LO internals… I have no much time for that, let’s see if I can do anything with that in the future.

Hm, it seems that there’re few examples for C++, but I found ones for python! Perhaps not everything lost.

Hi

If I understand correctly, in my opinion you do not need a script. You can use the same technique as that used by the master documents: the linked section.

In your TOC (table of content) document, where you want to insert the “content” document:

  • Insert Section
  • Check the Link box
  • Click the […] button to select the “inserted” file.
  • Click Insert.

On opening, TOC document updates the links with the current version of the “content” document.

Regards

Thank you, that worked! I should mention however that I had problems with it: the only combination that worked — when both the files are «.odt». With «.docx» LOWriter always shows a message «Can’t read content!», and disappears with an advice to restore the document at the next start. An interesting and strange thing is that despite the critical error the app prints no messages to stdin/stderr.

Okay, since it isn’t the last thing I need to automate, I finally wrote a script using LO UNO API with python.

First one needs to start a server with the command below, so the executed script would connect to this instance.

soffice "--accept=socket,host=localhost,port=8100;urp;" --headless --invisible

I commented the code below, I hope it is clear. This code workig for me atm.

#!/usr/bin/python3
import uno
import os

def absoluteUrl(relativeFile):
    """Constructs absolute path to the current dir in the format required by PyUNO that working with files"""
    return "file:///" + os.path.realpath(".") + "/" + relativeFile

def parBreak(document, cursor):
    """Inserts a paragraph break at cursor position"""
    document.Text.insertControlCharacter( cursor.End,
                                          uno.getConstantByName('com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK'),
                                  False)

def updateTOC(document):
    """Update links in table of contents"""
    iList = document.getDocumentIndexes()
    assert(iList.getCount() > 0), "Table of contents not found, aborting!"
    for i in range(0, iList.getCount()):
        iList.getByIndex(i).update()

localContext = uno.getComponentContext()
resolver = localContext.ServiceManager.createInstanceWithContext(
                "com.sun.star.bridge.UnoUrlResolver", localContext )
smgr = resolver.resolve( "uno:socket,host=localhost,port=8100;urp;StarOffice.ServiceManager" )
remoteContext = smgr.getPropertyValue( "DefaultContext" )
desktop = smgr.createInstanceWithContext( "com.sun.star.frame.Desktop",remoteContext)
file = desktop.loadComponentFromURL(absoluteUrl("./build/output.odt") ,"_blank", 0, ())

#insert at the beginning the file with title page and TOC
cursor = file.Text.createTextCursor()
cursor.gotoStart(False)
#to not screw the first paragraph formatting let's first make an empty one here
parBreak(file, cursor)
cursor.gotoStart(False)
cursor.insertDocumentFromURL(absoluteUrl("./Title\'n\'TOC.odt"), ())
updateTOC(file) #the inserted TOC needs to be updated

#save the file
file.storeAsURL(absoluteUrl("./build/Курсовая.odt"),())
file.dispose()

A possible pit — the function insertDocumentFromURL doesn’t tell anything when something gone wrong, e.g. if the file not exist (with the weird format for file paths that would happen pretty often). So one could use only indirect logic to figure out whether something gone wrong. In the code above the logic is the assert() in the function that updates TOC.