[Scribus] Scripting

Randolph Bentson bentson
Wed Sep 10 18:19:51 CEST 2003


On Wed, Sep 10, 2003 at 07:19:25AM -0400, Marshall Lake wrote:
> 
> Can someone briefly explain to me the advantages of scripting in Scribus?
> I have never used Python.  Would it be worth my while to learn the
> language in order to do scripting on Scribus?  Is scripting on Scribus
> available in any other languages?

I used scripting to typeset much of my wife's cookbook.  The scripts
extracted structured text which she wrote, one recipe per file, and
put it on pages in the cookbook. (See attached program.)

As is true for most programs, were I to do it again ("refactoring"
in today's jargon), the program and process would have a somewhat
different form.  The important point here is that the script made
it possible to import these files and deal with them correctly.
(I've a list of scripting features I'd like to see, but that's
another topic.)


I've also been using Scribus to write a monthly newsletter.  You
can find issues at http://grieg.holmsjoen.com/NWMultihull/, but
I ask that you only pick up a small issue.  I've also put the .scd
for one of these issues in the same directory for your consideration.
I've used a simple script to add page numbers, but now that I have
learned of the special tags one can use, this may be cast aside.

-- 
Randolph Bentson
bentson at holmsjoen.com
-------------- next part --------------
#!/usr/bin/env python
"""
Extract recipe from TXT file and place it onto a
page appended to current Scribus document.
"""

import os
import sys
import scribus

pagewidth = 396
pageheight = 612
in_margin = 56
out_margin = 18
t_margin = 72
b_margin = 18

filenamelist = "input.files"

def fix(lines):
    str = ''.join(lines)
    str = str.replace("\xe2\x80\x93","-") # ??? dash
    str = str.replace("\xe2\x80\x98","'") # ??? open quote
    str = str.replace("\xe2\x80\x99","'") # ??? close quote
    str = str.replace("\xe2\x80\x9c","\"") # ??? open double quote
    str = str.replace("\xe2\x80\x9d","\"") # ??? close double quote
    str = str.replace("\xc3\x89","E") # ?? E-acute
    str = str.replace("\xc3\xa9","e") # ?? e-acute
    str = str.replace("\xc3\xa8","e") # ?? e-grave
    str = str.replace("\xc3\xb1","n") # ?? enya
    str = str.replace("\xc3\xb1","??") # Registered Trademark
    str = str.replace("\r\n","\n") # DOS to Unix line structure
    return str

def get_recipe(filename):
    ''' Get six major elements of recipe from TXT or DOC file.'''
    # find file -- use .txt file if it is more recent than .doc file
    altfilename = filename.replace(".doc",".txt")
    if os.path.exists(altfilename):
        if os.path.exists(filename):
            astat = os.stat(altfilename)
            bstat = os.stat(filename)
            if astat[8] > bstat[8]:
                fd = open(altfilename,'r')
                print "using %s" % altfilename
            else:
                # I was surprised when this failed
                #   fd = os.popen("/home/bentson/bin/antiword '%s'" % filename,'r')
                # because there was a "'" in the filename
                fd = os.popen('/home/bentson/bin/antiword "%s"' % filename,'r')
                print "using %s" % filename
        else:
            fd = open(altfilename,'r')
            print "using %s" % altfilename
    else:
        if os.path.exists(filename):
            fd = os.popen('/home/bentson/bin/antiword "%s"' % filename,'r')
            print "using %s" % filename
        else:
            raise OSError
    lines = fd.readlines()
    fd.close()
    line = 0

    (title, introduction, servings, ingredients,
     instructions, nutrition, suggestions) =\
    ([''], [''], [''], [''], [''], [''], [[''],[''],],)
    try:
        # first non-blank line is title
        while lines[line] == "\n" or lines[line] == "\r\n":
            # above test should really be for whitespace only line
            line = line + 1 # eat blank lines
        title.append(lines[line].strip())
        line = line + 1
        # The following repeated idiom should be moved to a function!!!
        # non-blank lines up to "Servings:" are introduction
        while lines[line].find('Servings') == -1:
            if lines[line] != "\n" and lines[line] != "\r\n":
                introduction.append(lines[line])
            line = line + 1
        # non-blank lines up to "Ingredients" are servings
        while lines[line].find('Ingredients') == -1:
            if lines[line] != "\n" and lines[line] != "\r\n":
                servings.append(lines[line])
            line = line + 1
        line = line + 1 # skip line which says 'Ingredients'
        # non-blank lines up to "Instructions" are ingredients
        while lines[line].find('Instructions') == -1:
            if lines[line] != "\n" and lines[line] != "\r\n":
                ingredients.append(lines[line])
            line = line + 1
        line = line + 1 # skip line which says 'Instructions'
        # non-blank lines up to "Nutritional Information" are instructions
        while lines[line].find('Nutritional Information') == -1:
            if lines[line] != "\n" and lines[line] != "\r\n":
                instructions.append(lines[line])
            line = line + 1
        line = line + 1 # skip line which says 'Nutritional Information'
        # non-blank lines up to "Suggest...." are nutritional information
        while lines[line].find('Suggest') == -1:
            if lines[line] != "\n" and lines[line] != "\r\n":
                nutrition.append(lines[line])
            line = line + 1
        suggestions[0].append(lines[line])
        line = line + 1
        # remaining non-blank lines are suggestions
        while line < len(lines):
            if lines[line] != "\n" and lines[line] != "\r\n":
                suggestions[1].append(lines[line])
            line = line + 1
    except:
        pass
    return (fix(title), fix(introduction),
            fix(servings), fix(ingredients),
            fix(instructions), fix(nutrition),
            [fix(suggestions[0]), fix(suggestions[1]),])

# TEXT PLACEMENT ROUTINES
# Emit appropriate Scribus commands for each of blocks.

fontname = {}
fontsize = {}
align = {}
fontname['title']="Times Bold"
fontsize['title']=16
align['title'] = scribus.Centered
fontname['subtitle']="Times Bold"
fontsize['subtitle']=11
align['subtitle'] = scribus.LeftAlign
fontname['italic']="Times Medium Italic"
fontsize['italic']=11
align['italic'] = scribus.LeftAlign
fontname['regular']="Times Medium"
fontsize['regular']=11
align['regular'] = scribus.LeftAlign
fontname['small']="Times Medium Italic"
fontsize['small']=9
align['small'] = scribus.LeftAlign

def insert_block(what,where,str):
    "stuff multiple lines of text in newly formed text block"
    x,y,lines = where
    h = (fontsize[what] * leading ) * lines + descender
    w = pagewidth - in_margin - out_margin
    ob = scribus.CreateText(x,y,w,h,hex(hash(str)))
    scribus.SetTextAlignment(align[what],ob)
    scribus.SetFont(fontname[what],ob)
    scribus.SetFontSize(fontsize[what],ob)
    scribus.SetLineSpacing(fontsize[what]*leading,ob)
    scribus.SetText(str, ob)
    return h

def one_page(pagenum, title, introduction,
             servings, ingredients, instructions,
             nutrition, suggestions):
    if pagenum % 2:
        x = in_margin
    else:
        x = out_margin
    y = t_margin

    d_h = insert_block('title',(x,y,1),title)
    y = y + d_h + para_break
    lc = introduction.count('\n')
    d_h = insert_block('italic',(x,y,lc), introduction)
    y = y + d_h + para_break
    lc = servings.count('\n')
    d_h = insert_block('regular',(x,y,lc),servings)
    y = y + d_h + para_break
    d_h = insert_block('subtitle',(x,y,1),"Ingredients")
    y = y + d_h
    lc = ingredients.count('\n')
    d_h = insert_block('regular',(x,y,lc), ingredients)
    y = y + d_h + para_break
    d_h = insert_block('subtitle',(x,y,1),"Instructions")
    y = y + d_h
    lc = instructions.count('\n')
    d_h = insert_block('regular',(x,y,lc), instructions)
    y = y + d_h + para_break
    d_h = insert_block('subtitle',(x,y,1),"Nutritional Information")
    y = y + d_h
    lc = nutrition.count('\n')
    d_h = insert_block('small',(x,y,lc), nutrition)
    y = y + d_h + para_break
    if suggestions[0] != '':
        d_h = insert_block('subtitle',(x,y,1),suggestions[0])
        y = y + d_h
        lc = suggestions[1].count('\n')
        d_h = insert_block('small',(x,y,lc), suggestions[1])
        y = y + d_h

if __name__ == "__main__" and scribus.HaveDoc():
    #import time
    #start_at = time.time()
    para_break = 5#11
    leading = 1.1 # to make large pages fit? 1.2
    descender = 7
    firstpagenum = scribus.PageCount()

    fd = open(filenamelist,'r')
    lines = fd.readlines()
    for line in lines:
        if line[0] == '#':
            continue
        filename = line.strip()
        ####
        try:
            (title, introduction, servings,
             ingredients, instructions, nutrition,
             suggestions) = get_recipe(filename)
            scribus.NewPage(-1)
            pagenum = scribus.PageCount()
            scribus.GotoPage(pagenum)
            #print '>',pagenum,'<'
            #print '>',title,'<'
            #print '>',introduction,'<'
            #print '>',servings,'<'
            #print '>',ingredients,'<'
            #print '>',instructions,'<'
            #print '>',nutrition,'<'
            #print '>',suggestions[0],'<'
            #print '>',suggestions[1],'<'
            one_page(pagenum, title, introduction,
                     servings, ingredients, instructions,
                     nutrition, suggestions)
        except OSError:
            print "Error error processing %s" % filename
    scribus.GotoPage(firstpagenum + 1)
    #done_at = time.time()
    #elapsed = done_at - start_at
    #print "used %d seconds" % elapsed



More information about the scribus mailing list