Formatxml

Import xml and apply styles using formatxml
This script places the content of a xml file in a selected Scribus document. The content is every text node including ignorable whitespace.

The content is placed in a text frame that is created automatically in the selected Scribus document. The dimensions of the text frame are based on the live area of the document. That is the size of the page minus the margins. New pages with connected text frames will be created while the current text frame overflows.

Upon execution the script will prompt for three files:
 * 1) the xml file that will be imported;
 * 2) the scribus template (an empty document);
 * 3) the location where the document should be saved.

When the script is done the document will be saved and closed.

Apply a style to the content of an element
The script handles two attributes in the namespace "http://www.scribus.net/formatxml": In the following example the style of the title of a (very short) chapter is set to "header 1" and the style of the para's is set to "body". The contents of the is set in "Verdana Italic".  The title of the chapter Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer egestas mi nec lectus molestie condimentum. Duis quam sapien, pharetra non tempor quis, dignissim eleifend eros. Note that the script imports every text node including any whitespace and line ends. So paragraphs are imported as is in the xml file.
 * style The value is a style to be applied to the content of the element.
 * override The value is a font to be applied to the content of an element.

Styles are inherited by default
In the previous example every para was labeled with a style-attribute. That is not necessary because styles are inherited by default. The following example will give the same result:  The title of the chapter Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer egestas mi nec lectus molestie condimentum. Duis quam sapien, pharetra non tempor. The para's don't have a style attribute. The style attribute is set to the chapter so the contents every descendant of chapter will be set to "body". However "body" is not applied to because it has a style attribute of its own. So "header 1" will be applied to the contents of. The para's do not have a style attribute so "body" is applied which inherited from.

Source
import sys try: # Please do not use 'from scribus import *'. If you must use a 'from import', # Do so _after_ the 'import scribus' and only import the names you need, such # as commonly used constants. import scribus except ImportError, err: print "This Python script is written for the Scribus scripting interface." print "It can only be run from within Scribus." sys.exit(1) import xml.sax import xml.sax.handler class XMLFormatter (xml.sax.handler.ContentHandler): """Formats xml in scribus document   Every text node including whitespace is placed in the document    Paragraph styles are applied through an attribute sla:style in the namespace "http://www.scribus.net/formatxml".    Character styles are applied through the attribute sla:override in the same namespace    Paragraph and character styles are inherited automatically""" def __init__ (self): self.styles = [None] self.overrides = [None] self.template = "" self.document = "" self.name = "" self.in_namespace = False self.prefix = None self.first = True def make_textframe (self): margins = scribus.getPageMargins size = scribus.getPageSize w = size[0] - margins[1] - margins[3] h = size[1] - margins[0] - margins[2] return scribus.createText (margins[1], margins[0], w, h)   def startPrefixMapping(self, prefix, uri): """checks if current node is in proper namespace""" if uri == "http://www.scribus.net/formatxml": self.in_namespace = True if prefix != "": self.prefix = prefix + ":" def endPrefixMapping(self, prefix): """signal that we are no longer in namespace""" if self.in_namespace: self.in_namespace = False self.prefix = None def startDocument(self): """Open document""" scribus.openDoc(self.template) self.name = self.make_textframe def add_style (self, stack, style): if style == None: style = stack[-1] stack.append(style) def startElementNS(self, name, qname, attrs): """record styles or overrides""" attrs_names = attrs.getQNames if self.in_namespace: if self.prefix + "style" in attrs_names: style = attrs.getValueByQName(self.prefix + "style") else: style = None self.add_style(self.styles, style) if self.prefix + "override" in attrs_names: override = attrs.getValueByQName(self.prefix + "override") else: override = None self.add_style(self.overrides, override) def endElementNS(self, name, qname): self.styles.pop self.overrides.pop def shouldSetStyle (self): if self.first: return True else: return scribus.getAllText(self.name)[-1] == "\r" def characters(self, content): """place text, apply style""" start = scribus.getTextLength(self.name) go_ahead = self.shouldSetStyle scribus.insertText (content, -1, self.name) scribus.selectText(start, len(content), self.name) if self.styles[-1] != None and go_ahead: try: scribus.setStyle(self.styles[-1], self.name) except scribus.NotFoundError: scribus.createParagraphStyle(self.styles[-1]) scribus.setStyle(self.styles[-1], self.name) if self.overrides[-1] != None: try: scribus.setFont(self.overrides[-1], self.name) except ValueError: pass self.first = False def flow(self): while(scribus.textOverflows(self.name) > 0 and scribus.getTextLines(self.name)): current = self.name scribus.newPage(-1) scribus.gotoPage( scribus.pageCount ) self.name = self.make_textframe scribus.linkTextFrames(current, self.name) def endDocument(self): """Save and close document""" self.flow scribus.saveDocAs(self.document) scribus.closeDoc class UserCanceled (Exception): pass def format(xml_file, scribus_template, document): fmt = XMLFormatter fmt.template = scribus_template fmt.document = document p = xml.sax.make_parser p.setFeature(xml.sax.handler.feature_namespaces, True) p.setContentHandler(fmt) p.parse(xml_file) def getFile(caption, filter, defaultname, issave): file = scribus.fileDialog(caption, filter, defaultname, issave) if len(file) == 0: raise UserCanceled("canceled") else: return file def main: """Formats xml file using Scribus template""" try: xml_file = getFile("XML File", 'XML (*.xml)') template = getFile("Scribus template", "Scribus document (*.sla)") document = getFile("Save document", "Alles (*.*)", xml_file.replace(".xml", ".sla"), False, True) format (xml_file, template, document) except UserCanceled: pass except xml.sax.SAXParseException: scribus.messageBox("XML Error", "XML Error: please check your document") def main_wrapper: """The main_wrapper function disables redrawing, sets a sensible generic   status bar message, and optionally sets up the progress bar. It then runs    the main function. Once everything finishes it cleans up after the main    function, making sure everything is sane before the script terminates.""" try: scribus.statusMessage("Running script...") scribus.progressReset main finally: # Exit neatly even if the script terminated with an exception, # so we leave the progress bar and status bar blank and make sure # drawing is enabled. if scribus.haveDoc: scribus.setRedraw(True) scribus.statusMessage("") scribus.progressReset if __name__ == '__main__': main_wrapper
 * 1) !/usr/bin/env python
 * 2) -*- coding: utf-8 -*-
 * 1) end class XMLFormatter
 * 1) end class UserCanceled
 * 1) This code detects if the script is being run as a script, or imported as a module.
 * 2) It only runs main if being run as a script. This permits you to import your script
 * 3) and control it manually for debugging.