[reportlab-users] PyCanvas : a Canvas to Python converter

Jerome Alet reportlab-users@reportlab.com
Thu, 26 Sep 2002 15:40:18 +0200


--UlVJffcvxoiEqYs2
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Hi,

the attached file contains the PyCanvas class.

use it like the normal canvas.Canvas one.

PyCanvas will work exactly just like a normal Canvas, but it also
features an __str__ method.

Calling str(yourinstance_of_PyCanvas) will give you the serialized
Python code which when run will produce an equivalent PDF document
to the original one created BY your PyCanvas instance.

Not very clear, but it should work reasonnably well considering
it's only 55 lines long including comments...

Another essay to clarify :

----
    from PyCanvas import PyCanvas

    canv = PyCanvas("out.pdf", (800, 600))
    ...
    canv.save()
----

This will REALLY produce the "out.pdf" file as you
expect.

BUT :

----
    str(canv)
----

Will return you the Python code which you can save and run again
to produce another version of "out.pdf"

Both files should look the same.

I've tested it on a sample program I had and it seems to work fine.

NB : some methods which return a meaningful value but doesn't modify
the canvas will also be called in the resulting Python code, even
if their use isn't needed.

Enjoy !

Jerome Alet

--UlVJffcvxoiEqYs2
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="PyCanvas.py"

#
# Author : Jerome Alet
#
# License : ReportLab's license
#

import cStringIO
from reportlab.pdfgen import canvas

header = """#! /usr/bin/env python

from reportlab.pdfgen import canvas

"""

class PyCanvas :
    class Action :
	def __init__(self, parent, action) :
	    self.__parent = parent
	    self.__action = action

	def __call__(self, *args, **kwargs) :
	    arguments = ""
	    for arg in args :
		arguments += "%s, " % repr(arg)
	    for (kw, val) in kwargs.items() :
		arguments += "%s=%s, " % (kw, repr(val))
	    if arguments[-2:] == ", " :
		arguments = arguments[:-2]
	    self.__parent._PyWrite("c.%s(%s)" % (self.__action, arguments))
	    return apply(getattr(self.__parent._canvas, self.__action), args, kwargs)

    def __init__(self, *args, **kwargs) :
	self._canvas = apply(canvas.Canvas, args, kwargs)
	self._pyfile = cStringIO.StringIO()
	arguments = ""
	for arg in args :
	    arguments += "%s, " % repr(arg)
	for (kw, val) in kwargs.items() :
	    arguments += "%s=%s, " % (kw, repr(val))
	if arguments[-2:] == ", " :
	    arguments = arguments[:-2]
	self._PyWrite(header)
	self._PyWrite("c = canvas.Canvas(%s)" % arguments)

    def __str__(self) :
	return self._pyfile.getvalue()

    def __getattr__(self, name) :
	# if hasattr(self._canvas, name) :
	return self.Action(self, name)

    def _PyWrite(self, pycode) :
	self._pyfile.write("%s\n" % pycode)


--UlVJffcvxoiEqYs2--