Setting Text Distances from a Script: Difference between revisions

From Scribus Wiki
Jump to navigation Jump to search
 
(21 intermediate revisions by the same user not shown)
Line 1: Line 1:
{{Scripting Index}}
{{Scripting Index}}


Here is a simple script for setting the text distances for a text frame. In this particular version, we set all the distances the same, so only one value is needed for the '''value.Dialog'''.
Here is a simple script for setting the text distances for a text frame. In this particular version, we set all the distances the same, so only one value is needed for the '''value.Dialog()'''.
==settextdistance.py==
==settextdistance.py==
<syntaxhighlight lang="python">
<syntaxhighlight lang="python">
Line 36: Line 36:


Select a text frame, run script.
Select a text frame, run script.
A dialog asks for the amount of text distance.


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


Line 86: Line 87:


</syntaxhighlight>
</syntaxhighlight>
==More complex but more versatile==
==More complex but more versatile==
What if we didn't want all the distances to be the same? Look at this modification of the distance value.Dialog, and subsequent lines:
What if we didn't want all the distances to be the same? Look at this modification of the distance '''value.Dialog()''', and subsequent lines:
<syntaxhighlight lang='python'>
<syntaxhighlight lang='python'>
distances = scribus.valueDialog("Text Distance", 'Enter your text distances,\n white space in between.\nLeft Right Top Bottom', '10  10  10  10')
distances = scribus.valueDialog("Text Distance", 'Enter your text distances,\n white space in between.\nLeft Right Top Bottom', '10  10  10  10')
distance = distances.split
distance = distances.split()
distanceleft = float(distance[0])
distanceleft = float(distance[0])
distanceright = float(distance[1])
distanceright = float(distance[1])
distancetop = float(distance[2])
distancetop = float(distance[2])
distancebottom = float(distance[3]
distancebottom = float(distance[3])
</syntaxhighlight>
We could use int(distance...), but using float allows for decimals - whatever you enter into the dialog will be a string until converted, and the '''setTextDistances()''' command needs number values. In case you haven't used the built-in split function in Python, this breaks a series of values or words into a list, eliminating the white space (which can be of variable length). So here we create the list distance[] from the 4 values. I think this is more efficient than making a series of value.Dialogs.
 
I could save some lines by doing this:
<syntaxhighlight lang='python'>
scribus.setTextDistances = (float(distance[0]), float(distance[1]), float(distance[2]), float(distance[3]))
</syntaxhighlight>
</syntaxhighlight>
We could use int(distance...), but using float allows for decimals. In case you haven't used the built-in split function in Python, this breaks a series of values or words into a list, eliminating the white space (which can be of variable length). So here we create the list distance[] from the 4 values.
but this makes later review, editing, and understanding of the script more difficult.
 
==Oh yes, there's some ''voodoo'' here too!==
Look at these lines:
<syntaxhighlight lang='python'>
        scribus.moveObject(-4,0,textbox)
        scribus.moveObject(4,0,textbox)
</syntaxhighlight>
I move the text frame, then I move it back! Doesn't make sense, does it? For whatever reason, if I didn't put these in there, Scribus wouldn't redraw the frame, and I don't know why. If you're thinking that it's because I forgot the '''redrawAll()''' command, think again. I tried various combinations of '''setRedraw(True/False)''', and nothing worked.
 
What I found out was that if I moved the frame after the script ran, Scribus would redraw and place the text inside the distances, but then I'd have to move it back. So here the script does it, and voilà! ''It just works.''
==A new version==
Seth Kenlon has contributed a modified version that will set text distances on a number of selected frames. Note that this version does not check to see if all the selected frames are text frames. If they are not, you will get a WrongFrameType error.
<pre>
#!/usr/bin/env python
# -*- coding: utf-8  -*-
 
# ****************************************************************************
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# ****************************************************************************
 
 
"""
 
© 2015 by Gregory Pittman
* 2019 modified by Seth Kenlon <skenlon@redhat.com>
 
setmultiframetextdistances.py
 
Sets the text distances of selected text frames
 
USAGE
 
Select one or more text frames, and then run this script.
A dialog asks for the amount of text distance.
 
"""
 
import sys
 
try:
    import scribus
except ImportError:
    print("Unable to import the 'scribus' module. This script only runs within 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)
 
if scribus.selectionCount() == 0:
    scribus.messageBox('Scribus - Script Error', "Select a text frame and try again.", scribus.ICON_WARNING, scribus.BUTTON_OK)
    sys.exit(2)
 
# use CSS order for values (N E S W)
distances = scribus.valueDialog("Text Distance", 'Enter text padding values (in current page units) delimited by white space.\nTop Right Bottom Left', '0.2  0.2  0.2  0.2')
distance = distances.split()
distancetop = float(distance[0])
distanceright = float(distance[1])
distancebottom = float(distance[2])
distanceleft = float(distance[3])
 
n = scribus.selectionCount()
 
for i in range(0, n):
    textbox = scribus.getSelectedObject(i)
    scribus.setRedraw(False)
    scribus.setTextDistances(distanceleft,distanceright,distancetop,distancebottom,textbox)
 
    scribus.moveObject(-4,0,textbox)
    scribus.moveObject(4,0,textbox)
 
    scribus.setRedraw(True)
</pre>

Latest revision as of 22:30, 17 December 2019

This article is part of the Scripts series.

Here is a simple script for setting the text distances for a text frame. In this particular version, we set all the distances the same, so only one value is needed for the value.Dialog().

settextdistance.py

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

# ****************************************************************************
#  This program is free software; you can redistribute it and/or modify 
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# 
# ****************************************************************************


"""

© 2015 by Gregory Pittman

settextdistance.py

Sets the text distances of the selected text frame

USAGE

Select a text frame, run script.
A dialog asks for the amount of text distance.

"""

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)

if scribus.selectionCount() == 0:
    scribus.messageBox('Scribus - Script Error',
            "There is no object selected.\nPlease select a text frame and try again.",
            scribus.ICON_WARNING, scribus.BUTTON_OK)
    sys.exit(2)
if scribus.selectionCount() > 1:
    scribus.messageBox('Scribus - Script Error',
            "You have more than one object selected.\nPlease select one text frame and try again.",
            scribus.ICON_WARNING, scribus.BUTTON_OK)
    sys.exit(2)
    
distance = scribus.valueDialog("Text Distance", 'Enter your text distance', '10')
distance = float(distance)
distanceleft = distance
distanceright = distance
distancetop = distance
distancebottom = distance

textbox = scribus.getSelectedObject()
pageitems = scribus.getPageItems()
scribus.setRedraw(False)

for item in pageitems:
    if (item[0] == textbox):
        if (item[1] != 4):
            scribus.messageBox('Scribus - Script Error', 
                          "This is not a textframe. Try again.", scribus.ICON_WARNING, scribus.BUTTON_OK)
            sys.exit(2)
            
        scribus.setTextDistances(distanceleft,distanceright,distancetop,distancebottom,textbox)
        scribus.moveObject(-4,0,textbox)
        scribus.moveObject(4,0,textbox)
scribus.setRedraw(True)

More complex but more versatile

What if we didn't want all the distances to be the same? Look at this modification of the distance value.Dialog(), and subsequent lines:

distances = scribus.valueDialog("Text Distance", 'Enter your text distances,\n white space in between.\nLeft Right Top Bottom', '10  10  10  10')
distance = distances.split()
distanceleft = float(distance[0])
distanceright = float(distance[1])
distancetop = float(distance[2])
distancebottom = float(distance[3])

We could use int(distance...), but using float allows for decimals - whatever you enter into the dialog will be a string until converted, and the setTextDistances() command needs number values. In case you haven't used the built-in split function in Python, this breaks a series of values or words into a list, eliminating the white space (which can be of variable length). So here we create the list distance[] from the 4 values. I think this is more efficient than making a series of value.Dialogs.

I could save some lines by doing this:

scribus.setTextDistances = (float(distance[0]), float(distance[1]), float(distance[2]), float(distance[3]))

but this makes later review, editing, and understanding of the script more difficult.

Oh yes, there's some voodoo here too!

Look at these lines:

        scribus.moveObject(-4,0,textbox)
        scribus.moveObject(4,0,textbox)

I move the text frame, then I move it back! Doesn't make sense, does it? For whatever reason, if I didn't put these in there, Scribus wouldn't redraw the frame, and I don't know why. If you're thinking that it's because I forgot the redrawAll() command, think again. I tried various combinations of setRedraw(True/False), and nothing worked.

What I found out was that if I moved the frame after the script ran, Scribus would redraw and place the text inside the distances, but then I'd have to move it back. So here the script does it, and voilà! It just works.

A new version

Seth Kenlon has contributed a modified version that will set text distances on a number of selected frames. Note that this version does not check to see if all the selected frames are text frames. If they are not, you will get a WrongFrameType error.

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

# ****************************************************************************
#  This program is free software; you can redistribute it and/or modify 
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# 
# ****************************************************************************


"""

© 2015 by Gregory Pittman
* 2019 modified by Seth Kenlon <skenlon@redhat.com> 

setmultiframetextdistances.py

Sets the text distances of selected text frames

USAGE

Select one or more text frames, and then run this script.
A dialog asks for the amount of text distance.

"""

import sys

try:
    import scribus
except ImportError:
    print("Unable to import the 'scribus' module. This script only runs within 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)

if scribus.selectionCount() == 0:
    scribus.messageBox('Scribus - Script Error', "Select a text frame and try again.", scribus.ICON_WARNING, scribus.BUTTON_OK)
    sys.exit(2)

# use CSS order for values (N E S W)
distances = scribus.valueDialog("Text Distance", 'Enter text padding values (in current page units) delimited by white space.\nTop Right Bottom Left', '0.2  0.2  0.2  0.2')
distance = distances.split()
distancetop = float(distance[0])
distanceright = float(distance[1])
distancebottom = float(distance[2])
distanceleft = float(distance[3])

n = scribus.selectionCount()

for i in range(0, n):
    textbox = scribus.getSelectedObject(i)
    scribus.setRedraw(False)
    scribus.setTextDistances(distanceleft,distanceright,distancetop,distancebottom,textbox)

    scribus.moveObject(-4,0,textbox)
    scribus.moveObject(4,0,textbox)

    scribus.setRedraw(True)