Added the first of the demo drawings
authorandy_robinson
Tue, 16 May 2000 11:18:10 +0000
changeset 217 8d8a980841a8
parent 216 ca3b59b4b768
child 218 274db2129c04
Added the first of the demo drawings
utils/yaml/platdemos.py
utils/yaml/platprop.yml
utils/yaml/yaml.py
utils/yaml/yaml2pdf.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/utils/yaml/platdemos.py	Tue May 16 11:18:10 2000 +0000
@@ -0,0 +1,135 @@
+#platdemos.py
+"""This includes some demos of platypus for use in the API proposal"""
+from reportlab.lib import colors
+from reportlab.pdfgen.canvas import Canvas
+from reportlab.lib.styles import ParagraphStyle
+from reportlab.platypus.layout import SimpleFrame, Flowable
+from reportlab.platypus.paragraph import Paragraph
+from reportlab.lib.units import inch
+from reportlab.lib.enums import TA_LEFT, TA_RIGHT, TA_CENTER
+
+captionStyle = ParagraphStyle('Caption',
+                       fontName='Times-Italic',
+                       fontSize=10,
+                       alignment=TA_CENTER)
+
+
+class Figure(Flowable):
+    def __init__(self, width, height):
+        Flowable.__init__(self)
+        self.width = width
+        self.figureHeight = height
+        self.captionHeight = 0  # work out later
+        self.caption = None
+        self.captionStyle = ParagraphStyle('Default')
+        self.spaceBefore = 12
+        self.spaceAfter = 12
+
+    def wrap(self, availWidth, availHeight):
+        # try to get the caption aligned
+        self.captionPara = Paragraph(self.caption, self.captionStyle)
+        (w, h) = self.captionPara.wrap(self.width, availHeight - self.figureHeight)
+        self.captionHeight = h
+        self.height = self.captionHeight + self.figureHeight
+        self.dx = 0.5 * (availWidth - self.width)
+        return (self.width, self.height)
+
+    def draw(self):
+        self.canv.translate(self.dx, 0)
+        self.drawCaption()
+        self.canv.translate(0, self.captionHeight)
+        self.drawBorder()
+        self.drawFigure()
+        
+    def drawBorder(self):
+        print 'drawing border'
+        self.canv.rect(0, 0, self.width, self.figureHeight)
+
+    def drawCaption(self):
+        self.captionPara.drawOn(self.canv, 0, 0)
+
+    def drawFigure(self):
+        pass
+
+def drawPage(canvas,x, y, width, height):
+    #draws something which looks like a page
+    pth = canvas.beginPath()
+    corner = 0.05*width
+
+    # shaded backdrop offset a little    
+    canvas.setFillColorRGB(0.5,0.5,0.5)
+    canvas.rect(x + corner, y - corner, width, height, stroke=0, fill=1)
+
+    #'sheet of paper' in light yellow
+    canvas.setFillColorRGB(1,1,0.9)
+    canvas.setLineWidth(0)
+    canvas.rect(x, y, width, height, stroke=1, fill=1)
+
+    #reset    
+    canvas.setFillColorRGB(0,0,0)
+    canvas.setStrokeColorRGB(0,0,0)
+    
+
+
+class PageFigure(Figure):
+    """Shows a blank page in a frame, and draws on that.  Used in
+    illustrations."""
+    def __init__(self):
+        Figure.__init__(self, 3*inch, 3*inch)
+        self.caption = 'Figure 1 - a blank page'
+        self.captionStyle = captionStyle
+
+    def drawVirtualPage(self):
+        pass
+
+    def drawFigure(self):
+        drawPage(self.canv, 0.625*inch, 0.25*inch, 1.75*inch, 2.5*inch)
+        self.canv.translate(0.625*inch, 0.25*inch)
+        self.canv.scale(1.75/8.27, 2.5/11.69)
+        self.drawVirtualPage()
+
+class PlatPropFigure1(PageFigure):
+    """This shows a page with a frame on it"""
+    def __init__(self):
+        PageFigure.__init__(self)
+        self.caption = "Figure 1 - a page with a simple frame"
+    def drawVirtualPage(self):
+        demo1(self.canv)
+
+
+def demo1(canvas):
+    frame = SimpleFrame(
+                    canvas,
+                    2*inch,     # x
+                    4*inch,     # y at bottom
+                    4*inch,     # width
+                    5*inch     # height
+                    )
+    frame.showBoundary = 1  # helps us see what's going on
+
+    bodyStyle = ParagraphStyle('Body',
+                       fontName='Times-Roman',
+                       fontSize=24,
+                       leading=28,
+                       spaceBefore=6)
+
+    para1 = Paragraph('Spam spam spam spam. ' * 5, bodyStyle)
+    para2 = Paragraph('Eggs eggs eggs. ' * 5, bodyStyle)
+
+    mydata = [para1, para2]
+
+    #this does the packing and drawing.  The frame will consume
+    #items from the front of the list as it prints them
+    frame.addFromList(mydata)
+
+
+def test1():
+    c  = Canvas('platdemos.pdf')
+    f = SimpleFrame(c, inch, inch, 6*inch, 9*inch)
+    f.showBoundary = 1
+    v = PlatPropFigure1()
+    f.addFromList([v])
+    c.save()
+    
+if __name__ == '__main__':
+    test1()
\ No newline at end of file
--- a/utils/yaml/platprop.yml	Tue May 16 08:32:40 2000 +0000
+++ b/utils/yaml/platprop.yml	Tue May 16 11:18:10 2000 +0000
@@ -3,6 +3,9 @@
 CVS Revision History
 .beginPre Code
 $Log: platprop.yml,v $
+Revision 1.4  2000/05/16 11:18:10  andy_robinson
+Added the first of the demo drawings
+
 Revision 1.3  2000/05/15 16:02:41  andy_robinson
 More Paragraph Documentation
 
@@ -17,11 +20,52 @@
 .bu     Document Templates
 
 
-.h1 What is PLATYPUS about?
+.h1 Introduction
+
+.h2 What is this document about?
+
+The ReportLab toolkit aims to be a new generation of reporting tool, with no limits to formatting.  We expect it to grow large, so have divided it into a number of subpackages with clear layers of functionality.
+
+The most basic layer for mist users is the pdfgen subpackage.  This exposes a Canvas object with methods which correspond almost one-to-one with the page marking operators in the PDF file format.  This means that programmers can write code to do anything they want, and build up their own layers of reusable code on top.  However, many common requirements are not met by PDF directly - it does not do anything to help you wrap paragraphs or move down the page.  
+
+PLATYPUS stands for "Page Layout and Typography Using Scripts".  It is the "next layer up" and deals with frames on pages, and "flowable objects" such as paragraphs, images or tables which can be placed within them.  Users will be able to generate "stories" containing paragraphs and other objects, and write "document templates" to process them, hopefully with very few limitations on the effects thatcan be achieved.
+
+This was always an envisaged part of the package, but has taken a long time to get right.  The first try was done in July 1999 for the Open Source conference (in fact, it was needed to make the presentation slides), but was simply too hideous to release.  A second try was put together in November 1999 and progressively refined, appearing when PDFgen was renamed to ReportLab.  This made it possible to produce very basic flowing documents, but lacked many key features and still wasn't general enough.  
+
+We have been discussing better implementations for several months and now think we have something promising.  Robin Becker has just checked a trial implementation into CVS, and we have used it to create this document.  Our main goals in May and June are to get feedback on and solidify this API, and to use it to produce our own documentation.  We therefore invite comment from the ReportLab and Python community.   The content of this document will be updated as comments are received, and the formatting will hopefully get prettier as we learn how to make nice DocTemplates!
+
+Please pay close attention - you will have to live with this for some time, and this I your chance to make sure it is clean and usable!
 
 
+.h2 Use Cases
+
+PLATYPUS should facilitate at least the following kinds of applications:
+.bu     Text Wrapping:  you are writing code to create a form, but this needs a few paragraphs of justified, wrapped text.  You don't want to do the wrapping yourself!
+.bu    Word-Processor style reports which automatically flow from one page to the next, with page headers and footers which can be related to the story content (e.g. page numbers, chapter headings in titles)
+.bu    Database style reports where a large data set is divided into groups with group headers and footers, each occupying a rectangular region on the page, and which flow from page to page
+.bu    Tables and box constructions in which each cell can contain flowing text, images and other graphic objects
+
+Specifically, we would like to be able to build a book, or the Python Library Reference, automatically from source.
+
+PLATYPUS is NOT designed for
+.bu    Precision typesetting by hand - if you are hand-editing a document and want PDF, use something else (Word, FrameMaker, TeX) and distill the output to PDF instead.  ReportLab is about reports, where you want to automatically generate the same kind of document many times.
+
+.bu   Mathematical typography.  While people no doubt could create some nice equation widgets in our framework, TEX will probably never be exceeded in this regard.
+
+.bu     Quick and dirty database reports on Windows machines which go straight to a printer - Access, Crystal et al. handle this well already.
+
+
+
+ 
 .h1 Frames and Flowables
 
+There are several concepts in PLATYPUS and we will go a stage at a time.  We presume familiarity with the use of PDFgen package to create basic documents.  The stage we will save until last is how to create a flowing multi-page document from some data source.  The simplest thing you can do with PLATYPUS is to
+place a frame on a page, add some content to it, and tell it to draw.  Let's
+do this.  
+
+.Comment For the rest of this chapter, let's imagine we're using really tiny pieces of paper about a couple of inches high, so the illustrations below are the correct scale.  This is probably easier on the reader than doing scaling in your head.  Remember that the origin of the coordinate system is the bottom left of the page.
+
+.custom platdemos PlatPropFigure1
 
 
 .h2 Paragraphs, Paragraph Styles and Text
--- a/utils/yaml/yaml.py	Tue May 16 08:32:40 2000 +0000
+++ b/utils/yaml/yaml.py	Tue May 16 11:18:10 2000 +0000
@@ -37,6 +37,7 @@
 
 import sys
 import string
+import imp
 
 #modes:
 PLAIN = 1
@@ -127,7 +128,12 @@
             #we have data, add to para
             self._buf.append(line)            
 
-    
+    def custom(self, moduleName, funcName):
+        """Goes and gets the Python object and adds it to the story"""
+        self.endPara()
+        self._results.append(('Custom',moduleName, funcName))
+        
+        
 
 if __name__=='__main__':
     if len(sys.argv) <> 2:
--- a/utils/yaml/yaml2pdf.py	Tue May 16 08:32:40 2000 +0000
+++ b/utils/yaml/yaml2pdf.py	Tue May 16 11:18:10 2000 +0000
@@ -12,6 +12,7 @@
 
 import sys
 import os
+import imp
 
 import yaml
 
@@ -95,8 +96,23 @@
         elif typ == 'VSpace':
             height = thingy[1]
             story.append(Spacer(0, height))
+        elif typ == 'Custom':
+            # go find it
+            searchPath = [os.getcwd()+'\\']
+            print 'search path',searchPath
+            (typ2, moduleName, funcName) = thingy
+            found = imp.find_module(moduleName, searchPath)
+            assert found, "Custom object module %s not found" % moduleName
+            (file, pathname, description) = found
+            mod = imp.load_module(moduleName, file, pathname, description)
+        
+            #now get the function
+            func = getattr(mod, funcName)
+            story.append(func())
+        
         else:
             print 'skipping',typ, 'for now'
+            
 
     #print it
     doc = MyDocTemplate(outfilename, pagesize=A4)