left/right template support
authorandy
Fri, 10 Dec 2004 07:27:50 +0000
changeset 2418 9f4ad36c767f
parent 2417 033a21784720
child 2419 30033c8145c3
left/right template support
reportlab/lib/corp.py
reportlab/platypus/doctemplate.py
reportlab/test/test_platypus_leftright.py
--- a/reportlab/lib/corp.py	Mon Dec 06 17:00:44 2004 +0000
+++ b/reportlab/lib/corp.py	Fri Dec 10 07:27:50 2004 +0000
@@ -409,7 +409,7 @@
 def test():
     """This function produces a pdf with examples. """
 
-    #wbite on blue
+    #white on blue
     rl = RL_CorpLogo()
     rl.width = 129
     rl.height = 86
@@ -428,6 +428,15 @@
     D.__dict__['verbose'] = 1
     D.save(fnRoot='corplogo_blueonwhite',formats=['pdf','eps','jpg','gif'])
 
+    #gray on white
+    rl = RL_CorpLogoReversed()
+    rl.fillColor = Color(0.2, 0.2, 0.2)
+    rl.width = 129
+    rl.height = 86
+    D = Drawing(rl.width,rl.height)
+    D.add(rl)
+    D.__dict__['verbose'] = 1
+    D.save(fnRoot='corplogo_grayonwhite',formats=['pdf','eps','jpg','gif'])
 
 
     rl = RL_BusinessCard()
--- a/reportlab/platypus/doctemplate.py	Mon Dec 06 17:00:44 2004 +0000
+++ b/reportlab/platypus/doctemplate.py	Fri Dec 10 07:27:50 2004 +0000
@@ -407,7 +407,15 @@
             self.pageTemplate.onPageEnd(self.canv, self)
             self.afterPage()
             self.canv.showPage()
-            if hasattr(self,'_nextPageTemplateIndex'):
+
+            if hasattr(self,'_nextPageTemplateCycle'):
+                #they are cycling through pages'; we keep the index
+                cyc = self._nextPageTemplateCycle
+                idx = self._nextPageTemplateIndex
+                self.pageTemplate = cyc[idx]  #which is one of the ones in the list anyway
+                #bump up by 1
+                self._nextPageTemplateIndex = (idx + 1) % len(cyc)
+            elif hasattr(self,'_nextPageTemplateIndex'):
                 self.pageTemplate = self.pageTemplates[self._nextPageTemplateIndex]
                 del self._nextPageTemplateIndex
             if self._emptyPages==0:
@@ -455,15 +463,35 @@
     def handle_nextPageTemplate(self,pt):
         '''On endPage chenge to the page template with name or index pt'''
         if type(pt) is StringType:
+            if hasattr(self, '_nextPageTemplateCycle'): del self._nextPageTemplateCycle
             for t in self.pageTemplates:
                 if t.id == pt:
                     self._nextPageTemplateIndex = self.pageTemplates.index(t)
                     return
             raise ValueError, "can't find template('%s')"%pt
         elif type(pt) is IntType:
+            if hasattr(self, '_nextPageTemplateCycle'): del self._nextPageTemplateCycle
             self._nextPageTemplateIndex = pt
+        elif type(pt) in (ListType, TupleType):
+            #used for alternating left/right pages
+            #collect the refs to the template objects, complain if any are bad
+            cycle = []
+            for templateName in pt:
+                found = 0
+                for t in self.pageTemplates:
+                    if t.id == templateName:
+                        cycle.append(t)
+                        found = 1
+                if not found:
+                    raise ValueError("Cannot find page template called %s" % templateName)
+            #double-check all of them are there...
+            
+            first = cycle[0]
+            #ensure we start on the first one
+            self._nextPageTemplateCycle = cycle
+            self._nextPageTemplateIndex = 0  #indexes into the cycle
         else:
-            raise TypeError, "argument pt should be string or integer"
+            raise TypeError, "argument pt should be string or integer or list"
 
     def handle_nextFrame(self,fx):
         '''On endFrame chenge to the frame with name or index fx'''
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/reportlab/test/test_platypus_leftright.py	Fri Dec 10 07:27:50 2004 +0000
@@ -0,0 +1,157 @@
+#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/test/test_platypus_breaking.py
+"""Tests ability to cycle through multiple page templates
+"""
+
+import sys, os, time
+from string import split, strip, join, whitespace
+from operator import truth
+from types import StringType, ListType
+
+from reportlab.test import unittest
+from reportlab.test.utils import makeSuiteForClasses, outputfile
+
+from reportlab.platypus.flowables import Flowable
+from reportlab.lib import colors
+from reportlab.lib.pagesizes import A4
+from reportlab.lib.units import cm
+from reportlab.lib.enums import TA_LEFT, TA_RIGHT, TA_CENTER, TA_JUSTIFY
+from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
+from reportlab.platypus.paragraph import Paragraph
+from reportlab.platypus.frames import Frame
+from reportlab.lib.randomtext import randomText, PYTHON
+from reportlab.platypus.doctemplate import PageTemplate, BaseDocTemplate, NextPageTemplate
+from reportlab.platypus.paragraph import *
+
+
+def myMainPageFrame(canvas, doc):
+    "The page frame used for all PDF documents."
+
+    canvas.saveState()
+    canvas.setFont('Times-Roman', 12)
+    pageNumber = canvas.getPageNumber()
+    canvas.drawString(10*cm, cm, str(pageNumber))
+    canvas.restoreState()
+
+
+
+class LeftPageTemplate(PageTemplate):
+    def __init__(self):
+        #allow a bigger margin on the right for the staples
+        frame = Frame(1.5*cm, 2.5*cm, 16*cm, 25*cm, id='F1')
+
+        PageTemplate.__init__(self,
+                              id='left',
+                              frames=[frame],
+                              pagesize=A4)
+    def beforeDrawPage(self, canv, doc):
+        "Decorate the page with an asymetric design"
+        canv.setFillColor(colors.cyan)
+                          
+        canv.rect(0.5*cm, 2.5*cm, 1*cm, 25*cm, stroke=1, fill=1)
+        canv.circle(19*cm, 10*cm, 0.5*cm, stroke=1, fill=1)
+        canv.circle(19*cm, 20*cm, 0.5*cm, stroke=1, fill=1)
+        canv.setFillColor(colors.black)
+        
+
+class RightPageTemplate(PageTemplate):
+    def __init__(self):
+        #allow a bigger margin on the right for the staples
+        frame = Frame(3.5*cm, 2.5*cm, 16*cm, 25*cm, id='F1')
+
+        PageTemplate.__init__(self,
+                              id='right',
+                              frames=[frame],
+                              pagesize=A4)
+    def beforeDrawPage(self, canv, doc):
+        "Decorate the page with an asymetric design"
+        canv.setFillColor(colors.cyan)
+        canv.rect(19.5*cm, 2.5*cm, 1*cm, 25*cm, stroke=1, fill=1)
+        canv.circle(2*cm, 10*cm, 0.5*cm, stroke=1, fill=1)
+        canv.circle(2*cm, 20*cm, 0.5*cm, stroke=1, fill=1)
+        canv.setFillColor(colors.black)
+
+
+class MyDocTemplate(BaseDocTemplate):
+    _invalidInitArgs = ('pageTemplates',)
+
+    def __init__(self, filename, **kw):
+        apply(BaseDocTemplate.__init__, (self, filename), kw)
+        self.addPageTemplates(
+            [
+             PageTemplate(id='plain',
+                          frames=[Frame(2.5*cm, 2.5*cm, 16*cm, 25*cm, id='F1')]
+                          ),
+             LeftPageTemplate(),
+             RightPageTemplate()
+            ]
+            )
+
+
+class LeftRightTestCase(unittest.TestCase):
+    "Test multi-page splitting of paragraphs (eyeball-test)."
+    def testIt(self):
+        "This makes one long multi-page paragraph."
+
+        # Build story.
+        story = []
+
+        styleSheet = getSampleStyleSheet()
+        h1 = styleSheet['Heading1']
+        h1.pageBreakBefore = 1
+        h1.keepWithNext = 1
+
+        h2 = styleSheet['Heading2']
+        h2.frameBreakBefore = 1
+        h2.keepWithNext = 1
+
+        h3 = styleSheet['Heading3']
+        h3.backColor = colors.cyan
+        h3.keepWithNext = 1
+
+        bt = styleSheet['BodyText']
+
+        story.append(Paragraph("""
+            This tests ability to alternate left and right templates.  We start on
+            a plain one. The next page should display a left-side template,
+            with a big inner margin and staple-like holes on the right.""",style=bt))
+
+        story.append(NextPageTemplate(['left','right']))
+
+
+        story.append(Paragraph("""
+            One can specify a list of templates instead of a single one in
+            order to sequence through them.""",style=bt))
+        for i in range(10):
+            story.append(Paragraph('Heading 1 always starts a new page (%d)' % len(story), h1))
+            for j in range(3):
+                story.append(Paragraph('Heading1 paragraphs should always'
+                                'have a page break before.  Heading 2 on the other hand'
+                                'should always have a FRAME break before (%d)' % len(story), bt))
+                story.append(Paragraph('Heading 2 always starts a new frame (%d)' % len(story), h2))
+                story.append(Paragraph('Heading1 paragraphs should always'
+                                'have a page break before.  Heading 2 on the other hand'
+                                'should always have a FRAME break before (%d)' % len(story), bt))
+                for j in range(3):
+                    story.append(Paragraph(randomText(theme=PYTHON, sentences=2)+' (%d)' % len(story), bt))
+                    story.append(Paragraph('I should never be at the bottom of a frame (%d)' % len(story), h3))
+                    story.append(Paragraph(randomText(theme=PYTHON, sentences=1)+' (%d)' % len(story), bt))
+
+        story.append(NextPageTemplate('plain'))
+        story.append(Paragraph('Back to plain old page template',h1))
+        story.append(Paragraph('Back to plain old formatting', bt))
+
+
+        #doc = MyDocTemplate(outputfile('test_platypus_leftright.pdf'))
+        doc = MyDocTemplate('test_platypus_leftright.pdf')
+        doc.multiBuild(story)
+
+
+def makeSuite():
+    return makeSuiteForClasses(LeftRightTestCase)
+
+
+#noruntests
+if __name__ == "__main__": #NORUNTESTS
+    unittest.TextTestRunner().run(makeSuite())