Scribus XML using Scripter

From Scribus Wiki
Jump to navigation Jump to search

One of the issues that very quickly was noticeable with using a modified SLA file as in Scribus files as XML was the realization that PAGEOBJECTS in an SLA file are appended at the end of the file as they are created. There is an attribute, OwnPage, that tells which page the object is placed on. Even though there might be a trend to add objects in sequence with the pages, it isn't unusual sometime near the end of the layout process to add something up front. This can be overcome (most likely), but requires a lot more logic in the XSL file.

Scripter, of course has a LOT of access to document and object information, thus this idea was born.

This is a work-in-progress, so expect it to change as new features are added.

#!/usr/bin/env python
# File: - Extracts the content from a document, saving to an xml file
# 2013.10.29 Gregory Pittman
# 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.

import scribus

def exportText(textfile):
    page = 1
    pagenum = scribus.pageCount()
    T = []
    content = []
    T.append('<?xml version="1.0" encoding="UTF-8"?>\n')
    T.append('<?xml-stylesheet type="text/xsl" href="scribus.xsl"?>\n')
    T.append('<version>Scribus ' + str(scribus.scribus_version_info[0]) + '.' + str(scribus.scribus_version_info[1]) + '.' + str(scribus.scribus_version_info[2]) + str(scribus.scribus_version_info[3]) + '</version>\n')
    while (page <= pagenum):
        pagesize = scribus.getPageSize()
        d = scribus.getPageItems()
        strpage = str(page)
        T.append('<page number="'+ strpage + '">\n')
        for item in d:
            if (item[1] == 4):
                filtered = '<para>'
                contents = scribus.getAllText(item[0])
                if (contents in content):
                    contents = ''
                    for char in contents:
                        if (ord(char) == 28):
                            char = ' '
                        elif (ord(char) == 27):
                            char = chr(10)
                        elif (ord(char) == 38):
                            char = '&'
                        elif ((ord(char) == 13) or (ord(char) == 10)):
                            char = "</para><para>"
                        filtered = filtered + char
                    contents = filtered
                T.append('<object type="text">' + contents + '</para>\n')
            elif (item[1] == 2):
                imgname = scribus.getImageFile(item[0])
                imgsize = scribus.getSize(item[0])
                picwidth = int(700 * imgsize[0]/pagesize[0])
                T.append('<object type="image" width="' + str(picwidth) + 'px" source="' + imgname + '">' + imgname + '</object>\n')
        page += 1
    output_file = open(textfile,'w')
    endmessage = textfile + ' was created'
    scribus.messageBox("Finished", endmessage,icon=0,button1=1)

if scribus.haveDoc():
    textfile = scribus.fileDialog('Enter name of file to save to', \
                                  filter='Text Files (*.xml);;All Files (*)')
        if textfile == '':
            raise Exception
    except Exception, e:
        print e

    scribus.messageBox('Export Error', 'You need a Document open, and a frame selected.', \
                       icon=0, button1=1)

The starting point was to generate pseudopages (this is all just one big webpage) by using the table tags to map out a space. By using page dimensions, a proportionally-sized area could be made, with the plan to have additional tables inside for objects.

Some initial issues

Similar to the overall object-ordering problem in a SLA file, each page numbers frames as you add them, so as you make a list of page object, this order is created, but this is at least a smaller problem than ordering objects from many different pages. My plan is to use the Position data on objects to then sort them. Presently, I still haven't decided whether to use CSS or some other method to try to semi-accurately position objects on the table page space.

In contrast to using an SLA file, the output from Scripter with text frames may not be XML-compliant. For example, the '&' character comes out as that character. The answer is to send it to XML as &amp; instead.

Another issue is tabs, which come out as a Ctrl-something-inscrutable character. So far, I have simply deleted these.

Next is the issue with CR/nextline characters, which come out as ASCII 10 or 13. Taking a cue from the SLA files, I instead create a para tag to handle this, to create p tags.

At this point, the script works, but only handles text and image frames. No usage of style information is present, as of yet. It does work with both Scribus 1.4.3 and 1.5.0svn.


This is not the same as the one used to convert the modified SLA/XML files, so watch the naming, and change as needed.