diff options
Diffstat (limited to 'bin/reportlab/tools/pythonpoint')
28 files changed, 5702 insertions, 0 deletions
diff --git a/bin/reportlab/tools/pythonpoint/README b/bin/reportlab/tools/pythonpoint/README new file mode 100644 index 00000000000..f6d8808bdab --- /dev/null +++ b/bin/reportlab/tools/pythonpoint/README @@ -0,0 +1,29 @@ +PythonPoint is a utility for generating PDF slides from +a simple XML format - "PythonPoint Markup Language". + +This is early days. It lets you produce quite sophisticated +output, but the DTD will undoubtedly evolve and change. +However, I want people to be able to use it this summer so am +releasing now. + +It is part of the ReportLab distribution; if you have managed +to run the ReportLab tests, and have installed the Python +Imaging Library, usage should be straightforward. PIL is not +required to make slides, but the demo will have a few blanks if +you omit it. + +To use, cd to the pythonpoint directory and execute: + pythonpoint.py pythonpoint.xml +This will create pythonpoint.pdf, which is your manual. + +You can also try 'monterey.xml', which is a talk I gave +at the O'Reilly Open Source conference in Monterey +in summer 1999. + +We have issues to resolve over module load paths; +the easiest solution for now is to put the PythonPoint +directory on your path; work in a new directory; +and explicitly include the paths to any custom shapes, +and style sheets you use. + +- Andy Robinson, 6 April 2000
\ No newline at end of file diff --git a/bin/reportlab/tools/pythonpoint/__init__.py b/bin/reportlab/tools/pythonpoint/__init__.py new file mode 100644 index 00000000000..c4b994f848b --- /dev/null +++ b/bin/reportlab/tools/pythonpoint/__init__.py @@ -0,0 +1,3 @@ +#Copyright ReportLab Europe Ltd. 2000-2004 +#see license.txt for license details +#history http://www.reportlab.co.uk/cgi-bin/viewcvs.cgi/public/reportlab/trunk/reportlab/tools/pythonpoint/__init__.py diff --git a/bin/reportlab/tools/pythonpoint/customshapes.py b/bin/reportlab/tools/pythonpoint/customshapes.py new file mode 100644 index 00000000000..779a236eec6 --- /dev/null +++ b/bin/reportlab/tools/pythonpoint/customshapes.py @@ -0,0 +1,298 @@ +#Copyright ReportLab Europe Ltd. 2000-2004 +#see license.txt for license details +#history http://www.reportlab.co.uk/cgi-bin/viewcvs.cgi/public/reportlab/trunk/reportlab/tools/pythonpoint/customshapes.py +__version__=''' $Id: customshapes.py 2385 2004-06-17 15:26:05Z rgbecker $ ''' + +# xml parser stuff for PythonPoint +# PythonPoint Markup Language! + +__doc__=""" +This demonstrates a custom shape for use with the <customshape> tag. +The shape must fulfil a very simple interface, which may change in +future. + +The XML tag currently has this form: + <customshape + module="customshapes.py" + class = "MyShape" + initargs="(100,200,3)" + /> + +PythonPoint will look in the given module for the given class, +evaluate the arguments string and pass it to the constructor. +Then, it will call + + object.drawOn(canvas) + +Thus your object must be fully defined by the constructor. +For this one, we pass three argumenyts: x, y and scale. +This does a five-tile jigsaw over which words can be overlaid; +based on work done for a customer's presentation. +""" + + +import reportlab.pdfgen.canvas +from reportlab.lib import colors +from reportlab.lib.corp import RL_CorpLogo +from reportlab.graphics.shapes import Drawing + +## custom shape for use with PythonPoint. + +class Jigsaw: + """This draws a jigsaw patterm. By default it is centred on 0,0 + and has dimensions of 200 x 140; use the x/y/scale attributes + to move it around.""" + #Using my usual bulldozer coding style - I am sure a mathematician could + #derive an elegant way to draw this, but I just took a ruler, guessed at + #the control points, and reflected a few lists at the interactive prompt. + + def __init__(self, x, y, scale=1): + self.width = 200 + self.height = 140 + self.x = x + self.y = y + self.scale = scale + + + def drawOn(self, canvas): + canvas.saveState() + + canvas.setFont('Helvetica-Bold',24) + canvas.drawString(600, 100, 'A Custom Shape') + + canvas.translate(self.x, self.y) + canvas.scale(self.scale, self.scale) + self.drawBounds(canvas) + + self.drawCentre(canvas) + self.drawTopLeft(canvas) + self.drawBottomLeft(canvas) + self.drawBottomRight(canvas) + self.drawTopRight(canvas) + + canvas.restoreState() + + + def curveThrough(self, path, pointlist): + """Helper to curve through set of control points.""" + assert len(pointlist) % 3 == 1, "No. of points must be 3n+1 for integer n" + (x,y) = pointlist[0] + path.moveTo(x, y) + idx = 1 + while idx < len(pointlist)-2: + p1, p2, p3 = pointlist[idx:idx+3] + path.curveTo(p1[0], p1[1], p2[0], p2[1], p3[0], p3[1]) + idx = idx + 3 + + + def drawShape(self, canvas, controls, color): + """Utlity to draw a closed shape through a list of control points; + extends the previous proc""" + canvas.setFillColor(color) + p = canvas.beginPath() + self.curveThrough(p, controls) + p.close() + canvas.drawPath(p, stroke=1, fill=1) + + + def drawBounds(self, canvas): + """Guidelines to help me draw - not needed in production""" + canvas.setStrokeColor(colors.red) + canvas.rect(-100,-70,200,140) + canvas.line(-100,0,100,0) + canvas.line(0,70,0,-70) + canvas.setStrokeColor(colors.black) + + + def drawCentre(self, canvas): + controls = [ (0,50), #top + + #top right edge - duplicated for that corner piece + (5,50),(10,45),(10,40), + (10,35),(15,30),(20,30), + (25,30),(30,25),(30,20), + (30,15),(35,10),(40,10), + (45,10),(50,5),(50,0), + + #bottom right edge + (50, -5), (45,-10), (40,-10), + (35,-10), (30,-15), (30, -20), + (30,-25), (25,-30), (20,-30), + (15,-30), (10,-35), (10,-40), + (10,-45),(5,-50),(0,-50), + + #bottom left + (-5,-50),(-10,-45),(-10,-40), + (-10,-35),(-15,-30),(-20,-30), + (-25,-30),(-30,-25),(-30,-20), + (-30,-15),(-35,-10),(-40,-10), + (-45,-10),(-50,-5),(-50,0), + + #top left + (-50,5),(-45,10),(-40,10), + (-35,10),(-30,15),(-30,20), + (-30,25),(-25,30),(-20,30), + (-15,30),(-10,35),(-10,40), + (-10,45),(-5,50),(0,50) + + ] + + self.drawShape(canvas, controls, colors.yellow) + + + def drawTopLeft(self, canvas): + controls = [(-100,70), + (-100,69),(-100,1),(-100,0), + (-99,0),(-91,0),(-90,0), + + #jigsaw interlock - 4 sections + (-90,5),(-92,5),(-92,10), + (-92,15), (-85,15), (-80,15), + (-75,15),(-68,15),(-68,10), + (-68,5),(-70,5),(-70,0), + (-69,0),(-51,0),(-50,0), + + #five distinct curves + (-50,5),(-45,10),(-40,10), + (-35,10),(-30,15),(-30,20), + (-30,25),(-25,30),(-20,30), + (-15,30),(-10,35),(-10,40), + (-10,45),(-5,50),(0,50), + + (0,51),(0,69),(0,70), + (-1,70),(-99,70),(-100,70) + ] + self.drawShape(canvas, controls, colors.teal) + + + def drawBottomLeft(self, canvas): + + controls = [(-100,-70), + (-99,-70),(-1,-70),(0,-70), + (0,-69),(0,-51),(0,-50), + + #wavyline + (-5,-50),(-10,-45),(-10,-40), + (-10,-35),(-15,-30),(-20,-30), + (-25,-30),(-30,-25),(-30,-20), + (-30,-15),(-35,-10),(-40,-10), + (-45,-10),(-50,-5),(-50,0), + + #jigsaw interlock - 4 sections + + (-51, 0), (-69, 0), (-70, 0), + (-70, 5), (-68, 5), (-68, 10), + (-68, 15), (-75, 15), (-80, 15), + (-85, 15), (-92, 15), (-92, 10), + (-92, 5), (-90, 5), (-90, 0), + + (-91,0),(-99,0),(-100,0) + + ] + self.drawShape(canvas, controls, colors.green) + + + def drawBottomRight(self, canvas): + + controls = [ (100,-70), + (100,-69),(100,-1),(100,0), + (99,0),(91,0),(90,0), + + #jigsaw interlock - 4 sections + (90, -5), (92, -5), (92, -10), + (92, -15), (85, -15), (80, -15), + (75, -15), (68, -15), (68, -10), + (68, -5), (70, -5), (70, 0), + (69, 0), (51, 0), (50, 0), + + #wavyline + (50, -5), (45,-10), (40,-10), + (35,-10), (30,-15), (30, -20), + (30,-25), (25,-30), (20,-30), + (15,-30), (10,-35), (10,-40), + (10,-45),(5,-50),(0,-50), + + (0,-51), (0,-69), (0,-70), + (1,-70),(99,-70),(100,-70) + + ] + self.drawShape(canvas, controls, colors.navy) + + + def drawBottomLeft(self, canvas): + + controls = [(-100,-70), + (-99,-70),(-1,-70),(0,-70), + (0,-69),(0,-51),(0,-50), + + #wavyline + (-5,-50),(-10,-45),(-10,-40), + (-10,-35),(-15,-30),(-20,-30), + (-25,-30),(-30,-25),(-30,-20), + (-30,-15),(-35,-10),(-40,-10), + (-45,-10),(-50,-5),(-50,0), + + #jigsaw interlock - 4 sections + + (-51, 0), (-69, 0), (-70, 0), + (-70, 5), (-68, 5), (-68, 10), + (-68, 15), (-75, 15), (-80, 15), + (-85, 15), (-92, 15), (-92, 10), + (-92, 5), (-90, 5), (-90, 0), + + (-91,0),(-99,0),(-100,0) + + ] + self.drawShape(canvas, controls, colors.green) + + + def drawTopRight(self, canvas): + controls = [(100, 70), + (99, 70), (1, 70), (0, 70), + (0, 69), (0, 51), (0, 50), + (5, 50), (10, 45), (10, 40), + (10, 35), (15, 30), (20, 30), + (25, 30), (30, 25), (30, 20), + (30, 15), (35, 10), (40, 10), + (45, 10), (50, 5), (50, 0), + (51, 0), (69, 0), (70, 0), + (70, -5), (68, -5), (68, -10), + (68, -15), (75, -15), (80, -15), + (85, -15), (92, -15), (92, -10), + (92, -5), (90, -5), (90, 0), + (91, 0), (99, 0), (100, 0) + ] + + self.drawShape(canvas, controls, colors.magenta) + + +class Logo: + """This draws a ReportLab Logo.""" + + def __init__(self, x, y, width, height): + logo = RL_CorpLogo() + logo.x = x + logo.y = y + logo.width = width + logo.height = height + self.logo = logo + + def drawOn(self, canvas): + logo = self.logo + x, y = logo.x, logo.y + w, h = logo.width, logo.height + D = Drawing(w, h) + D.add(logo) + D.drawOn(canvas, 0, 0) + + +def run(): + c = reportlab.pdfgen.canvas.Canvas('customshape.pdf') + + J = Jigsaw(300, 540, 2) + J.drawOn(c) + c.save() + + +if __name__ == '__main__': + run()
\ No newline at end of file diff --git a/bin/reportlab/tools/pythonpoint/demos/LeERC___.AFM b/bin/reportlab/tools/pythonpoint/demos/LeERC___.AFM new file mode 100644 index 00000000000..fe491e473a2 --- /dev/null +++ b/bin/reportlab/tools/pythonpoint/demos/LeERC___.AFM @@ -0,0 +1,93 @@ +StartFontMetrics 2.0 +Comment Generated by RoboFog 08-06-2001 4:26:40 PM +FontName LettErrorRobot-Chrome +FullName LettErrorRobot-Chrome +FamilyName LettErrorRobot +Weight Medium +Notice (C) 1998-2001 LettError, Just van Rossum, Erik van Blokland, http://www.letterror.com/ +ItalicAngle 0 +IsFixedPitch false +UnderlinePosition -133 +UnderlineThickness 20 +Version 001.000 +EncodingScheme AdobeStandardEncoding +FontBBox -53 -252 1047 752 +CapHeight 647 +XHeight 548 +Descender -252 +Ascender 747 +StartCharMetrics 68 +C 32 ; WX 300 ; N space ; B 0 0 0 0 ; +C 33 ; WX 300 ; N exclam ; B 48 -52 253 652 ; +C 38 ; WX 700 ; N ampersand ; B 48 -47 653 647 ; +C 42 ; WX 700 ; N asterisk ; B 48 148 653 752 ; +C 48 ; WX 700 ; N zero ; B 53 -47 648 548 ; +C 49 ; WX 500 ; N one ; B 48 -47 453 553 ; +C 50 ; WX 600 ; N two ; B 48 -47 553 548 ; +C 51 ; WX 600 ; N three ; B 48 -147 553 548 ; +C 52 ; WX 700 ; N four ; B 48 -152 653 553 ; +C 53 ; WX 600 ; N five ; B 48 -147 553 548 ; +C 54 ; WX 600 ; N six ; B 53 -47 553 647 ; +C 55 ; WX 600 ; N seven ; B 48 -152 548 548 ; +C 56 ; WX 600 ; N eight ; B 48 -47 553 647 ; +C 57 ; WX 600 ; N nine ; B 48 -147 548 548 ; +C 63 ; WX 500 ; N question ; B 48 -52 448 647 ; +C 64 ; WX 800 ; N at ; B 53 -47 748 647 ; +C 65 ; WX 700 ; N A ; B 53 -52 648 652 ; +C 66 ; WX 600 ; N B ; B 53 -47 553 647 ; +C 67 ; WX 600 ; N C ; B 53 -47 553 647 ; +C 68 ; WX 700 ; N D ; B 53 -47 648 647 ; +C 69 ; WX 600 ; N E ; B 53 -47 553 647 ; +C 70 ; WX 600 ; N F ; B 53 -52 553 647 ; +C 71 ; WX 700 ; N G ; B 53 -47 653 647 ; +C 72 ; WX 700 ; N H ; B 53 -52 648 652 ; +C 73 ; WX 300 ; N I ; B 53 -52 248 652 ; +C 74 ; WX 300 ; N J ; B -53 -252 248 652 ; +C 75 ; WX 700 ; N K ; B 53 -52 653 652 ; +C 76 ; WX 600 ; N L ; B 53 -47 553 652 ; +C 77 ; WX 900 ; N M ; B 53 -52 848 652 ; +C 78 ; WX 700 ; N N ; B 53 -52 648 652 ; +C 79 ; WX 700 ; N O ; B 53 -47 648 647 ; +C 80 ; WX 600 ; N P ; B 53 -52 548 647 ; +C 81 ; WX 700 ; N Q ; B 53 -252 653 647 ; +C 82 ; WX 600 ; N R ; B 53 -52 653 647 ; +C 83 ; WX 600 ; N S ; B 48 -47 553 647 ; +C 84 ; WX 700 ; N T ; B 48 -52 653 647 ; +C 85 ; WX 700 ; N U ; B 53 -47 648 652 ; +C 86 ; WX 700 ; N V ; B 53 -52 648 652 ; +C 87 ; WX 1100 ; N W ; B 53 -52 1047 652 ; +C 88 ; WX 700 ; N X ; B 48 -52 653 652 ; +C 89 ; WX 700 ; N Y ; B 53 -52 648 652 ; +C 90 ; WX 700 ; N Z ; B 48 -47 653 647 ; +C 97 ; WX 600 ; N a ; B 48 -47 548 548 ; +C 98 ; WX 600 ; N b ; B 53 -47 548 752 ; +C 99 ; WX 600 ; N c ; B 53 -47 553 548 ; +C 100 ; WX 600 ; N d ; B 53 -47 548 752 ; +C 101 ; WX 600 ; N e ; B 53 -47 553 548 ; +C 102 ; WX 400 ; N f ; B -53 -52 453 747 ; +C 103 ; WX 600 ; N g ; B 48 -247 548 548 ; +C 104 ; WX 600 ; N h ; B 53 -52 548 752 ; +C 105 ; WX 300 ; N i ; B 48 -52 253 752 ; +C 106 ; WX 300 ; N j ; B -53 -252 253 752 ; +C 107 ; WX 600 ; N k ; B 53 -52 553 752 ; +C 108 ; WX 300 ; N l ; B 53 -52 248 752 ; +C 109 ; WX 900 ; N m ; B 53 -52 848 548 ; +C 110 ; WX 600 ; N n ; B 53 -52 548 548 ; +C 111 ; WX 600 ; N o ; B 53 -47 548 548 ; +C 112 ; WX 600 ; N p ; B 53 -252 548 548 ; +C 113 ; WX 600 ; N q ; B 53 -252 548 548 ; +C 114 ; WX 400 ; N r ; B 53 -52 453 553 ; +C 115 ; WX 600 ; N s ; B 48 -47 553 548 ; +C 116 ; WX 400 ; N t ; B -53 -47 453 652 ; +C 117 ; WX 600 ; N u ; B 53 -47 548 553 ; +C 118 ; WX 600 ; N v ; B 53 -52 548 553 ; +C 119 ; WX 900 ; N w ; B 53 -52 848 553 ; +C 120 ; WX 700 ; N x ; B 48 -52 653 553 ; +C 121 ; WX 600 ; N y ; B 48 -252 548 553 ; +C 122 ; WX 500 ; N z ; B -53 -47 553 548 ; +EndCharMetrics +StartKernData +StartKernPairs 0 +EndKernPairs +EndKernData +EndFontMetrics diff --git a/bin/reportlab/tools/pythonpoint/demos/LeERC___.PFB b/bin/reportlab/tools/pythonpoint/demos/LeERC___.PFB Binary files differnew file mode 100644 index 00000000000..c1cf7ec189a --- /dev/null +++ b/bin/reportlab/tools/pythonpoint/demos/LeERC___.PFB diff --git a/bin/reportlab/tools/pythonpoint/demos/examples.py b/bin/reportlab/tools/pythonpoint/demos/examples.py new file mode 100644 index 00000000000..14aee2336fb --- /dev/null +++ b/bin/reportlab/tools/pythonpoint/demos/examples.py @@ -0,0 +1,841 @@ +import string + +testannotations=""" +def annotations(canvas): + from reportlab.lib.units import inch + canvas.drawString(inch, 2.5*inch, + "setAuthor, setTitle, setSubject have no visible effect") + canvas.drawString(inch, inch, "But if you are viewing this document dynamically") + canvas.drawString(inch, 0.5*inch, "please look at File/Document Info") + canvas.setAuthor("the ReportLab Team") + canvas.setTitle("ReportLab PDF Generation User Guide") + canvas.setSubject("How to Generate PDF files using the ReportLab modules") +""" + +# magic function making module + +test1 = """ +def f(a,b): + print "it worked", a, b + return a+b +""" + +test2 = """ +def g(n): + if n==0: return 1 + else: return n*g(n-1) + """ + +testhello = """ +def hello(c): + from reportlab.lib.units import inch + # move the origin up and to the left + c.translate(inch,inch) + # define a large font + c.setFont("Helvetica", 14) + # choose some colors + c.setStrokeColorRGB(0.2,0.5,0.3) + c.setFillColorRGB(1,0,1) + # draw some lines + c.line(0,0,0,1.7*inch) + c.line(0,0,1*inch,0) + # draw a rectangle + c.rect(0.2*inch,0.2*inch,1*inch,1.5*inch, fill=1) + # make text go straight up + c.rotate(90) + # change color + c.setFillColorRGB(0,0,0.77) + # say hello (note after rotate the y coord needs to be negative!) + c.drawString(0.3*inch, -inch, "Hello World") +""" + +testcoords = """ +def coords(canvas): + from reportlab.lib.units import inch + from reportlab.lib.colors import pink, black, red, blue, green + c = canvas + c.setStrokeColor(pink) + c.grid([inch, 2*inch, 3*inch, 4*inch], [0.5*inch, inch, 1.5*inch, 2*inch, 2.5*inch]) + c.setStrokeColor(black) + c.setFont("Times-Roman", 20) + c.drawString(0,0, "(0,0) the Origin") + c.drawString(2.5*inch, inch, "(2.5,1) in inches") + c.drawString(4*inch, 2.5*inch, "(4, 2.5)") + c.setFillColor(red) + c.rect(0,2*inch,0.2*inch,0.3*inch, fill=1) + c.setFillColor(green) + c.circle(4.5*inch, 0.4*inch, 0.2*inch, fill=1) +""" + +testtranslate = """ +def translate(canvas): + from reportlab.lib.units import cm + canvas.translate(2.3*cm, 0.3*cm) + coords(canvas) + """ + +testscale = """ +def scale(canvas): + canvas.scale(0.75, 0.5) + coords(canvas) +""" + +testscaletranslate = """ +def scaletranslate(canvas): + from reportlab.lib.units import inch + canvas.setFont("Courier-BoldOblique", 12) + # save the state + canvas.saveState() + # scale then translate + canvas.scale(0.3, 0.5) + canvas.translate(2.4*inch, 1.5*inch) + canvas.drawString(0, 2.7*inch, "Scale then translate") + coords(canvas) + # forget the scale and translate... + canvas.restoreState() + # translate then scale + canvas.translate(2.4*inch, 1.5*inch) + canvas.scale(0.3, 0.5) + canvas.drawString(0, 2.7*inch, "Translate then scale") + coords(canvas) +""" + +testmirror = """ +def mirror(canvas): + from reportlab.lib.units import inch + canvas.translate(5.5*inch, 0) + canvas.scale(-1.0, 1.0) + coords(canvas) +""" + +testcolors = """ +def colors(canvas): + from reportlab.lib import colors + from reportlab.lib.units import inch + black = colors.black + y = x = 0; dy=inch*3/4.0; dx=inch*5.5/5; w=h=dy/2; rdx=(dx-w)/2 + rdy=h/5.0; texty=h+2*rdy + canvas.setFont("Helvetica",10) + for [namedcolor, name] in ( + [colors.lavenderblush, "lavenderblush"], + [colors.lawngreen, "lawngreen"], + [colors.lemonchiffon, "lemonchiffon"], + [colors.lightblue, "lightblue"], + [colors.lightcoral, "lightcoral"]): + canvas.setFillColor(namedcolor) + canvas.rect(x+rdx, y+rdy, w, h, fill=1) + canvas.setFillColor(black) + canvas.drawCentredString(x+dx/2, y+texty, name) + x = x+dx + y = y + dy; x = 0 + for rgb in [(1,0,0), (0,1,0), (0,0,1), (0.5,0.3,0.1), (0.4,0.5,0.3)]: + r,g,b = rgb + canvas.setFillColorRGB(r,g,b) + canvas.rect(x+rdx, y+rdy, w, h, fill=1) + canvas.setFillColor(black) + canvas.drawCentredString(x+dx/2, y+texty, "r%s g%s b%s"%rgb) + x = x+dx + y = y + dy; x = 0 + for cmyk in [(1,0,0,0), (0,1,0,0), (0,0,1,0), (0,0,0,1), (0,0,0,0)]: + c,m,y1,k = cmyk + canvas.setFillColorCMYK(c,m,y1,k) + canvas.rect(x+rdx, y+rdy, w, h, fill=1) + canvas.setFillColor(black) + canvas.drawCentredString(x+dx/2, y+texty, "c%s m%s y%s k%s"%cmyk) + x = x+dx + y = y + dy; x = 0 + for gray in (0.0, 0.25, 0.50, 0.75, 1.0): + canvas.setFillGray(gray) + canvas.rect(x+rdx, y+rdy, w, h, fill=1) + canvas.setFillColor(black) + canvas.drawCentredString(x+dx/2, y+texty, "gray: %s"%gray) + x = x+dx +""" + +testspumoni = """ +def spumoni(canvas): + from reportlab.lib.units import inch + from reportlab.lib.colors import pink, green, brown, white + x = 0; dx = 0.4*inch + for i in range(4): + for color in (pink, green, brown): + canvas.setFillColor(color) + canvas.rect(x,0,dx,3*inch,stroke=0,fill=1) + x = x+dx + canvas.setFillColor(white) + canvas.setStrokeColor(white) + canvas.setFont("Helvetica-Bold", 85) + canvas.drawCentredString(2.75*inch, 1.3*inch, "SPUMONI") +""" + +testspumoni2 = """ +def spumoni2(canvas): + from reportlab.lib.units import inch + from reportlab.lib.colors import pink, green, brown, white, black + # draw the previous drawing + spumoni(canvas) + # now put an ice cream cone on top of it: + # first draw a triangle (ice cream cone) + p = canvas.beginPath() + xcenter = 2.75*inch + radius = 0.45*inch + p.moveTo(xcenter-radius, 1.5*inch) + p.lineTo(xcenter+radius, 1.5*inch) + p.lineTo(xcenter, 0) + canvas.setFillColor(brown) + canvas.setStrokeColor(black) + canvas.drawPath(p, fill=1) + # draw some circles (scoops) + y = 1.5*inch + for color in (pink, green, brown): + canvas.setFillColor(color) + canvas.circle(xcenter, y, radius, fill=1) + y = y+radius +""" + +testbezier = """ +def bezier(canvas): + from reportlab.lib.colors import yellow, green, red, black + from reportlab.lib.units import inch + i = inch + d = i/4 + # define the bezier curve control points + x1,y1, x2,y2, x3,y3, x4,y4 = d,1.5*i, 1.5*i,d, 3*i,d, 5.5*i-d,3*i-d + # draw a figure enclosing the control points + canvas.setFillColor(yellow) + p = canvas.beginPath() + p.moveTo(x1,y1) + for (x,y) in [(x2,y2), (x3,y3), (x4,y4)]: + p.lineTo(x,y) + canvas.drawPath(p, fill=1, stroke=0) + # draw the tangent lines + canvas.setLineWidth(inch*0.1) + canvas.setStrokeColor(green) + canvas.line(x1,y1,x2,y2) + canvas.setStrokeColor(red) + canvas.line(x3,y3,x4,y4) + # finally draw the curve + canvas.setStrokeColor(black) + canvas.bezier(x1,y1, x2,y2, x3,y3, x4,y4) +""" + +testbezier2 = """ +def bezier2(canvas): + from reportlab.lib.colors import yellow, green, red, black + from reportlab.lib.units import inch + # make a sequence of control points + xd,yd = 5.5*inch/2, 3*inch/2 + xc,yc = xd,yd + dxdy = [(0,0.33), (0.33,0.33), (0.75,1), (0.875,0.875), + (0.875,0.875), (1,0.75), (0.33,0.33), (0.33,0)] + pointlist = [] + for xoffset in (1,-1): + yoffset = xoffset + for (dx,dy) in dxdy: + px = xc + xd*xoffset*dx + py = yc + yd*yoffset*dy + pointlist.append((px,py)) + yoffset = -xoffset + for (dy,dx) in dxdy: + px = xc + xd*xoffset*dx + py = yc + yd*yoffset*dy + pointlist.append((px,py)) + # draw tangent lines and curves + canvas.setLineWidth(inch*0.1) + while pointlist: + [(x1,y1),(x2,y2),(x3,y3),(x4,y4)] = pointlist[:4] + del pointlist[:4] + canvas.setLineWidth(inch*0.1) + canvas.setStrokeColor(green) + canvas.line(x1,y1,x2,y2) + canvas.setStrokeColor(red) + canvas.line(x3,y3,x4,y4) + # finally draw the curve + canvas.setStrokeColor(black) + canvas.bezier(x1,y1, x2,y2, x3,y3, x4,y4) +""" + +testpencil = """ +def pencil(canvas, text="No.2"): + from reportlab.lib.colors import yellow, red, black,white + from reportlab.lib.units import inch + u = inch/10.0 + canvas.setStrokeColor(black) + canvas.setLineWidth(4) + # draw erasor + canvas.setFillColor(red) + canvas.circle(30*u, 5*u, 5*u, stroke=1, fill=1) + # draw all else but the tip (mainly rectangles with different fills) + canvas.setFillColor(yellow) + canvas.rect(10*u,0,20*u,10*u, stroke=1, fill=1) + canvas.setFillColor(black) + canvas.rect(23*u,0,8*u,10*u,fill=1) + canvas.roundRect(14*u, 3.5*u, 8*u, 3*u, 1.5*u, stroke=1, fill=1) + canvas.setFillColor(white) + canvas.rect(25*u,u,1.2*u,8*u, fill=1,stroke=0) + canvas.rect(27.5*u,u,1.2*u,8*u, fill=1, stroke=0) + canvas.setFont("Times-Roman", 3*u) + canvas.drawCentredString(18*u, 4*u, text) + # now draw the tip + penciltip(canvas,debug=0) + # draw broken lines across the body. + canvas.setDash([10,5,16,10],0) + canvas.line(11*u,2.5*u,22*u,2.5*u) + canvas.line(22*u,7.5*u,12*u,7.5*u) + """ + +testpenciltip = """ +def penciltip(canvas, debug=1): + from reportlab.lib.colors import tan, black, green + from reportlab.lib.units import inch + u = inch/10.0 + canvas.setLineWidth(4) + if debug: + canvas.scale(2.8,2.8) # make it big + canvas.setLineWidth(1) # small lines + canvas.setStrokeColor(black) + canvas.setFillColor(tan) + p = canvas.beginPath() + p.moveTo(10*u,0) + p.lineTo(0,5*u) + p.lineTo(10*u,10*u) + p.curveTo(11.5*u,10*u, 11.5*u,7.5*u, 10*u,7.5*u) + p.curveTo(12*u,7.5*u, 11*u,2.5*u, 9.7*u,2.5*u) + p.curveTo(10.5*u,2.5*u, 11*u,0, 10*u,0) + canvas.drawPath(p, stroke=1, fill=1) + canvas.setFillColor(black) + p = canvas.beginPath() + p.moveTo(0,5*u) + p.lineTo(4*u,3*u) + p.lineTo(5*u,4.5*u) + p.lineTo(3*u,6.5*u) + canvas.drawPath(p, stroke=1, fill=1) + if debug: + canvas.setStrokeColor(green) # put in a frame of reference + canvas.grid([0,5*u,10*u,15*u], [0,5*u,10*u]) +""" + +testnoteannotation = """ +from reportlab.platypus.flowables import Flowable +class NoteAnnotation(Flowable): + '''put a pencil in the margin.''' + def wrap(self, *args): + return (1,10) # I take up very little space! (?) + def draw(self): + canvas = self.canv + canvas.translate(-10,-10) + canvas.rotate(180) + canvas.scale(0.2,0.2) + pencil(canvas, text="NOTE") +""" + +testhandannotation = """ +from reportlab.platypus.flowables import Flowable +from reportlab.lib.colors import tan, green +class HandAnnotation(Flowable): + '''A hand flowable.''' + def __init__(self, xoffset=0, size=None, fillcolor=tan, strokecolor=green): + from reportlab.lib.units import inch + if size is None: size=4*inch + self.fillcolor, self.strokecolor = fillcolor, strokecolor + self.xoffset = xoffset + self.size = size + # normal size is 4 inches + self.scale = size/(4.0*inch) + def wrap(self, *args): + return (self.xoffset, self.size) + def draw(self): + canvas = self.canv + canvas.setLineWidth(6) + canvas.setFillColor(self.fillcolor) + canvas.setStrokeColor(self.strokecolor) + canvas.translate(self.xoffset+self.size,0) + canvas.rotate(90) + canvas.scale(self.scale, self.scale) + hand(canvas, debug=0, fill=1) +""" + +lyrics = '''\ +well she hit Net Solutions +and she registered her own .com site now +and filled it up with yahoo profile pics +she snarfed in one night now +and she made 50 million when Hugh Hefner +bought up the rights now +and she'll have fun fun fun +til her Daddy takes the keyboard away''' + +lyrics = string.split(lyrics, "\n") +testtextsize = """ +def textsize(canvas): + from reportlab.lib.units import inch + from reportlab.lib.colors import magenta, red + canvas.setFont("Times-Roman", 20) + canvas.setFillColor(red) + canvas.drawCentredString(2.75*inch, 2.5*inch, "Font size examples") + canvas.setFillColor(magenta) + size = 7 + y = 2.3*inch + x = 1.3*inch + for line in lyrics: + canvas.setFont("Helvetica", size) + canvas.drawRightString(x,y,"%s points: " % size) + canvas.drawString(x,y, line) + y = y-size*1.2 + size = size+1.5 +""" + +teststar = """ +def star(canvas, title="Title Here", aka="Comment here.", + xcenter=None, ycenter=None, nvertices=5): + from math import pi + from reportlab.lib.units import inch + radius=inch/3.0 + if xcenter is None: xcenter=2.75*inch + if ycenter is None: ycenter=1.5*inch + canvas.drawCentredString(xcenter, ycenter+1.3*radius, title) + canvas.drawCentredString(xcenter, ycenter-1.4*radius, aka) + p = canvas.beginPath() + p.moveTo(xcenter,ycenter+radius) + from math import pi, cos, sin + angle = (2*pi)*2/5.0 + startangle = pi/2.0 + for vertex in range(nvertices-1): + nextangle = angle*(vertex+1)+startangle + x = xcenter + radius*cos(nextangle) + y = ycenter + radius*sin(nextangle) + p.lineTo(x,y) + if nvertices==5: + p.close() + canvas.drawPath(p) +""" + +testjoins = """ +def joins(canvas): + from reportlab.lib.units import inch + # make lines big + canvas.setLineWidth(5) + star(canvas, "Default: mitered join", "0: pointed", xcenter = 1*inch) + canvas.setLineJoin(1) + star(canvas, "Round join", "1: rounded") + canvas.setLineJoin(2) + star(canvas, "Bevelled join", "2: square", xcenter=4.5*inch) +""" + +testcaps = """ +def caps(canvas): + from reportlab.lib.units import inch + # make lines big + canvas.setLineWidth(5) + star(canvas, "Default", "no projection",xcenter = 1*inch, + nvertices=4) + canvas.setLineCap(1) + star(canvas, "Round cap", "1: ends in half circle", nvertices=4) + canvas.setLineCap(2) + star(canvas, "Square cap", "2: projects out half a width", xcenter=4.5*inch, + nvertices=4) +""" + +testdashes = """ +def dashes(canvas): + from reportlab.lib.units import inch + # make lines big + canvas.setDash(6,3) + star(canvas, "Simple dashes", "6 points on, 3 off", xcenter = 1*inch) + canvas.setDash(1,2) + star(canvas, "Dots", "One on, two off") + canvas.setDash([1,1,3,3,1,4,4,1], 0) + star(canvas, "Complex Pattern", "[1,1,3,3,1,4,4,1]", xcenter=4.5*inch) +""" + +testcursormoves1 = """ +def cursormoves1(canvas): + from reportlab.lib.units import inch + textobject = canvas.beginText() + textobject.setTextOrigin(inch, 2.5*inch) + textobject.setFont("Helvetica-Oblique", 14) + for line in lyrics: + textobject.textLine(line) + textobject.setFillGray(0.4) + textobject.textLines(''' + With many apologies to the Beach Boys + and anyone else who finds this objectionable + ''') + canvas.drawText(textobject) +""" + +testcursormoves2 = """ +def cursormoves2(canvas): + from reportlab.lib.units import inch + textobject = canvas.beginText() + textobject.setTextOrigin(2, 2.5*inch) + textobject.setFont("Helvetica-Oblique", 14) + for line in lyrics: + textobject.textOut(line) + textobject.moveCursor(14,14) # POSITIVE Y moves down!!! + textobject.setFillColorRGB(0.4,0,1) + textobject.textLines(''' + With many apologies to the Beach Boys + and anyone else who finds this objectionable + ''') + canvas.drawText(textobject) +""" + +testcharspace = """ +def charspace(canvas): + from reportlab.lib.units import inch + textobject = canvas.beginText() + textobject.setTextOrigin(3, 2.5*inch) + textobject.setFont("Helvetica-Oblique", 10) + charspace = 0 + for line in lyrics: + textobject.setCharSpace(charspace) + textobject.textLine("%s: %s" %(charspace,line)) + charspace = charspace+0.5 + textobject.setFillGray(0.4) + textobject.textLines(''' + With many apologies to the Beach Boys + and anyone else who finds this objectionable + ''') + canvas.drawText(textobject) +""" + +testwordspace = """ +def wordspace(canvas): + from reportlab.lib.units import inch + textobject = canvas.beginText() + textobject.setTextOrigin(3, 2.5*inch) + textobject.setFont("Helvetica-Oblique", 12) + wordspace = 0 + for line in lyrics: + textobject.setWordSpace(wordspace) + textobject.textLine("%s: %s" %(wordspace,line)) + wordspace = wordspace+2.5 + textobject.setFillColorCMYK(0.4,0,0.4,0.2) + textobject.textLines(''' + With many apologies to the Beach Boys + and anyone else who finds this objectionable + ''') + canvas.drawText(textobject) +""" +testhorizontalscale = """ +def horizontalscale(canvas): + from reportlab.lib.units import inch + textobject = canvas.beginText() + textobject.setTextOrigin(3, 2.5*inch) + textobject.setFont("Helvetica-Oblique", 12) + horizontalscale = 80 # 100 is default + for line in lyrics: + textobject.setHorizScale(horizontalscale) + textobject.textLine("%s: %s" %(horizontalscale,line)) + horizontalscale = horizontalscale+10 + textobject.setFillColorCMYK(0.0,0.4,0.4,0.2) + textobject.textLines(''' + With many apologies to the Beach Boys + and anyone else who finds this objectionable + ''') + canvas.drawText(textobject) +""" +testleading = """ +def leading(canvas): + from reportlab.lib.units import inch + textobject = canvas.beginText() + textobject.setTextOrigin(3, 2.5*inch) + textobject.setFont("Helvetica-Oblique", 14) + leading = 8 + for line in lyrics: + textobject.setLeading(leading) + textobject.textLine("%s: %s" %(leading,line)) + leading = leading+2.5 + textobject.setFillColorCMYK(0.8,0,0,0.3) + textobject.textLines(''' + With many apologies to the Beach Boys + and anyone else who finds this objectionable + ''') + canvas.drawText(textobject) +""" + +testhand = """ +def hand(canvas, debug=1, fill=0): + (startx, starty) = (0,0) + curves = [ + ( 0, 2), ( 0, 4), ( 0, 8), # back of hand + ( 5, 8), ( 7,10), ( 7,14), + (10,14), (10,13), ( 7.5, 8), # thumb + (13, 8), (14, 8), (17, 8), + (19, 8), (19, 6), (17, 6), + (15, 6), (13, 6), (11, 6), # index, pointing + (12, 6), (13, 6), (14, 6), + (16, 6), (16, 4), (14, 4), + (13, 4), (12, 4), (11, 4), # middle + (11.5, 4), (12, 4), (13, 4), + (15, 4), (15, 2), (13, 2), + (12.5, 2), (11.5, 2), (11, 2), # ring + (11.5, 2), (12, 2), (12.5, 2), + (14, 2), (14, 0), (12.5, 0), + (10, 0), (8, 0), (6, 0), # pinky, then close + ] + from reportlab.lib.units import inch + if debug: canvas.setLineWidth(6) + u = inch*0.2 + p = canvas.beginPath() + p.moveTo(startx, starty) + ccopy = list(curves) + while ccopy: + [(x1,y1), (x2,y2), (x3,y3)] = ccopy[:3] + del ccopy[:3] + p.curveTo(x1*u,y1*u,x2*u,y2*u,x3*u,y3*u) + p.close() + canvas.drawPath(p, fill=fill) + if debug: + from reportlab.lib.colors import red, green + (lastx, lasty) = (startx, starty) + ccopy = list(curves) + while ccopy: + [(x1,y1), (x2,y2), (x3,y3)] = ccopy[:3] + del ccopy[:3] + canvas.setStrokeColor(red) + canvas.line(lastx*u,lasty*u, x1*u,y1*u) + canvas.setStrokeColor(green) + canvas.line(x2*u,y2*u, x3*u,y3*u) + (lastx,lasty) = (x3,y3) +""" + +testhand2 = """ +def hand2(canvas): + canvas.translate(20,10) + canvas.setLineWidth(3) + canvas.setFillColorRGB(0.1, 0.3, 0.9) + canvas.setStrokeGray(0.5) + hand(canvas, debug=0, fill=1) +""" + +testfonts = """ +def fonts(canvas): + from reportlab.lib.units import inch + text = "Now is the time for all good men to..." + x = 1.8*inch + y = 2.7*inch + for font in canvas.getAvailableFonts(): + canvas.setFont(font, 10) + canvas.drawString(x,y,text) + canvas.setFont("Helvetica", 10) + canvas.drawRightString(x-10,y, font+":") + y = y-13 +""" + +testarcs = """ +def arcs(canvas): + from reportlab.lib.units import inch + canvas.setLineWidth(4) + canvas.setStrokeColorRGB(0.8, 1, 0.6) + # draw rectangles enclosing the arcs + canvas.rect(inch, inch, 1.5*inch, inch) + canvas.rect(3*inch, inch, inch, 1.5*inch) + canvas.setStrokeColorRGB(0, 0.2, 0.4) + canvas.setFillColorRGB(1, 0.6, 0.8) + p = canvas.beginPath() + p.moveTo(0.2*inch, 0.2*inch) + p.arcTo(inch, inch, 2.5*inch,2*inch, startAng=-30, extent=135) + p.arc(3*inch, inch, 4*inch, 2.5*inch, startAng=-45, extent=270) + canvas.drawPath(p, fill=1, stroke=1) +""" +testvariousshapes = """ +def variousshapes(canvas): + from reportlab.lib.units import inch + inch = int(inch) + canvas.setStrokeGray(0.5) + canvas.grid(range(0,11*inch/2,inch/2), range(0,7*inch/2,inch/2)) + canvas.setLineWidth(4) + canvas.setStrokeColorRGB(0, 0.2, 0.7) + canvas.setFillColorRGB(1, 0.6, 0.8) + p = canvas.beginPath() + p.rect(0.5*inch, 0.5*inch, 0.5*inch, 2*inch) + p.circle(2.75*inch, 1.5*inch, 0.3*inch) + p.ellipse(3.5*inch, 0.5*inch, 1.2*inch, 2*inch) + canvas.drawPath(p, fill=1, stroke=1) +""" + +testclosingfigures = """ +def closingfigures(canvas): + from reportlab.lib.units import inch + h = inch/3.0; k = inch/2.0 + canvas.setStrokeColorRGB(0.2,0.3,0.5) + canvas.setFillColorRGB(0.8,0.6,0.2) + canvas.setLineWidth(4) + p = canvas.beginPath() + for i in (1,2,3,4): + for j in (1,2): + xc,yc = inch*i, inch*j + p.moveTo(xc,yc) + p.arcTo(xc-h, yc-k, xc+h, yc+k, startAng=0, extent=60*i) + # close only the first one, not the second one + if j==1: + p.close() + canvas.drawPath(p, fill=1, stroke=1) +""" + +testforms = """ +def forms(canvas): + #first create a form... + canvas.beginForm("SpumoniForm") + #re-use some drawing functions from earlier + spumoni(canvas) + canvas.endForm() + + #then draw it + canvas.doForm("SpumoniForm") +""" + +def doctemplateillustration(canvas): + from reportlab.lib.units import inch + canvas.setFont("Helvetica", 10) + canvas.drawString(inch/4.0, 2.75*inch, "DocTemplate") + W = 4/3.0*inch + H = 2*inch + Wd = x = inch/4.0 + Hd =y = inch/2.0 + for name in ("two column", "chapter page", "title page"): + canvas.setFillColorRGB(0.5,1.0,1.0) + canvas.rect(x,y,W,H, fill=1) + canvas.setFillColorRGB(0,0,0) + canvas.drawString(x+inch/8, y+H-Wd, "PageTemplate") + canvas.drawCentredString(x+W/2.0, y-Wd, name) + x = x+W+Wd + canvas.saveState() + d = inch/16 + dW = (W-3*d)/2.0 + hD = H -2*d-Wd + canvas.translate(Wd+d, Hd+d) + for name in ("left Frame", "right Frame"): + canvas.setFillColorRGB(1.0,0.5,1.0) + canvas.rect(0,0, dW,hD, fill=1) + canvas.setFillGray(0.7) + dd= d/2.0 + ddH = (hD-6*dd)/5.0 + ddW = dW-2*dd + yy = dd + xx = dd + for i in range(5): + canvas.rect(xx,yy,ddW,ddH, fill=1, stroke=0) + yy = yy+ddH+dd + canvas.setFillColorRGB(0,0,0) + canvas.saveState() + canvas.rotate(90) + canvas.drawString(d,-dW/2, name) + canvas.restoreState() + canvas.translate(dW+d,0) + canvas.restoreState() + canvas.setFillColorRGB(1.0, 0.5, 1.0) + mx = Wd+W+Wd+d + my = Hd+d + mW = W-2*d + mH = H-d-Hd + canvas.rect(mx, my, mW, mH, fill=1) + canvas.rect(Wd+2*(W+Wd)+d, Hd+3*d, W-2*d, H/2.0, fill=1) + canvas.setFillGray(0.7) + canvas.rect(Wd+2*(W+Wd)+d+dd, Hd+5*d, W-2*d-2*dd, H/2.0-2*d-dd, fill=1) + xx = mx+dd + yy = my+mH/5.0 + ddH = (mH-6*dd-mH/5.0)/3.0 + ddW = mW - 2*dd + for i in range(3): + canvas.setFillGray(0.7) + canvas.rect(xx,yy,ddW,ddH, fill=1, stroke=1) + canvas.setFillGray(0) + canvas.drawString(xx+dd/2.0,yy+dd/2.0, "flowable %s" %(157-i)) + yy = yy+ddH+dd + canvas.drawCentredString(3*Wd+2*W+W/2, Hd+H/2.0, "First Flowable") + canvas.setFont("Times-BoldItalic", 8) + canvas.setFillGray(0) + canvas.drawCentredString(mx+mW/2.0, my+mH+3*dd, "Chapter 6: Lubricants") + canvas.setFont("Times-BoldItalic", 10) + canvas.drawCentredString(3*Wd+2*W+W/2, Hd+H-H/4, "College Life") + +class PlatIllust: + #wrap the above for PP# + def __init__(self, x, y, scale=1): + self.x = x + self.y = y + self.scale = scale + def drawOn(self, canvas): + canvas.saveState() + canvas.translate(self.x, self.y) + canvas.scale(self.scale, self.scale) + doctemplateillustration(canvas) + canvas.restoreState() + +class PingoIllust: + #wrap the above for PP# + def __init__(self, x, y, scale=1): +## print 'Pingo illustration %f, %f, %f' % (x,y,scale) + self.x = x + self.y = y + self.scale = scale + def drawOn(self, canvas): + canvas.rect(self.x, self.y, 100,100, stroke=1, fill=1) +## from pingo import testdrawings +## from pingo import pingopdf +## drawing = testdrawings.getDrawing3() +## canvas.saveState() +## canvas.scale(self.scale, self.scale) +## pingopdf.draw(drawing, canvas, self.x, self.y) +## canvas.restoreState() + +# D = dir() +g = globals() +Dprime = {} +from types import StringType +from string import strip +for (a,b) in g.items(): + if a[:4]=="test" and type(b) is StringType: + #print 'for', a + #print b + b = strip(b) + exec(b+'\n') + +platypussetup = """ +from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer +from reportlab.lib.styles import getSampleStyleSheet +from reportlab.lib.pagesizes import DEFAULT_PAGE_SIZE +from reportlab.lib.units import inch +PAGE_HEIGHT=DEFAULT_PAGE_SIZE[1]; PAGE_WIDTH=DEFAULT_PAGE_SIZE[0] +styles = getSampleStyleSheet() +""" +platypusfirstpage = """ +Title = "Hello world" +pageinfo = "platypus example" +def myFirstPage(canvas, doc): + canvas.saveState() + canvas.setFont('Times-Bold',16) + canvas.drawCentredString(PAGE_WIDTH/2.0, PAGE_HEIGHT-108, Title) + canvas.setFont('Times-Roman',9) + canvas.drawString(inch, 0.75 * inch, "First Page / %s" % pageinfo) + canvas.restoreState() +""" +platypusnextpage = """ +def myLaterPages(canvas, doc): + canvas.saveState() + canvas.setFont('Times-Roman',9) + canvas.drawString(inch, 0.75 * inch, "Page %d %s" % (doc.page, pageinfo)) + canvas.restoreState() +""" +platypusgo = """ +def go(): + doc = SimpleDocTemplate("phello.pdf") + Story = [Spacer(1,2*inch)] + style = styles["Normal"] + for i in range(100): + bogustext = ("This is Paragraph number %s. " % i) *20 + p = Paragraph(bogustext, style) + Story.append(p) + Story.append(Spacer(1,0.2*inch)) + doc.build(Story, onFirstPage=myFirstPage, onLaterPages=myLaterPages) +""" + +if __name__=="__main__": + # then do the platypus hello world + for b in platypussetup, platypusfirstpage, platypusnextpage, platypusgo: + b = strip(b) + exec(b+'\n') + go() diff --git a/bin/reportlab/tools/pythonpoint/demos/figures.xml b/bin/reportlab/tools/pythonpoint/demos/figures.xml new file mode 100644 index 00000000000..b3314ed8298 --- /dev/null +++ b/bin/reportlab/tools/pythonpoint/demos/figures.xml @@ -0,0 +1,71 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- edited with XMLSPY v2004 rel. 3 U (http://www.xmlspy.com) by Andy Robinson (ReportLab Europe Ltd.) --> +<!DOCTYPE presentation SYSTEM "../pythonpoint.dtd"> +<presentation filename="figures.xml" pageDuration="10"> + <stylesheet module="standard" function="getParagraphStyles"/> + <title>New Feature Tests</title> + <author> + Andy Robinson + </author> + <subject> + Reportlab Sample Applications + </subject> + <section name="Main"> + <!-- any graphics in the section go on all its pages as a backdrop --> + <rectangle height="555" fill="ReportLabBlue" x="20" width="96" y="20"/> + <!--fixedimage height="64" filename="leftlogo.gif" x="20" width="96" y="510"/--> + <customshape module="customshapes" class="Logo" initargs="(20,510,96,64)"/> + <!--infostring size="14" align="right" x="800" y="36"> + »%(title)s, page %(page)s« + </infostring--> + <!-- Now for the slides --> + <slide title="Introduction" id="Slide001" effectname="Box" effectduration="2"> + <frame height="468" x="120" y="72" rightmargin="36" width="700" leftmargin="36"> + <para style="Heading1"> + New Feature Test Cases - Figures, Drawings and Included Pages + </para> + <para style="BodyText"> + especially images and pagecatcher stuff... + </para> + <para style="BodyText"> + <i> + PythonPoint + </i> + lets you create attractive and consistent presentation slides + on any platform. It is a demo app built on top of the PDFgen PDF library + and the PLATYPUS Page Layout library. Essentially, it converts slides + in an XML format to PDF. + </para> + <para style="BodyText"> + It can be used right now to create slide shows, but will + undoubtedly change and evolve. Read on for a tutorial... + </para> + </frame> + </slide> + <slide title="Test Drawing Tag" id="Slide002" effectname="Dissolve" effectduration="2"> + <frame height="468" x="120" y="72" rightmargin="36" width="700" leftmargin="36" border="true"> + <para style="Heading1"> + Drawing Tag In Action within story context + </para> + <para style="BodyText"> + especially images and pagecatcher stuff... + </para> + <para style="BodyText">Hope that came out right-aligned with a box around it...</para> + <drawing module="slidebox" constructor="SlideBoxDrawing" showBoundary="1" hAlign="CENTER"/> + </frame> + </slide> + <slide title="Test PageFigure Tag" id="Slide002" effectname="Glitter" effectduration="2"> + <frame height="468" x="120" y="72" rightmargin="36" width="300" leftmargin="36" border="true"> + <para style="Heading1">PageFigure</para> + <para style="BodyText">This imports a page and displays it. Since this will typically be used to show + A4/Letter pages, it does a 'shrink to fit' based on frame width. The scaleFactor attribute can override this, + as I did below... + </para> + <pageCatcherFigure filename="../../../../rlextra/pageCatcher/test/ir684.pdf" pageNo="0" caption="IR684 - Authorizing your Agent" scaleFactor="0.1"/> + </frame> + <frame height="468" x="450" y="72" width="325" border="true"> + <pageCatcherFigure filename="../../../rlextra/pageCatcher/test/ir684.pdf" pageNo="0" caption="IR684 - Authorizing your Agent"/> + </frame> + </slide> + </section> +</presentation> diff --git a/bin/reportlab/tools/pythonpoint/demos/htu.xml b/bin/reportlab/tools/pythonpoint/demos/htu.xml new file mode 100644 index 00000000000..56cb92457dc --- /dev/null +++ b/bin/reportlab/tools/pythonpoint/demos/htu.xml @@ -0,0 +1,96 @@ +<?xml version="1.0" encoding="utf-8" standalone="no"?> +<!DOCTYPE presentation SYSTEM "../pythonpoint.dtd"> +<presentation filename="htu.pdf"> + <stylesheet module="htu" function="getParagraphStyles"/> + <section name="Main"> + <rectangle x="20" width="96" y="20" height="555" fill="ReportLabBlue"/> + <infostring size="14" align="right" x="800" y="36"> + © 2002, H. Turgut UYAR + </infostring> + <slide title="New Features" id="Slide000"> + <frame x="120" y="72" width="700" height="418" leftmargin="36" rightmargin="36"> + <image filename="pplogo.gif" width="200" height="150"/> + <spacer height="30"/> + <para style="Title">New features in PythonPoint</para> + <para style="Author">H. Turgut Uyar</para> + <para style="EMail">uyar@cs.itu.edu.tr</para> + </frame> + </slide> + <slide title="TrueType Support" id="Slide002"> + <frame x="120" y="515" width="700" height="60" leftmargin="36" rightmargin="36"> + <para style="Heading1">TrueType Support</para> + </frame> + <frame x="120" y="72" width="700" height="418" leftmargin="36" rightmargin="36"> + <para>PythonPoint can read UTF-8 encoded input files and produce + correct output (provided your font has all necessary + characters). That enables you, for example, to have native (in my + case, Turkish) characters in your document:</para> + <para style="Indent"> + <!-- if you have any trouble with these, execute the lines below + to find out what we really intended + >>> turkishChars = u"\u011e \u011f \u0130 \u0131 \u015e \u015f" + >>> print turkishChars + >>> print turkishChars.encode("utf-8") + þ ø İ ı ľ ĸ + >>> + --> + <font name="Serif" size="32"> 0 ^ 1 _</font> + </para> + </frame> + </slide> + <slide title="Effects" id="Slide003"> + <frame x="120" y="515" width="700" height="60" leftmargin="36" rightmargin="36"> + <para style="Heading1">Effects</para> + </frame> + <frame x="120" y="72" width="700" height="418" leftmargin="36" rightmargin="36"> + <para>Paragraphs, images, tables and geometric shapes can now have + effectname, effectdirection, effectdimension, effectmotion and + effectduration attributes:</para> + <para style="Indent" effectname="Dissolve">A paragraph</para> + <image filename="pplogo.gif" width="80" height="60" effectname="Box"/> + <table style="table1" effectname="Split"> + Col1,Col2,Col3 + Row1Col1,Row1Col2,Row1Col3 + Row2Col1,Row2Col2,Row2Col3 + </table> + </frame> + <roundrect x="180" y="150" width="110" height="50" radius="15" fill="(0,1,0)" effectname="Glitter"/> + <string font="Helvetica" size="32" x="200" y="165" align="left" color="(1,0,0)" effectname="Blinds">String</string> + <line x1="248" y1="84" x2="520" y2="84" stroke="(1,0,1)" effectname="Wipe"/> + </slide> + <slide title="Printing" id="Slide004" outlinelevel="1"> + <frame x="120" y="515" width="700" height="60" leftmargin="36" rightmargin="36"> + <para style="Heading1">Printing</para> + </frame> + <frame x="120" y="72" width="700" height="418" leftmargin="36" rightmargin="36"> + <para>Be careful when using effects: A new slide is created for + each effect, so DON'T print the resulting PDF file.</para> + <para effectname="Box">new command-line option: --printout</para> + <para style="Indent">produces printable PDF</para> + </frame> + </slide> + <slide title="New Paragraph Styles" id="Slide005"> + <frame x="120" y="515" width="700" height="60" leftmargin="36" rightmargin="36"> + <para style="Heading1">New Paragraph Styles</para> + </frame> + <frame x="120" y="72" width="700" height="418" leftmargin="36" rightmargin="36"> + <para style="Bullet">Bullet2 - Second level bullets</para> + <para style="Bullet2">Here's an example</para> + <para style="Bullet2">Or an example with a longer text to see + how it wraps at the end of each line</para> + <para style="Bullet">Author and EMail</para> + <para style="Bullet2">See the cover page for examples</para> + <para style="Bullet">They have to be in the style file, so either use + the htu style file or edit your style file</para> + </frame> + </slide> + <slide title="ToDo" id="Slide006"> + <frame x="120" y="515" width="700" height="60" leftmargin="36" rightmargin="36"> + <para style="Heading1">ToDo</para> + </frame> + <frame x="120" y="72" width="700" height="418" leftmargin="36" rightmargin="36"> + <para style="Bullet">Unicode chars in the outline</para> + </frame> + </slide> + </section> +</presentation> diff --git a/bin/reportlab/tools/pythonpoint/demos/leftlogo.a85 b/bin/reportlab/tools/pythonpoint/demos/leftlogo.a85 new file mode 100644 index 00000000000..7d55afcf348 --- /dev/null +++ b/bin/reportlab/tools/pythonpoint/demos/leftlogo.a85 @@ -0,0 +1,53 @@ +BI +/W 103 /H 68 /BPC 8 /CS /RGB /F [/A85 /Fl] +ID +Gb"/*cYjIe']/l*^;)UQj:Ec+nd!,-,*G/5;0"E.+@qg.\92h2HbiE)jC5*M +$a,@:RoXB@WPjMu=[F;88l[?@OO=6qV,HNNiL#(cac+!&rF)2^DHJ?_:WQkn +1[fb`hOBr--B>FoSDXMt35Gnj6n\3XT8sf/Y%-NPLqg'pmQ+*EiV6D:,$akf +!i2MA/A-"n[R.R)S!ePi$u('8mrCG8[3:WLlB[amBYAS4hR2*f7tR;&\%]Ld +ZX5^f6Qj@\h7^FuQ(">[ml32FW<uUbK'hr2?[K]^D"^NBW@O0*-#'S9X\g_F +SYE1G3(8PLW#-KN>hJG;Z)t2oADV4[H6GbW.mH`MDlesQZO5+Q5)]O<r(Z![ +VmGDC"b6h]?JZB+V33e(TZD-HKE7<2d\OKT7macAe_OQDp+mO))_2[22<Jb% +\k]o7Be+6"nn[fbQR6Dm77(ij1n4FYflokM/!o_(c;V/"XKVZ![CCJOTo*G. +`L+#cL'lYP!_1B2q!p=#[76oJ;FF]do.OhJK1R!%SC-8k#a*AX1,`02mU%7f +4ap-1K!c.O!DQb:1k61fiAer=f)fd@jQ]"MQAu[\kB-D?g2*"JR/O2_H!SD2 +_UR(81;)KaB24OhoM!X%1D9gR5[b2,[#9dJ@_(:B_l^(Z.ae[g,)m+0jml?6 +1`=Z#U4jpgmeoc&B&Bh*B5]<?;J'XU$Cj3P@rO\[Dpm@6'?OID%os>Wf2G9[ +U9W99*2'#PD+cIXnp"J"(BrY^=(rg;ITf("c#0"S<;fjK,APV+p9p+05LO&X +jQNf`8c26f]J54N'k#I9=Bt4]e&6gN'#S[nK3*VhQ!`PpXcJ0i<sYK4+orF( +-qFEU#H1b4O<Lc=k3J0Qc(!7M1PjL=,1VdG4FR'urjd<)3iWt^plJ*3A8+L' +[RqBu+MoI1>:J_2rC@=<l=3,MSD5$[mUNC$200Kld\2C9?P]=X&kbd;iMr:d +o'[-mD9bK"`5ki%Rn/GH-sj\3d>>X\5dUbEcCZ?\6O)+F/35ZJD6R$H^-Z!R +5;8=l//9SUkC;LhQ*?di<'6e&/BNIqm(%(S<Q9IJ\ug@o;(c@0gW3p.>DYXJ +p%%Z+J.IshkX$tLPOD'"jSV#/6iY?QI>8P-%o0k3`e#X33RJS`f'D!D2rTJ- +(4Znb03&koo>X[bKs.qpBOkU,K<BP+F35$P(IIZK&F^U8SNceK*`.Lp3\Yth +DiF4Hr/;0#,ub"@Q:)]U%,YT(ckW`\_GIkW$"ms@es$i8@I16iOCr.d$$Y.g +lt!Gp#$'#T\$t,Q\[.aW7+H@h2YX0iR)rr%kf!@*YlEtPBAVgU?LDQKOonm1 +B')C@,\ZZ]hm%8:#FPcb@"6UVZ;n1r]SVJ@31k_=Ze=g?f.0oD@hah4[KNj@ +Y?=oK%;PJ-r]m9E!9l7$=njO\OC'mrIFY!$\9b]:i58?larmF9MMaHLqiJg# +IB0KR59(W[_5%Vd#snt]Q_.Xfi4?Di=(.*eYNQ=`K+75LcsK4LY:J+1W2<%\ +WMqcR6r^&[74V%[O)#1M;LC>CCO3S$2.Gr@<NBm*k!PRPNjsj2TdGq%F$)'# +BB8Yk"/]I+#fCt.!D^Rm3_Or$I#HSsYqbZn*2g3lO-N1eSNoo+g"G+^J1U7' +nar#WZZk-_KTbZXJDIN#>e8E=$On&hUiAB2[.;G@FQf7_<g_,@/;qjYEf-l" +#p0YU5nQ`u=mBQ:q.h>K1&D6RJ.Ih@-56Ss<i&p->&B1q:\)MgJ8P4Sa-(Fm +J"d8Z]Mf`Q$G^\tK@pQWQs3iRB[KP=+H&@+<eJVa9[CPgFV$Fi[oV1K)4R#' +c<\Qi:XK&nEqpb'1e<d^hQhLY)Tul_%_ng0bnt*d%h<7*Qs?U)'_dL=Cd,sO +0&V5g\%1)CmnbV\;N*DE54\tJOeXg4rPH2DR5(:!'u#RAS?,"T/H%+"M[]cm +`\R90YD#$o6A*TZ?>iH@XGFQ'#n!DJ$)Mc?"U#od!oYl3En7nT"7UC,,Q&Hr +9.SPlHak6s)J0;k;hQC:k82'=COeskp&dB-#@RrY1B=H^'L=,;9uJssq%XGf +h/fXmq>1G\?k6ZH*GSk&M)?&TJ?rYW.9f!gdM2&:Kr51A3^MX?GV'T@$h)Da +-RIIcpl8fhiQr=`\k[7;3`X"d!or<JS3FXO\QVoW+fhW8&9W*[dZTpJJq9`f +6/.R;@NP%LrsQia^)8D2Q/J^E"YFmbQNj[eIj8-teIq#\bkMZYNP]`Q,`+Fc +^kG%9V@ulcF&5&o0][1B%)LoGUI()Z`kMbB+q&dLTdLnu?sC!U[nC@bMJ8S( +UJsA@G[Jh[0ebiL<eAkS@8(tI.Xj"IO4#17pl<F>(jb1YM>"Ppi`,67@]M"d ++mXd;WRE"IKX@n&dNNV/55(]`==+_r?K5bp?$^4Pn/[2ncL(/l#CfSYAg:iN +@3j5R$qtm;AIF7k%^ak'%4Z1354d"1VT\g]cm[^hI.Yf>DcLS\rq+As2F?LI +'gq+/_o9&kK,4@]qbdfA8FauP;!N'$5J@1P/\Th=9i^\b$/-6-kL#$E&39t% +/O[1Fm`/F?!q;%bB')DM`KY&D!,6)lG5TQ88ejHiTWKt;3_8:@M!NnP'D2s$ +2Q25"dX)7pQ%VUq+r1%.iMQiLR#&.@\:Pe96FEbkgLu`Fb;!#d,DPC-H/d?u +^']=P86?6qr/@_/T-T0?,+>brI`?=13["Y(3DYSMX7UAUk0'!l!aPN<dOAp/ +2\gYH7?Iq;ln?q8(%Ag:SW86?Kti9[-7,Lh5fc*A\=4l^Pg&oj%apAq0i?"b +jdfr6IBIK$,+s'>4$e\f&(i2TTrbVuOYhc05Rko:?UP0</LE?hksnprYNQW[ +MB4QH,ADP93Y%HB:l-XOR0[N<?s68?2);KK4cL5m>9gLc(-/ni'Q6T.B&8]k +#a_e\0FTMV`IT;W7M>_'NT_f=~> +EI diff --git a/bin/reportlab/tools/pythonpoint/demos/leftlogo.gif b/bin/reportlab/tools/pythonpoint/demos/leftlogo.gif Binary files differnew file mode 100644 index 00000000000..2d9c990ba7a --- /dev/null +++ b/bin/reportlab/tools/pythonpoint/demos/leftlogo.gif diff --git a/bin/reportlab/tools/pythonpoint/demos/lj8100.jpg b/bin/reportlab/tools/pythonpoint/demos/lj8100.jpg Binary files differnew file mode 100644 index 00000000000..be3c6183d3b --- /dev/null +++ b/bin/reportlab/tools/pythonpoint/demos/lj8100.jpg diff --git a/bin/reportlab/tools/pythonpoint/demos/monterey.xml b/bin/reportlab/tools/pythonpoint/demos/monterey.xml new file mode 100644 index 00000000000..41bd979fa67 --- /dev/null +++ b/bin/reportlab/tools/pythonpoint/demos/monterey.xml @@ -0,0 +1,306 @@ +<?xml version="1.0" encoding="iso-8859-1" standalone="no"?> +<!-- edited with XMLSPY v2004 rel. 3 U (http://www.xmlspy.com) by Andy Robinson (ReportLab Europe Ltd.) --> +<!DOCTYPE presentation SYSTEM "../pythonpoint.dtd"> +<presentation filename="monterey.pdf"> + <stylesheet module="modern" function="getParagraphStyles"/> + <!-- + sections define a colection of stuff to be drawn on all pages they contain. + They must begin with a graphics list + --> + <section name="Main"> + <fixedimage filename="vertpython.gif" height="595" width="144" x="0" y="0"/> + <slide title="Cover" id="Slide001" effectname="Wipe"> + <!-- + put stuff here to be drawn on the page directly + --> + <frame height="432" x="160" y="72" rightmargin="0" width="600" leftmargin="36"> + <para/> + <para/> + <para/> + <para style="Title"> + Printing with Python + </para> + <image filename="lj8100.jpg"/> + <para style="BigCentered"> + Andy Robinson, Robinson Analytics Ltd. + </para> + <para style="BigCentered"> + O'Reilly Python Conference, Monterey, 24th August 1999 + </para> + </frame> + </slide> + <slide title="Background" id="Slide002" effectname="Wipe"> + <frame height="432" x="160" y="72" rightmargin="0" width="600" leftmargin="36"> + <para style="Heading2"> + Background to the project: + </para> + <para style="Bullet"> + London-based consultant and corporate developer + </para> + <para style="Bullet"> + want to do neat Python stuff in the daytime + </para> + <para style="Bullet"> + working for many years on financial modelling + </para> + <para style="Bullet"> + this is one of 6 modules in that system + </para> + <para style="Bullet"> + quickest to deliver, offers very wide benefits + </para> + <para style="Bullet"> + 25% of architecture done, but already very useful + </para> + <para style="Bullet"> + Release early, release often! + </para> + </frame> + </slide> + <slide title="Goal" id="Slide003" effectname="Wipe"> + <fixedimage filename="vertpython.gif" height="595" width="144" x="0" y="0"/> + <frame height="432" x="160" y="72" rightmargin="0" width="600" leftmargin="36"> + <para style="Heading2"> + Goal: + </para> + <para style="BodyText"> + A Reporting Package on the Next Curve... + </para> + <para style="Bullet"> + Report on objects, not databases + </para> + <para style="Bullet"> + Scalable to million page runs + </para> + <para style="Bullet"> + Light enough to embed in any application + </para> + <para style="Bullet"> + Allow reuse of graphical objects across reports + </para> + <para style="Bullet"> + Open and extensible on several levels + </para> + <para style="Bullet"> + Publication quality + </para> + <para style="Bullet"> + Support all the world's languages - one day + </para> + </frame> + </slide> + <slide title="Portable Document Format" id="Slide004" effectname="Wipe"> + <frame height="432" x="160" y="72" rightmargin="0" width="600" leftmargin="36"> + <para style="Heading2"> + Portable Document Format + </para> + <para style="Italic"> + The New PostScript + </para> + <para style="Bullet"> + Free readers on all platforms + </para> + <para style="Bullet"> + Better than paper - view it, email it, print it + </para> + <para style="Bullet"> + 'Final Form' for documents + </para> + <para style="Bullet"> + High end solution - no limits to quality + </para> + <para style="Italic"> + ...but you can't learn it in Notepad! + </para> + </frame> + </slide> + <slide title="PDFgen and PIDDLE" id="Slide005" effectname="Wipe"> + <frame height="432" x="160" y="72" rightmargin="0" width="600" leftmargin="36"> + <para/> + <para/> + <para style="Title"> + PDFgen and PIDDLE + </para> + </frame> + </slide> + <slide title="PDFgen layer" id="Slide006" effectname="Wipe"> + <frame height="432" x="160" y="72" rightmargin="0" width="600" leftmargin="36"> + <para style="Heading2"> + Layer One - PDFgen + </para> + <para style="Bullet"> + makes PDF documents from pure Python + </para> + <para style="Bullet"> + wraps up PDF document structure + </para> + <para style="Bullet"> + exposes nice effects - page transitions, outline trees (RSN!) + </para> + <para style="Bullet"> + low level graphics promitives (postscript imaging model) + </para> + <para style="Bullet"> + Fine control of text placement + </para> + <para style="Bullet"> + Supports Asian text + </para> + <para style="Bullet"> + Supports coordinate transformations and clipping + </para> + <para style="Italic"> + ...a foundation for other apps to build on + </para> + </frame> + </slide> + <slide title="PDF Image Suport" id="Slide007" effectname="Wipe"> + <frame height="432" x="160" y="72" rightmargin="0" width="600" leftmargin="36"> + <para style="Heading2"> + PDFgen Image Support + </para> + <para> + Python Imaging Library and zlib do all the work - many formats. + Images cached (like .pyc files) - very fast builds possible. + </para> + <image filename="python.gif" width="588" height="200"/> + </frame> + </slide> + <slide title="Layer Two: PIDDLE" id="Slide008" effectname="Wipe"> + <frame height="432" x="160" y="72" rightmargin="0" width="600" leftmargin="36"> + <para style="Heading2"> + Layer Two: PIDDLE + </para> + <para style="Italic"> + Plug In Drawing, Does Little Else + </para> + <para style="Bullet"> + Easy Graphics Library + </para> + <para style="Bullet"> + Abstract Canvas Interface + </para> + <para style="Bullet"> + Pluggable Back Ends + </para> + <para style="Bullet"> + Same code can do viewing and printing + </para> + <para style="Bullet"> + Standard set of test patterns + </para> + <para style="Bullet"> + Uses Python Imaging Library + </para> + <para style="BodyText"> + Back ends includeTkinter, wxPython, Mac, Pythonwin, PDF, PostScript, + OpenGL, Adobe Illustrator and PIL. Really easy to add a new one! + </para> + </frame> + </slide> + <slide title="Layer Three: PLATYPUS" id="Slide009" effectname="Wipe"> + <frame height="432" x="160" y="72" rightmargin="0" width="600" leftmargin="36"> + <para style="Heading2"> + Layer Three: PLATYPUS + </para> + <para style="Italic"> + "Page Layout And Typography Using Scripts" + </para> + <para style="BodyText"> + Trying to work out the API now. Key Concepts: + </para> + <para style="Bullet"> + Drawable objects - can 'wrap to fit' + </para> + <para style="Bullet"> + Frames on page + </para> + <para style="Bullet"> + Frame consumes from a list of drawables until full + </para> + <para style="Bullet"> + Document Models e.g. SimpleFlowDocument + </para> + <para style="BodyText"> + XSL Flow Object model may be a good target + </para> + </frame> + </slide> + <slide title="Drawable Objects" id="Slide010" effectname="Wipe"> + <frame height="432" x="160" y="72" rightmargin="0" width="600" leftmargin="36"> + <para style="Heading2"> + Drawable Objects + </para> + <para style="BodyText"> + Next layer of PIDDLE extensibility. + Each draws in its own coodinate system + </para> + <para style="Bullet"> + paragraph, image, table + </para> + <para style="Bullet"> + chart libraries + </para> + <para style="Bullet"> + diagrams + </para> + <para style="BodyText"> + Open Source - let people contribute new ones. + Anything you could have in a view can be a new + drawable type. + </para> + </frame> + </slide> + <slide title="Style Sheets" id="Slide011" effectname="Wipe"> + <frame height="432" x="160" y="72" rightmargin="0" width="600" leftmargin="36"> + <para style="Heading2"> + Style Sheet Driven + </para> + <para style="BodyText"> + Styles use instance inheritance + </para> + <para style="Bullet"> + Paragraph Styles - Style Sheet Compulsory! + </para> + <para style="Bullet"> + Text Styles within a paragraph + </para> + <para style="Bullet"> + Table and Table Cell Styles + </para> + </frame> + </slide> + <slide title="Vision" id="Slide012" effectname="Wipe"> + <frame height="432" x="160" y="72" rightmargin="0" width="600" leftmargin="36"> + <para style="Heading2"> + Vision + </para> + <para style="Bullet"> + XML to PDF in one step + </para> + <para style="Bullet"> + Publish to web and print from same source + </para> + <para style="Bullet"> + Financial and Scientific reporting tool + </para> + <para style="Bullet"> + Embedded reporting engine + </para> + <para style="Bullet"> + Volume reporting tool for business + </para> + </frame> + </slide> + <slide title="PythonPoint" id="Slide013" effectname="Wipe"> + <frame height="432" x="160" y="72" rightmargin="0" width="600" leftmargin="36"> + <para style="Heading2"> + PythonPoint + </para> + <para style="Italic"> + How I made this presentation... + </para> + </frame> + </slide> + </section> +</presentation> diff --git a/bin/reportlab/tools/pythonpoint/demos/outline.gif b/bin/reportlab/tools/pythonpoint/demos/outline.gif Binary files differnew file mode 100644 index 00000000000..4a294b59277 --- /dev/null +++ b/bin/reportlab/tools/pythonpoint/demos/outline.gif diff --git a/bin/reportlab/tools/pythonpoint/demos/pplogo.gif b/bin/reportlab/tools/pythonpoint/demos/pplogo.gif Binary files differnew file mode 100644 index 00000000000..d0344497ca5 --- /dev/null +++ b/bin/reportlab/tools/pythonpoint/demos/pplogo.gif diff --git a/bin/reportlab/tools/pythonpoint/demos/python.gif b/bin/reportlab/tools/pythonpoint/demos/python.gif Binary files differnew file mode 100644 index 00000000000..c68e1e4ec37 --- /dev/null +++ b/bin/reportlab/tools/pythonpoint/demos/python.gif diff --git a/bin/reportlab/tools/pythonpoint/demos/pythonpoint.xml b/bin/reportlab/tools/pythonpoint/demos/pythonpoint.xml new file mode 100644 index 00000000000..15d1ad709b5 --- /dev/null +++ b/bin/reportlab/tools/pythonpoint/demos/pythonpoint.xml @@ -0,0 +1,1051 @@ +<?xml version="1.0" encoding="iso-8859-1" standalone="no"?> +<!DOCTYPE presentation SYSTEM "../pythonpoint.dtd"> +<presentation filename="pythonpoint.pdf" pageDuration="3"> + <stylesheet module="standard" function="getParagraphStyles"/> + <title>PythonPoint Demonstration</title> + <author>Andy Robinson</author> + <subject>Reportlab Sample Applications</subject> + <section name="Main"> + <!-- any graphics in the section go on all its pages as a backdrop --> + <rectangle height="555" fill="ReportLabBlue" x="20" width="96" y="20"/> + <!--fixedimage height="64" filename="leftlogo.gif" x="20" width="96" y="510"/--> + <customshape module="customshapes" class="Logo" initargs="(20,510,96,64)"/> + <!--infostring size="14" align="right" x="800" y="36"> + »%(title)s, page %(page)s« + </infostring--> + <!-- Now for the slides --> + <slide title="Introduction" id="Slide001" effectname="Wipe"> + <frame height="468" x="120" y="72" rightmargin="36" width="700" leftmargin="36"> + <para style="Heading1"> + Welcome to PythonPoint + </para> + <para style="BodyText"> + ...a library for creating presentation slides. + </para> + <para style="BodyText"> + <i> + PythonPoint + </i> + lets you create attractive and consistent presentation slides + on any platform. It is a demo app built on top of the PDFgen PDF library + and the PLATYPUS Page Layout library. Essentially, it converts slides + in an XML format to PDF. + </para> + <para style="BodyText"> + It can be used right now to create slide shows, but will + undoubtedly change and evolve. Read on for a tutorial... + </para> + </frame> + <notes> + <para> + Smile and look them in the eye! + </para> + </notes> + </slide> + <slide title="Part 1" id="Part1" effectname="Blinds" effectdirection="0"> + <frame height="468" x="120" y="72" rightmargin="36" width="700" leftmargin="36"> + <para/> + <para/> + <para/> + <para style="Heading1"> + Part 1 – Feature Overview + </para> + </frame> + </slide> + <slide title="XML Notation" id="Slide002" effectname="Blinds" effectdirection="0" outlinelevel="1"> + <frame height="468" x="120" y="72" rightmargin="36" width="700" leftmargin="36"> + <para style="Heading1"> + XML Notation + </para> + <para style="BodyText"> + You create slides in a text editor with a basic + XML syntax looking like this: + </para> + <prefmt style="Code"><![CDATA[ +<frame x="160" y="72" width="600" height="468" + leftmargin="36" rightmargin="36"> + <para style='Heading1'> + Welcome to PythonPoint + </para> + <para style='BodyText'> + ...a library for creating presentation slides. + </para> +</frame> ]]></prefmt> + <para style="BodyText"> + Pythonpoint then converts these into slides. Just enter + "pythonpoint.py myfile.xml" to create a PDF document + (usually called "myfile.pdf", but you specify that in the XML). + </para> + </frame> + </slide> + <slide title="Page Layout" id="Slide003" effectname="Box" outlinelevel="1"> + <frame height="468" border="true" x="120" y="72" rightmargin="36" width="700" leftmargin="36"> + <para style="Heading1"> + Page Layout Model + </para> + <para style="BodyText"> + The Page Layout model comes from PLATYPUS (Page Layout and Typography Using Scripts), + a key component of the toolkit. This covers concepts such as: + </para> + <para style="Bullet"> + Reusable 'Drawable Objects' + </para> + <para style="Bullet"> + Frames into which objects flow (like this one, around which we have drawn a border) + </para> + <para style="Bullet"> + Style Sheets for text, table cells, line styles etc. + </para> + <para style="Bullet"> + Wrapping, page breaking an document management logic + </para> + <para style="BodyText"> + Everything is open and extensible. I hope a library of + reusable objects such as charts and diagrams will grow up. + </para> + </frame> + </slide> + <slide title="Reuse" id="Slide004" effectname="Wipe" outlinelevel="1"> + <frame height="468" x="120" y="72" rightmargin="36" width="700" leftmargin="36"> + <para style="Heading1"> + Reuse and Consistency – Sections + </para> + <para style="BodyText"> + You can create a 'section' spanning some or all tags in the presentation + and place graphics on this. The blue border and title come from the + section. Here's how we did the border: + </para> + <prefmt style="Code"><![CDATA[ +<presentation filename='pythonpoint.pdf'> + <section name = 'Main'> + <!-- any graphics in the section go on all its pages as a backdrop --> + <rectangle x="20" y="510" width="800" height="65" fill="(0,0,1)"/> + <rectangle x="20" y="20" width="65" height="555" fill="(0,0,1)"/> + ...all slides go here... + </section> +</presentation> +]]></prefmt> + <para style="BodyText"> + Thus you can re-brand an entire presentation for + a new audience in seconds. + </para> + </frame> + </slide> + <slide title="Styles" id="Slide005" effectname="Dissolve" outlinelevel="1"> + <frame height="468" x="120" y="72" rightmargin="36" width="700" leftmargin="36"> + <para style="Heading1"> + Style Sheets + </para> + <para style="BodyText"> + Paragraph styles are defined externally. You may specify a filename + from which to load a stylesheet with the stylesheet tag. + </para> + <para style="BodyText"> + Thus you can have different sizes and formats by switching + stylesheets, or colour and black-and-white options. + </para> + <para style="BodyText"> + When they are added, tables will be driven by line and cell + styles in a similar way. + </para> + </frame> + </slide> + <slide title="Special Effects" id="Slide006" effectname="Dissolve" outlinelevel="1"> + <frame height="468" x="120" y="72" rightmargin="36" width="700" leftmargin="36"> + <para style="Heading1"> + Special Effects + </para> + <para style="BodyText"> + Acrobat Reader supports tags to define page transition effects. + If you are reading this on screen, you should have seen a selection + of these: + </para> + <para style="Bullet"> + Split + </para> + <para style="Bullet"> + Blinds + </para> + <para style="Bullet"> + Box + </para> + <para style="Bullet"> + Wipe + </para> + <para style="Bullet"> + Dissolve + </para> + <para style="Bullet"> + Glitter + </para> + <para style="BodyText"> + Each has a range of options to fine-tune. + </para> + <para style="BodyText"> + When they are added, tables will be driven by line and cell + styles in a similar way. + </para> + </frame> + </slide> + <slide title="Outlines and Hyperlinks" id="Slide007" effectname="Wipe" outlinelevel="1"> + <frame height="468" x="120" y="72" rightmargin="36" width="700" leftmargin="36"> + <para style="Heading1"> + Outlines and Hyperlinks + </para> + <para style="BodyText"> + By default, we generate an outline view in the left pane to + help you navigate. Hyperlinks within documents are also + possible. + </para> + <para style="BodyText"> + As far as we know, this is the first PDF library to expose + these features. + </para> + </frame> + </slide> + <slide title="Basic Shapes" id="Slide008" effectname="Wipe" outlinelevel="1"> + <frame height="468" x="120" y="72" rightmargin="36" width="700" leftmargin="36"> + <para style="Heading1"> + Basic Shapes + </para> + <para> + Here are some of the basic shapes available for decorating pages... + </para> + </frame> + <rectangle height="50" fill="(0,1,1)" x="200" width="100" y="300"/> + <roundrect height="50" x="350" y="300" radius="15" fill="(0,1,1)" width="100"/> + <line y1="300" y2="350" x1="500" x2="600"/> + <ellipse fill="(0,1,1)" y1="300" y2="350" x1="650" x2="750"/> + <polygon points="(200,200),(300,200),(350,180),(250,150)" fill="(0,1,1)"/> + <string size="14" color="(1,0,0)" align="center" x="500" y="200"> + This is a\nmulti-line string\nplaced directly on the page.\n\nIt can be left-aligned,\ncentred,\nor right-aligned. + </string> + <customshape module="customshapes" class="Jigsaw" initargs="(700,200,1)"/> + </slide> + <slide title="Tables" id="Slide008a" effectname="Glitter" outlinelevel="1"> + <frame height="468" x="120" y="72" rightmargin="36" width="700" leftmargin="36"> + <para style="Heading1"> + Tables + </para> + <para> + The Table tag lets you paste in bulk data and format it attractively: + </para> + <spacer height="24"/> + <table heights="(28,28,28,28,28)" style="table1" widths="(144,72,72,72,108)"> + Division,Jan,Feb,Mar,Q1 Total + North,100,115,120,335 + South,215,145,180,540 + East,75,90,135,300 + West,100,120,115,335 + </table> + </frame> + </slide> + <slide title="Future Features" id="Slide009" effectname="Glitter" outlinelevel="1"> + <frame height="468" x="120" y="72" rightmargin="36" width="700" leftmargin="36"> + <para style="Heading1"> + Features Coming Soon + </para> + <para style="BodyText"> + This is the first version that runs. A lot can now be added fairly easily: + </para> + <para style="Bullet"> + Preprocessor to let you enter paragraphs and + bullets as one block of text, with less tag typing! + </para> + <para style="Bullet"> + PIDDLE drawings + </para> + <para style="Bullet"> + PINGO drawings – 'Object Graphics' tags with grouping and coordinate transformations + </para> + <para style="Bullet"> + Speaker notes and a mode to print them + </para> + <para style="Bullet"> + Tools to archive slides in a database and build presentations to order + </para> + <para style="Italic"> + ...what else can YOU think of? + </para> + </frame> + </slide> + <slide title="Part 2" id="Part2" effectname="Blinds" effectdirection="0" outlinelevel="0"> + <frame height="468" x="120" y="72" rightmargin="36" width="700" leftmargin="36"> + <para/> + <para/> + <para/> + <para style="Heading1"> + Part 2 – Reference + </para> + <para/> + <para style="Centered"> + This section covers all command line options + and tags currently in use. + </para> + </frame> + </slide> + <slide title="Command Line Options" id="Slide200" effectname="Blinds" effectdirection="0" outlinelevel="1"> + <frame height="510" x="120" y="72" rightmargin="36" width="700" leftmargin="36"> + <para style="Heading2"> + Command Line Options + </para> + <para> + Usage (NT, or executable Unix script): + </para> + <para> + <i> + pythonpoint.py [/notes] myslides.xml + </i> + </para> + <para> + or (Win9x or non-executable script) + </para> + <para> + <i> + python pythonpoint.py [/notes] myslides.xml + </i> + </para> + <para style="BodyText"> + Notes: + </para> + <para style="Bullet"> + The resulting PDF file has the same + name as the input file. + </para> + <para style="Bullet"> + The Speaker Notes mode prints a shrunken canvas with + room for notes around the edge. To create notes, make + an extra frame off the page. See the source of + Pythonpoint.xml slide 001 for an example. + </para> + </frame> + </slide> + <slide title="Tag: Presentation" id="Slide201" effectname="Blinds" effectdirection="0" outlinelevel="1"> + <frame height="510" x="120" y="72" rightmargin="36" width="700" leftmargin="36"> + <para style="Heading2"> + Tag "presentation" + </para> + <para style="BodyText"> + This is the outermost tag in an XML file and is always required. + </para> + <para style="Italic"> + Attributes: + </para> + <para style="Indent"> + filename (required) + </para> + <para style="Italic"> + Can Contain: + </para> + <para style="Indent"> + section, stylesheet, slides + </para> + <para/> + <para style="Italic"> + To Do: + </para> + <para style="Indent"> + Support for page sizes, opening modes + </para> + </frame> + </slide> + <slide title="Tag: Stylesheet" id="Slide202" effectname="Blinds" effectdirection="0" outlinelevel="1"> + <frame height="510" x="120" y="72" rightmargin="36" width="700" leftmargin="36"> + <para style="Heading2"> + Tag "stylesheet" + </para> + <para style="BodyText"> + This defines an external style sheet full of paragraph styles. + For now, these are Python modules conforming to a common interface, + and examples are given. If not declared, a default style sheet is + used. You are strongly advised to define your own style sheet, + as the built-in one will change a few more times. + </para> + <para style="Italic"> + Attributes: + </para> + <para style="Indent"> + path, module, function + </para> + <para style="Italic"> + Contained By: + </para> + <para style="Indent"> + Presentation, Section + </para> + <para style="Italic"> + Can Contain: + </para> + <para style="Indent"> + nothing + </para> + <para style="Italic"> + Example + </para> + <prefmt style="Code"><![CDATA[ +<stylesheet module="modern" function="getParagraphStyles"/> +]]></prefmt> + </frame> + </slide> + <slide title="Tag: Section" id="Slide203" effectname="Blinds" effectdirection="0" outlinelevel="1"> + <frame height="510" x="120" y="72" rightmargin="36" width="700" leftmargin="36"> + <para style="Heading2"> + Tag "section" + </para> + <para style="BodyText"> + A Section spans across a number of slides and can apply an + overall background to them. Place graphics directly within + the section tag, either before or after slides. This lets + you re-brand a presentation very quickly. Documents + may contain multiple sections; nesting of sections is + not (yet) permitted. + </para> + <para style="Italic"> + Attributes: + </para> + <para style="Indent"> + name (required, but not used yet) + </para> + <para style="Italic"> + Contained By: + </para> + <para style="Indent"> + Presentation + </para> + <para style="Italic"> + Can Contain: + </para> + <para style="Indent"> + all graphic shapes; slides + </para> + </frame> + </slide> + <slide title="Tag: Slide" id="Slide204" effectname="Blinds" effectdirection="0" outlinelevel="1"> + <frame height="510" x="120" y="72" rightmargin="36" width="700" leftmargin="36"> + <para style="Heading2"> + Tag "slide" + </para> + <para style="BodyText"> + Defines a single slide. The presentation effects are defined + in the PDF reference; best to just try the combinations. + </para> + <para style="Italic"> + Attributes (with defaults): + </para> + <para style="Indent"> + id (required) + </para> + <para style="Indent"> + title (required) + </para> + <para style="Indent"> + effectname: one of Split, Blinds, Box, Wipe, Dissolve, Glitter + </para> + <para style="Indent"> + effectdirection: '0','90','180' or '270' + </para> + <para style="Indent"> + effectdimension: 'H' or 'V' (Horiz./Vert.) + </para> + <para style="Indent"> + effectmotion: 'I' for inwards or 'O' for outwards + </para> + <para style="Indent"> + effectduration: time in seconds + </para> + <para style="Italic"> + Contained By: + </para> + <para style="Indent"> + Presentation + </para> + <para style="Italic"> + Can Contain: + </para> + <para style="Indent"> + all graphic shapes; frames + </para> + </frame> + </slide> + <slide title="Tag: Frame" id="Slide205" effectname="Blinds" effectdirection="0" outlinelevel="1"> + <frame height="510" x="120" y="72" rightmargin="36" width="700" leftmargin="36"> + <para style="Heading2"> + Tag "frame" + </para> + <para style="BodyText"> + Defines a frame on the page which can hold content. You may have + as many frames as you like, to allow multi-column text or flow + around pictures. + </para> + <para style="Italic"> + Attributes: + </para> + <para style="Indent"> + x, y, width, height (all required): in points + </para> + <para style="Indent"> + leftmargin, rightmargin, topmargin, bottommargin + (optional, default to zero) – define the 'inner rectangle' within + which content flows + </para> + <para style="Indent"> + border (defaults to 'false'): whether to show + a frame border – useful when designing pages. + </para> + <para style="Italic"> + Contained By: + </para> + <para style="Indent"> + Slide + </para> + <para style="Italic"> + Can Contain: + </para> + <para style="Indent"> + all 'flowable objects' – paragraphs, images + </para> + </frame> + </slide> + <slide title="Flowable Objects" id="Slide206" effectname="Blinds" effectdirection="0" outlinelevel="1"> + <frame height="510" x="120" y="72" rightmargin="36" width="700" leftmargin="36"> + <para style="Heading2"> + Tag family – "Flowable Objects" + </para> + <para style="BodyText"> + Flowable Objects currently include Paragraphs, Preformatted text + (used for code printing, where the line breaks and spaces matter) + and inline Images. More will be added in future. + They negotiate with their containing frame about height and + width; paragraphs do what you would expect, while images are centred. + </para> + <para style="Italic"> + Contained By: + </para> + <para style="Indent"> + Slide + </para> + <para style="Italic"> + Can Contain: + </para> + <para style="Indent"> + The three instances so far contain nothing. + </para> + </frame> + </slide> + <slide title="Tag: para" id="Slide207" effectname="Blinds" effectdirection="0" outlinelevel="2"> + <frame height="510" x="120" y="72" rightmargin="36" width="700" leftmargin="36"> + <para style="Heading2"> + Tag "para" – Paragraphs + </para> + <para style="BodyText"> + Paragraphs are used for wrapping text. They are very simple + – they have a style attribute, + and the stylesheet defines most attributes externally. + Currently we use a hack to handle 'bullets', which may be in + a different font (such as 'ZapfDingbats, specified in style) + and offset to the left. These are used + for bullets, numbering and definition lists + This will vanish as soon as one can + switch fonts in mid-paragraph (due mid April). + </para> + <para style="Italic"> + Attributes: + </para> + <para style="Indent"> + style (defaults to 'Normal') – + reference to stylesheet + </para> + <para style="Indent"> + bullettext – + text for the optional 'bullet' section. To be deprecated. + </para> + <para style="Italic"> + Contained By: + </para> + <para style="Indent"> + Frame + </para> + <para style="Italic"> + Can Contain: + </para> + <para style="Indent"> + Their text + </para> + </frame> + </slide> + <slide title="Tag: prefmt" id="Slide207" effectname="Blinds" effectdirection="0" outlinelevel="2"> + <frame height="510" x="120" y="72" rightmargin="36" width="700" leftmargin="36"> + <para style="Heading2"> + Tag "prefmt" + </para> + <para style="BodyText"> + This is used for printing code, or other text which contains + line breaks. + </para> + <para style="Italic"> + Attributes: + </para> + <para style="Indent"> + style (defaults to 'Normal') – + reference to stylesheet + </para> + <para style="Italic"> + Contained By: + </para> + <para style="Indent"> + Frame + </para> + <para style="Italic"> + Can Contain: + </para> + <para style="Indent"> + The text to be displayed + </para> + </frame> + </slide> + <slide title="Tag: image" id="Slide208" effectname="Blinds" effectdirection="0" outlinelevel="2"> + <frame height="510" x="120" y="72" rightmargin="36" width="700" leftmargin="36"> + <para style="Heading2"> + Tag "image" – flowing images + </para> + <para style="BodyText"> + This is used for an image to be displayed inline within + the frame. It will be drawn at a scale of 1 pixel to + 1 point, and centred in the frame. + </para> + <para style="Italic"> + Attributes: + </para> + <para style="Indent"> + filename (required) + </para> + <para style="Italic"> + Contained By: + </para> + <para style="Indent"> + Frame + </para> + <para style="Italic"> + Can Contain: + </para> + <para style="Indent"> + Nothing + </para> + <para style="Italic"> + To do + </para> + <para style="Indent"> + Rename it 'flowing image'? Control + over alignment and size if needed. Image caching. + </para> + </frame> + </slide> + <slide title="Tag: table" id="Slide208a" effectname="Blinds" effectdirection="0" outlinelevel="2"> + <frame height="510" x="120" y="72" rightmargin="36" width="700" leftmargin="36"> + <para style="Heading2"> + Tag "table" – tables + </para> + <para style="BodyText"> + This lets you draw tables with a wide variety of formatting + options. + </para> + <para style="Italic"> + Attributes: + </para> + <para style="Indent"> + <b> + widths + </b> + (optional) in points (auto-sizes if not given) + </para> + <para style="Indent"> + <b> + heights + </b> + (optional) in points (auto-sizes if not given) + </para> + <para style="Indent"> + <b> + style + </b> + (optional) – name of a ReportLab + tablestyle defined in the stylesheet. + </para> + <para style="Indent"> + <b> + colDelim + </b> + (optional) – the column + delimiter string for bulk data; defaults to a comma. + </para> + <para style="Indent"> + <b> + rowDelim + </b> + (optional) – the line + delimiter string for bulk data; defaults to a carriage + return. + </para> + <para style="Italic"> + Contained By: + </para> + <para style="Indent"> + Frame + </para> + <para style="Italic"> + Can Contain: + </para> + <para style="Indent"> + Bulk data, with the row and column delimiters + specified + </para> + </frame> + </slide> + <slide title="Drawable Objects" id="Slide209" effectname="Blinds" effectdirection="0" outlinelevel="1"> + <frame height="510" x="120" y="72" rightmargin="36" width="700" leftmargin="36"> + <para style="Heading2"> + Tag family – "Drawable Objects" + </para> + <para style="BodyText"> + These are objects which know how to draw themselves directly on + the page (or section template). Use them for designing the backdrop, + and for custom graphics. + </para> + <para style="Italic"> + Contained By: + </para> + <para style="Indent"> + Slide, Section + </para> + <para style="Italic"> + Can Contain: + </para> + <para style="Indent"> + Varies. + </para> + <para style="Italic"> + To Do: + </para> + <para style="Indent"> + Will include the full PINGO object + model – a subset of SVG – allowing any vector graphics + at all. + </para> + </frame> + </slide> + <slide title="Tag: FixedImage" id="Slide210" effectname="Blinds" effectdirection="0" outlinelevel="2"> + <frame height="510" x="120" y="72" rightmargin="36" width="700" leftmargin="36"> + <para style="Heading2"> + Tag "fixedimage" + </para> + <para style="BodyText"> + This is an image draw directly at a fixed position – + for example, the logo at top left of the page. + </para> + <para style="Italic"> + Attributes: + </para> + <para style="Indent"> + filename: required + </para> + <para style="Indent"> + x, y: required + </para> + <para style="Indent"> + width, height: optional, stretches image + to fit box if present. + </para> + <para style="Italic"> + Contained By: + </para> + <para style="Indent"> + Slide, Section + </para> + <para style="Italic"> + Can Contain: + </para> + <para style="Indent"> + Nothing + </para> + </frame> + </slide> + <slide title="Tag: Rectangle" id="Slide211" effectname="Blinds" effectdirection="0" outlinelevel="2"> + <frame height="510" x="120" y="72" rightmargin="36" width="700" leftmargin="36"> + <para style="Heading2"> + Tag "rectangle" + </para> + <para style="Italic"> + Attributes: + </para> + <para style="Indent"> + x, y, width, height: required + </para> + <para style="Indent"> + fill, stroke: either 'None', or an + (r,g,b) tuple. + </para> + <para style="Indent"> + linewidth: defaults to 0 (hairline) + </para> + <para style="Italic"> + Contained By: + </para> + <para style="Indent"> + Slide, Section + </para> + <para style="Italic"> + Can Contain: + </para> + <para style="Indent"> + Nothing + </para> + </frame> + </slide> + <slide title="Tag: RoundRect" id="Slide212" effectname="Blinds" effectdirection="0" outlinelevel="2"> + <frame height="510" x="120" y="72" rightmargin="36" width="700" leftmargin="36"> + <para style="Heading2"> + Tag "roundrect" + </para> + <para style="BodyText"> + This is exactly like Rectangle, + but with an extra 'radius' attribute defining the corner + radius in points – default is 6 points. + </para> + </frame> + </slide> + <slide title="Tag: Ellipse" id="Slide213" effectname="Blinds" effectdirection="0" outlinelevel="2"> + <frame height="510" x="120" y="72" rightmargin="36" width="700" leftmargin="36"> + <para style="Heading2"> + Tag "ellipse" + </para> + <para style="BodyText"> + Draws an ellipse, defined by its + bounding box. Note that it can + create circles if height and width are equal. + </para> + <para style="Italic"> + Attributes: + </para> + <para style="Indent"> + x1, y1, x2, y2: required + </para> + <para style="Indent"> + fill, stroke: either 'None', or an + (r,g,b) tuple. + </para> + <para style="Indent"> + linewidth: defaults to 0 (hairline) + </para> + <para style="Italic"> + Contained By: + </para> + <para style="Indent"> + Slide, Section + </para> + <para style="Italic"> + Can Contain: + </para> + <para style="Indent"> + Nothing + </para> + </frame> + </slide> + <slide title="Tag: Polygon" id="Slide214" effectname="Blinds" effectdirection="0" outlinelevel="2"> + <frame height="510" x="120" y="72" rightmargin="36" width="700" leftmargin="36"> + <para style="Heading2"> + Tag "polygon" + </para> + <para style="BodyText"> + Draws a polygon from a list + of points you provide. + </para> + <para style="Italic"> + Attributes: + </para> + <para style="Indent"> + points: list such as "(0,0),(50,0),(25,25)" + </para> + <para style="Indent"> + fill, stroke: either 'None', or an + (r,g,b) tuple. + </para> + <para style="Indent"> + linewidth: defaults to 0 (hairline) + </para> + <para style="Italic"> + Contained By: + </para> + <para style="Indent"> + Slide, Section + </para> + <para style="Italic"> + Can Contain: + </para> + <para style="Indent"> + Nothing + </para> + </frame> + </slide> + <slide title="Tag: Line" id="Slide215" effectname="Blinds" effectdirection="0" outlinelevel="2"> + <frame height="510" x="120" y="72" rightmargin="36" width="700" leftmargin="36"> + <para style="Heading2"> + Tag "line" + </para> + <para style="BodyText"> + Draws a line. + </para> + <para style="Italic"> + Attributes: + </para> + <para style="Indent"> + x1, y1, x2, y2 + </para> + <para style="Indent"> + stroke: either 'None', or an + (r,g,b) tuple. + </para> + <para style="Indent"> + width: defaults to 0 (hairline) + </para> + <para style="Italic"> + Contained By: + </para> + <para style="Indent"> + Slide, Section + </para> + <para style="Italic"> + Can Contain: + </para> + <para style="Indent"> + Nothing + </para> + </frame> + </slide> + <slide title="Tag: String" id="Slide215" effectname="Blinds" effectdirection="0" outlinelevel="2"> + <frame height="510" x="120" y="72" rightmargin="36" width="700" leftmargin="36"> + <para style="Heading2"> + Tag "string" + </para> + <para style="BodyText"> + This places strings directly on the page. They may have + embedded newlines (use a '\n' in the XML), in which + case multi-line strings are printed. Left, right + and centre alignment are allowed. + </para> + <para style="Italic"> + Attributes: + </para> + <para style="Indent"> + x, y: required + </para> + <para style="Indent"> + color: RGB colour tuple such as '(0,1,0)' + </para> + <para style="Indent"> + font: default is 'Times-Roman' + </para> + <para style="Indent"> + size: default 12 + </para> + <para style="Indent"> + align: default 'left', allows + also 'right' or 'center' + </para> + <para style="Italic"> + Contained By: + </para> + <para style="Indent"> + Slide, Section + </para> + <para style="Italic"> + Can Contain: + </para> + <para style="Indent"> + The text of the string + </para> + </frame> + </slide> + <slide title="Tag: CustomShape" id="Slide216" effectname="Blinds" effectdirection="0" outlinelevel="2"> + <frame height="510" x="120" y="72" rightmargin="36" width="700" leftmargin="36"> + <para style="Heading2"> + Tag "customshape" + </para> + <para style="BodyText"> + This looks in a specified Python module for a + 'drawable object' you write, and initialises + it with arguments you provide before drawing. + This must provide a 'self.drawOn(canvas)' method. + </para> + <para style="Italic"> + Attributes: + </para> + <para style="Indent"> + path: where to look; searches Python path + if None + </para> + <para style="Indent"> + module: module name + </para> + <para style="Indent"> + class: class name to create + </para> + <para style="Indent"> + initargs: tuple of arguments with which + to initialize the class. + </para> + <para style="Indent"> + align: default 'left', allows + also 'right' or 'center' + </para> + <para style="Italic"> + Contained By: + </para> + <para style="Indent"> + Slide, Section + </para> + <para style="Italic"> + Can Contain: + </para> + <para style="Indent"> + Nothing + </para> + </frame> + </slide> + <slide title="To Do" id="Part3" effectname="Blinds" effectdirection="0"> + <frame height="468" x="120" y="72" rightmargin="36" width="700" leftmargin="36"> + <para style="Heading1"> + Part 3 – To Do + </para> + <para style="Bullet"> + Lots of testing + </para> + <para style="Bullet"> + Text preprocessor to let you input text, styles and images + in something easier to type + </para> + <para style="Bullet"> + Support for Pingo (http://pingo.sourceforge.net/) drawings using + the Scalable Vector Graphics imaging model + </para> + <para style="Bullet"> + Proper caching of flowing images + </para> + <para style="Bullet"> + Basic Tables and Charts + </para> + <para style="Bullet"> + Use new XML parsers as wel as xmllib + </para> + <para style="Bullet"> + Slide indexing and database search tools + </para> + <para style="Bullet"> + Speaker Notes mode + </para> + <para> + Naturally, help is extremely welcome :-) + </para> + </frame> + </slide> + </section> +</presentation> diff --git a/bin/reportlab/tools/pythonpoint/demos/slidebox.py b/bin/reportlab/tools/pythonpoint/demos/slidebox.py new file mode 100644 index 00000000000..f0d9cf308e9 --- /dev/null +++ b/bin/reportlab/tools/pythonpoint/demos/slidebox.py @@ -0,0 +1,29 @@ +#Autogenerated by ReportLab guiedit do not edit +from reportlab.graphics.shapes import _DrawingEditorMixin +from reportlab.graphics.charts.slidebox import SlideBox +from rlextra.graphics.guiedit.datacharts import ODBCDataSource, CSVDataSource, DataAssociation, DataAwareDrawing + +class SlideBoxDrawing(_DrawingEditorMixin,DataAwareDrawing): + def __init__(self,width=400,height=200,*args,**kw): + apply(DataAwareDrawing.__init__,(self,width,height)+args,kw) + self._add(self,SlideBox(),name='SlideBox',validate=None,desc='The main chart') + self.height = 40 + self.width = 168 + #self.dataSource = ODBCDataSource() + self.dataSource = CSVDataSource() + self.dataSource.filename = 'slidebox.csv' + self.dataSource.integerColumns = ['chartId','value','numberOfBoxes'] + self.dataSource.sql = 'SELECT chartId,numberOfBoxes,label,value FROM generic_slidebox' + self.dataSource.associations.size = 4 + self.dataSource.associations.element00 = DataAssociation(column=0, target='chartId', assocType='scalar') + self.dataSource.associations.element01 = DataAssociation(column=1, target='SlideBox.numberOfBoxes', assocType='scalar') + self.dataSource.associations.element02 = DataAssociation(column=2, target='SlideBox.sourceLabelText', assocType='scalar') + self.dataSource.associations.element03 = DataAssociation(column=3, target='SlideBox.trianglePosition', assocType='scalar') + self.verbose = 1 + self.formats = ['eps', 'pdf'] + self.outDir = './output/' + self.fileNamePattern = 'slidebox%03d' + + +if __name__=="__main__": #NORUNTESTS + SlideBoxDrawing().go() diff --git a/bin/reportlab/tools/pythonpoint/demos/spectrum.png b/bin/reportlab/tools/pythonpoint/demos/spectrum.png Binary files differnew file mode 100644 index 00000000000..06747655056 --- /dev/null +++ b/bin/reportlab/tools/pythonpoint/demos/spectrum.png diff --git a/bin/reportlab/tools/pythonpoint/demos/vertpython.gif b/bin/reportlab/tools/pythonpoint/demos/vertpython.gif Binary files differnew file mode 100644 index 00000000000..5e5c60c3308 --- /dev/null +++ b/bin/reportlab/tools/pythonpoint/demos/vertpython.gif diff --git a/bin/reportlab/tools/pythonpoint/pythonpoint.dtd b/bin/reportlab/tools/pythonpoint/pythonpoint.dtd new file mode 100644 index 00000000000..ec876f68387 --- /dev/null +++ b/bin/reportlab/tools/pythonpoint/pythonpoint.dtd @@ -0,0 +1,275 @@ +<!-- + pythonpoint.dtd + + PythonPoint XML DTD, version 0.1k + Copyright 2001-2002 ReportLab, Inc. + + This is a draft of the DTD for PythonPoint, a program for creating + presentation slides based on XML. + + See http://www.reportlab.com for further information. + + Common declaration: + + <?xml version='1.0'?> + <!DOCTYPE presentation + PUBLIC "-//ReportLab//DTD PythonPoint XML v0.1k//EN" + "pythonpoint.dtd"> + + Please send bug reports, suggestions, etc. to: info@reportlab.com. +--> +<!-- Entities --> +<!ENTITY % bool "true|false"> +<!ENTITY % align.values "left|center|right"> +<!ENTITY % effectdimension.values "H|V"> +<!ENTITY % effectdirection.values "0|90|180|270"> +<!ENTITY % effectmotion.values "I|O"> +<!ENTITY % effectname.values "Blinds|Box|Dissolve|Glitter|Split|Wipe"> +<!-- Top-Level Element --> +<!ELEMENT presentation (subject?, title?, author?, section?, stylesheet?, registerFont?, slide*)+> +<!ATTLIST presentation + filename CDATA #REQUIRED + pageDuration CDATA #IMPLIED + pageWidth CDATA #IMPLIED + pageHeight CDATA #IMPLIED +> +<!-- First-Level Elements --> +<!ELEMENT author (#PCDATA)> +<!-- PDF Document Info --> +<!ELEMENT section (fixedimage*, rectangle*, roundrect*, ellipse*, polygon*, line*, string*, infostring*, customshape*, slide*)+> +<!ATTLIST section + name CDATA #REQUIRED +> +<!ELEMENT slide (fixedimage*, rectangle*, roundrect*, ellipse*, polygon*, line*, string*, infostring*, customshape*, frame*, notes*)+> +<!ATTLIST slide + id CDATA #REQUIRED + title CDATA #REQUIRED + outlineentry CDATA #IMPLIED + outlinelevel NMTOKEN #IMPLIED + showIDName (%bool;) "true" + effectname (%effectname.values;) #IMPLIED + effectdirection (%effectdirection.values;) "0" + effectdimension (%effectdimension.values;) "H" + effectmotion (%effectmotion.values;) "I" + effectduration NMTOKEN "1" +> +<!ELEMENT stylesheet EMPTY> +<!ATTLIST stylesheet + path CDATA #IMPLIED + module CDATA #REQUIRED + function CDATA #REQUIRED +> +<!ELEMENT registerFont EMPTY> +<!ATTLIST registerFont + name CDATA #REQUIRED + path CDATA #REQUIRED +> +<!ELEMENT subject (#PCDATA)> +<!-- PDF Document Info --> +<!ELEMENT title (#PCDATA)> +<!-- PDF Document Info --> +<!-- Other elements --> +<!ELEMENT b (#PCDATA)> +<!ELEMENT customshape EMPTY> +<!ATTLIST customshape + path CDATA #IMPLIED + module CDATA #IMPLIED + class CDATA #IMPLIED + initargs CDATA #IMPLIED + align (%align.values;) #IMPLIED +> +<!ELEMENT ellipse EMPTY> +<!ATTLIST ellipse + x1 NMTOKEN #REQUIRED + y1 NMTOKEN #REQUIRED + x2 NMTOKEN #REQUIRED + y2 NMTOKEN #REQUIRED + fill CDATA #IMPLIED + stroke CDATA "(0,0,0)" + linewidth NMTOKEN "0" + effectname (%effectname.values;) #IMPLIED + effectdirection (%effectdirection.values;) "0" + effectdimension (%effectdimension.values;) "H" + effectmotion (%effectmotion.values;) "I" + effectduration NMTOKEN "1" +> +<!ELEMENT fixedimage EMPTY> +<!ATTLIST fixedimage + filename CDATA #REQUIRED + x NMTOKEN #REQUIRED + y NMTOKEN #REQUIRED + width NMTOKEN #IMPLIED + height NMTOKEN #IMPLIED +> +<!ELEMENT font (#PCDATA)> +<!ATTLIST font + name CDATA #IMPLIED + color CDATA #IMPLIED + size NMTOKEN #IMPLIED +> +<!ELEMENT frame (para*, prefmt*, pycode*, image*, table*, fixedimage*, rectangle*, roundrect*, ellipse*, polygon*, line*, string*, customshape*, spacer*, drawing*, pageCatcherFigure*)+> +<!ATTLIST frame + x NMTOKEN #REQUIRED + y NMTOKEN #REQUIRED + width NMTOKEN #REQUIRED + height NMTOKEN #REQUIRED + leftmargin NMTOKEN "0" + rightmargin NMTOKEN "0" + topmargin NMTOKEN "0" + bottommargin NMTOKEN "0" + border (%bool;) "false" +> +<!ELEMENT greek (#PCDATA)> +<!ELEMENT i (#PCDATA)> +<!ELEMENT image EMPTY> +<!ATTLIST image + filename CDATA #REQUIRED + width NMTOKEN #IMPLIED + height NMTOKEN #IMPLIED + effectname (%effectname.values;) #IMPLIED + effectdirection (%effectdirection.values;) "0" + effectdimension (%effectdimension.values;) "H" + effectmotion (%effectmotion.values;) "I" + effectduration NMTOKEN "1" +> +<!ELEMENT infostring (#PCDATA)> +<!ATTLIST infostring + x NMTOKEN #REQUIRED + y NMTOKEN #REQUIRED + color CDATA "(0,0,0)" + font CDATA "Times-Roman" + size NMTOKEN "12" + align (%align.values;) "left" +> +<!ELEMENT line EMPTY> +<!ATTLIST line + x1 NMTOKEN #REQUIRED + y1 NMTOKEN #REQUIRED + x2 NMTOKEN #REQUIRED + y2 NMTOKEN #REQUIRED + stroke CDATA "(0,0,0)" + width NMTOKEN "0" + effectname (%effectname.values;) #IMPLIED + effectdirection (%effectdirection.values;) "0" + effectdimension (%effectdimension.values;) "H" + effectmotion (%effectmotion.values;) "I" + effectduration NMTOKEN "1" +> +<!ELEMENT notes (para+)> +<!ELEMENT para (#PCDATA | i | b | u | super | sub | font | greek)*> +<!ATTLIST para + style CDATA "Normal" + bullettext CDATA #IMPLIED + effectname (%effectname.values;) #IMPLIED + effectdirection (%effectdirection.values;) "0" + effectdimension (%effectdimension.values;) "H" + effectmotion (%effectmotion.values;) "I" + effectduration NMTOKEN "1" +> +<!ELEMENT polygon EMPTY> +<!ATTLIST polygon + points CDATA #REQUIRED + fill CDATA #REQUIRED + stroke CDATA "(0,0,0)" + linewidth NMTOKEN "0" + effectname (%effectname.values;) #IMPLIED + effectdirection (%effectdirection.values;) "0" + effectdimension (%effectdimension.values;) "H" + effectmotion (%effectmotion.values;) "I" + effectduration NMTOKEN "1" +> +<!ELEMENT prefmt (#PCDATA)> +<!ATTLIST prefmt + xml:space (default | preserve) #FIXED "preserve" + style CDATA #IMPLIED +> +<!ELEMENT pycode (#PCDATA)> +<!ATTLIST pycode + xml:space (default | preserve) #FIXED "preserve" + style CDATA #IMPLIED +> +<!ELEMENT rectangle EMPTY> +<!ATTLIST rectangle + x NMTOKEN #REQUIRED + y NMTOKEN #REQUIRED + width NMTOKEN #REQUIRED + height NMTOKEN #REQUIRED + fill CDATA #IMPLIED + stroke CDATA "(0,0,0)" + linewidth NMTOKEN "0" + effectname (%effectname.values;) #IMPLIED + effectdirection (%effectdirection.values;) "0" + effectdimension (%effectdimension.values;) "H" + effectmotion (%effectmotion.values;) "I" + effectduration NMTOKEN "1" +> +<!ELEMENT roundrect EMPTY> +<!ATTLIST roundrect + x NMTOKEN #REQUIRED + y NMTOKEN #REQUIRED + width NMTOKEN #REQUIRED + height NMTOKEN #REQUIRED + fill CDATA #IMPLIED + stroke CDATA "(0,0,0)" + linewidth NMTOKEN "0" + radius NMTOKEN "6" + effectname (%effectname.values;) #IMPLIED + effectdirection (%effectdirection.values;) "0" + effectdimension (%effectdimension.values;) "H" + effectmotion (%effectmotion.values;) "I" + effectduration NMTOKEN "1" +> +<!ELEMENT spacer EMPTY> +<!ATTLIST spacer + height NMTOKEN #REQUIRED +> +<!ELEMENT string (#PCDATA)> +<!ATTLIST string + x NMTOKEN #REQUIRED + y NMTOKEN #REQUIRED + color CDATA "(0,0,0)" + font CDATA "Times-Roman" + size NMTOKEN "12" + align (%align.values;) "left" + effectname (%effectname.values;) #IMPLIED + effectdirection (%effectdirection.values;) "0" + effectdimension (%effectdimension.values;) "H" + effectmotion (%effectmotion.values;) "I" + effectduration NMTOKEN "1" +> +<!ELEMENT sub (#PCDATA)> +<!ELEMENT super (#PCDATA)> +<!ELEMENT table (#PCDATA)> +<!ATTLIST table + xml:space (default | preserve) #FIXED "preserve" + widths CDATA #IMPLIED + heights CDATA #IMPLIED + style CDATA #IMPLIED + colDelim CDATA #IMPLIED + rowDelim CDATA #IMPLIED + effectname (%effectname.values;) #IMPLIED + effectdirection (%effectdirection.values;) "0" + effectdimension (%effectdimension.values;) "H" + effectmotion (%effectmotion.values;) "I" + effectduration NMTOKEN "1" +> +<!ELEMENT u (#PCDATA)> +<!ELEMENT drawing EMPTY> +<!ATTLIST drawing + module CDATA #REQUIRED + constructor CDATA #REQUIRED + baseDir CDATA #IMPLIED + hAlign CDATA #IMPLIED + showBoundary CDATA #IMPLIED +> +<!ELEMENT pageCatcherFigure (#PCDATA)> +<!ATTLIST pageCatcherFigure + filename CDATA #REQUIRED + pageNo CDATA #REQUIRED + caption CDATA #IMPLIED + width CDATA #IMPLIED + height CDATA #IMPLIED + background CDATA #IMPLIED + border CDATA #IMPLIED + scaleFactor CDATA #IMPLIED +> diff --git a/bin/reportlab/tools/pythonpoint/pythonpoint.py b/bin/reportlab/tools/pythonpoint/pythonpoint.py new file mode 100644 index 00000000000..c5e823de04d --- /dev/null +++ b/bin/reportlab/tools/pythonpoint/pythonpoint.py @@ -0,0 +1,1124 @@ +#!/usr/bin/env python + +""" +This is PythonPoint! + +The idea is a simple markup languages for describing presentation +slides, and other documents which run page by page. I expect most +of it will be reusable in other page layout stuff. + +Look at the sample near the top, which shows how the presentation +should be coded up. + +The parser, which is in a separate module to allow for multiple +parsers, turns the XML sample into an object tree. There is a +simple class hierarchy of items, the inner levels of which create +flowable objects to go in the frames. These know how to draw +themselves. + +The currently available 'Presentation Objects' are: + + The main hierarchy... + PPPresentation + PPSection + PPSlide + PPFrame + + PPAuthor, PPTitle and PPSubject are optional + + Things to flow within frames... + PPPara - flowing text + PPPreformatted - text with line breaks and tabs, for code.. + PPImage + PPTable - bulk formatted tabular data + PPSpacer + + Things to draw directly on the page... + PPRect + PPRoundRect + PPDrawingElement - user base class for graphics + PPLine + PPEllipse + +Features added by H. Turgut Uyar <uyar@cs.itu.edu.tr> +- TrueType support (actually, just an import in the style file); + this also enables the use of Unicode symbols +- para, image, table, line, rectangle, roundrect, ellipse, polygon + and string elements can now have effect attributes + (careful: new slide for each effect!) +- added printout mode (no new slides for effects, see item above) +- added a second-level bullet: Bullet2 +- small bugfixes in handleHiddenSlides: + corrected the outlineEntry of included hidden slide + and made sure to include the last slide even if hidden + +Recently added features are: + +- file globbing +- package structure +- named colors throughout (using names from reportlab/lib/colors.py) +- handout mode with arbitrary number of columns per page +- stripped off pages hidden in the outline tree (hackish) +- new <notes> tag for speaker notes (paragraphs only) +- new <pycode> tag for syntax-colorized Python code +- reformatted pythonpoint.xml and monterey.xml demos +- written/extended DTD +- arbitrary font support +- print proper speaker notes (TODO) +- fix bug with partially hidden graphics (TODO) +- save in combined presentation/handout mode (TODO) +- add pyRXP support (TODO) +""" + +import os, sys, imp, string, pprint, getopt, glob + +from reportlab import rl_config +from reportlab.lib import styles +from reportlab.lib import colors +from reportlab.lib.units import cm +from reportlab.lib.utils import getStringIO +from reportlab.lib.enums import TA_LEFT, TA_RIGHT, TA_CENTER, TA_JUSTIFY +from reportlab.pdfbase import pdfmetrics +from reportlab.pdfgen import canvas +from reportlab.platypus.doctemplate import SimpleDocTemplate +from reportlab.platypus.flowables import Flowable +from reportlab.platypus.xpreformatted import PythonPreformatted +from reportlab.platypus import Preformatted, Paragraph, Frame, \ + Image, Table, TableStyle, Spacer + + +USAGE_MESSAGE = """\ +PythonPoint - a tool for making presentations in PDF. + +Usage: + pythonpoint.py [options] file1.xml [file2.xml [...]] + + where options can be any of these: + + -h / --help prints this message + -n / --notes leave room for comments + -v / --verbose verbose mode + -s / --silent silent mode (NO output) + --handout produce handout document + --printout produce printout document + --cols specify number of columns + on handout pages (default: 2) + +To create the PythonPoint user guide, do: + pythonpoint.py pythonpoint.xml +""" + + +##################################################################### +# This should probably go into reportlab/lib/fonts.py... +##################################################################### + +class FontNameNotFoundError(Exception): + pass + + +class FontFilesNotFoundError(Exception): + pass + + +##def findFontName(path): +## "Extract a Type-1 font name from an AFM file." +## +## f = open(path) +## +## found = 0 +## while not found: +## line = f.readline()[:-1] +## if not found and line[:16] == 'StartCharMetrics': +## raise FontNameNotFoundError, path +## if line[:8] == 'FontName': +## fontName = line[9:] +## found = 1 +## +## return fontName +## +## +##def locateFilesForFontWithName(name): +## "Search known paths for AFM/PFB files describing T1 font with given name." +## +## join = os.path.join +## splitext = os.path.splitext +## +## afmFile = None +## pfbFile = None +## +## found = 0 +## while not found: +## for p in rl_config.T1SearchPath: +## afmFiles = glob.glob(join(p, '*.[aA][fF][mM]')) +## for f in afmFiles: +## T1name = findFontName(f) +## if T1name == name: +## afmFile = f +## found = 1 +## break +## if afmFile: +## break +## break +## +## if afmFile: +## pfbFile = glob.glob(join(splitext(afmFile)[0] + '.[pP][fF][bB]'))[0] +## +## return afmFile, pfbFile +## +## +##def registerFont(name): +## "Register Type-1 font for future use." +## +## rl_config.warnOnMissingFontGlyphs = 0 +## rl_config.T1SearchPath.append(r'C:\Programme\Python21\reportlab\test') +## +## afmFile, pfbFile = locateFilesForFontWithName(name) +## if not afmFile and not pfbFile: +## raise FontFilesNotFoundError +## +## T1face = pdfmetrics.EmbeddedType1Face(afmFile, pfbFile) +## T1faceName = name +## pdfmetrics.registerTypeFace(T1face) +## T1font = pdfmetrics.Font(name, T1faceName, 'WinAnsiEncoding') +## pdfmetrics.registerFont(T1font) + + +def registerFont0(sourceFile, name, path): + "Register Type-1 font for future use, simple version." + + rl_config.warnOnMissingFontGlyphs = 0 + + p = os.path.join(os.path.dirname(sourceFile), path) + afmFiles = glob.glob(p + '.[aA][fF][mM]') + pfbFiles = glob.glob(p + '.[pP][fF][bB]') + assert len(afmFiles) == len(pfbFiles) == 1, FontFilesNotFoundError + + T1face = pdfmetrics.EmbeddedType1Face(afmFiles[0], pfbFiles[0]) + T1faceName = name + pdfmetrics.registerTypeFace(T1face) + T1font = pdfmetrics.Font(name, T1faceName, 'WinAnsiEncoding') + pdfmetrics.registerFont(T1font) + +##################################################################### + + +def checkColor(col): + "Converts a color name to an RGB tuple, if possible." + + if type(col) == type('') and col in dir(colors): + col = getattr(colors, col) + col = (col.red, col.green, col.blue) + + return col + + +def handleHiddenSlides(slides): + """Filters slides from a list of slides. + + In a sequence of hidden slides all but the last one are + removed. Also, the slide before the sequence of hidden + ones is removed. + + This assumes to leave only those slides in the handout + that also appear in the outline, hoping to reduce se- + quences where each new slide only adds one new line + to a list of items... + """ + + itd = indicesToDelete = map(lambda s:s.outlineEntry == None, slides) + + for i in range(len(itd)-1): + if itd[i] == 1: + if itd[i+1] == 0: + itd[i] = 0 + if i > 0 and itd[i-1] == 0: + itd[i-1] = 1 + + itd[len(itd)-1] = 0 + + for i in range(len(itd)): + if slides[i].outlineEntry: + curOutlineEntry = slides[i].outlineEntry + if itd[i] == 1: + slides[i].delete = 1 + else: + slides[i].outlineEntry = curOutlineEntry + slides[i].delete = 0 + + slides = filter(lambda s:s.delete == 0, slides) + + return slides + + +def makeSlideTable(slides, pageSize, docWidth, numCols): + """Returns a table containing a collection of SlideWrapper flowables. + """ + + slides = handleHiddenSlides(slides) + + # Set table style. + tabStyle = TableStyle( + [('GRID', (0,0), (-1,-1), 0.25, colors.black), + ('ALIGN', (0,0), (-1,-1), 'CENTRE') + ]) + + # Build table content. + width = docWidth/numCols + height = width * pageSize[1]/pageSize[0] + matrix = [] + row = [] + for slide in slides: + sw = SlideWrapper(width, height, slide, pageSize) + if (len(row)) < numCols: + row.append(sw) + else: + matrix.append(row) + row = [] + row.append(sw) + if len(row) > 0: + for i in range(numCols-len(row)): + row.append('') + matrix.append(row) + + # Make Table flowable. + t = Table(matrix, + [width + 5]*len(matrix[0]), + [height + 5]*len(matrix)) + t.setStyle(tabStyle) + + return t + + +class SlideWrapper(Flowable): + """A Flowable wrapping a PPSlide object. + """ + + def __init__(self, width, height, slide, pageSize): + Flowable.__init__(self) + self.width = width + self.height = height + self.slide = slide + self.pageSize = pageSize + + + def __repr__(self): + return "SlideWrapper(w=%s, h=%s)" % (self.width, self.height) + + + def draw(self): + "Draw the slide in our relative coordinate system." + + slide = self.slide + pageSize = self.pageSize + canv = self.canv + + canv.saveState() + canv.scale(self.width/pageSize[0], self.height/pageSize[1]) + slide.effectName = None + slide.drawOn(self.canv) + canv.restoreState() + + +class PPPresentation: + def __init__(self): + self.sourceFilename = None + self.filename = None + self.outDir = None + self.description = None + self.title = None + self.author = None + self.subject = None + self.notes = 0 # different printing mode + self.handout = 0 # prints many slides per page + self.printout = 0 # remove hidden slides + self.cols = 0 # columns per handout page + self.slides = [] + self.effectName = None + self.showOutline = 1 #should it be displayed when opening? + self.compression = rl_config.pageCompression + self.pageDuration = None + #assume landscape + self.pageWidth = rl_config.defaultPageSize[1] + self.pageHeight = rl_config.defaultPageSize[0] + self.verbose = rl_config.verbose + + + def saveAsPresentation(self): + """Write the PDF document, one slide per page.""" + if self.verbose: + print 'saving presentation...' + pageSize = (self.pageWidth, self.pageHeight) + if self.sourceFilename: + filename = os.path.splitext(self.sourceFilename)[0] + '.pdf' + if self.outDir: filename = os.path.join(self.outDir,os.path.basename(filename)) + if self.verbose: + print filename + #canv = canvas.Canvas(filename, pagesize = pageSize) + outfile = getStringIO() + if self.notes: + #translate the page from landscape to portrait + pageSize= pageSize[1], pageSize[0] + canv = canvas.Canvas(outfile, pagesize = pageSize) + canv.setPageCompression(self.compression) + canv.setPageDuration(self.pageDuration) + if self.title: + canv.setTitle(self.title) + if self.author: + canv.setAuthor(self.author) + if self.subject: + canv.setSubject(self.subject) + + slideNo = 0 + for slide in self.slides: + #need diagnostic output if something wrong with XML + slideNo = slideNo + 1 + if self.verbose: + print 'doing slide %d, id = %s' % (slideNo, slide.id) + if self.notes: + #frame and shift the slide + #canv.scale(0.67, 0.67) + scale_amt = (min(pageSize)/float(max(pageSize)))*.95 + #canv.translate(self.pageWidth / 6.0, self.pageHeight / 3.0) + #canv.translate(self.pageWidth / 2.0, .025*self.pageHeight) + canv.translate(.025*self.pageHeight, (self.pageWidth/2.0) + 5) + #canv.rotate(90) + canv.scale(scale_amt, scale_amt) + canv.rect(0,0,self.pageWidth, self.pageHeight) + slide.drawOn(canv) + canv.showPage() + + #ensure outline visible by default + if self.showOutline: + canv.showOutline() + + canv.save() + return self.savetofile(outfile, filename) + + + def saveAsHandout(self): + """Write the PDF document, multiple slides per page.""" + + styleSheet = getSampleStyleSheet() + h1 = styleSheet['Heading1'] + bt = styleSheet['BodyText'] + + if self.sourceFilename : + filename = os.path.splitext(self.sourceFilename)[0] + '.pdf' + + outfile = getStringIO() + doc = SimpleDocTemplate(outfile, pagesize=rl_config.defaultPageSize, showBoundary=0) + doc.leftMargin = 1*cm + doc.rightMargin = 1*cm + doc.topMargin = 2*cm + doc.bottomMargin = 2*cm + multiPageWidth = rl_config.defaultPageSize[0] - doc.leftMargin - doc.rightMargin - 50 + + story = [] + orgFullPageSize = (self.pageWidth, self.pageHeight) + t = makeSlideTable(self.slides, orgFullPageSize, multiPageWidth, self.cols) + story.append(t) + +## #ensure outline visible by default +## if self.showOutline: +## doc.canv.showOutline() + + doc.build(story) + return self.savetofile(outfile, filename) + + def savetofile(self, pseudofile, filename): + """Save the pseudo file to disk and return its content as a + string of text.""" + pseudofile.flush() + content = pseudofile.getvalue() + pseudofile.close() + if filename : + outf = open(filename, "wb") + outf.write(content) + outf.close() + return content + + + + def save(self): + "Save the PDF document." + + if self.handout: + return self.saveAsHandout() + else: + return self.saveAsPresentation() + + +#class PPSection: +# """A section can hold graphics which will be drawn on all +# pages within it, before frames and other content are done. +# In other words, a background template.""" +# def __init__(self, name): +# self.name = name +# self.graphics = [] +# +# def drawOn(self, canv): +# for graphic in self.graphics: +### graphic.drawOn(canv) +# +# name = str(hash(graphic)) +# internalname = canv._doc.hasForm(name) +# +# canv.saveState() +# if not internalname: +# canv.beginForm(name) +# graphic.drawOn(canv) +# canv.endForm() +# canv.doForm(name) +# else: +# canv.doForm(name) +# canv.restoreState() + + +definedForms = {} + +class PPSection: + """A section can hold graphics which will be drawn on all + pages within it, before frames and other content are done. + In other words, a background template.""" + + def __init__(self, name): + self.name = name + self.graphics = [] + + def drawOn(self, canv): + for graphic in self.graphics: + graphic.drawOn(canv) + continue + name = str(hash(graphic)) + #internalname = canv._doc.hasForm(name) + if definedForms.has_key(name): + internalname = 1 + else: + internalname = None + definedForms[name] = 1 + if not internalname: + canv.beginForm(name) + canv.saveState() + graphic.drawOn(canv) + canv.restoreState() + canv.endForm() + canv.doForm(name) + else: + canv.doForm(name) + + +class PPNotes: + def __init__(self): + self.content = [] + + def drawOn(self, canv): + print self.content + + +class PPSlide: + def __init__(self): + self.id = None + self.title = None + self.outlineEntry = None + self.outlineLevel = 0 # can be higher for sub-headings + self.effectName = None + self.effectDirection = 0 + self.effectDimension = 'H' + self.effectMotion = 'I' + self.effectDuration = 1 + self.frames = [] + self.notes = [] + self.graphics = [] + self.section = None + + def drawOn(self, canv): + if self.effectName: + canv.setPageTransition( + effectname=self.effectName, + direction = self.effectDirection, + dimension = self.effectDimension, + motion = self.effectMotion, + duration = self.effectDuration + ) + + if self.outlineEntry: + #gets an outline automatically + self.showOutline = 1 + #put an outline entry in the left pane + tag = self.title + canv.bookmarkPage(tag) + canv.addOutlineEntry(tag, tag, self.outlineLevel) + + if self.section: + self.section.drawOn(canv) + + for graphic in self.graphics: + graphic.drawOn(canv) + + for frame in self.frames: + frame.drawOn(canv) + +## # Need to draw the notes *somewhere*... +## for note in self.notes: +## print note + + +class PPFrame: + def __init__(self, x, y, width, height): + self.x = x + self.y = y + self.width = width + self.height = height + self.content = [] + self.showBoundary = 0 + + def drawOn(self, canv): + #make a frame + frame = Frame( self.x, + self.y, + self.width, + self.height + ) + frame.showBoundary = self.showBoundary + + #build a story for the frame + story = [] + for thingy in self.content: + #ask it for any flowables + story.append(thingy.getFlowable()) + #draw it + frame.addFromList(story,canv) + + +class PPPara: + """This is a placeholder for a paragraph.""" + def __init__(self): + self.rawtext = '' + self.style = None + + def escapeAgain(self, text): + """The XML has been parsed once, so '>' became '>' + in rawtext. We need to escape this to get back to + something the Platypus parser can accept""" + pass + + def getFlowable(self): +## print 'rawText for para:' +## print repr(self.rawtext) + p = Paragraph( + self.rawtext, + getStyles()[self.style], + self.bulletText + ) + return p + + +class PPPreformattedText: + """Use this for source code, or stuff you do not want to wrap""" + def __init__(self): + self.rawtext = '' + self.style = None + + def getFlowable(self): + return Preformatted(self.rawtext, getStyles()[self.style]) + + +class PPPythonCode: + """Use this for colored Python source code""" + def __init__(self): + self.rawtext = '' + self.style = None + + def getFlowable(self): + return PythonPreformatted(self.rawtext, getStyles()[self.style]) + + +class PPImage: + """Flowing image within the text""" + def __init__(self): + self.filename = None + self.width = None + self.height = None + + def getFlowable(self): + return Image(self.filename, self.width, self.height) + + +class PPTable: + """Designed for bulk loading of data for use in presentations.""" + def __init__(self): + self.rawBlocks = [] #parser stuffs things in here... + self.fieldDelim = ',' #tag args can override + self.rowDelim = '\n' #tag args can override + self.data = None + self.style = None #tag args must specify + self.widths = None #tag args can override + self.heights = None #tag args can override + + def getFlowable(self): + self.parseData() + t = Table( + self.data, + self.widths, + self.heights) + if self.style: + t.setStyle(getStyles()[self.style]) + + return t + + def parseData(self): + """Try to make sense of the table data!""" + rawdata = string.strip(string.join(self.rawBlocks, '')) + lines = string.split(rawdata, self.rowDelim) + #clean up... + lines = map(string.strip, lines) + self.data = [] + for line in lines: + cells = string.split(line, self.fieldDelim) + self.data.append(cells) + + #get the width list if not given + if not self.widths: + self.widths = [None] * len(self.data[0]) + if not self.heights: + self.heights = [None] * len(self.data) + +## import pprint +## print 'table data:' +## print 'style=',self.style +## print 'widths=',self.widths +## print 'heights=',self.heights +## print 'fieldDelim=',repr(self.fieldDelim) +## print 'rowDelim=',repr(self.rowDelim) +## pprint.pprint(self.data) + + +class PPSpacer: + def __init__(self): + self.height = 24 #points + + def getFlowable(self): + return Spacer(72, self.height) + + + ############################################################# + # + # The following are things you can draw on a page directly. + # + ############################################################## + +##class PPDrawingElement: +## """Base class for something which you draw directly on the page.""" +## def drawOn(self, canv): +## raise "NotImplementedError", "Abstract base class!" + + +class PPFixedImage: + """You place this on the page, rather than flowing it""" + def __init__(self): + self.filename = None + self.x = 0 + self.y = 0 + self.width = None + self.height = None + + def drawOn(self, canv): + if self.filename: + x, y = self.x, self.y + w, h = self.width, self.height + canv.drawImage(self.filename, x, y, w, h) + + +class PPRectangle: + def __init__(self, x, y, width, height): + self.x = x + self.y = y + self.width = width + self.height = height + self.fillColor = None + self.strokeColor = (1,1,1) + self.lineWidth=0 + + def drawOn(self, canv): + canv.saveState() + canv.setLineWidth(self.lineWidth) + if self.fillColor: + r,g,b = checkColor(self.fillColor) + canv.setFillColorRGB(r,g,b) + if self.strokeColor: + r,g,b = checkColor(self.strokeColor) + canv.setStrokeColorRGB(r,g,b) + canv.rect(self.x, self.y, self.width, self.height, + stroke=(self.strokeColor<>None), + fill = (self.fillColor<>None) + ) + canv.restoreState() + + +class PPRoundRect: + def __init__(self, x, y, width, height, radius): + self.x = x + self.y = y + self.width = width + self.height = height + self.radius = radius + self.fillColor = None + self.strokeColor = (1,1,1) + self.lineWidth=0 + + def drawOn(self, canv): + canv.saveState() + canv.setLineWidth(self.lineWidth) + if self.fillColor: + r,g,b = checkColor(self.fillColor) + canv.setFillColorRGB(r,g,b) + if self.strokeColor: + r,g,b = checkColor(self.strokeColor) + canv.setStrokeColorRGB(r,g,b) + canv.roundRect(self.x, self.y, self.width, self.height, + self.radius, + stroke=(self.strokeColor<>None), + fill = (self.fillColor<>None) + ) + canv.restoreState() + + +class PPLine: + def __init__(self, x1, y1, x2, y2): + self.x1 = x1 + self.y1 = y1 + self.x2 = x2 + self.y2 = y2 + self.fillColor = None + self.strokeColor = (1,1,1) + self.lineWidth=0 + + def drawOn(self, canv): + canv.saveState() + canv.setLineWidth(self.lineWidth) + if self.strokeColor: + r,g,b = checkColor(self.strokeColor) + canv.setStrokeColorRGB(r,g,b) + canv.line(self.x1, self.y1, self.x2, self.y2) + canv.restoreState() + + +class PPEllipse: + def __init__(self, x1, y1, x2, y2): + self.x1 = x1 + self.y1 = y1 + self.x2 = x2 + self.y2 = y2 + self.fillColor = None + self.strokeColor = (1,1,1) + self.lineWidth=0 + + def drawOn(self, canv): + canv.saveState() + canv.setLineWidth(self.lineWidth) + if self.strokeColor: + r,g,b = checkColor(self.strokeColor) + canv.setStrokeColorRGB(r,g,b) + if self.fillColor: + r,g,b = checkColor(self.fillColor) + canv.setFillColorRGB(r,g,b) + canv.ellipse(self.x1, self.y1, self.x2, self.y2, + stroke=(self.strokeColor<>None), + fill = (self.fillColor<>None) + ) + canv.restoreState() + + +class PPPolygon: + def __init__(self, pointlist): + self.points = pointlist + self.fillColor = None + self.strokeColor = (1,1,1) + self.lineWidth=0 + + def drawOn(self, canv): + canv.saveState() + canv.setLineWidth(self.lineWidth) + if self.strokeColor: + r,g,b = checkColor(self.strokeColor) + canv.setStrokeColorRGB(r,g,b) + if self.fillColor: + r,g,b = checkColor(self.fillColor) + canv.setFillColorRGB(r,g,b) + + path = canv.beginPath() + (x,y) = self.points[0] + path.moveTo(x,y) + for (x,y) in self.points[1:]: + path.lineTo(x,y) + path.close() + canv.drawPath(path, + stroke=(self.strokeColor<>None), + fill=(self.fillColor<>None)) + canv.restoreState() + + +class PPString: + def __init__(self, x, y): + self.text = '' + self.x = x + self.y = y + self.align = TA_LEFT + self.font = 'Times-Roman' + self.size = 12 + self.color = (0,0,0) + self.hasInfo = 0 # these can have data substituted into them + + def normalizeText(self): + """It contains literal XML text typed over several lines. + We want to throw away + tabs, newlines and so on, and only accept embedded string + like '\n'""" + lines = string.split(self.text, '\n') + newtext = [] + for line in lines: + newtext.append(string.strip(line)) + #accept all the '\n' as newlines + + self.text = newtext + + def drawOn(self, canv): + # for a string in a section, this will be drawn several times; + # so any substitution into the text should be in a temporary + # variable + if self.hasInfo: + # provide a dictionary of stuff which might go into + # the string, so they can number pages, do headers + # etc. + info = {} + info['title'] = canv._doc.info.title + info['author'] = canv._doc.info.author + info['subject'] = canv._doc.info.subject + info['page'] = canv.getPageNumber() + drawText = self.text % info + else: + drawText = self.text + + if self.color is None: + return + lines = string.split(string.strip(drawText), '\\n') + canv.saveState() + + canv.setFont(self.font, self.size) + + r,g,b = checkColor(self.color) + canv.setFillColorRGB(r,g,b) + cur_y = self.y + for line in lines: + if self.align == TA_LEFT: + canv.drawString(self.x, cur_y, line) + elif self.align == TA_CENTER: + canv.drawCentredString(self.x, cur_y, line) + elif self.align == TA_RIGHT: + canv.drawRightString(self.x, cur_y, line) + cur_y = cur_y - 1.2*self.size + + canv.restoreState() + +class PPDrawing: + def __init__(self): + self.drawing = None + def getFlowable(self): + return self.drawing + +class PPFigure: + def __init__(self): + self.figure = None + def getFlowable(self): + return self.figure + +def getSampleStyleSheet(): + from reportlab.tools.pythonpoint.styles.standard import getParagraphStyles + return getParagraphStyles() + + +#make a singleton and a function to access it +_styles = None +def getStyles(): + global _styles + if not _styles: + _styles = getSampleStyleSheet() + return _styles + + +def setStyles(newStyleSheet): + global _styles + _styles = newStyleSheet + +_pyRXP_Parser = None +def validate(rawdata): + global _pyRXP_Parser + if not _pyRXP_Parser: + try: + import pyRXP + except ImportError: + return + from reportlab.lib.utils import open_and_read, _RL_DIR, rl_isfile + dtd = 'pythonpoint.dtd' + if not rl_isfile(dtd): + dtd = os.path.join(_RL_DIR,'tools','pythonpoint','pythonpoint.dtd') + if not rl_isfile(dtd): return + def eocb(URI,dtdText=open_and_read(dtd),dtd=dtd): + if os.path.basename(URI)=='pythonpoint.dtd': return dtd,dtdText + return URI + _pyRXP_Parser = pyRXP.Parser(eoCB=eocb) + return _pyRXP_Parser.parse(rawdata) + +def process(datafile, notes=0, handout=0, printout=0, cols=0, verbose=0, outDir=None, datafilename=None, fx=1): + "Process one PythonPoint source file." + if not hasattr(datafile, "read"): + if not datafilename: datafilename = datafile + datafile = open(datafile) + else: + if not datafilename: datafilename = "PseudoFile" + rawdata = datafile.read() + + #if pyRXP present, use it to check and get line numbers for errors... + validate(rawdata) + return _process(rawdata, datafilename, notes, handout, printout, cols, verbose, outDir, fx) + +def _process(rawdata, datafilename, notes=0, handout=0, printout=0, cols=0, verbose=0, outDir=None, fx=1): + #print 'inner process fx=%d' % fx + from reportlab.tools.pythonpoint.stdparser import PPMLParser + parser = PPMLParser() + parser.fx = fx + parser.sourceFilename = datafilename + parser.feed(rawdata) + pres = parser.getPresentation() + pres.sourceFilename = datafilename + pres.outDir = outDir + pres.notes = notes + pres.handout = handout + pres.printout = printout + pres.cols = cols + pres.verbose = verbose + + if printout: + pres.slides = handleHiddenSlides(pres.slides) + + #this does all the work + pdfcontent = pres.save() + + if verbose: + print 'saved presentation %s.pdf' % os.path.splitext(datafilename)[0] + parser.close() + + return pdfcontent +##class P: +## def feed(self, text): +## parser = stdparser.PPMLParser() +## d = pyRXP.parse(text) +## +## +##def process2(datafilename, notes=0, handout=0, cols=0): +## "Process one PythonPoint source file." +## +## import pyRXP, pprint +## +## rawdata = open(datafilename).read() +## d = pyRXP.parse(rawdata) +## pprint.pprint(d) + + +def handleOptions(): + # set defaults + from reportlab import rl_config + options = {'cols':2, + 'handout':0, + 'printout':0, + 'help':0, + 'notes':0, + 'fx':1, + 'verbose':rl_config.verbose, + 'silent':0, + 'outDir': None} + + args = sys.argv[1:] + args = filter(lambda x: x and x[0]=='-',args) + filter(lambda x: not x or x[0]!='-',args) + try: + shortOpts = 'hnvsx' + longOpts = string.split('cols= outdir= handout help notes printout verbose silent nofx') + optList, args = getopt.getopt(args, shortOpts, longOpts) + except getopt.error, msg: + options['help'] = 1 + + if not args and os.path.isfile('pythonpoint.xml'): + args = ['pythonpoint.xml'] + + # Remove leading dashes (max. two). + for i in range(len(optList)): + o, v = optList[i] + while o[0] == '-': + o = o[1:] + optList[i] = (o, v) + + if o == 'cols': options['cols'] = int(v) + elif o=='outdir': options['outDir'] = v + + if filter(lambda ov: ov[0] == 'handout', optList): + options['handout'] = 1 + + if filter(lambda ov: ov[0] == 'printout', optList): + options['printout'] = 1 + + if optList == [] and args == [] or \ + filter(lambda ov: ov[0] in ('h', 'help'), optList): + options['help'] = 1 + + if filter(lambda ov: ov[0] in ('n', 'notes'), optList): + options['notes'] = 1 + + if filter(lambda ov: ov[0] in ('x', 'nofx'), optList): + options['fx'] = 0 + + if filter(lambda ov: ov[0] in ('v', 'verbose'), optList): + options['verbose'] = 1 + + #takes priority over verbose. Used by our test suite etc. + #to ensure no output at all + if filter(lambda ov: ov[0] in ('s', 'silent'), optList): + options['silent'] = 1 + options['verbose'] = 0 + + + return options, args + +def main(): + options, args = handleOptions() + + if options['help']: + print USAGE_MESSAGE + sys.exit(0) + + if options['verbose'] and options['notes']: + print 'speaker notes mode' + + if options['verbose'] and options['handout']: + print 'handout mode' + + if options['verbose'] and options['printout']: + print 'printout mode' + + if not options['fx']: + print 'suppressing special effects' + for fileGlobs in args: + files = glob.glob(fileGlobs) + if not files: + print fileGlobs, "not found" + return + for datafile in files: + if os.path.isfile(datafile): + file = os.path.join(os.getcwd(), datafile) + notes, handout, printout, cols, verbose, fx = options['notes'], options['handout'], options['printout'], options['cols'], options['verbose'], options['fx'] + process(file, notes, handout, printout, cols, verbose, options['outDir'], fx=fx) + else: + print 'Data file not found:', datafile + +if __name__ == '__main__': + main() diff --git a/bin/reportlab/tools/pythonpoint/stdparser.py b/bin/reportlab/tools/pythonpoint/stdparser.py new file mode 100644 index 00000000000..aaca2df2000 --- /dev/null +++ b/bin/reportlab/tools/pythonpoint/stdparser.py @@ -0,0 +1,813 @@ +""" +Parser for PythonPoint using the xmllib.py in the standard Python +distribution. Slow, but always present. We intend to add new parsers +as Python 2.x and the XML package spread in popularity and stabilise. + +The parser has a getPresentation method; it is called from +pythonpoint.py. +""" + +import string, imp, sys, os, copy +from reportlab.lib.utils import SeqTypes +from reportlab.lib import xmllib +from reportlab.lib import colors +from reportlab.lib.enums import TA_LEFT, TA_RIGHT, TA_CENTER, TA_JUSTIFY +from reportlab.lib.utils import recursiveImport +from reportlab.tools.pythonpoint import pythonpoint +from reportlab.platypus import figures + + +def getModule(modulename,fromPath='reportlab.tools.pythonpoint.styles'): + """Get a module containing style declarations. + + Search order is: + reportlab/tools/pythonpoint/ + reportlab/tools/pythonpoint/styles/ + ./ + """ + + try: + exec 'from reportlab.tools.pythonpoint import '+modulename + return eval(modulename) + except ImportError: + try: + exec 'from reportlab.tools.pythonpoint.styles import '+modulename + return eval(modulename) + except ImportError: + exec 'import '+modulename + return eval(modulename) + + +class PPMLParser(xmllib.XMLParser): + attributes = { + #this defines the available attributes for all objects, + #and their default values. Although these don't have to + #be strings, the ones parsed from the XML do, so + #everything is a quoted string and the parser has to + #convert these to numbers where appropriate. + 'stylesheet': { + 'path':'None', + 'module':'None', + 'function':'getParagraphStyles' + }, + 'frame': { + 'x':'0', + 'y':'0', + 'width':'0', + 'height':'0', + 'border':'false', + 'leftmargin':'0', #this is ignored + 'topmargin':'0', #this is ignored + 'rightmargin':'0', #this is ignored + 'bottommargin':'0', #this is ignored + }, + 'slide': { + 'id':'None', + 'title':'None', + 'effectname':'None', # Split, Blinds, Box, Wipe, Dissolve, Glitter + 'effectdirection':'0', # 0,90,180,270 + 'effectdimension':'H', # H or V - horizontal or vertical + 'effectmotion':'I', # Inwards or Outwards + 'effectduration':'1', #seconds, + 'outlineentry':'None', + 'outlinelevel':'0' # 1 is a child, 2 is a grandchild etc. + }, + 'para': { + 'style':'Normal', + 'bullettext':'', + 'effectname':'None', + 'effectdirection':'0', + 'effectdimension':'H', + 'effectmotion':'I', + 'effectduration':'1' + }, + 'image': { + 'filename':'', + 'width':'None', + 'height':'None', + 'effectname':'None', + 'effectdirection':'0', + 'effectdimension':'H', + 'effectmotion':'I', + 'effectduration':'1' + }, + 'table': { + 'widths':'None', + 'heights':'None', + 'fieldDelim':',', + 'rowDelim':'\n', + 'style':'None', + 'effectname':'None', + 'effectdirection':'0', + 'effectdimension':'H', + 'effectmotion':'I', + 'effectduration':'1' + }, + 'rectangle': { + 'x':'0', + 'y':'0', + 'width':'100', + 'height':'100', + 'fill':'None', + 'stroke':'(0,0,0)', + 'linewidth':'0', + 'effectname':'None', + 'effectdirection':'0', + 'effectdimension':'H', + 'effectmotion':'I', + 'effectduration':'1' + }, + 'roundrect': { + 'x':'0', + 'y':'0', + 'width':'100', + 'height':'100', + 'radius':'6', + 'fill':'None', + 'stroke':'(0,0,0)', + 'linewidth':'0', + 'effectname':'None', + 'effectdirection':'0', + 'effectdimension':'H', + 'effectmotion':'I', + 'effectduration':'1' + }, + 'line': { + 'x1':'0', + 'y1':'0', + 'x2':'100', + 'y2':'100', + 'stroke':'(0,0,0)', + 'width':'0', + 'effectname':'None', + 'effectdirection':'0', + 'effectdimension':'H', + 'effectmotion':'I', + 'effectduration':'1' + }, + 'ellipse': { + 'x1':'0', + 'y1':'0', + 'x2':'100', + 'y2':'100', + 'stroke':'(0,0,0)', + 'fill':'None', + 'linewidth':'0', + 'effectname':'None', + 'effectdirection':'0', + 'effectdimension':'H', + 'effectmotion':'I', + 'effectduration':'1' + }, + 'polygon': { + 'points':'(0,0),(50,0),(25,25)', + 'stroke':'(0,0,0)', + 'linewidth':'0', + 'stroke':'(0,0,0)', + 'fill':'None', + 'effectname':'None', + 'effectdirection':'0', + 'effectdimension':'H', + 'effectmotion':'I', + 'effectduration':'1' + }, + 'string':{ + 'x':'0', + 'y':'0', + 'color':'(0,0,0)', + 'font':'Times-Roman', + 'size':'12', + 'align':'left', + 'effectname':'None', + 'effectdirection':'0', + 'effectdimension':'H', + 'effectmotion':'I', + 'effectduration':'1' + }, + 'customshape':{ + 'path':'None', + 'module':'None', + 'class':'None', + 'initargs':'None' + } + } + + def __init__(self): + self.presentations = [] + #yes, I know a generic stack would be easier... + #still, testing if we are 'in' something gives + #a degree of validation. + self._curPres = None + self._curSection = None + self._curSlide = None + self._curFrame = None + self._curPara = None #the only places we are interested in + self._curPrefmt = None + self._curPyCode = None + self._curString = None + self._curTable = None + self._curTitle = None + self._curAuthor = None + self._curSubject = None + self.fx = 1 + xmllib.XMLParser.__init__(self) + + def _arg(self,tag,args,name): + "What's this for???" + if args.has_key(name): + v = args[name] + else: + if self.attributes.has_key(tag): + v = self.attributes[tag][name] + else: + v = None + return v + + def ceval(self,tag,args,name): + if args.has_key(name): + v = args[name] + else: + if self.attributes.has_key(tag): + v = self.attributes[tag][name] + else: + return None + + # handle named colors (names from reportlab.lib.colors) + if name in ('color', 'stroke', 'fill'): + v = str(pythonpoint.checkColor(v)) + + return eval(v) + + def getPresentation(self): + return self._curPres + + + def handle_data(self, data): + #the only data should be paragraph text, preformatted para + #text, 'string text' for a fixed string on the page, + #or table data + + if self._curPara: + self._curPara.rawtext = self._curPara.rawtext + data + elif self._curPrefmt: + self._curPrefmt.rawtext = self._curPrefmt.rawtext + data + elif self._curPyCode: + self._curPyCode.rawtext = self._curPyCode.rawtext + data + elif self._curString: + self._curString.text = self._curString.text + data + elif self._curTable: + self._curTable.rawBlocks.append(data) + elif self._curTitle <> None: # need to allow empty strings, + # hence explicitly testing for None + self._curTitle = self._curTitle + data + elif self._curAuthor <> None: + self._curAuthor = self._curAuthor + data + elif self._curSubject <> None: + self._curSubject = self._curSubject + data + + def handle_cdata(self, data): + #just append to current paragraph text, so we can quote XML + if self._curPara: + self._curPara.rawtext = self._curPara.rawtext + data + elif self._curPrefmt: + self._curPrefmt.rawtext = self._curPrefmt.rawtext + data + elif self._curPyCode: + self._curPyCode.rawtext = self._curPyCode.rawtext + data + elif self._curString: + self._curString.text = self._curString.text + data + elif self._curTable: + self._curTable.rawBlocks.append(data) + elif self._curAuthor <> None: + self._curAuthor = self._curAuthor + data + elif self._curSubject <> None: + self._curSubject = self._curSubject + data + + def start_presentation(self, args): + self._curPres = pythonpoint.PPPresentation() + self._curPres.filename = self._arg('presentation',args,'filename') + self._curPres.effectName = self._arg('presentation',args,'effect') + self._curPres.pageDuration = self._arg('presentation',args,'pageDuration') + + h = self._arg('presentation',args,'pageHeight') + if h: + self._curPres.pageHeight = h + w = self._arg('presentation',args,'pageWidth') + if w: + self._curPres.pageWidth = w + #print 'page size =', self._curPres.pageSize + + def end_presentation(self): + pass +## print 'Fully parsed presentation',self._curPres.filename + + def start_title(self, args): + self._curTitle = '' + + + def end_title(self): + self._curPres.title = self._curTitle + self._curTitle = None + + def start_author(self, args): + self._curAuthor = '' + + def end_author(self): + self._curPres.author = self._curAuthor + self._curAuthor = None + + def start_subject(self, args): + self._curSubject = '' + + def end_subject(self): + self._curPres.subject = self._curSubject + self._curSubject = None + + def start_stylesheet(self, args): + #makes it the current style sheet. + path = self._arg('stylesheet',args,'path') + if path=='None': path = [] + if type(path) not in SeqTypes: path = [path] + path.append('styles') + path.append(os.getcwd()) + modulename = self._arg('stylesheet', args, 'module') + funcname = self._arg('stylesheet', args, 'function') + try: + found = imp.find_module(modulename, path) + (file, pathname, description) = found + mod = imp.load_module(modulename, file, pathname, description) + except ImportError: + #last gasp + mod = getModule(modulename) + + #now get the function + func = getattr(mod, funcname) + pythonpoint.setStyles(func()) +## print 'set global stylesheet to %s.%s()' % (modulename, funcname) + + def end_stylesheet(self): + pass + + def start_section(self, args): + name = self._arg('section',args,'name') + self._curSection = pythonpoint.PPSection(name) + + def end_section(self): + self._curSection = None + + + def start_slide(self, args): + s = pythonpoint.PPSlide() + s.id = self._arg('slide',args,'id') + s.title = self._arg('slide',args,'title') + a = self._arg('slide',args,'effectname') + if a <> 'None': + s.effectName = a + s.effectDirection = self.ceval('slide',args,'effectdirection') + s.effectDimension = self._arg('slide',args,'effectdimension') + s.effectDuration = self.ceval('slide',args,'effectduration') + s.effectMotion = self._arg('slide',args,'effectmotion') + + #HACK - may not belong here in the long run... + #by default, use the slide title for the outline entry, + #unless it is specified as an arg. + a = self._arg('slide',args,'outlineentry') + if a == "Hide": + s.outlineEntry = None + elif a <> 'None': + s.outlineEntry = a + else: + s.outlineEntry = s.title + + s.outlineLevel = self.ceval('slide',args,'outlinelevel') + + #let it know its section, which may be none + s.section = self._curSection + self._curSlide = s + + def end_slide(self): + self._curPres.slides.append(self._curSlide) + self._curSlide = None + + def start_frame(self, args): + self._curFrame = pythonpoint.PPFrame( + self.ceval('frame',args,'x'), + self.ceval('frame',args,'y'), + self.ceval('frame',args,'width'), + self.ceval('frame',args,'height') + ) + if self._arg('frame',args,'border')=='true': + self._curFrame.showBoundary = 1 + + def end_frame(self): + self._curSlide.frames.append(self._curFrame) + self._curFrame = None + + def start_notes(self, args): + name = self._arg('notes',args,'name') + self._curNotes = pythonpoint.PPNotes() + + def end_notes(self): + self._curSlide.notes.append(self._curNotes) + self._curNotes = None + + def start_registerFont(self, args): + name = self._arg('font',args,'name') + path = self._arg('font',args,'path') + pythonpoint.registerFont0(self.sourceFilename, name, path) + + + def end_registerFont(self): + pass + + + def pack_slide(self, element, args): + if self.fx: + effectName = self._arg(element,args,'effectname') + if effectName <> 'None': + curSlide = copy.deepcopy(self._curSlide) + if self._curFrame: + curFrame = copy.deepcopy(self._curFrame) + curSlide.frames.append(curFrame) + self._curPres.slides.append(curSlide) + self._curSlide.effectName = effectName + self._curSlide.effectDirection = self.ceval(element,args,'effectdirection') + self._curSlide.effectDimension = self._arg(element,args,'effectdimension') + self._curSlide.effectDuration = self.ceval(element,args,'effectduration') + self._curSlide.effectMotion = self._arg(element,args,'effectmotion') + self._curSlide.outlineEntry = None + + def start_para(self, args): + self.pack_slide('para', args) + self._curPara = pythonpoint.PPPara() + self._curPara.style = self._arg('para',args,'style') + + # hack - bullet character if bullet style + bt = self._arg('para',args,'bullettext') + if bt == '': + if self._curPara.style == 'Bullet': + bt = '\xc2\xb7' # Symbol Font bullet character, reasonable default + elif self._curPara.style == 'Bullet2': + bt = '\xc2\xb7' # second-level bullet + else: + bt = None + + self._curPara.bulletText = bt + + def end_para(self): + if self._curFrame: + self._curFrame.content.append(self._curPara) + self._curPara = None + elif self._curNotes: + self._curNotes.content.append(self._curPara) + self._curPara = None + + + def start_prefmt(self, args): + self._curPrefmt = pythonpoint.PPPreformattedText() + self._curPrefmt.style = self._arg('prefmt',args,'style') + + + def end_prefmt(self): + self._curFrame.content.append(self._curPrefmt) + self._curPrefmt = None + + + def start_pycode(self, args): + self._curPyCode = pythonpoint.PPPythonCode() + self._curPyCode.style = self._arg('pycode',args,'style') + + + def end_pycode(self): + self._curFrame.content.append(self._curPyCode) + self._curPyCode = None + + + def start_image(self, args): + self.pack_slide('image',args) + sourceFilename = self.sourceFilename # XXX + filename = self._arg('image',args,'filename') + filename = os.path.join(os.path.dirname(sourceFilename), filename) + self._curImage = pythonpoint.PPImage() + self._curImage.filename = filename + self._curImage.width = self.ceval('image',args,'width') + self._curImage.height = self.ceval('image',args,'height') + + + def end_image(self): + self._curFrame.content.append(self._curImage) + self._curImage = None + + + def start_table(self, args): + self.pack_slide('table',args) + self._curTable = pythonpoint.PPTable() + self._curTable.widths = self.ceval('table',args,'widths') + self._curTable.heights = self.ceval('table',args,'heights') + #these may contain escapes like tabs - handle with + #a bit more care. + if args.has_key('fieldDelim'): + self._curTable.fieldDelim = eval('"' + args['fieldDelim'] + '"') + if args.has_key('rowDelim'): + self._curTable.rowDelim = eval('"' + args['rowDelim'] + '"') + if args.has_key('style'): + self._curTable.style = args['style'] + + + def end_table(self): + self._curFrame.content.append(self._curTable) + self._curTable = None + + + def start_spacer(self, args): + """No contents so deal with it here.""" + sp = pythonpoint.PPSpacer() + sp.height = eval(args['height']) + self._curFrame.content.append(sp) + + + def end_spacer(self): + pass + + + ## the graphics objects - go into either the current section + ## or the current slide. + def start_fixedimage(self, args): + sourceFilename = self.sourceFilename + filename = self._arg('image',args,'filename') + filename = os.path.join(os.path.dirname(sourceFilename), filename) + img = pythonpoint.PPFixedImage() + img.filename = filename + img.x = self.ceval('fixedimage',args,'x') + img.y = self.ceval('fixedimage',args,'y') + img.width = self.ceval('fixedimage',args,'width') + img.height = self.ceval('fixedimage',args,'height') + self._curFixedImage = img + + + def end_fixedimage(self): + if self._curSlide: + self._curSlide.graphics.append(self._curFixedImage) + elif self._curSection: + self._curSection.graphics.append(self._curFixedImage) + self._curFixedImage = None + + + def start_rectangle(self, args): + self.pack_slide('rectangle', args) + rect = pythonpoint.PPRectangle( + self.ceval('rectangle',args,'x'), + self.ceval('rectangle',args,'y'), + self.ceval('rectangle',args,'width'), + self.ceval('rectangle',args,'height') + ) + rect.fillColor = self.ceval('rectangle',args,'fill') + rect.strokeColor = self.ceval('rectangle',args,'stroke') + self._curRectangle = rect + + + def end_rectangle(self): + if self._curSlide: + self._curSlide.graphics.append(self._curRectangle) + elif self._curSection: + self._curSection.graphics.append(self._curRectangle) + self._curRectangle = None + + + def start_roundrect(self, args): + self.pack_slide('roundrect', args) + rrect = pythonpoint.PPRoundRect( + self.ceval('roundrect',args,'x'), + self.ceval('roundrect',args,'y'), + self.ceval('roundrect',args,'width'), + self.ceval('roundrect',args,'height'), + self.ceval('roundrect',args,'radius') + ) + rrect.fillColor = self.ceval('roundrect',args,'fill') + rrect.strokeColor = self.ceval('roundrect',args,'stroke') + self._curRoundRect = rrect + + + def end_roundrect(self): + if self._curSlide: + self._curSlide.graphics.append(self._curRoundRect) + elif self._curSection: + self._curSection.graphics.append(self._curRoundRect) + self._curRoundRect = None + + + def start_line(self, args): + self.pack_slide('line', args) + self._curLine = pythonpoint.PPLine( + self.ceval('line',args,'x1'), + self.ceval('line',args,'y1'), + self.ceval('line',args,'x2'), + self.ceval('line',args,'y2') + ) + self._curLine.strokeColor = self.ceval('line',args,'stroke') + + + def end_line(self): + if self._curSlide: + self._curSlide.graphics.append(self._curLine) + elif self._curSection: + self._curSection.graphics.append(self._curLine) + self._curLine = None + + + def start_ellipse(self, args): + self.pack_slide('ellipse', args) + self._curEllipse = pythonpoint.PPEllipse( + self.ceval('ellipse',args,'x1'), + self.ceval('ellipse',args,'y1'), + self.ceval('ellipse',args,'x2'), + self.ceval('ellipse',args,'y2') + ) + self._curEllipse.strokeColor = self.ceval('ellipse',args,'stroke') + self._curEllipse.fillColor = self.ceval('ellipse',args,'fill') + + + def end_ellipse(self): + if self._curSlide: + self._curSlide.graphics.append(self._curEllipse) + elif self._curSection: + self._curSection.graphics.append(self._curEllipse) + self._curEllipse = None + + + def start_polygon(self, args): + self.pack_slide('polygon', args) + self._curPolygon = pythonpoint.PPPolygon(self.ceval('polygon',args,'points')) + self._curPolygon.strokeColor = self.ceval('polygon',args,'stroke') + self._curPolygon.fillColor = self.ceval('polygon',args,'fill') + + + def end_polygon(self): + if self._curSlide: + self._curSlide.graphics.append(self._curPolygon) + elif self._curSection: + self._curSection.graphics.append(self._curPolygon) + self._curEllipse = None + + + def start_string(self, args): + self.pack_slide('string', args) + self._curString = pythonpoint.PPString( + self.ceval('string',args,'x'), + self.ceval('string',args,'y') + ) + self._curString.color = self.ceval('string',args,'color') + self._curString.font = self._arg('string',args,'font') + self._curString.size = self.ceval('string',args,'size') + if args['align'] == 'left': + self._curString.align = TA_LEFT + elif args['align'] == 'center': + self._curString.align = TA_CENTER + elif args['align'] == 'right': + self._curString.align = TA_RIGHT + elif args['align'] == 'justify': + self._curString.align = TA_JUSTIFY + #text comes later within the tag + + + def end_string(self): + #controller should have set the text + if self._curSlide: + self._curSlide.graphics.append(self._curString) + elif self._curSection: + self._curSection.graphics.append(self._curString) + self._curString = None + + + def start_infostring(self, args): + # like a string, but lets them embed page no, author etc. + self.start_string(args) + self._curString.hasInfo = 1 + + + def end_infostring(self): + self.end_string() + + + def start_customshape(self, args): + #loads one + path = self._arg('customshape',args,'path') + if path=='None': + path = [] + else: + path=[path] + + # add package root folder and input file's folder to path + path.append(os.path.dirname(self.sourceFilename)) + path.append(os.path.dirname(pythonpoint.__file__)) + + modulename = self._arg('customshape',args,'module') + funcname = self._arg('customshape',args,'class') + try: + found = imp.find_module(modulename, path) + (file, pathname, description) = found + mod = imp.load_module(modulename, file, pathname, description) + except ImportError: + mod = getModule(modulename) + + #now get the function + + func = getattr(mod, funcname) + initargs = self.ceval('customshape',args,'initargs') + self._curCustomShape = apply(func, initargs) + + def end_customshape(self): + if self._curSlide: + self._curSlide.graphics.append(self._curCustomShape) + elif self._curSection: + self._curSection.graphics.append(self._curCustomShape) + self._curCustomShape = None + + def start_drawing(self, args): + #loads one + moduleName = args["module"] + funcName = args["constructor"] + showBoundary = int(args.get("showBoundary", "0")) + hAlign = args.get("hAlign", "CENTER") + + + # the path for the imports should include: + # 1. document directory + # 2. python path if baseDir not given, or + # 3. baseDir if given + try: + dirName = sdict["baseDir"] + except: + dirName = None + importPath = [os.getcwd()] + if dirName is None: + importPath.extend(sys.path) + else: + importPath.insert(0, dirName) + + modul = recursiveImport(moduleName, baseDir=importPath) + func = getattr(modul, funcName) + drawing = func() + + drawing.hAlign = hAlign + if showBoundary: + drawing._showBoundary = 1 + + self._curDrawing = pythonpoint.PPDrawing() + self._curDrawing.drawing = drawing + + def end_drawing(self): + self._curFrame.content.append(self._curDrawing) + self._curDrawing = None + + def start_pageCatcherFigure(self, args): + filename = args["filename"] + pageNo = int(args["pageNo"]) + width = float(args.get("width", "595")) + height = float(args.get("height", "842")) + + + fig = figures.PageCatcherFigureNonA4(filename, pageNo, args.get("caption", ""), width, height) + sf = args.get('scaleFactor', None) + if sf: sf = float(sf) + border = not (args.get('border', None) in ['0','no']) + + fig.scaleFactor = sf + fig.border = border + + #self.ceval('pageCatcherFigure',args,'scaleFactor'), + #initargs = self.ceval('customshape',args,'initargs') + self._curFigure = pythonpoint.PPFigure() + self._curFigure.figure = fig + + def end_pageCatcherFigure(self): + self._curFrame.content.append(self._curFigure) + self._curFigure = None + + ## intra-paragraph XML should be allowed through into PLATYPUS + def unknown_starttag(self, tag, attrs): + if self._curPara: + echo = '<%s' % tag + for (key, value) in attrs.items(): + echo = echo + ' %s="%s"' % (key, value) + echo = echo + '>' + self._curPara.rawtext = self._curPara.rawtext + echo + else: + print 'Unknown start tag %s' % tag + + + def unknown_endtag(self, tag): + if self._curPara: + self._curPara.rawtext = self._curPara.rawtext + '</%s>'% tag + else: + print 'Unknown end tag %s' % tag + + def handle_charref(self, name): + try: + if name[0]=='x': + n = int(name[1:],16) + else: + n = int(name) + except ValueError: + self.unknown_charref(name) + return + self.handle_data(unichr(n).encode('utf8')) diff --git a/bin/reportlab/tools/pythonpoint/styles/__init__.py b/bin/reportlab/tools/pythonpoint/styles/__init__.py new file mode 100644 index 00000000000..e67468fd9ee --- /dev/null +++ b/bin/reportlab/tools/pythonpoint/styles/__init__.py @@ -0,0 +1,3 @@ +#Copyright ReportLab Europe Ltd. 2000-2004 +#see license.txt for license details +#history http://www.reportlab.co.uk/cgi-bin/viewcvs.cgi/public/reportlab/trunk/reportlab/tools/pythonpoint/styles/__init__.py diff --git a/bin/reportlab/tools/pythonpoint/styles/horrible.py b/bin/reportlab/tools/pythonpoint/styles/horrible.py new file mode 100644 index 00000000000..fa6d501b043 --- /dev/null +++ b/bin/reportlab/tools/pythonpoint/styles/horrible.py @@ -0,0 +1,101 @@ +#Copyright ReportLab Europe Ltd. 2000-2004 +#see license.txt for license details +#history http://www.reportlab.co.uk/cgi-bin/viewcvs.cgi/public/reportlab/trunk/reportlab/tools/pythonpoint/styles/horrible.py +__version__=''' $Id: horrible.py 2385 2004-06-17 15:26:05Z rgbecker $ ''' +# style_modern.py +__doc__="""This is an example style sheet. You can create your own, and +have them loaded by the presentation. A style sheet is just a +dictionary, where they keys are style names and the values are +ParagraphStyle objects. + +You must provide a function called "getParagraphStyles()" to +return it. In future, we can put things like LineStyles, +TableCellStyles etc. in the same modules. + +You might wish to have two parallel style sheets, one for colour +and one for black and white, so you can switch your presentations +easily. + +A style sheet MUST define a style called 'Normal'. +""" + +from reportlab.lib import styles, enums +def getParagraphStyles(): + """Returns a dictionary of styles based on Helvetica""" + stylesheet = {} + + para = styles.ParagraphStyle('Normal', None) #the ancestor of all + para.fontName = 'Courier' + para.fontSize = 24 + para.leading = 28 + stylesheet['Normal'] = para + + para = ParagraphStyle('BodyText', stylesheet['Normal']) + para.spaceBefore = 12 + stylesheet['BodyText'] = para + + para = ParagraphStyle('BigCentered', stylesheet['Normal']) + para.spaceBefore = 12 + para.alignment = enums.TA_CENTER + stylesheet['BigCentered'] = para + + para = ParagraphStyle('Italic', stylesheet['BodyText']) + para.fontName = 'Courier-Oblique' + stylesheet['Italic'] = para + + para = ParagraphStyle('Title', stylesheet['Normal']) + para.fontName = 'Courier' + para.fontSize = 48 + para.Leading = 58 + para.spaceAfter = 36 + para.alignment = enums.TA_CENTER + stylesheet['Title'] = para + + para = ParagraphStyle('Heading1', stylesheet['Normal']) + para.fontName = 'Courier-Bold' + para.fontSize = 36 + para.leading = 44 + para.spaceAfter = 36 + para.alignment = enums.TA_CENTER + stylesheet['Heading1'] = para + + para = ParagraphStyle('Heading2', stylesheet['Normal']) + para.fontName = 'Courier-Bold' + para.fontSize = 28 + para.leading = 34 + para.spaceBefore = 24 + para.spaceAfter = 12 + stylesheet['Heading2'] = para + + para = ParagraphStyle('Heading3', stylesheet['Normal']) + para.fontName = 'Courier-BoldOblique' + para.spaceBefore = 24 + para.spaceAfter = 12 + stylesheet['Heading3'] = para + + para = ParagraphStyle('Bullet', stylesheet['Normal']) + para.firstLineIndent = -18 + para.leftIndent = 72 + para.spaceBefore = 6 + #para.bulletFontName = 'Symbol' + para.bulletFontSize = 24 + para.bulletIndent = 36 + stylesheet['Bullet'] = para + + para = ParagraphStyle('Definition', stylesheet['Normal']) + #use this for definition lists + para.firstLineIndent = 0 + para.leftIndent = 72 + para.bulletIndent = 0 + para.spaceBefore = 12 + para.bulletFontName = 'Couruer-BoldOblique' + stylesheet['Definition'] = para + + para = ParagraphStyle('Code', stylesheet['Normal']) + para.fontName = 'Courier' + para.fontSize = 16 + para.leading = 18 + para.leftIndent = 36 + stylesheet['Code'] = para + + return stylesheet
\ No newline at end of file diff --git a/bin/reportlab/tools/pythonpoint/styles/htu.py b/bin/reportlab/tools/pythonpoint/styles/htu.py new file mode 100644 index 00000000000..bc79a7ba68e --- /dev/null +++ b/bin/reportlab/tools/pythonpoint/styles/htu.py @@ -0,0 +1,158 @@ +from reportlab.lib import styles +from reportlab.lib import colors +from reportlab.lib.units import cm +from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_RIGHT, TA_JUSTIFY +from reportlab.platypus import Preformatted, Paragraph, Frame, \ + Image, Table, TableStyle, Spacer +from reportlab.pdfbase import pdfmetrics +from reportlab.pdfbase.ttfonts import TTFont + + +def getParagraphStyles(): + """Returns a dictionary of styles to get you started. + + We will provide a way to specify a module of these. Note that + this just includes TableStyles as well as ParagraphStyles for any + tables you wish to use. + """ + + pdfmetrics.registerFont(TTFont('Verdana','verdana.ttf')) + pdfmetrics.registerFont(TTFont('Verdana-Bold','verdanab.ttf')) + pdfmetrics.registerFont(TTFont('Verdana-Italic','verdanai.ttf')) + pdfmetrics.registerFont(TTFont('Verdana-BoldItalic','verdanaz.ttf')) + pdfmetrics.registerFont(TTFont('Arial Narrow','arialn.ttf')) + pdfmetrics.registerFont(TTFont('Arial Narrow-Bold','arialnb.ttf')) + pdfmetrics.registerFont(TTFont('Arial Narrow-Italic','arialni.ttf')) + pdfmetrics.registerFont(TTFont('Arial Narrow-BoldItalic','arialnbi.ttf')) + + stylesheet = {} + ParagraphStyle = styles.ParagraphStyle + + para = ParagraphStyle('Normal', None) #the ancestor of all + para.fontName = 'Verdana' + para.fontSize = 28 + para.leading = 32 + para.spaceAfter = 6 + stylesheet['Normal'] = para + + #This one is spaced out a bit... + para = ParagraphStyle('BodyText', stylesheet['Normal']) + para.spaceBefore = 12 + stylesheet['BodyText'] = para + + #Indented, for lists + para = ParagraphStyle('Indent', stylesheet['Normal']) + para.leftIndent = 60 + para.firstLineIndent = 0 + stylesheet['Indent'] = para + + para = ParagraphStyle('Centered', stylesheet['Normal']) + para.alignment = TA_CENTER + stylesheet['Centered'] = para + + para = ParagraphStyle('BigCentered', stylesheet['Normal']) + para.fontSize = 32 + para.alignment = TA_CENTER + para.spaceBefore = 12 + para.spaceAfter = 12 + stylesheet['BigCentered'] = para + + para = ParagraphStyle('Italic', stylesheet['BodyText']) + para.fontName = 'Verdana-Italic' + stylesheet['Italic'] = para + + para = ParagraphStyle('Title', stylesheet['Normal']) + para.fontName = 'Arial Narrow-Bold' + para.fontSize = 48 + para.leading = 58 + para.alignment = TA_CENTER + stylesheet['Title'] = para + + para = ParagraphStyle('Heading1', stylesheet['Normal']) + para.fontName = 'Arial Narrow-Bold' + para.fontSize = 40 + para.leading = 44 + para.alignment = TA_CENTER + stylesheet['Heading1'] = para + + para = ParagraphStyle('Heading2', stylesheet['Normal']) + para.fontName = 'Verdana' + para.fontSize = 32 + para.leading = 36 + para.spaceBefore = 32 + para.spaceAfter = 12 + stylesheet['Heading2'] = para + + para = ParagraphStyle('Heading3', stylesheet['Normal']) + para.fontName = 'Verdana' + para.spaceBefore = 20 + para.spaceAfter = 6 + stylesheet['Heading3'] = para + + para = ParagraphStyle('Heading4', stylesheet['Normal']) + para.fontName = 'Verdana-BoldItalic' + para.spaceBefore = 6 + stylesheet['Heading4'] = para + + para = ParagraphStyle('Bullet', stylesheet['Normal']) + para.firstLineIndent = 0 + para.leftIndent = 56 + para.spaceBefore = 6 + para.bulletFontName = 'Symbol' + para.bulletFontSize = 24 + para.bulletIndent = 20 + stylesheet['Bullet'] = para + + para = ParagraphStyle('Bullet2', stylesheet['Normal']) + para.firstLineIndent = 0 + para.leftIndent = 80 + para.spaceBefore = 6 + para.fontSize = 24 + para.bulletFontName = 'Symbol' + para.bulletFontSize = 20 + para.bulletIndent = 60 + stylesheet['Bullet2'] = para + + para = ParagraphStyle('Definition', stylesheet['Normal']) + #use this for definition lists + para.firstLineIndent = 0 + para.leftIndent = 60 + para.bulletIndent = 0 + para.bulletFontName = 'Verdana-BoldItalic' + para.bulletFontSize = 24 + stylesheet['Definition'] = para + + para = ParagraphStyle('Code', stylesheet['Normal']) + para.fontName = 'Courier' + para.fontSize = 16 + para.leading = 18 + para.leftIndent = 36 + stylesheet['Code'] = para + + para = ParagraphStyle('PythonCode', stylesheet['Normal']) + para.fontName = 'Courier' + para.fontSize = 16 + para.leading = 18 + para.leftIndent = 36 + stylesheet['Code'] = para + + para = ParagraphStyle('Small', stylesheet['Normal']) + para.fontSize = 12 + para.leading = 14 + stylesheet['Small'] = para + + #now for a table + ts = TableStyle([ + ('FONT', (0,0), (-1,-1), 'Arial Narrow', 22), + ('LINEABOVE', (0,1), (-1,1), 2, colors.green), + ('LINEABOVE', (0,2), (-1,-1), 0.25, colors.black), + ('LINEBELOW', (0,-1), (-1,-1), 2, colors.green), + ('LINEBEFORE', (0,1), (-1,-1), 2, colors.black), + ('LINEAFTER', (0,1), (-1,-1), 2, colors.black), + ('ALIGN', (4,1), (-1,-1), 'RIGHT'), #all numeric cells right aligned + ('TEXTCOLOR', (0,2), (0,-1), colors.black), + ('BACKGROUND', (0,1), (-1,1), colors.Color(0,0.7,0.7)) + ]) + stylesheet['table1'] = ts + + return stylesheet diff --git a/bin/reportlab/tools/pythonpoint/styles/modern.py b/bin/reportlab/tools/pythonpoint/styles/modern.py new file mode 100644 index 00000000000..97583b57857 --- /dev/null +++ b/bin/reportlab/tools/pythonpoint/styles/modern.py @@ -0,0 +1,120 @@ +#Copyright ReportLab Europe Ltd. 2000-2004 +#see license.txt for license details +#history http://www.reportlab.co.uk/cgi-bin/viewcvs.cgi/public/reportlab/trunk/reportlab/tools/pythonpoint/styles/modern.py +__version__=''' $Id: modern.py 2385 2004-06-17 15:26:05Z rgbecker $ ''' +# style_modern.py +__doc__="""This is an example style sheet. You can create your own, and +have them loaded by the presentation. A style sheet is just a +dictionary, where they keys are style names and the values are +ParagraphStyle objects. + +You must provide a function called "getParagraphStyles()" to +return it. In future, we can put things like LineStyles, +TableCellStyles etc. in the same modules. + +You might wish to have two parallel style sheets, one for colour +and one for black and white, so you can switch your presentations +easily. + +A style sheet MUST define a style called 'Normal'. +""" + +from reportlab.lib import styles +from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_RIGHT, TA_JUSTIFY + +def getParagraphStyles(): + """Returns a dictionary of styles based on Helvetica""" + stylesheet = {} + ParagraphStyle = styles.ParagraphStyle + + para = ParagraphStyle('Normal', None) #the ancestor of all + para.fontName = 'Helvetica' + para.fontSize = 24 + para.leading = 28 + stylesheet['Normal'] = para + + para = ParagraphStyle('BodyText', stylesheet['Normal']) + para.spaceBefore = 12 + stylesheet['BodyText'] = para + + para = ParagraphStyle('Indent', stylesheet['Normal']) + para.leftIndent = 36 + para.firstLineIndent = 0 + stylesheet['Indent'] = para + + para = ParagraphStyle('Centered', stylesheet['Normal']) + para.alignment = TA_CENTER + stylesheet['Centered'] = para + + para = ParagraphStyle('BigCentered', stylesheet['Normal']) + para.spaceBefore = 12 + para.alignment = TA_CENTER + stylesheet['BigCentered'] = para + + para = ParagraphStyle('Italic', stylesheet['BodyText']) + para.fontName = 'Helvetica-Oblique' + stylesheet['Italic'] = para + + para = ParagraphStyle('Title', stylesheet['Normal']) + para.fontName = 'Helvetica' + para.fontSize = 48 + para.Leading = 58 + para.spaceAfter = 36 + para.alignment = TA_CENTER + stylesheet['Title'] = para + + para = ParagraphStyle('Heading1', stylesheet['Normal']) + para.fontName = 'Helvetica-Bold' + para.fontSize = 36 + para.leading = 44 + para.spaceAfter = 36 + para.alignment = TA_CENTER + stylesheet['Heading1'] = para + + para = ParagraphStyle('Heading2', stylesheet['Normal']) + para.fontName = 'Helvetica-Bold' + para.fontSize = 28 + para.leading = 34 + para.spaceBefore = 24 + para.spaceAfter = 12 + stylesheet['Heading2'] = para + + para = ParagraphStyle('Heading3', stylesheet['Normal']) + para.fontName = 'Helvetica-BoldOblique' + para.spaceBefore = 24 + para.spaceAfter = 12 + stylesheet['Heading3'] = para + + para = ParagraphStyle('Bullet', stylesheet['Normal']) + para.firstLineIndent = -18 + para.leftIndent = 72 + para.spaceBefore = 6 + para.bulletFontName = 'Symbol' + para.bulletFontSize = 24 + para.bulletIndent = 36 + stylesheet['Bullet'] = para + + para = ParagraphStyle('Bullet2', stylesheet['Bullet']) + para.firstLineIndent = 0 + para.bulletIndent = 72 + para.leftIndent = 108 + stylesheet['Bullet2'] = para + + + para = ParagraphStyle('Definition', stylesheet['Normal']) + #use this for definition lists + para.firstLineIndent = 0 + para.leftIndent = 72 + para.bulletIndent = 0 + para.spaceBefore = 12 + para.bulletFontName = 'Helvetica-BoldOblique' + stylesheet['Definition'] = para + + para = ParagraphStyle('Code', stylesheet['Normal']) + para.fontName = 'Courier' + para.fontSize = 16 + para.leading = 18 + para.leftIndent = 36 + stylesheet['Code'] = para + + return stylesheet
\ No newline at end of file diff --git a/bin/reportlab/tools/pythonpoint/styles/projection.py b/bin/reportlab/tools/pythonpoint/styles/projection.py new file mode 100644 index 00000000000..a3c818556d0 --- /dev/null +++ b/bin/reportlab/tools/pythonpoint/styles/projection.py @@ -0,0 +1,106 @@ +"""This is an example style sheet. You can create your own, and +have them loaded by the presentation. A style sheet is just a +dictionary, where they keys are style names and the values are +ParagraphStyle objects. + +You must provide a function called "getParagraphStyles()" to +return it. In future, we can put things like LineStyles, +TableCellStyles etc. in the same modules. + +You might wish to have two parallel style sheets, one for colour +and one for black and white, so you can switch your presentations +easily. + +A style sheet MUST define a style called 'Normal'. +""" + +from reportlab.lib import styles +from reportlab.lib.colors import * +from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_RIGHT, TA_JUSTIFY + + +def getParagraphStyles(): + """Returns a dictionary of styles based on Helvetica""" + + stylesheet = {} + ParagraphStyle = styles.ParagraphStyle + + para = ParagraphStyle('Normal', None) #the ancestor of all + para.fontName = 'Helvetica-Bold' + para.fontSize = 24 + para.leading = 28 + para.textColor = white + stylesheet['Normal'] = para + + para = ParagraphStyle('BodyText', stylesheet['Normal']) + para.spaceBefore = 12 + stylesheet['BodyText'] = para + + para = ParagraphStyle('BigCentered', stylesheet['Normal']) + para.spaceBefore = 12 + para.alignment = TA_CENTER + stylesheet['BigCentered'] = para + + para = ParagraphStyle('Italic', stylesheet['BodyText']) + para.fontName = 'Helvetica-Oblique' + para.textColor = white + stylesheet['Italic'] = para + + para = ParagraphStyle('Title', stylesheet['Normal']) + para.fontName = 'Helvetica' + para.fontSize = 48 + para.Leading = 58 + para.spaceAfter = 36 + para.alignment = TA_CENTER + stylesheet['Title'] = para + + para = ParagraphStyle('Heading1', stylesheet['Normal']) + para.fontName = 'Helvetica-Bold' + para.fontSize = 48# 36 + para.leading = 44 + para.spaceAfter = 36 + para.textColor = green + para.alignment = TA_LEFT + stylesheet['Heading1'] = para + + para = ParagraphStyle('Heading2', stylesheet['Normal']) + para.fontName = 'Helvetica-Bold' + para.fontSize = 28 + para.leading = 34 + para.spaceBefore = 24 + para.spaceAfter = 12 + stylesheet['Heading2'] = para + + para = ParagraphStyle('Heading3', stylesheet['Normal']) + para.fontName = 'Helvetica-BoldOblique' + para.spaceBefore = 24 + para.spaceAfter = 12 + stylesheet['Heading3'] = para + + para = ParagraphStyle('Bullet', stylesheet['Normal']) + para.firstLineIndent = -18 + para.leftIndent = 72 + para.spaceBefore = 6 + para.bulletFontName = 'Symbol' + para.bulletFontSize = 24 + para.bulletIndent = 36 + stylesheet['Bullet'] = para + + para = ParagraphStyle('Definition', stylesheet['Normal']) + #use this for definition lists + para.firstLineIndent = 0 + para.leftIndent = 72 + para.bulletIndent = 0 + para.spaceBefore = 12 + para.bulletFontName = 'Helvetica-BoldOblique' + stylesheet['Definition'] = para + + para = ParagraphStyle('Code', stylesheet['Normal']) + para.fontName = 'Courier-Bold' + para.fontSize = 16 + para.leading = 18 + para.leftIndent = 36 + para.textColor = chartreuse + stylesheet['Code'] = para + + return stylesheet
\ No newline at end of file diff --git a/bin/reportlab/tools/pythonpoint/styles/standard.py b/bin/reportlab/tools/pythonpoint/styles/standard.py new file mode 100644 index 00000000000..c525964585d --- /dev/null +++ b/bin/reportlab/tools/pythonpoint/styles/standard.py @@ -0,0 +1,132 @@ +from reportlab.lib import styles +from reportlab.lib import colors +from reportlab.lib.units import cm +from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_RIGHT, TA_JUSTIFY +from reportlab.platypus import Preformatted, Paragraph, Frame, \ + Image, Table, TableStyle, Spacer + + +def getParagraphStyles(): + """Returns a dictionary of styles to get you started. + + We will provide a way to specify a module of these. Note that + this just includes TableStyles as well as ParagraphStyles for any + tables you wish to use. + """ + + stylesheet = {} + ParagraphStyle = styles.ParagraphStyle + + para = ParagraphStyle('Normal', None) #the ancestor of all + para.fontName = 'Times-Roman' + para.fontSize = 24 + para.leading = 28 + stylesheet['Normal'] = para + + #This one is spaced out a bit... + para = ParagraphStyle('BodyText', stylesheet['Normal']) + para.spaceBefore = 12 + stylesheet['BodyText'] = para + + #Indented, for lists + para = ParagraphStyle('Indent', stylesheet['Normal']) + para.leftIndent = 36 + para.firstLineIndent = 0 + stylesheet['Indent'] = para + + para = ParagraphStyle('Centered', stylesheet['Normal']) + para.alignment = TA_CENTER + stylesheet['Centered'] = para + + para = ParagraphStyle('BigCentered', stylesheet['Normal']) + para.spaceBefore = 12 + para.alignment = TA_CENTER + stylesheet['BigCentered'] = para + + para = ParagraphStyle('Italic', stylesheet['BodyText']) + para.fontName = 'Times-Italic' + stylesheet['Italic'] = para + + para = ParagraphStyle('Title', stylesheet['Normal']) + para.fontName = 'Times-Roman' + para.fontSize = 48 + para.leading = 58 + para.alignment = TA_CENTER + stylesheet['Title'] = para + + para = ParagraphStyle('Heading1', stylesheet['Normal']) + para.fontName = 'Times-Bold' + para.fontSize = 36 + para.leading = 44 + para.alignment = TA_CENTER + stylesheet['Heading1'] = para + + para = ParagraphStyle('Heading2', stylesheet['Normal']) + para.fontName = 'Times-Bold' + para.fontSize = 28 + para.leading = 34 + para.spaceBefore = 24 + stylesheet['Heading2'] = para + + para = ParagraphStyle('Heading3', stylesheet['Normal']) + para.fontName = 'Times-BoldItalic' + para.spaceBefore = 24 + stylesheet['Heading3'] = para + + para = ParagraphStyle('Heading4', stylesheet['Normal']) + para.fontName = 'Times-BoldItalic' + para.spaceBefore = 6 + stylesheet['Heading4'] = para + + para = ParagraphStyle('Bullet', stylesheet['Normal']) + para.firstLineIndent = 0 + para.leftIndent = 56 + para.spaceBefore = 6 + para.bulletFontName = 'Symbol' + para.bulletFontSize = 24 + para.bulletIndent = 20 + stylesheet['Bullet'] = para + + para = ParagraphStyle('Definition', stylesheet['Normal']) + #use this for definition lists + para.firstLineIndent = 0 + para.leftIndent = 72 + para.bulletIndent = 0 + para.spaceBefore = 12 + para.bulletFontName = 'Helvetica-BoldOblique' + para.bulletFontSize = 24 + stylesheet['Definition'] = para + + para = ParagraphStyle('Code', stylesheet['Normal']) + para.fontName = 'Courier' + para.fontSize = 16 + para.leading = 18 + para.leftIndent = 36 + stylesheet['Code'] = para + + para = ParagraphStyle('PythonCode', stylesheet['Normal']) + para.fontName = 'Courier' + para.fontSize = 16 + para.leading = 18 + para.leftIndent = 36 + stylesheet['PythonCode'] = para + + para = ParagraphStyle('Small', stylesheet['Normal']) + para.fontSize = 12 + para.leading = 14 + stylesheet['Small'] = para + + #now for a table + ts = TableStyle([ + ('FONT', (0,0), (-1,-1), 'Times-Roman', 24), + ('LINEABOVE', (0,0), (-1,0), 2, colors.green), + ('LINEABOVE', (0,1), (-1,-1), 0.25, colors.black), + ('LINEBELOW', (0,-1), (-1,-1), 2, colors.green), + ('LINEBEFORE', (-1,0), (-1,-1), 2, colors.black), + ('ALIGN', (1,1), (-1,-1), 'RIGHT'), #all numeric cells right aligned + ('TEXTCOLOR', (0,1), (0,-1), colors.red), + ('BACKGROUND', (0,0), (-1,0), colors.Color(0,0.7,0.7)) + ]) + stylesheet['table1'] = ts + + return stylesheet |
