Ask Your Question
0

Automate file insert?

asked 2015-08-03 07:28:58 +0200

Hi-Angel gravatar image

updated 2015-08-03 09:14:37 +0200

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.

edit retag flag offensive close merge delete

Comments

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.

Hi-Angel gravatar imageHi-Angel ( 2015-08-03 11:58:51 +0200 )edit

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.

Hi-Angel gravatar imageHi-Angel ( 2015-08-03 21:28:55 +0200 )edit

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

Hi-Angel gravatar imageHi-Angel ( 2015-08-04 11:51:40 +0200 )edit

2 Answers

Sort by » oldest newest most voted
1

answered 2015-08-04 15:10:07 +0200

pierre-yves samyn gravatar image

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

edit flag offensive delete link more

Comments

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.

Hi-Angel gravatar imageHi-Angel ( 2015-08-04 19:17:49 +0200 )edit
0

answered 2015-08-09 14:37:47 +0200

Hi-Angel gravatar image

updated 2015-08-09 15:08:01 +0200

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.

edit flag offensive delete link more
Login/Signup to Answer

Question Tools

1 follower

Stats

Asked: 2015-08-03 07:28:58 +0200

Seen: 388 times

Last updated: Aug 09 '15