Text and Text Manipulation

From Scribus Wiki
Jump to navigation Jump to search

After having just finished a script which involved creating a variable number, sometimes large number of text frames, along the way I learned quite a bit about how to use the various commands for styles and text. Some of this is not found in the online manual, and would be difficult to include there. What I'd like to do here is save others the time it took me to find out these important aspects of scripting.

The Setting

The particular project I was involved with took color data from a file, creating colors from that data, then making a document which displayed those colors with an informational label underneath. Here is a small detail from the eventually created pages:


This is the appearance in Scribus, so in the actual document these text frames will have no color to the border. The top line in the text frame is the name of the color, then the column of numbers underneath represent the L, a, and b values that created the above color. The input came from a plain text file, where entries look like this:

HLC 010 50 60	50	59,1	10,4
HLC 010 50 70	50	68,9	12,2

To the left we see the color name, represented by 3 letters followed by 7 digits with some intervening spaces. Although not visible here, there are tabs separating the name from the 3 following numbers and the numbers from each other. This helps as we try to parse these lines with Python. Notice that the numbers use a comma as a decimal separator, something else we will need to contend with, since to create a color from these Python will need to have floating point numbers.

Parsing the Color Data

for line in open(colorfile).xreadlines():
    content = line.split('\t')
    fields = len(content)
    if (fields == 4):
        Lval = content[fields - 3]
        Lval = re.sub(r',','.',Lval)
        Lval = float(Lval)
        aval = content[fields - 2]
        aval = re.sub(r',','.',aval)
        aval = float(aval)
        bval = content[fields - 1]
        bval = re.sub(r',','.',bval)
        bval = float(bval)

The first line opens the file that we have identified in a fileDialog() line by line. This line is imported as a string. The string is then split using a tab ('\t') as the separator, and assigned as a list to the variable content. We have previously created empty lists, color[], L[], a[], and b[]. The color name remains a string appended to colors[]. The L value is contained in the part of content[] which is 3rd from the end, the a value 2nd from the end, and b from the last item in contents. From the re module that we imported at the beginning of the script (re contains regex operations) we use the re.sub method to change the commas to periods, but of course this remains a string, so then we must convert each to a float value, which we append to the appropriate list.

Creating the Colors

This is one of the simplest parts of the script, accomplished by looping through our color data lists, then using this command:

        scribus.defineColorLab(colors[index], float(L[index]), float(a[index]), float(b[index]))

Now the Document

Once we have the colors, the next step is to go on to the display of the colors and information about them. It was desired that the document be A4 paper, with units in millimeters. Looping through the colors list creates the color patches:

           newrectangle = scribus.createRect(xpos,ypos,22,12)
           scribus.setFillColor(colors[index], newrectangle)

The variables xpos and ypos begin at 25, 30, after which the array is formed mathematically, jumping 25 mm in the X direction to complete a row, and 35 mm in the Y direction to jump to the next row.

Creating the associated label text frames is best done after each color patch is created:

           newtext = scribus.createText(xpos, ypos + 13.5, 22, 15)
           if (len(colors[index])<18):
               spacer = '\n'
               spacer = ''
           data = str(L[index]) + '\n' + str(a[index]) + '\n' + str(b[index])
           scribus.setText(colors[index]+spacer+'\n'+ data, newtext)

Notice this variable spacer. This was created because of the variability in the length of color names; some used only one line, some two, a few three, and rarely four. Trial and error came up with this scheme to use 18 characters as the decision point to add an extra newline character or not. It's imperfect, since a proportional font is used and also since line breaks depend on length of and spacing between parts of the name. This label size will take care of most situations, but occasionally the height was too small. The answer came from check for overflowing text:

           overflow = scribus.textOverflows(newtext)
           if overflow == 1:
               scribus.sizeObject(22,20, newtext)

This needed to be done after the particular font and font size were set.

Working with Fonts and Styles