FLOSS Manuals

 English |  Español |  Français |  Italiano |  Português |  Русский |  Shqip

Python Scripting with Scribus

shiftobjects.py

Here is another mail list-driven set of scripts. The problem as posed was that a document had been created with left and right pages. For many situations this means that content on a right page is shifted to the right making a smaller outer margin, and the reverse for left-sided page. The questioner had then inserted a new page somewhere in the middle of the document, and thus the content after the new page was shifted in the wrong direction. Was there any help for this issue? Scripter, of course.

The first script, shiftobjects.py, would shift the content on the current page. The user was asked how much to shift in the current page units, and then which direction to shift, and then all of the items on the page were shifted accordingly. This meant of course that the user had to run this script page by page for all which needed shifting. Thus, shiftobj2.py.

shiftobj2.py

The second version of this process allowed the user to enter a series of page numbers to be shifted, then asked about the amount of shift and direction.

#!/usr/bin/env python
# -*- coding: utf-8  -*-

"""

shift_objects.py


USAGE

Select a page where you need to shift all objects, run script.

The first dialog asks how much to shift, using a distance of 40 points

as the default, but modified to your units.

The second dialog asks whether to shift objects Left (the default), or Right.

Simply enter anything other than Left to shift right.

This version allows for a series of pages to be shifted at once.

"""

try:
    import scribus
except ImportError:
    print "Unable to import the 'scribus' module. This script will only run within"
    print "the Python interpreter embedded in Scribus. Try Script->Execute Script."
    sys.exit(1)

if not scribus.haveDoc():
    scribus.messageBox('Scribus - Script Error', "No document open", scribus.ICON_WARNING, scribus.BUTTON_OK)
    sys.exit(1)
pgerr = 0
pgcount = scribus.pageCount()
page = scribus.currentPage()
scribus.setRedraw(False)
units = scribus.getUnit()
if units == 0:
    shift = 40
elif units == 1:
    shift = 14.111   # millimeters = points/2.8346
elif units == 2:
    shift = 0.5556   # inches = points/72.0

shiftamount = scribus.valueDialog('Amount of shift?','Enter the amount to shift',str(shift))
shiftamount = float(shiftamount)

shiftdir = scribus.valueDialog('Direction to shift?','Which direction to shift...\nAny change from default shifts to Right','Left')
if ((shiftdir == 'Left') or (shiftdir == 'left')):
    shiftamount = -shiftamount

pages = scribus.valueDialog('Pages to Alter','List pages to shift, separated by white space\n(no commas)',str(page))
pagelist = pages.split()

for pg in pagelist:
    if ((int(pg) < 1) or (int(pg) > pgcount)):
        pgerr = pgerr + 1
    else:
        scribus.gotoPage(int(pg))
        pageitems = scribus.getAllObjects()
        for item in pageitems:
            scribus.moveObject(shiftamount, 0, item)
scribus.setRedraw(True)

if pgerr == 1:
    scribus.messageBox('OOPS!',str(pgerr)+' of the pages you entered was\n outside the range of the document\n and therefore ignored.',scribus.ICON_WARNING, scribus.BUTTON_OK)
if pgerr > 1:
    scribus.messageBox('OOPS!',str(pgerr)+' of the pages you entered were\n outside the range of the document\n and therefore ignored.',scribus.ICON_WARNING, scribus.BUTTON_OK)

Not surprisingly, we start out with our error-checking for Scribus and also that a document is open. Next we get a page count, and then we find out which page units the document is using. We're a bit shallow here, since we are only looking for points, millimeters, or inches, but that will likely cover most users. We do this so we can set a default value for shift, the equivalent of 40 points. I could have done the shift to points, then back again, as we saw before, but chances are if the user is used to millimeters, he'll know how much to shift in those units, not in points.

We then ask how much the user wants to shift the objects, and then which direction, left or right. Notice how I have simplified the logic. I might have tried to cover all the possible entries, l, r, L, R, Left, Right, left, right, and so on. Instead, I make the default 'Left', and in the next line I only look for Left or left, and if neither of these is the entry, then Right is assumed. All this does is to decide whether to negate the amount of shift. Realistically, I should have added language to the valueDialog() to indicate an absolute value should be entered, especially since the amount was asked for before the direction. Alternatively and perhaps better would have been to change shiftamount = -shiftamount to shiftamount = -(abs(shiftamount)).

Next we ask for a series of pages to alter, and we don't want commas, just whitespace between the numbers, since this is the default way that the split() string function works. Now let's imagine that, in his haste, the user has entered some values which don't exist, maybe 0 or 21 in a twenty page document. We cover this by seeing if any entered value is outside the page range and create an error counter, pgerr, and skip over those. Look how small the actual action part of the script is:

        scribus.gotoPage(int(pg))
        pageitems = scribus.getAllObjects()
        for item in pageitems:
            scribus.moveObject(shiftamount, 0, item)

That's it! The rest is all error-handling and user input. But we do also throw in some feedback at the end in case there were erroneous pages, and we even go the extra grammatical mile to cover one versus many in our feedback.

shiftobj3.py

After this, what's left? How about some even better automation? Imagine that your user is working on a 100 page document, and somewhere about page 7 is where he inserted a new page. Now he will have to enter '8 10 12 14 16 18' and so on all the way to the end of the document. What can we do for this?

#!/usr/bin/env python
# -*- coding: utf-8  -*-

"""

shift_obj3.py


USAGE

Select a page where you need to shift all objects, run script.

The first dialog asks how much to shift, using a distance of 40 points

as the default, but modified to your units.

The second dialog asks whether to shift objects Left (the default), or Right.

Simply enter anything other than Left to shift right.

This version allows for a series of pages to be shifted at once.

Enter odd or even to shift every other page to the end.

"""

try:
    import scribus
except ImportError:
    print "Unable to import the 'scribus' module. This script will only run within"
    print "the Python interpreter embedded in Scribus. Try Script->Execute Script."
    sys.exit(1)

if not scribus.haveDoc():
    scribus.messageBox('Scribus - Script Error', "No document open", scribus.ICON_WARNING, scribus.BUTTON_OK)
    sys.exit(1)
pgerr = 0
pgcount = scribus.pageCount()
page = scribus.currentPage()
scribus.setRedraw(False)
units = scribus.getUnit()
if units == 0:
    shift = 40
elif units == 1:
    shift = 14.111   # millimeters = points/2.8346
elif units == 2:
    shift = 0.5556   # inches = points/72.0

shiftamount = scribus.valueDialog('Amount of shift?','Enter the amount to shift',str(shift))
shiftamount = float(shiftamount)

shiftdir = scribus.valueDialog('Direction to shift?','Which direction to shift...\nAny change from default shifts to Right','Left')
if ((shiftdir == 'Left') or (shiftdir == 'left')):
    shiftamount = -shiftamount

pages = scribus.valueDialog('Pages to Alter','List pages to shift, separated by white space\n(no commas)\nEnter odd or even for every other page',str(page))

if (pages == 'odd') or (pages == 'even'):
    startendpages = scribus.valueDialog('Odd/Even','Where to start (and end)?\n(One or 2 page numbers, separated by white space)',str(page) + ' ' +str(pgcount))
    startend = startendpages.split()
    pgadd = int(startend[0])
    if (startend[1] != ""):
        pgcount = int(startend[1])
    pagelist = []
    while pgadd <= pgcount:
        pagelist.append(str(pgadd))
        pgadd += 2
else:
    pagelist = pages.split()

for pg in pagelist:
    if ((int(pg) < 1) or (int(pg) > pgcount)):
        pgerr += 1
    else:
        scribus.gotoPage(int(pg))
        pageitems = scribus.getAllObjects()
        for item in pageitems:
            scribus.moveObject(shiftamount, 0, item)
scribus.setRedraw(True)

if pgerr == 1:
    scribus.messageBox('OOPS!',str(pgerr)+' of the pages you entered was\n outside the range of the document\n and therefore ignored.',scribus.ICON_WARNING, scribus.BUTTON_OK)
if pgerr > 1:
    scribus.messageBox('OOPS!',str(pgerr)+' of the pages you entered were\n outside the range of the document\n and therefore ignored.',scribus.ICON_WARNING, scribus.BUTTON_OK)
Most of this should look familiar, that is, until we get to this:

pages = scribus.valueDialog('Pages to Alter','List pages to shift, separated by white space\n(no commas)\nEnter odd or even for every other page',str(page))

if (pages == 'odd') or (pages == 'even'):
    startendpages = scribus.valueDialog('Odd/Even','Where to start (and end)?\n(One or 2 page numbers, separated by white space)',str(page) + ' ' +str(pgcount))

First of all, in addition to the option of listing page numbers, we can just enter 'odd' or 'even'. If we do that, then we get another valueDialog() asking where to start, with an option to put in where to end. After all, the user might have inserted a page, then somewhere later in the document inserted another, so everything after that second insertion will be Ok. Notice however, that we don't check for the error where a user might say 'odd', but then enter even numbers. At some point you have to draw the line on error-checking. Another reason to save your document just before you run any script.

So with the following lines we have to handle all these possibilities a series of numbers, odd or even, and if these latter two, one or maybe two more page numbers. We then wind our way through these issues to create our list of pages to shift, and finish with our message about any page errors.

There has been error in communication with Booktype server. Not sure right now where is the problem.

You should refresh this page.