Scribus - Vertically Align Text Within A Text Frame

Solution 1:

Using Scribus 1.5.4:

  1. Right-click on a text box and select Text Properties;
  2. Click on Column & Text Distances;
  3. On the first line, change Vertical Alignment to the desired value (for example Middle).

Screenshot of the Text Properties menu

No need for scripts, manual margins or black magic.

Solution 2:

Using Scribus 1.4.6, the following script center (vertical) align the content of a text frame by Alessandro Rimoldi was able to vertically align the text within a text frame:

  • doing so automatically even when the linespacing and/or the first line offset is changed afterwards
  • and with multiple paragraphs of different styles

Here is the script (if needed, a brief instruction on how to use the script follows these lines of code):

#!/usr/bin/python
"""
this script adjust the top and bottom distance of a text frame
to exactly put its content in the middle of the frame
@author: alessandro rimoldi
@version: 1.0 / 20090209
@copyright (c) 2009 alessandro rimoldi under the mit license
           http://www.opensource.org/licenses/mit-license.html
"""
import sys
try:
   import scribus
except ImportError:
   print "This script only works from within Scribus"
   sys.exit(1)

# check that the selection is one text frame and get that frame
frame_n = scribus.selectionCount()
if frame_n == 0 :
    scribus.messageBox('Error:', 'No frame selected');
    sys.exit(1)
elif frame_n > 1 :
    scribus.messageBox('Error:', 'You may select only one frame');
    sys.exit(1)

frame = scribus.getSelectedObject(0)
try:
    char_n = scribus.getTextLength(frame)
except scribus.WrongFrameTypeError:
    scribus.messageBox('Error:', 'You may only adjust text frames');
    sys.exit(1)

if char_n == 0 :
    scribus.messageBox('Error:', 'You can\'t adjust an empty frame');
    sys.exit(1)

if (scribus.textOverflows(frame) == 1) :
    scribus.messageBox('Error:', 'You can\' center a text which is overflowing');
    sys.exit(1)

# get some page and frame measure

(x, y) = scribus.getPosition(frame)

(w, h) = scribus.getSize(frame)

original_height = h

(dl, dr, dt, db) = scribus.getTextDistances();

scribus.setTextDistances(dl, dr, 0, 0);

# if the frame doesn't overflow, shorten it to make it overflow
while ((scribus.textOverflows(frame) == 0) and (h > 0)) :
    h -= 10
    scribus.sizeObject(w, h, frame)

# resize the frame in 10pt steps
while (scribus.textOverflows(frame) > 0) :
    h += 10
    scribus.sizeObject(w, h, frame)

# undo the latest 10pt step and fine adjust in 1pt steps
h -= 10
scribus.sizeObject(w, h, frame)

while (scribus.textOverflows(frame) > 0) :
    h += 1
    scribus.sizeObject(w, h, frame)


scribus.sizeObject(w, original_height, frame)

dt = (original_height - h) / 2

scribus.setTextDistances(dl, dr, dt, dt);

Here is how to use the script:

  1. copy and paste the script in a text document (using bloc note or notepad for example) with no style formatting applied to the document;
  2. save the document as a .py file, calling it whatever name you want;
  3. in Scribus, select the text frame;
  4. go to Script (next to Extras) in the main menu at the top, then select Execute Scripts...;
  5. a Run Script window appears in which you select the .py file you have created;
  6. press OK.

The text inside the selected text frame will then be vertically centred.

I could experience at least two drawbacks with this script:

  • it is necessary to rerun the script if either the height or width of the text frame has been modified
  • it cannot center the text if it is overflowing as it creates some kind of top and bottom margins (so maybe not ideal for large texts)

This script overcomes the fact that the script mentioned in Jon Bentley's answer did not work for me (in Scribus 1.4.6 at least), showing an error message with the following line:

ValueError: Text distances out of bounds, must be positive.

which is maybe related more to the document than the script itself.

Solution 3:

Select the text frame and hit F2 or right-click and choose properties. Then select the Shape section. There you can set a left margin offset from the edge of the text frame that will align the text in the frame. You can also set tabs and columns if that is more in line with your goal.

Solution 4:

Surprisingly for such a simple and common feature, there doesn't appear to be an option for this in Scribus as of version 1.4.5. Here are three workarounds (none of which are ideal solutions unfortunately), one of which is based on @W_Whalley's answer (which is out of date for Scribus' current UI):

Manually set the spacing within the text frame

Adapted from @W_Whalley's answer:

  1. Open Properties for the text frame (select and press F2, or right click and select Properties).
  2. Select the Text tab.
  3. Open the Columns & Text Distances drop-down.
  4. Adjust the margins to achieve the desired alignment.

Disadvantages:

  • You will have to work out the margins manually.
  • It will only result in an approximation unless you work hard to calculate the margins.
  • You will have to redo it every time you make a change that alters the alignment.

Align the text frame itself within another object

Based on the suggested solution on the Scribus Wiki:

  1. Surround the text frame with another object (e.g. another text frame).
  2. Select the inner frame and the outer frame together in that order (using the shift key).
  3. Open the Align and Distribute window.
  4. Set Relative to to Last Selected.
  5. Click Centre on horizontal axis.

Disadvantages:

  • It is imprecise due to the text not being vertically aligned within the inner text frame.
  • You will have to redo it every time you make a change that alters the alignment.

Use a script

  1. Use this script from the Scribus Wiki.

I have not personally tried this option so can't confirm how effective it is. From the description it would appear to solve most of the disadvantages of the other two methods leaving just one:

  • You will have to redo it every time you make a change that alters the alignment.