[Checkins] SVN: z3c.rml/trunk/src/z3c/rml/ * Implemented
'drawAlignedString' tag, since the functionality is directly
Stephan Richter
srichter at cosmos.phy.tufts.edu
Thu Mar 15 15:23:16 EDT 2007
Log message for revision 73204:
* Implemented 'drawAlignedString' tag, since the functionality is directly
available in the canvas. The tests show that it does not look that good
anyways. Maybe with another font it works better.
* Implemented 'mergePage' tag for page drawings. This feature allows you to
specify a page of another PDF file to be used as the background of the
page that you are working on.
This feature is extremly useful if you have existing PDF files/forms that
you need to fill out. A demonstration for a W-2 form is attached. ;-)
You need pyPdf to use this feature.
Changed:
U z3c.rml/trunk/src/z3c/rml/attr.py
U z3c.rml/trunk/src/z3c/rml/canvas.py
U z3c.rml/trunk/src/z3c/rml/interfaces.py
A z3c.rml/trunk/src/z3c/rml/page.py
A z3c.rml/trunk/src/z3c/rml/tests/input/data/
A z3c.rml/trunk/src/z3c/rml/tests/input/data/fw2.pdf
A z3c.rml/trunk/src/z3c/rml/tests/input/tag-drawAlignedString.rml
A z3c.rml/trunk/src/z3c/rml/tests/input/tag-mergePage.rml
D z3c.rml/trunk/src/z3c/rml/tests/input/tag-mergeWith.rml
-=-
Modified: z3c.rml/trunk/src/z3c/rml/attr.py
===================================================================
--- z3c.rml/trunk/src/z3c/rml/attr.py 2007-03-15 18:52:33 UTC (rev 73203)
+++ z3c.rml/trunk/src/z3c/rml/attr.py 2007-03-15 19:23:10 UTC (rev 73204)
@@ -163,15 +163,16 @@
return unit[1]*float(res.group(1))
raise ValueError('The value %r is not a valid measurement.' %value)
-class Image(Text):
+class File(Text):
+
open = staticmethod(urllib.urlopen)
packageExtract = re.compile('^\[([0-9A-z_.]*)\]/(.*)$')
- def __init__(self, name=None, default=DEFAULT, onlyOpen=False):
- super(Image, self).__init__(name, default)
- self.onlyOpen = onlyOpen
+ def __init__(self, name=None, default=DEFAULT):
+ super(File, self).__init__(name, default)
+
def convert(self, value, context=None):
# Check whether the value is of the form:
# [<module.path>]/rel/path/image.gif"
@@ -185,17 +186,25 @@
value = os.path.join(os.path.dirname(module.__file__), path)
# Open/Download the file
fileObj = self.open(value)
- if self.onlyOpen:
- return fileObj
- # ImageReader wants to be able to seek, but URL info objects can only
- # be read, so we make a string IO object out of it
- sio = cStringIO.StringIO()
- sio.write(fileObj.read())
+ sio = cStringIO.StringIO(fileObj.read())
fileObj.close()
sio.seek(0)
- return reportlab.lib.utils.ImageReader(sio)
+ return sio
+class Image(File):
+
+ def __init__(self, name=None, default=DEFAULT, onlyOpen=False):
+ super(Image, self).__init__(name, default)
+ self.onlyOpen = onlyOpen
+
+ def convert(self, value, context=None):
+ fileObj = super(Image, self).convert(value, context)
+ if self.onlyOpen:
+ return fileObj
+ return reportlab.lib.utils.ImageReader(fileObj)
+
+
class Color(Text):
def convert(self, value, context=None):
Modified: z3c.rml/trunk/src/z3c/rml/canvas.py
===================================================================
--- z3c.rml/trunk/src/z3c/rml/canvas.py 2007-03-15 18:52:33 UTC (rev 73203)
+++ z3c.rml/trunk/src/z3c/rml/canvas.py 2007-03-15 19:23:10 UTC (rev 73204)
@@ -16,10 +16,11 @@
$Id$
"""
__docformat__ = "reStructuredText"
+import cStringIO
import zope.interface
import reportlab.pdfgen.canvas
from z3c.rml import attr, element, flowable, interfaces, stylesheet
-from z3c.rml import chart, form
+from z3c.rml import chart, form, page
class DrawString(element.FunctionElement):
@@ -38,6 +39,12 @@
functionName = 'drawCentredString'
+class DrawAlignedString(DrawString):
+ functionName = 'drawAlignedString'
+ args = DrawString.args + (
+ attr.Text('pivotChar', '.'), )
+
+
class Shape(element.FunctionElement):
args = (
attr.Measurement('x'),
@@ -333,6 +340,7 @@
'drawRightString': DrawRightString,
'drawCenteredString': DrawCenteredString,
'drawCentredString': DrawCenteredString,
+ 'drawAlignedString': DrawAlignedString,
# Drawing Operations
'ellipse': Ellipse,
'circle': Circle,
@@ -369,6 +377,9 @@
class PageDrawing(Drawing):
subElements = Drawing.subElements.copy()
+ subElements.update({
+ 'mergePage': page.MergePage
+ })
def process(self):
super(Drawing, self).process()
@@ -378,13 +389,13 @@
class PageInfo(element.Element):
def process(self):
- pageSize = attr.Sequence(
- 'pageSize', attr.Measurement(), length=2).get(self.element)
+ pageSize = attr.PageSize('pageSize').get(self.element)
self.context.setPageSize(pageSize)
class Canvas(element.ContainerElement):
- zope.interface.implements(interfaces.IStylesManager)
+ zope.interface.implements(
+ interfaces.IStylesManager, interfaces.IPostProcessorManager)
subElements = {
'stylesheet': stylesheet.Stylesheet,
@@ -395,15 +406,28 @@
def __init__(self, element):
self.element = element
self.styles = {}
+ self.postProcessors = []
def process(self, outputFile):
verbosity = attr.Bool('verbosity').get(self.element, 0)
compression = attr.DefaultBool('compression').get(self.element, 0)
+ # Create a temporary output file, so that post-processors can massage
+ # the output
+ tempOutput = cStringIO.StringIO()
+
canvas = reportlab.pdfgen.canvas.Canvas(
- outputFile,
+ tempOutput,
pageCompression=compression,
verbosity=verbosity)
self.processSubElements(canvas)
+ canvas.save()
- canvas.save()
+ # Process all post processors
+ for name, processor in self.postProcessors:
+ tempOutput.seek(0)
+ tempOutput = processor.process(tempOutput)
+
+ # Save the result into our real output file
+ tempOutput.seek(0)
+ outputFile.write(tempOutput.getvalue())
Modified: z3c.rml/trunk/src/z3c/rml/interfaces.py
===================================================================
--- z3c.rml/trunk/src/z3c/rml/interfaces.py 2007-03-15 18:52:33 UTC (rev 73203)
+++ z3c.rml/trunk/src/z3c/rml/interfaces.py 2007-03-15 19:23:10 UTC (rev 73204)
@@ -32,3 +32,10 @@
"""Manages custom styles"""
styles = zope.interface.Attribute("Styles dict")
+
+
+class IPostProcessorManager(zope.interface.Interface):
+ """Manages all post processors"""
+
+ postProcessors = zope.interface.Attribute(
+ "List of tuples of the form: (name, processor)")
Added: z3c.rml/trunk/src/z3c/rml/page.py
===================================================================
--- z3c.rml/trunk/src/z3c/rml/page.py 2007-03-15 18:52:33 UTC (rev 73203)
+++ z3c.rml/trunk/src/z3c/rml/page.py 2007-03-15 19:23:10 UTC (rev 73204)
@@ -0,0 +1,75 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Page Drawing Related Element Processing
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+import cStringIO
+from z3c.rml import attr, element, interfaces
+
+try:
+ import pyPdf
+except ImportError:
+ # We don't want to require pyPdf, if you do not want to use the features
+ # in this module.
+ pyPdf = None
+
+class MergePostProcessor(object):
+
+ def __init__(self):
+ self.operations = {}
+
+ def process(self, inputFile1):
+ input1 = pyPdf.PdfFileReader(inputFile1)
+ output = pyPdf.PdfFileWriter()
+ for (num, page) in enumerate(input1.pages):
+ if num in self.operations:
+ for mergeFile, mergeNumber in self.operations[num]:
+ merger = pyPdf.PdfFileReader(mergeFile)
+ mergerPage = merger.getPage(mergeNumber)
+ mergerPage.mergePage(page)
+ page = mergerPage
+ output.addPage(page)
+
+ outputFile = cStringIO.StringIO()
+ output.write(outputFile)
+ return outputFile
+
+
+class MergePage(element.FunctionElement):
+ args = ( attr.File('filename'), attr.Int('page') )
+
+ def getProcessor(self):
+ elem = self.parent
+ while (not interfaces.IPostProcessorManager.providedBy(elem)
+ and elem is not None):
+ elem = elem.parent
+ procs = dict(elem.postProcessors)
+ if 'MERGE' not in procs:
+ proc = MergePostProcessor()
+ elem.postProcessors.append(('MERGE', proc))
+ return proc
+ return procs['MERGE']
+
+ def process(self):
+ if pyPdf is None:
+ raise Exception(
+ 'pyPdf is not installed, so this feature is not available.')
+ inputFile, inPage = self.getPositionalArguments()
+ outPage = self.context.getPageNumber()-1
+
+ proc = self.getProcessor()
+ pageOperations = proc.operations.setdefault(outPage, [])
+ pageOperations.append((inputFile, inPage))
Property changes on: z3c.rml/trunk/src/z3c/rml/page.py
___________________________________________________________________
Name: svn:keywords
+ Id
Added: z3c.rml/trunk/src/z3c/rml/tests/input/data/fw2.pdf
===================================================================
(Binary files differ)
Property changes on: z3c.rml/trunk/src/z3c/rml/tests/input/data/fw2.pdf
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: z3c.rml/trunk/src/z3c/rml/tests/input/tag-drawAlignedString.rml
===================================================================
--- z3c.rml/trunk/src/z3c/rml/tests/input/tag-drawAlignedString.rml 2007-03-15 18:52:33 UTC (rev 73203)
+++ z3c.rml/trunk/src/z3c/rml/tests/input/tag-drawAlignedString.rml 2007-03-15 19:23:10 UTC (rev 73204)
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE document SYSTEM "rml.dtd">
+
+<document filename="drawString.pdf">
+ <pageDrawing>
+
+ <drawAlignedString x="4.1in" y="9.8in">
+ $ 13.63
+ </drawAlignedString>
+ <drawAlignedString x="4.1in" y="9.6in">
+ $ 121.01
+ </drawAlignedString>
+ <drawAlignedString x="4.1in" y="9.4in">
+ $ 7.13
+ </drawAlignedString>
+ <drawAlignedString x="4.1in" y="9.2in">
+ $ -97.45
+ </drawAlignedString>
+
+ <drawAlignedString x="4.1in" y="7.8in">
+ 12,345.67
+ </drawAlignedString>
+ <drawAlignedString x="4.1in" y="7.6in">
+ 987.15
+ </drawAlignedString>
+ <drawAlignedString x="4.1in" y="7.4in">
+ 42
+ </drawAlignedString>
+ <drawAlignedString x="4.1in" y="7.2in">
+ -1,234.56
+ </drawAlignedString>
+ <drawAlignedString x="4.1in" y="7.0in">
+ (456.78)
+ </drawAlignedString>
+ <drawAlignedString x="4.1in" y="6.8in">
+ (456)
+ </drawAlignedString>
+ <drawAlignedString x="4.1in" y="6.6in">
+ 27 inches
+ </drawAlignedString>
+ <drawAlignedString x="4.1in" y="6.4in">
+ 13cm
+ </drawAlignedString>
+
+ <drawAlignedString x="4.1in" y="5.8in" pivotChar="=">
+ a = 2b + 3
+ </drawAlignedString>
+ <drawAlignedString x="4.1in" y="5.6in" pivotChar="=">
+ a - 3 = 2b
+ </drawAlignedString>
+ <drawAlignedString x="4.1in" y="5.4in" pivotChar="=">
+ (a - 3)/2 = b
+ </drawAlignedString>
+
+ </pageDrawing>
+</document>
Added: z3c.rml/trunk/src/z3c/rml/tests/input/tag-mergePage.rml
===================================================================
--- z3c.rml/trunk/src/z3c/rml/tests/input/tag-mergePage.rml 2007-03-15 18:52:33 UTC (rev 73203)
+++ z3c.rml/trunk/src/z3c/rml/tests/input/tag-mergePage.rml 2007-03-15 19:23:10 UTC (rev 73204)
@@ -0,0 +1,84 @@
+<!DOCTYPE document SYSTEM "rml.dtd">
+<document filename="rml-guide-example-01.pdf">
+ <docinit>
+ <registerFont name="ZapfDingbats" faceName="ZapfDingbats"
+ encName="StandardEncoding"/>
+ </docinit>
+
+ <stylesheet>
+ <paraStyle
+ name="Normal"
+ parent="style.Normal"
+ fontSize="12"
+ />
+ </stylesheet>
+
+ <pageDrawing>
+ <mergePage filename="[z3c.rml.tests]/input/data/fw2.pdf" page="1" />
+ <setFont name="Times-Roman" size="12" />
+
+ <!-- Field a -->
+ <drawString x="62.0mm" y="265.0mm">
+ 555-55-5555
+ </drawString>
+
+ <!-- Field b -->
+ <drawString x="24mm" y="256.5mm">
+ MA 123-9424-90
+ </drawString>
+
+ <!-- Field c -->
+ <place x="24mm" y="225.0mm" width="75.0mm" height="25mm">
+ <para>Future Corporation</para>
+ <para>1 Belltower Place</para>
+ <para>Maynard, MA 01754</para>
+ <para>USA</para>
+ </place>
+
+ <!-- Field d -->
+ <drawString x="24mm" y="223mm">
+ CTRL-FC-2982
+ </drawString>
+
+ <!-- Field e -->
+ <drawString x="24mm" y="214.5mm">
+ Jonathan
+ </drawString>
+ <drawString x="68.5mm" y="214.5mm">
+ Duddley
+ </drawString>
+
+ <!-- Field f -->
+ <place x="24mm" y="184.0mm" width="75.0mm" height="25mm">
+ <para>10 Main Street</para>
+ <para>Maynard, MA 01754</para>
+ <para>USA</para>
+ </place>
+
+ <!-- Field 1 -->
+ <drawRightString x="161mm" y="256.5mm">
+ 78,000
+ </drawRightString>
+
+ <!-- Field 2 -->
+ <drawRightString x="203mm" y="256.5mm">
+ 13,260
+ </drawRightString>
+
+ <!-- Field 15 -->
+ <drawString x="20mm" y="175.5mm">
+ MA
+ </drawString>
+ <drawString x="32.4mm" y="175.5mm">
+ MA-FC-23410
+ </drawString>
+
+ <drawRightString x="101.3mm" y="175.5mm">
+ 78,000
+ </drawRightString>
+ <drawRightString x="128mm" y="175.5mm">
+ 6,240
+ </drawRightString>
+
+ </pageDrawing>
+</document>
Deleted: z3c.rml/trunk/src/z3c/rml/tests/input/tag-mergeWith.rml
===================================================================
--- z3c.rml/trunk/src/z3c/rml/tests/input/tag-mergeWith.rml 2007-03-15 18:52:33 UTC (rev 73203)
+++ z3c.rml/trunk/src/z3c/rml/tests/input/tag-mergeWith.rml 2007-03-15 19:23:10 UTC (rev 73204)
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!DOCTYPE document SYSTEM "rml.dtd">
-
-<document filename="pdf-template.pdf">
- <pageDrawing>
- <!--mergeWith filename="data/w-2.pdf" page="0" /-->
-
- </pageDrawing>
-</document>
More information about the Checkins
mailing list