reportlab/platypus/doctemplate.py
author andy_robinson
Thu, 23 Nov 2000 14:01:59 +0000
changeset 512 c12ae96634d5
parent 500 58d712fef651
child 550 1fcf530ec15b
permissions -rw-r--r--
Added working table of contents framework
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
494
54257447cfe9 Changed to indirect copyright
rgbecker
parents: 405
diff changeset
     1
#copyright ReportLab Inc. 2000
54257447cfe9 Changed to indirect copyright
rgbecker
parents: 405
diff changeset
     2
#see license.txt for license details
54257447cfe9 Changed to indirect copyright
rgbecker
parents: 405
diff changeset
     3
#history http://cvs.sourceforge.net/cgi-bin/cvsweb.cgi/reportlab/platypus/doctemplate.py?cvsroot=reportlab
512
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
     4
#$Header: /tmp/reportlab/reportlab/platypus/doctemplate.py,v 1.31 2000/11/23 14:01:58 andy_robinson Exp $
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
     5
__version__=''' $Id: doctemplate.py,v 1.31 2000/11/23 14:01:58 andy_robinson Exp $ '''
197
b8ca098f5ec7 Initial try at a document template class
rgbecker
parents:
diff changeset
     6
__doc__="""
268
8414113fa500 more documentation changes
aaron_watters
parents: 255
diff changeset
     7
This module contains the core structure of platypus.
8414113fa500 more documentation changes
aaron_watters
parents: 255
diff changeset
     8
512
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
     9
Platypus constructs documents.  Document styles are determined by DocumentTemplates.
268
8414113fa500 more documentation changes
aaron_watters
parents: 255
diff changeset
    10
8414113fa500 more documentation changes
aaron_watters
parents: 255
diff changeset
    11
Each DocumentTemplate contains one or more PageTemplates which defines the look of the
8414113fa500 more documentation changes
aaron_watters
parents: 255
diff changeset
    12
pages of the document.
8414113fa500 more documentation changes
aaron_watters
parents: 255
diff changeset
    13
8414113fa500 more documentation changes
aaron_watters
parents: 255
diff changeset
    14
Each PageTemplate has a procedure for drawing the "non-flowing" part of the page
8414113fa500 more documentation changes
aaron_watters
parents: 255
diff changeset
    15
(for example the header, footer, page number, fixed logo graphic, watermark, etcetera) and
8414113fa500 more documentation changes
aaron_watters
parents: 255
diff changeset
    16
a set of Frames which enclose the flowing part of the page (for example the paragraphs,
8414113fa500 more documentation changes
aaron_watters
parents: 255
diff changeset
    17
tables, or non-fixed diagrams of the text).
8414113fa500 more documentation changes
aaron_watters
parents: 255
diff changeset
    18
8414113fa500 more documentation changes
aaron_watters
parents: 255
diff changeset
    19
A document is built when a DocumentTemplate is fed a sequence of Flowables.
8414113fa500 more documentation changes
aaron_watters
parents: 255
diff changeset
    20
The action of the build consumes the flowables in order and places them onto
8414113fa500 more documentation changes
aaron_watters
parents: 255
diff changeset
    21
frames on pages as space allows.  When a frame runs out of space the next frame
8414113fa500 more documentation changes
aaron_watters
parents: 255
diff changeset
    22
of the page is used.  If no frame remains a new page is created.  A new page
8414113fa500 more documentation changes
aaron_watters
parents: 255
diff changeset
    23
can also be created if a page break is forced.
8414113fa500 more documentation changes
aaron_watters
parents: 255
diff changeset
    24
8414113fa500 more documentation changes
aaron_watters
parents: 255
diff changeset
    25
The special invisible flowable NextPageTemplate can be used to specify
8414113fa500 more documentation changes
aaron_watters
parents: 255
diff changeset
    26
the page template for the next page (which by default is the one being used
8414113fa500 more documentation changes
aaron_watters
parents: 255
diff changeset
    27
for the current frame).
197
b8ca098f5ec7 Initial try at a document template class
rgbecker
parents:
diff changeset
    28
"""
279
e7d8b3631d5c Global sequencer put in the 'story builder'.
andy_robinson
parents: 272
diff changeset
    29
from reportlab.platypus.flowables import *
e7d8b3631d5c Global sequencer put in the 'story builder'.
andy_robinson
parents: 272
diff changeset
    30
from reportlab.platypus.paragraph import Paragraph
e7d8b3631d5c Global sequencer put in the 'story builder'.
andy_robinson
parents: 272
diff changeset
    31
from reportlab.platypus.frames import Frame
500
58d712fef651 Fixed page transitions; extended Pythonpoint
andy_robinson
parents: 494
diff changeset
    32
from reportlab.lib.pagesizes import DEFAULT_PAGE_SIZE
279
e7d8b3631d5c Global sequencer put in the 'story builder'.
andy_robinson
parents: 272
diff changeset
    33
import reportlab.lib.sequencer
197
b8ca098f5ec7 Initial try at a document template class
rgbecker
parents:
diff changeset
    34
from types import *
b8ca098f5ec7 Initial try at a document template class
rgbecker
parents:
diff changeset
    35
import sys
b8ca098f5ec7 Initial try at a document template class
rgbecker
parents:
diff changeset
    36
253
cfcf8d555a2c Platypus re-organisation
rgbecker
parents: 249
diff changeset
    37
def _doNothing(canvas, doc):
512
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    38
    "Dummy callback for onPage"
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    39
    pass
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    40
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    41
class IndexingFlowable0(Flowable):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    42
    """Abstract interface definition for flowables which might
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    43
    hold references to other pages or themselves be targets
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    44
    of cross-references.  XRefStart, XRefDest, Table of Contents,
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    45
    Indexes etc."""
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    46
    def isIndexing(self):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    47
        return 1
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    48
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    49
    def isSatisfied(self):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    50
        return 1
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    51
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    52
    def notify(self, kind, stuff):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    53
        """This will be called by the framework wherever 'stuff' happens.
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    54
        'kind' will be a value that can be used to decide whether to
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    55
        pay attention or not."""
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    56
        pass
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    57
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    58
    def beforeBuild(self):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    59
        """Called by multiBuild before it starts; use this to clear
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    60
        old contents"""
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    61
        pass
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    62
    
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    63
    def afterBuild(self):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    64
        """Called after build ends but before isSatisfied"""
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    65
        pass
253
cfcf8d555a2c Platypus re-organisation
rgbecker
parents: 249
diff changeset
    66
197
b8ca098f5ec7 Initial try at a document template class
rgbecker
parents:
diff changeset
    67
class ActionFlowable(Flowable):
512
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    68
    '''This Flowable is never drawn, it can be used for data driven controls
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    69
       For example to change a page template (from one column to two, for example)
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    70
       use NextPageTemplate which creates an ActionFlowable.
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    71
    '''
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    72
    def __init__(self,action=[]):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    73
        if type(action) not in (ListType, TupleType):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    74
            action = (action,)
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    75
        self.action = action
197
b8ca098f5ec7 Initial try at a document template class
rgbecker
parents:
diff changeset
    76
512
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    77
    def wrap(self, availWidth, availHeight):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    78
        '''Should never be called.'''
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    79
        raise NotImplementedError
197
b8ca098f5ec7 Initial try at a document template class
rgbecker
parents:
diff changeset
    80
512
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    81
    def draw(self):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    82
        '''Should never be called.'''
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    83
        raise NotImplementedError
197
b8ca098f5ec7 Initial try at a document template class
rgbecker
parents:
diff changeset
    84
512
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    85
    def apply(self,doc):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    86
        '''
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    87
        This is called by the doc.build processing to allow the instance to
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    88
        implement its behaviour
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    89
        '''
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    90
        action = self.action[0]
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    91
        args = tuple(self.action[1:])
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    92
        arn = 'handle_'+action
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    93
        try:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    94
            apply(getattr(doc,arn), args)
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    95
        except AttributeError, aerr:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    96
            if aerr.args[0]==arn:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    97
                raise NotImplementedError, "Can't handle ActionFlowable(%s)" % action
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    98
            else:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
    99
                raise
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   100
        except "bogus":
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   101
            t, v, None = sys.exc_info()
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   102
            raise t, "%s\n   handle_%s args=%s"%(v,action,args)
197
b8ca098f5ec7 Initial try at a document template class
rgbecker
parents:
diff changeset
   103
512
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   104
    def __call__(self):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   105
        return self
218
274db2129c04 Fixes/Changes to get testplatypus to work with new framework
rgbecker
parents: 214
diff changeset
   106
274db2129c04 Fixes/Changes to get testplatypus to work with new framework
rgbecker
parents: 214
diff changeset
   107
FrameBreak = ActionFlowable('frameEnd')
197
b8ca098f5ec7 Initial try at a document template class
rgbecker
parents:
diff changeset
   108
PageBegin = ActionFlowable('pageBegin')
b8ca098f5ec7 Initial try at a document template class
rgbecker
parents:
diff changeset
   109
512
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   110
197
b8ca098f5ec7 Initial try at a document template class
rgbecker
parents:
diff changeset
   111
class NextPageTemplate(ActionFlowable):
512
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   112
    """When you get to the next page, use the template specified (change to two column, for example)  """
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   113
    def __init__(self,pt):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   114
        ActionFlowable.__init__(self,('nextPageTemplate',pt))
197
b8ca098f5ec7 Initial try at a document template class
rgbecker
parents:
diff changeset
   115
b8ca098f5ec7 Initial try at a document template class
rgbecker
parents:
diff changeset
   116
class PageTemplate:
512
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   117
    """
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   118
    essentially a list of Frames and an onPage routine to call at the start
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   119
    of a page when this is selected. onPageEnd gets called at the end.
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   120
    derived classes can also implement beforeDrawPage and afterDrawPage if they want
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   121
    """
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   122
    def __init__(self,id=None,frames=[],onPage=_doNothing, onPageEnd=_doNothing,
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   123
                 pagesize=DEFAULT_PAGE_SIZE):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   124
        if type(frames) not in (ListType,TupleType): frames = [frames]
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   125
        assert filter(lambda x: not isinstance(x,Frame), frames)==[], "frames argument error"
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   126
        self.id = id
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   127
        self.frames = frames
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   128
        self.onPage = onPage
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   129
        self.onPageEnd = onPageEnd
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   130
        self.pagesize = pagesize
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   131
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   132
    def beforeDrawPage(self,canv,doc):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   133
        """Override this if you want additional functionality or prefer
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   134
        a class based page routine.  Called before any flowables for
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   135
        this page are processed."""
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   136
        pass
197
b8ca098f5ec7 Initial try at a document template class
rgbecker
parents:
diff changeset
   137
512
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   138
    def afterDrawPage(self, canv, doc):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   139
        """This is called after the last flowable for the page has
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   140
        been processed.  You might use this if the page header or
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   141
        footer needed knowledge of what flowables were drawn on
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   142
        this page."""
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   143
        pass
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   144
        
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   145
class BaseDocTemplate:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   146
    """
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   147
    First attempt at defining a document template class.
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   148
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   149
    The basic idea is simple.
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   150
    0)  The document has a list of data associated with it
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   151
        this data should derive from flowables. We'll have
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   152
        special classes like PageBreak, FrameBreak to do things
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   153
        like forcing a page end etc.
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   154
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   155
    1)  The document has one or more page templates.
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   156
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   157
    2)  Each page template has one or more frames.
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   158
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   159
    3)  The document class provides base methods for handling the
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   160
        story events and some reasonable methods for getting the
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   161
        story flowables into the frames.
214
be55cfb3e54f Added drawPage
rgbecker
parents: 206
diff changeset
   162
512
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   163
    4)  The document instances can override the base handler routines.
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   164
    
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   165
    Most of the methods for this class are not called directly by the user,
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   166
    but in some advanced usages they may need to be overridden via subclassing.
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   167
    
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   168
    EXCEPTION: doctemplate.build(...) must be called for most reasonable uses
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   169
    since it builds a document using the page template.
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   170
    
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   171
    Each document template builds exactly one document into a file specified
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   172
    by the filename argument on initialization.
197
b8ca098f5ec7 Initial try at a document template class
rgbecker
parents:
diff changeset
   173
512
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   174
    Possible keyword arguments for the initialization:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   175
    
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   176
    pageTemplates: A list of templates.  Must be nonempty.  Names
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   177
      assigned to the templates are used for referring to them so no two used
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   178
      templates should have the same name.  For example you might want one template
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   179
      for a title page, one for a section first page, one for a first page of
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   180
      a chapter and two more for the interior of a chapter on odd and even pages.
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   181
      If this argument is omitted then at least one pageTemplate should be provided
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   182
      using the addPageTemplates method before the document is built.
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   183
    showBoundary: if set draw a box around the frame boundaries.
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   184
    leftMargin:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   185
    rightMargin:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   186
    topMargin:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   187
    bottomMargin:  Margin sizes in points (default 1 inch)
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   188
      These margins may be overridden by the pageTemplates.  They are primarily of interest
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   189
      for the SimpleDocumentTemplate subclass.
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   190
    allowSplitting:  If set flowables (eg, paragraphs) may be split across frames or pages
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   191
      (default: 1)
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   192
    title: Internal title for document (does not automatically display on any page)
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   193
    author: Internal author for document (does not automatically display on any page)
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   194
    """
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   195
    _initArgs = {   'pagesize':DEFAULT_PAGE_SIZE,
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   196
                    'pageTemplates':[],
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   197
                    'showBoundary':0,
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   198
                    'leftMargin':inch,
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   199
                    'rightMargin':inch,
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   200
                    'topMargin':inch,
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   201
                    'bottomMargin':inch,
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   202
                    'allowSplitting':1,
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   203
                    'title':None,
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   204
                    'author':None,
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   205
                    '_pageBreakQuick':1}
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   206
    _invalidInitArgs = ()
197
b8ca098f5ec7 Initial try at a document template class
rgbecker
parents:
diff changeset
   207
512
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   208
    def __init__(self, filename, **kw):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   209
        """create a document template bound to a filename (see class documentation for keyword arguments)"""
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   210
        self.filename = filename
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   211
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   212
        for k in self._initArgs.keys():
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   213
            if not kw.has_key(k):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   214
                v = self._initArgs[k]
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   215
            else:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   216
                if k in self._invalidInitArgs:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   217
                    raise ValueError, "Invalid argument %s" % k
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   218
                v = kw[k]
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   219
            setattr(self,k,v)
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   220
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   221
        p = self.pageTemplates
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   222
        self.pageTemplates = []
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   223
        self.addPageTemplates(p)
310
cbec783cfb81 Documentation changes
rgbecker
parents: 305
diff changeset
   224
512
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   225
        # facility to assist multi-build and cross-referencing.
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   226
        # various hooks can put things into here - key is what
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   227
        # you want, value is a page number.  This can then be
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   228
        # passed to indexing flowables.
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   229
        self._pageRefs = {}
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   230
        self._indexingFlowables = []
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   231
        
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   232
        self._calc()
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   233
        self.afterInit()
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   234
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   235
    def _calc(self):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   236
        self._rightMargin = self.pagesize[0] - self.rightMargin
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   237
        self._topMargin = self.pagesize[1] - self.topMargin
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   238
        self.width = self._rightMargin - self.leftMargin
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   239
        self.height = self._topMargin - self.bottomMargin
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   240
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   241
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   242
    def clean_hanging(self):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   243
        'handle internal postponed actions'
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   244
        while len(self._hanging):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   245
            self.handle_flowable(self._hanging)
197
b8ca098f5ec7 Initial try at a document template class
rgbecker
parents:
diff changeset
   246
512
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   247
    def addPageTemplates(self,pageTemplates):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   248
        'add one or a sequence of pageTemplates'
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   249
        if type(pageTemplates) not in (ListType,TupleType):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   250
            pageTemplates = [pageTemplates]
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   251
        #this test below fails due to inconsistent imports!
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   252
        #assert filter(lambda x: not isinstance(x,PageTemplate), pageTemplates)==[], "pageTemplates argument error"
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   253
        for t in pageTemplates:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   254
            self.pageTemplates.append(t)
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   255
            
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   256
    def handle_documentBegin(self):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   257
        '''implement actions at beginning of document'''
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   258
        self._hanging = [PageBegin]
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   259
        self.pageTemplate = self.pageTemplates[0]
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   260
        self.page = 0
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   261
        self.beforeDocument()
253
cfcf8d555a2c Platypus re-organisation
rgbecker
parents: 249
diff changeset
   262
512
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   263
    def handle_pageBegin(self):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   264
        '''Perform actions required at beginning of page.
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   265
        shouldn't normally be called directly'''
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   266
        self.page = self.page + 1
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   267
        self.pageTemplate.beforeDrawPage(self.canv,self)
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   268
        self.pageTemplate.onPage(self.canv,self)
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   269
        self.beforePage()
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   270
        if hasattr(self,'_nextFrameIndex'):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   271
            del self._nextFrameIndex
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   272
        self.frame = self.pageTemplate.frames[0]
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   273
        self.handle_frameBegin()
197
b8ca098f5ec7 Initial try at a document template class
rgbecker
parents:
diff changeset
   274
512
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   275
    def handle_pageEnd(self):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   276
        ''' show the current page
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   277
            check the next page template
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   278
            hang a page begin
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   279
        '''
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   280
        self.pageTemplate.afterDrawPage(self.canv, self)
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   281
        self.pageTemplate.onPageEnd(self.canv, self)
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   282
        self.afterPage()
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   283
        self.canv.showPage()
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   284
        if hasattr(self,'_nextPageTemplateIndex'):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   285
            self.pageTemplate = self.pageTemplates[self._nextPageTemplateIndex]
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   286
            del self._nextPageTemplateIndex
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   287
        self._hanging.append(PageBegin)
197
b8ca098f5ec7 Initial try at a document template class
rgbecker
parents:
diff changeset
   288
512
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   289
    def handle_pageBreak(self):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   290
        '''some might choose not to end all the frames'''
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   291
        if self._pageBreakQuick:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   292
            self.handle_pageEnd()
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   293
        else:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   294
            n = len(self._hanging)
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   295
            while len(self._hanging)==n:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   296
                self.handle_frameEnd()
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   297
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   298
    def handle_frameBegin(self,*args):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   299
        '''What to do at the beginning of a page'''
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   300
        self.frame._reset()
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   301
        if self.showBoundary or self.frame.showBoundary:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   302
            self.frame.drawBoundary(self.canv)
197
b8ca098f5ec7 Initial try at a document template class
rgbecker
parents:
diff changeset
   303
512
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   304
    def handle_frameEnd(self):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   305
        ''' Handles the semantics of the end of a frame. This includes the selection of
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   306
            the next frame or if this is the last frame then invoke pageEnd.
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   307
        '''
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   308
        if hasattr(self,'_nextFrameIndex'):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   309
            frame = self.pageTemplate.frames[self._nextFrameIndex]
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   310
            del self._nextFrameIndex
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   311
            self.handle_frameBegin()
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   312
        elif hasattr(self.frame,'lastFrame') or self.frame is self.pageTemplate.frames[-1]:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   313
            self.handle_pageEnd()
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   314
            self.frame = None
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   315
        else:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   316
            f = self.frame
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   317
            self.frame = self.pageTemplate.frames[self.pageTemplate.frames.index(f) + 1]
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   318
            self.handle_frameBegin()
197
b8ca098f5ec7 Initial try at a document template class
rgbecker
parents:
diff changeset
   319
512
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   320
    def handle_nextPageTemplate(self,pt):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   321
        '''On endPage chenge to the page template with name or index pt'''
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   322
        if type(pt) is StringType:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   323
            for t in self.pageTemplates:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   324
                if t.id == pt:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   325
                    self._nextPageTemplateIndex = self.pageTemplates.index(t)
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   326
                    return
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   327
            raise ValueError, "can't find template('%s')"%pt
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   328
        elif type(pt) is IntType:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   329
            self._nextPageTemplateIndex = pt
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   330
        else:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   331
            raise TypeError, "argument pt should be string or integer"
197
b8ca098f5ec7 Initial try at a document template class
rgbecker
parents:
diff changeset
   332
512
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   333
    def handle_nextFrame(self,fx):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   334
        '''On endFrame chenge to the frame with name or index fx'''
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   335
        if type(fx) is StringType:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   336
            for f in self.pageTemplate.frames:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   337
                if f.id == fx:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   338
                    self._nextFrameIndex = self.pageTemplate.frames.index(f)
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   339
                    return
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   340
            raise ValueError, "can't find frame('%s')"%fx
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   341
        elif type(fx) is IntType:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   342
            self._nextFrameIndex = fx
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   343
        else:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   344
            raise TypeError, "argument fx should be string or integer"
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   345
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   346
    def handle_currentFrame(self,fx):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   347
        '''chenge to the frame with name or index fx'''
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   348
        if type(fx) is StringType:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   349
            for f in self.pageTemplate.frames:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   350
                if f.id == fx:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   351
                    self._nextFrameIndex = self.pageTemplate.frames.index(f)
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   352
                    return
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   353
            raise ValueError, "can't find frame('%s')"%fx
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   354
        elif type(fx) is IntType:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   355
            self._nextFrameIndex = fx
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   356
        else:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   357
            raise TypeError, "argument fx should be string or integer"
197
b8ca098f5ec7 Initial try at a document template class
rgbecker
parents:
diff changeset
   358
512
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   359
    def handle_flowable(self,flowables):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   360
        '''try to handle one flowable from the front of list flowables.'''
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   361
        
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   362
        #allow document a chance to look at, modify or ignore
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   363
        #the object(s) about to be processed
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   364
        self.filterFlowables(flowables)
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   365
        f = flowables[0]
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   366
        del flowables[0]
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   367
        if f is None:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   368
            return
197
b8ca098f5ec7 Initial try at a document template class
rgbecker
parents:
diff changeset
   369
512
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   370
        if isinstance(f,PageBreak):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   371
            self.handle_pageBreak()
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   372
            self.afterFlowable(f)
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   373
        elif isinstance(f,ActionFlowable):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   374
            f.apply(self)
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   375
            self.afterFlowable(f)
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   376
        else:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   377
            #general case we have to do something
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   378
            if self.frame.add(f, self.canv, trySplit=self.allowSplitting):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   379
                self.afterFlowable(f)
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   380
            else:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   381
                if self.allowSplitting:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   382
                    # see if this is a splittable thing
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   383
                    S = self.frame.split(f,self.canv)
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   384
                    n = len(S)
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   385
                else:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   386
                    n = 0
197
b8ca098f5ec7 Initial try at a document template class
rgbecker
parents:
diff changeset
   387
512
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   388
                if n:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   389
                    if self.frame.add(S[0], self.canv, trySplit=0):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   390
                        self.afterFlowable(f)
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   391
                    else:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   392
                        raise "LayoutError", "splitting error"
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   393
                    del S[0]
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   394
                    for f in xrange(n-1):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   395
                        flowables.insert(f,S[f])    # put split flowables back on the list
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   396
                else:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   397
                    # this must e cleared when they are finally drawn!
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   398
                    if hasattr(f,'postponed'):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   399
                        message = "Flowable %s too large on page %d" % (f, self.page)
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   400
                        #show us, it might be handy
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   401
                        #HACK = it seems within tables we sometimes
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   402
                        #get an empty paragraph that won't fit and this
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   403
                        #causes it to fall over.  FIXME FIXME FIXME
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   404
                        if hasattr(f, 'getPlainText'):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   405
                            print 'Offending Paragraph:'
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   406
                            print f.getPlainText()
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   407
                        raise "LayoutError", message
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   408
                    f.postponed = 1
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   409
                    flowables.insert(0,f)           # put the flowable back
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   410
                    self.handle_frameEnd()
197
b8ca098f5ec7 Initial try at a document template class
rgbecker
parents:
diff changeset
   411
512
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   412
    #these are provided so that deriving classes can refer to them
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   413
    _handle_documentBegin = handle_documentBegin
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   414
    _handle_pageBegin = handle_pageBegin
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   415
    _handle_pageEnd = handle_pageEnd
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   416
    _handle_frameBegin = handle_frameBegin
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   417
    _handle_frameEnd = handle_frameEnd
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   418
    _handle_flowable = handle_flowable
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   419
    _handle_nextPageTemplate = handle_nextPageTemplate
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   420
    _handle_currentFrame = handle_currentFrame
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   421
    _handle_nextFrame = handle_nextFrame
197
b8ca098f5ec7 Initial try at a document template class
rgbecker
parents:
diff changeset
   422
512
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   423
    def _startBuild(self, filename=None, canvasmaker=canvas.Canvas):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   424
        self._calc()
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   425
        self.canv = canvasmaker(filename or self.filename,pagesize=self.pagesize)
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   426
        self.handle_documentBegin()
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   427
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   428
    def _endBuild(self):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   429
        if self._hanging!=[] and self._hanging[-1] is PageBegin:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   430
            del self._hanging[-1]
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   431
            self.clean_hanging()
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   432
        else:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   433
            self.clean_hanging()
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   434
            self.handle_pageBreak()
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   435
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   436
        self.canv.save()
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   437
        #AR - hack - for some reason a document did not
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   438
        #have these:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   439
        #if hasattr(self, 'frame'): del self.frame
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   440
        #if hasattr(self, 'pageTemplate'): del self.pageTemplate
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   441
        #del self.frame, self.pageTemplate
218
274db2129c04 Fixes/Changes to get testplatypus to work with new framework
rgbecker
parents: 214
diff changeset
   442
512
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   443
    def build(self, flowables, filename=None, canvasmaker=canvas.Canvas):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   444
        """Build the document from a list of flowables.
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   445
           If the filename argument is provided then that filename is used
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   446
           rather than the one provided upon initialization.
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   447
           If the canvasmaker argument is provided then it will be used
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   448
           instead of the default.  For example a slideshow might use
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   449
           an alternate canvas which places 6 slides on a page (by
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   450
           doing translations, scalings and redefining the page break
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   451
           operations).
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   452
        """
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   453
        #assert filter(lambda x: not isinstance(x,Flowable), flowables)==[], "flowables argument error"
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   454
        self._startBuild(filename,canvasmaker)
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   455
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   456
        while len(flowables):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   457
            self.clean_hanging()
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   458
            self.handle_flowable(flowables)
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   459
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   460
        self._endBuild()
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   461
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   462
    def _allSatisfied0(self):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   463
        """Called by multi-build - are all cross-references resolved?"""
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   464
        allHappy = 1
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   465
        for f in self._indexingFlowables:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   466
            if not f.isSatisfied():
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   467
                allHappy = 0
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   468
                break
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   469
        return allHappy    
197
b8ca098f5ec7 Initial try at a document template class
rgbecker
parents:
diff changeset
   470
512
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   471
    def notify0(self, kind, stuff):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   472
        """"Forward to any listeners"""
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   473
        for l in self._indexingFlowables:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   474
            l.notify(kind, stuff)
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   475
            
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   476
    def pageRef0(self, label):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   477
        """hook to register a page number"""
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   478
        print "pageRef called with label '%s' on page %d" % (
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   479
            label, self.page)
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   480
        self._pageRefs[label] = self.page
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   481
        
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   482
    def multiBuild0(self, story,
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   483
                   filename=None,
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   484
                   canvasmaker=canvas.Canvas,
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   485
                   maxPasses = 10):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   486
        """Makes multiple passes until all indexing flowables
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   487
        are happy."""
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   488
        self._indexingFlowables = []
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   489
        #scan the story and keep a copy
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   490
        for thing in story:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   491
            if thing.isIndexing():
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   492
                self._indexingFlowables.append(thing)
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   493
        #print 'scanned story, found these indexing flowables:\n'
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   494
        #print self._indexingFlowables
197
b8ca098f5ec7 Initial try at a document template class
rgbecker
parents:
diff changeset
   495
512
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   496
        passes = 0
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   497
        while 1:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   498
            passes = passes + 1
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   499
            print 'building pass '+str(passes) + '...',
197
b8ca098f5ec7 Initial try at a document template class
rgbecker
parents:
diff changeset
   500
512
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   501
            for fl in self._indexingFlowables:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   502
                fl.beforeBuild()
218
274db2129c04 Fixes/Changes to get testplatypus to work with new framework
rgbecker
parents: 214
diff changeset
   503
512
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   504
            # work with a copy of the story, since it is consumed
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   505
            tempStory = story[:]
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   506
            self.build(tempStory, filename, canvasmaker)
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   507
            #self.notify0('debug',None)
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   508
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   509
            #clean up so multi-build does not go wrong - the frame
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   510
            #packer might have tacked an attribute onto some
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   511
            #paragraphs
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   512
            for elem in story:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   513
                if hasattr(elem, 'postponed'):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   514
                    del elem.postponed
218
274db2129c04 Fixes/Changes to get testplatypus to work with new framework
rgbecker
parents: 214
diff changeset
   515
512
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   516
            for fl in self._indexingFlowables:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   517
                fl.afterBuild()
218
274db2129c04 Fixes/Changes to get testplatypus to work with new framework
rgbecker
parents: 214
diff changeset
   518
512
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   519
            happy = self._allSatisfied0()
221
3d71b66b14c6 Changes related to removal of SimpleFlowDocument
rgbecker
parents: 218
diff changeset
   520
512
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   521
            if happy:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   522
                print 'OK'
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   523
                break
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   524
            else:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   525
                print 'failed'
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   526
            if passes > maxPasses:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   527
                raise IndexError, "Index entries not resolved after %d passes" % maxPasses
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   528
        
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   529
        print 'saved', filename
284
eabeb5f4e851 Added UserDocTemplate class, and paragraph.getPlainText()
andy_robinson
parents: 279
diff changeset
   530
512
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   531
    #these are pure virtuals override in derived classes
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   532
    #NB these get called at suitable places by the base class
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   533
    #so if you derive and override the handle_xxx methods
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   534
    #it's up to you to ensure that they maintain the needed consistency
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   535
    def afterInit(self):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   536
        """This is called after initialisation of the base class."""
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   537
        pass
284
eabeb5f4e851 Added UserDocTemplate class, and paragraph.getPlainText()
andy_robinson
parents: 279
diff changeset
   538
512
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   539
    def beforeDocument(self):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   540
        """This is called before any processing is
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   541
        done on the document."""
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   542
        pass
284
eabeb5f4e851 Added UserDocTemplate class, and paragraph.getPlainText()
andy_robinson
parents: 279
diff changeset
   543
512
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   544
    def beforePage(self):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   545
        """This is called at the beginning of page
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   546
        processing, and immediately before the
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   547
        beforeDrawPage method of the current page
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   548
        template."""
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   549
        pass
284
eabeb5f4e851 Added UserDocTemplate class, and paragraph.getPlainText()
andy_robinson
parents: 279
diff changeset
   550
512
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   551
    def afterPage(self):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   552
        """This is called after page processing, and
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   553
        immediately after the afterDrawPage method
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   554
        of the current page template."""
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   555
        pass
284
eabeb5f4e851 Added UserDocTemplate class, and paragraph.getPlainText()
andy_robinson
parents: 279
diff changeset
   556
512
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   557
    def filterFlowables(self,flowables):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   558
        '''called to filter flowables at the start of the main handle_flowable method.
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   559
        Upon return if flowables[0] has been set to None it is discarded and the main
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   560
        method returns.
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   561
        '''
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   562
        pass
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   563
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   564
    def afterFlowable(self, flowable):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   565
        '''called after a flowable has been rendered'''
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   566
        pass
284
eabeb5f4e851 Added UserDocTemplate class, and paragraph.getPlainText()
andy_robinson
parents: 279
diff changeset
   567
221
3d71b66b14c6 Changes related to removal of SimpleFlowDocument
rgbecker
parents: 218
diff changeset
   568
class SimpleDocTemplate(BaseDocTemplate):
512
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   569
    """A special case document template that will handle many simple documents.
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   570
       See documentation for BaseDocTemplate.  No pageTemplates are required 
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   571
       for this special case.   A page templates are inferred from the
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   572
       margin information and the onFirstPage, onLaterPages arguments to the build method.
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   573
       
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   574
       A document which has all pages with the same look except for the first
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   575
       page may can be built using this special approach.
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   576
    """
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   577
    _invalidInitArgs = ('pageTemplates',)
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   578
    def handle_pageBegin(self):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   579
        '''override base method to add a change of page template after the firstpage.
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   580
        '''
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   581
        self._handle_pageBegin()
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   582
        self._handle_nextPageTemplate('Later')
221
3d71b66b14c6 Changes related to removal of SimpleFlowDocument
rgbecker
parents: 218
diff changeset
   583
512
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   584
    def build(self,flowables,onFirstPage=_doNothing, onLaterPages=_doNothing):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   585
        """build the document using the flowables.  Annotate the first page using the onFirstPage
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   586
               function and later pages using the onLaterPages function.  The onXXX pages should follow
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   587
               the signature
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   588
               
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   589
                  def myOnFirstPage(canvas, document):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   590
                      # do annotations and modify the document
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   591
                      ...
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   592
                      
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   593
               The functions can do things like draw logos, page numbers,
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   594
               footers, etcetera. They can use external variables to vary
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   595
               the look (for example providing page numbering or section names).
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   596
        """
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   597
        self._calc()    #in case we changed margins sizes etc
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   598
        frameT = Frame(self.leftMargin, self.bottomMargin, self.width, self.height, id='normal')
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   599
        self.addPageTemplates([PageTemplate(id='First',frames=frameT, onPage=onFirstPage),
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   600
                        PageTemplate(id='Later',frames=frameT, onPage=onLaterPages)])
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   601
        if onFirstPage is _doNothing and hasattr(self,'onFirstPage'):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   602
            self.pageTemplates[0].beforeDrawPage = self.onFirstPage
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   603
        if onLaterPages is _doNothing and hasattr(self,'onLaterPages'):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   604
            self.pageTemplates[1].beforeDrawPage = self.onLaterPages
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   605
        BaseDocTemplate.build(self,flowables)
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   606
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   607
    ##########################################################
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   608
    ##
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   609
    ##   testing
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   610
    ##
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   611
    ##########################################################
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   612
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   613
def randomText():
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   614
    #this may or may not be appropriate in your company
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   615
    from random import randint, choice
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   616
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   617
    RANDOMWORDS = ['strategic','direction','proactive',
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   618
    'reengineering','forecast','resources',
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   619
    'forward-thinking','profit','growth','doubletalk',
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   620
    'venture capital','IPO']
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   621
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   622
    sentences = 5
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   623
    output = ""
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   624
    for sentenceno in range(randint(1,5)):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   625
        output = output + 'Blah'
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   626
        for wordno in range(randint(10,25)):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   627
            if randint(0,4)==0:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   628
                word = choice(RANDOMWORDS)
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   629
            else:
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   630
                word = 'blah'
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   631
            output = output + ' ' +word
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   632
        output = output+'.'
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   633
    return output
221
3d71b66b14c6 Changes related to removal of SimpleFlowDocument
rgbecker
parents: 218
diff changeset
   634
3d71b66b14c6 Changes related to removal of SimpleFlowDocument
rgbecker
parents: 218
diff changeset
   635
if __name__ == '__main__':
3d71b66b14c6 Changes related to removal of SimpleFlowDocument
rgbecker
parents: 218
diff changeset
   636
512
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   637
    def myFirstPage(canvas, doc):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   638
        canvas.saveState()
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   639
        canvas.setStrokeColor(red)
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   640
        canvas.setLineWidth(5)
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   641
        canvas.line(66,72,66,PAGE_HEIGHT-72)
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   642
        canvas.setFont('Times-Bold',24)
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   643
        canvas.drawString(108, PAGE_HEIGHT-108, "TABLE OF CONTENTS DEMO")
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   644
        canvas.setFont('Times-Roman',12)
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   645
        canvas.drawString(4 * inch, 0.75 * inch, "First Page")
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   646
        canvas.restoreState()
221
3d71b66b14c6 Changes related to removal of SimpleFlowDocument
rgbecker
parents: 218
diff changeset
   647
512
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   648
    def myLaterPages(canvas, doc):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   649
        canvas.saveState()
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   650
        canvas.setStrokeColor(red)
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   651
        canvas.setLineWidth(5)
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   652
        canvas.line(66,72,66,PAGE_HEIGHT-72)
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   653
        canvas.setFont('Times-Roman',12)
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   654
        canvas.drawString(4 * inch, 0.75 * inch, "Page %d" % doc.page)
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   655
        canvas.restoreState()
221
3d71b66b14c6 Changes related to removal of SimpleFlowDocument
rgbecker
parents: 218
diff changeset
   656
512
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   657
    def run():
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   658
        objects_to_draw = []
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   659
        from reportlab.lib.styles import ParagraphStyle
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   660
        #from paragraph import Paragraph
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   661
        from doctemplate import SimpleDocTemplate
221
3d71b66b14c6 Changes related to removal of SimpleFlowDocument
rgbecker
parents: 218
diff changeset
   662
512
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   663
        #need a style
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   664
        normal = ParagraphStyle('normal')
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   665
        normal.firstLineIndent = 18
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   666
        normal.spaceBefore = 6
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   667
        import random
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   668
        for i in range(15):
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   669
            height = 0.5 + (2*random.random())
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   670
            box = XBox(6 * inch, height * inch, 'Box Number %d' % i)
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   671
            objects_to_draw.append(box)
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   672
            para = Paragraph(randomText(), normal)
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   673
            objects_to_draw.append(para)
221
3d71b66b14c6 Changes related to removal of SimpleFlowDocument
rgbecker
parents: 218
diff changeset
   674
512
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   675
        SimpleDocTemplate('doctemplate.pdf').build(objects_to_draw,
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   676
            onFirstPage=myFirstPage,onLaterPages=myLaterPages)
221
3d71b66b14c6 Changes related to removal of SimpleFlowDocument
rgbecker
parents: 218
diff changeset
   677
512
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 500
diff changeset
   678
    run()
221
3d71b66b14c6 Changes related to removal of SimpleFlowDocument
rgbecker
parents: 218
diff changeset
   679