Difference between revisions of "Scribus XML using Scripter"

From Scribus Wiki
Jump to: navigation, search
(Some initial issues)
(scribus.xsl)
 
(13 intermediate revisions by 2 users not shown)
Line 1: Line 1:
 +
{{Experimental}}{{Scripting_Index}}
 +
 
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.
 
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.
+
Scripter, of course has a LOT of access to document and object information, thus this idea was born. You might also be interested in [[Scribus xhtml using Scripter]].
  
 
===export2xml.py===
 
===export2xml.py===
 
This is a work-in-progress, so expect it to change as new features are added.
 
This is a work-in-progress, so expect it to change as new features are added.
<pre>
+
 
 +
'''EDIT 2013-11-4:''' I have now incorporated position attributes, but not using them yet in the XSL below.
 +
<syntaxhighlight lang='python'>
 
#!/usr/bin/env python
 
#!/usr/bin/env python
 
# File: export2xml.py - Extracts the content from a document, saving to an xml file
 
# File: export2xml.py - Extracts the content from a document, saving to an xml file
Line 33: Line 37:
 
         T.append('<page number="'+ strpage + '">\n')
 
         T.append('<page number="'+ strpage + '">\n')
 
         for item in d:
 
         for item in d:
 +
            Xpos, Ypos = scribus.getPosition(item[0])
 +
            Xpos = str(int(Xpos))
 +
            Ypos = str(int(Ypos))
 
             if (item[1] == 4):
 
             if (item[1] == 4):
 
                 filtered = '<para>'
 
                 filtered = '<para>'
Line 50: Line 57:
 
                         filtered = filtered + char
 
                         filtered = filtered + char
 
                     contents = filtered
 
                     contents = filtered
                 T.append('<object type="text">' + contents + '</para>\n')
+
                 T.append('<object type="text" Xpos="' + Xpos +'" Ypos ="' + Ypos + '" >' + contents + '</para>\n')
 
                 T.append('</object>\n')
 
                 T.append('</object>\n')
 
                 content.append(contents)
 
                 content.append(contents)
Line 57: Line 64:
 
                 imgsize = scribus.getSize(item[0])
 
                 imgsize = scribus.getSize(item[0])
 
                 picwidth = int(700 * imgsize[0]/pagesize[0])
 
                 picwidth = int(700 * imgsize[0]/pagesize[0])
                 T.append('<object type="image" width="' + str(picwidth) + 'px" source="' + imgname + '">' + imgname + '</object>\n')
+
                 T.append('<object type="image" width="' + str(picwidth) + 'px" source="' + imgname + '" Xpos="' + Xpos +'" Ypos ="' + Ypos + '" >' + imgname + '</object>\n')
 
                  
 
                  
 
         T.append('</page>\n')
 
         T.append('</page>\n')
Line 71: Line 78:
 
if scribus.haveDoc():
 
if scribus.haveDoc():
 
     textfile = scribus.fileDialog('Enter name of file to save to', \
 
     textfile = scribus.fileDialog('Enter name of file to save to', \
                                   filter='XML Files (*.xml);;All Files (*)')
+
                                   filter='Text Files (*.xml);;All Files (*)')
 
     try:
 
     try:
 
         if textfile == '':
 
         if textfile == '':
Line 83: Line 90:
 
                       icon=0, button1=1)
 
                       icon=0, button1=1)
  
</pre>
+
</syntaxhighlight>
 +
And here is an example of the XML you get from this:
 +
<syntaxhighlight lang='xml'>
 +
<?xml version="1.0" encoding="UTF-8"?>
 +
<?xml-stylesheet type="text/xsl" href="scribus.xsl"?>
 +
<document>
 +
<version>Scribus 1.4.3</version>
 +
<page number="1">
 +
<object type="image" width="426px" source="/home/gregp/.scribus/scrapbook/main/Image1/galapagos1.jpeg" Xpos="51" Ypos ="67" >/home/gregp/.scribus/scrapbook/main/Image1/galapagos1.jpeg
 +
</object>
 +
<object type="image" width="408px" source="/home/gregp/.scribus/scrapbook/main/Image2/galapagos2.jpeg" Xpos="214" Ypos ="510" >/home/gregp/.scribus/scrapbook/main/Image2/galapagos2.jpeg
 +
</object>
 +
<object type="text" Xpos="49" Ypos ="327" ><para>3 May. Bistritz.--Left Munich at 8:35 P.M., on 1st May, arriving at Vienna early next morning; should have arrived at 6:46, but train was an hour late. Buda-Pesth seems a wonderful place, from the glimpse which I got of it from the train and the little I could walk through the streets. I feared to go very far from the station, as we had arrived late and would start as near the correct time as possible.</para><para>I found my smattering of German very useful here, indeed, I don't know how I should be able to get on without it.</para>
 +
</object>
 +
</page>
 +
<page number="2">
 +
<object type="image" width="370px" source="/home/gregp/.scribus/scrapbook/main/Image4/galapagos3.jpeg" Xpos="46" Ypos ="44" >/home/gregp/.scribus/scrapbook/main/Image4/galapagos3.jpeg
 +
</object>
 +
</page>
 +
</document>
 +
 
 +
</syntaxhighlight>
 +
 
 
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 based on an arbitrary width of 900px, with the plan to have additional tables inside for objects.
 
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 based on an arbitrary width of 900px, with the plan to have additional tables inside for objects.
  
Line 100: Line 129:
 
This is not the same as the one used to convert the modified SLA/XML files, so watch the naming not only here, but also in the script above, and change as needed. Note that the background of the webpage is a grey, while the background of the document "pages" is white.
 
This is not the same as the one used to convert the modified SLA/XML files, so watch the naming not only here, but also in the script above, and change as needed. Note that the background of the webpage is a grey, while the background of the document "pages" is white.
  
<pre>
+
<syntaxhighlight lang="xml">
 
<?xml version="1.0" encoding="utf-8"?>
 
<?xml version="1.0" encoding="utf-8"?>
  
Line 139: Line 168:
 
</xsl:stylesheet>
 
</xsl:stylesheet>
  
</pre>
+
</syntaxhighlight>

Latest revision as of 02:29, 30 November 2013

 Hourglass1.png This feature/option is considered experimental
This article is part of the Scripts series.

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. You might also be interested in Scribus xhtml using Scripter.

export2xml.py

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

EDIT 2013-11-4: I have now incorporated position attributes, but not using them yet in the XSL below.

#!/usr/bin/env python
# File: export2xml.py - 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('<document>\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):
        scribus.gotoPage(page)
        pagesize = scribus.getPageSize()
        d = scribus.getPageItems()
        strpage = str(page)
        T.append('<page number="'+ strpage + '">\n')
        for item in d:
            Xpos, Ypos = scribus.getPosition(item[0])
            Xpos = str(int(Xpos))
            Ypos = str(int(Ypos))
            if (item[1] == 4):
                filtered = '<para>'
                contents = scribus.getAllText(item[0])
                if (contents in content):
                    contents = ''
                else:
                    for char in contents:
                        if (ord(char) == 28):
                            char = ' '
                        elif (ord(char) == 27):
                            char = chr(10)
                        elif (ord(char) == 38):
                            char = '&amp;'
                        elif ((ord(char) == 13) or (ord(char) == 10)):
                            char = "</para><para>"
                        filtered = filtered + char
                    contents = filtered
                T.append('<object type="text" Xpos="' + Xpos +'" Ypos ="' + Ypos + '" >' + contents + '</para>\n')
                T.append('</object>\n')
                content.append(contents)
            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 + '" Xpos="' + Xpos +'" Ypos ="' + Ypos + '" >' + imgname + '</object>\n')
                
        T.append('</page>\n')
        page += 1
    T.append('</document>\n')
    output_file = open(textfile,'w')
    output_file.writelines(T)
    output_file.close()
    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 (*)')
    try:
        if textfile == '':
            raise Exception
        exportText(textfile)
    except Exception, e:
        print e

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

And here is an example of the XML you get from this:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="scribus.xsl"?>
<document>
<version>Scribus 1.4.3</version>
<page number="1">
<object type="image" width="426px" source="/home/gregp/.scribus/scrapbook/main/Image1/galapagos1.jpeg" Xpos="51" Ypos ="67" >/home/gregp/.scribus/scrapbook/main/Image1/galapagos1.jpeg
</object>
<object type="image" width="408px" source="/home/gregp/.scribus/scrapbook/main/Image2/galapagos2.jpeg" Xpos="214" Ypos ="510" >/home/gregp/.scribus/scrapbook/main/Image2/galapagos2.jpeg
</object>
<object type="text" Xpos="49" Ypos ="327" ><para>3 May. Bistritz.--Left Munich at 8:35 P.M., on 1st May, arriving at Vienna early next morning; should have arrived at 6:46, but train was an hour late. Buda-Pesth seems a wonderful place, from the glimpse which I got of it from the train and the little I could walk through the streets. I feared to go very far from the station, as we had arrived late and would start as near the correct time as possible.</para><para>I found my smattering of German very useful here, indeed, I don't know how I should be able to get on without it.</para>
</object>
</page>
<page number="2">
<object type="image" width="370px" source="/home/gregp/.scribus/scrapbook/main/Image4/galapagos3.jpeg" Xpos="46" Ypos ="44" >/home/gregp/.scribus/scrapbook/main/Image4/galapagos3.jpeg
</object>
</page>
</document>

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 based on an arbitrary width of 900px, 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 objects, 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 getPosition data on objects to then sort them – after that, the trick is to use some positioning method. 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. I suspect I will discover other characters that need similar treatment.

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.

scribus.xsl

This is not the same as the one used to convert the modified SLA/XML files, so watch the naming not only here, but also in the script above, and change as needed. Note that the background of the webpage is a grey, while the background of the document "pages" is white.

<?xml version="1.0" encoding="utf-8"?>

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">

    <html>
    <body bgcolor="#eeeeee">
      <xsl:for-each select="document">
	<h3>This document was created using <xsl:value-of select="version" /></h3>
	<xsl:for-each select="page">
	  <table border="1" cellspacing="0" bgcolor="ffffff">
	    <tr><td width="900px" height="1160px" valign="top">
	  <p><strong>Page <xsl:value-of select="@number" /></strong></p>
	  <xsl:for-each select="object">
	    <xsl:if test="(@type='text')">
	      <table border="0">
		<tr><td width="20px"></td><td>
		<xsl:for-each select="para">
		  <p><xsl:value-of select="." /></p>
		</xsl:for-each></td></tr>
	      </table>
	    </xsl:if>
	    <xsl:if test="@type='image'">
	      <table border="0" style="position: relative; left: 150;">
		<tr><td width="20px"></td><td><img src="{@source}" width="{@width}" /></td></tr>
	      </table>
	    </xsl:if>
	  </xsl:for-each>
	  </td></tr>
	</table>
	</xsl:for-each>
      </xsl:for-each>
    </body>
    </html>
  </xsl:template>
</xsl:stylesheet>