more documentation changes
authoraaron_watters
Tue, 13 Jun 2000 13:03:31 +0000
changeset 268 8414113fa500
parent 267 52a348f6c4c3
child 269 125fb70bb53a
more documentation changes
reportlab/platypus/doctemplate.py
reportlab/platypus/flowables.py
reportlab/platypus/frames.py
reportlab/platypus/paragraph.py
reportlab/platypus/tables.py
--- a/reportlab/platypus/doctemplate.py	Tue Jun 13 04:11:49 2000 +0000
+++ b/reportlab/platypus/doctemplate.py	Tue Jun 13 13:03:31 2000 +0000
@@ -31,9 +31,12 @@
 #
 ###############################################################################
 #	$Log: doctemplate.py,v $
+#	Revision 1.15  2000/06/13 13:03:31  aaron_watters
+#	more documentation changes
+#
 #	Revision 1.14  2000/06/01 16:27:56  rgbecker
 #	pageSize is wrong at present
-#
+#	
 #	Revision 1.13  2000/06/01 15:23:06  rgbecker
 #	Platypus re-organisation
 #	
@@ -73,9 +76,29 @@
 #	Revision 1.1  2000/05/12 12:53:33  rgbecker
 #	Initial try at a document template class
 #	
-__version__=''' $Id: doctemplate.py,v 1.14 2000/06/01 16:27:56 rgbecker Exp $ '''
+__version__=''' $Id: doctemplate.py,v 1.15 2000/06/13 13:03:31 aaron_watters Exp $ '''
 __doc__="""
-More complicated Document model
+This module contains the core structure of platypus.
+
+Platypus constructs documents.  Document styles are determined by DocumentTemplates.
+
+Each DocumentTemplate contains one or more PageTemplates which defines the look of the
+pages of the document.
+
+Each PageTemplate has a procedure for drawing the "non-flowing" part of the page
+(for example the header, footer, page number, fixed logo graphic, watermark, etcetera) and
+a set of Frames which enclose the flowing part of the page (for example the paragraphs,
+tables, or non-fixed diagrams of the text).
+
+A document is built when a DocumentTemplate is fed a sequence of Flowables.
+The action of the build consumes the flowables in order and places them onto
+frames on pages as space allows.  When a frame runs out of space the next frame
+of the page is used.  If no frame remains a new page is created.  A new page
+can also be created if a page break is forced.
+
+The special invisible flowable NextPageTemplate can be used to specify
+the page template for the next page (which by default is the one being used
+for the current frame).
 """
 from flowables import *
 from frames import Frame
@@ -87,7 +110,10 @@
 	pass
 
 class ActionFlowable(Flowable):
-	'''This Flowable is never drawn, it can be used for data driven controls'''
+	'''This Flowable is never drawn, it can be used for data driven controls
+	   For example to change a page template (from one column to two, for example)
+	   use NextPageTemplate which creates an ActionFlowable.
+	'''
 	def __init__(self,action=[]):
 		if type(action) not in (ListType, TupleType):
 			action = (action,)
@@ -110,7 +136,7 @@
 				raise NotImplementedError, "Can't handle ActionFlowable(%s)" % action
 			else:
 				raise
-		except:
+		except "bogus":
 			t, v, None = sys.exc_info()
 			raise t, "%s\n   handle_%s args=%s"%(v,action,args)
 
@@ -121,6 +147,7 @@
 PageBegin = ActionFlowable('pageBegin')
 
 class NextPageTemplate(ActionFlowable):
+	"""When you get to the next page, use the template specified (change to two column, for example)  """
 	def __init__(self,pt):
 		ActionFlowable.__init__(self,('nextPageTemplate',pt))
 
@@ -162,6 +189,36 @@
 		story flowables into the frames.
 
 	4)	The document instances can override the base handler routines.
+	
+	Most of the methods for this class are not called directly by the user,
+	but in some advanced usages they may need to be overridden via subclassing.
+	
+	EXCEPTION: doctemplate.build(...) must be called for most reasonable uses
+	since it builds a document using the page template.
+	
+        Each document template builds exactly one document into a file specified
+        by the filename argument on initialization.
+	
+	Possible keyword arguments for the initialization:
+	
+	pageTemplates: A list of templates.  Must be nonempty.  Names
+	  assigned to the templates are used for referring to them so no two used
+	  templates should have the same name.  For example you might want one template
+	  for a title page, one for a section first page, one for a first page of
+	  a chapter and two more for the interior of a chapter on odd and even pages.
+	  If this argument is omitted then at least one pageTemplate should be provided
+	  using the addPageTemplates method before the document is built.
+	showBoundary: (for debugging) if set draw a box around the frame boundaries.
+	leftMargin:
+	rightMargin:
+	topMargin:
+	bottomMargin:  Margin sizes in points (default 1 inch)
+	  These margins may be overridden by the pageTemplates.  They are primarily of interest
+	  for the SimpleDocumentTemplate subclass.
+	allowSplitting:  If set flowables (eg, paragraphs) may be split across frames or pages
+	  (default: 1)
+	title: Internal title for document (does not automatically display on any page)
+	author: Internal author for document (does not automatically display on any page)
 	"""
 	_initArgs = {	'pagesize':DEFAULT_PAGE_SIZE,
 					'pageTemplates':[],
@@ -177,6 +234,7 @@
 	_invalidInitArgs = ()
 
 	def __init__(self, filename, **kw):
+		"""create a document template bound to a filename (see class documentation for keyword arguments)"""
 		self.filename = filename
 
 		for k in self._initArgs.keys():
@@ -205,7 +263,7 @@
 			self.handle_flowable(self._hanging)
 
 	def addPageTemplates(self,pageTemplates):
-		'add one or a sequence of pageTamplates'
+		'add one or a sequence of pageTemplates'
 		if type(pageTemplates) not in (ListType,TupleType):
 			pageTemplates = [pageTemplates]
 		assert filter(lambda x: not isinstance(x,PageTemplate), pageTemplates)==[], "pageTemplates argument error"
@@ -370,7 +428,8 @@
 		del self.frame, self.pageTemplate
 
 	def build(self, flowables):
-		assert filter(lambda x: not isinstance(x,Flowable), flowables)==[], "flowables argument error"
+		"""Build the document from a list of flowables."""
+		#assert filter(lambda x: not isinstance(x,Flowable), flowables)==[], "flowables argument error"
 		self._startBuild()
 
 		while len(flowables):
@@ -380,11 +439,31 @@
 		self._endBuild()
 
 class SimpleDocTemplate(BaseDocTemplate):
+	"""A special case document template that will handle many simple documents.
+	   See documentation for BaseDocTemplate.  No pageTemplates are required 
+	   for this special case.   A page templates are inferred from the
+	   margin information and the onFirstPage, onLaterPages arguments to the build method.
+	   
+	   A document which has all pages with the same look except for the first
+	   page may can be built using this special approach.
+	   """
 	def handle_pageBegin(self):
 		self._handle_pageBegin()
 		self._handle_nextPageTemplate('Later')
 
 	def build(self,flowables,onFirstPage=_doNothing, onLaterPages=_doNothing):
+	        """build the document using the flowables.  Annotate the first page using the onFirstPage
+	           function and later pages using the onLaterPages function.  The onXXX pages should follow
+	           the signature
+	           
+	              def myOnFirstPage(canvas, document):
+	                  # do annotations and modify the document
+	                  ...
+	                  
+	           The functions can do thing like draw logos, page numbers,
+	           footers, etcetera. They can use external variables to vary
+	           the look (for example providing page numbering or section names).
+	        """
 		frameT = Frame(self.leftMargin, self.bottomMargin, self.width, self.height, id='normal')
 		self.addPageTemplates([PageTemplate(id='First',frames=frameT, onPage=onFirstPage),
 						PageTemplate(id='Later',frames=frameT, onPage=onLaterPages)])
--- a/reportlab/platypus/flowables.py	Tue Jun 13 04:11:49 2000 +0000
+++ b/reportlab/platypus/flowables.py	Tue Jun 13 13:03:31 2000 +0000
@@ -31,15 +31,31 @@
 #
 ###############################################################################
 #	$Log: flowables.py,v $
+#	Revision 1.3  2000/06/13 13:03:31  aaron_watters
+#	more documentation changes
+#
 #	Revision 1.2  2000/06/01 16:27:56  rgbecker
 #	pageSize is wrong at present
-#
+#	
 #	Revision 1.1  2000/06/01 15:23:06  rgbecker
 #	Platypus re-organisation
 #	
 #	
-__version__=''' $Id: flowables.py,v 1.2 2000/06/01 16:27:56 rgbecker Exp $ '''
+__version__=''' $Id: flowables.py,v 1.3 2000/06/13 13:03:31 aaron_watters Exp $ '''
 __doc__="""
+A flowable is a "floating element" in a document whose exact position is determined by the
+other elements that precede it, such as a paragraph, a diagram interspersed between paragraphs,
+a section header, etcetera.  Examples of non-flowables include page numbering annotations,
+headers, footers, fixed diagrams or logos, among others.
+
+Flowables are defined here as objects which know how to determine their size and which
+can draw themselves onto a page with respect to a relative "origin" position determined
+at a higher level.  Some Flowables also know how to "split themselves".  For example a
+long paragraph might split itself between one page and the next.
+
+The "text" of a document usually consists mainly of a sequence of flowables which
+flow into a document from top to bottom (with column and page breaks controlled by
+higher level components).
 """
 
 # 200-10-13 gmcm
@@ -100,11 +116,13 @@
 		return []
 
 	def getSpaceAfter(self):
+	        """returns how much space should follow this item if another item follows on the same page."""
 		if hasattr(self,'spaceAfter'): return self.spaceAfter
 		elif hasattr(self,'style') and hasattr(self.style,'spaceAfter'): return self.style.spaceAfter
 		else: return 0
 
 	def getSpaceBefore(self):
+	        """returns how much space should precede this item if another item precedess on the same page."""
 		if hasattr(self,'spaceBefore'): return self.spaceBefore
 		elif hasattr(self,'style') and hasattr(self.style,'spaceBefore'): return self.style.spaceBefore
 		else: return 0
@@ -128,9 +146,15 @@
 		self.canv.drawCentredString(0.5*self.width, 0.5*self.height, self.text)
 
 class Preformatted(Flowable):
-	"""This is like the HTML <PRE> tag.  The line breaks are exactly where you put
-	them, and it will not be wrapped.  So it is much simpler to implement!"""
+	"""This is like the HTML <PRE> tag.  
+	It attempts to display text exactly as you typed it in a fixed width "typewriter" font.
+	The line breaks are exactly where you put
+	them, and it will not be wrapped."""
 	def __init__(self, text, style, bulletText = None, dedent=0):
+	        """text is the text to display. If dedent is set then common leading space
+	           will be chopped off the front (for example if the entire text is indented
+	           6 spaces or more then each line will have 6 spaces removed from the front).
+	        """
 		self.style = style
 		self.bulletText = bulletText
 
@@ -194,6 +218,10 @@
 		self.canv.drawText(tx)
 
 class Image(Flowable):
+	"""an image (digital picture).  Formats supported by PIL (the Python Imaging Library
+	   are supported.  At the present time images as flowables are always centered horozontally
+	   in the frame.
+	"""
 	def __init__(self, filename, width=None, height=None):
 		"""If size to draw at not specified, get it from the image."""
 		import Image  #this will raise an error if they do not have PIL.
@@ -231,8 +259,8 @@
 								  self.drawHeight
 								  )
 class Spacer(Flowable):
-	"""A spacer just takes up space and doesn't draw anything - it can
-	ensure a gap between objects."""
+	"""A spacer just takes up space and doesn't draw anything - it guarantees
+	   a gap between objects."""
 	def __init__(self, width, height):
 		self.width = width
 		self.height = height
@@ -244,7 +272,8 @@
 		pass
 
 class PageBreak(Flowable):
-	"""This works by consuming all remaining space in the frame!"""
+	"""Move on to the next page in the document.
+	   This works by consuming all remaining space in the frame!"""
 
 	def wrap(self, availWidth, availHeight):
 		self.width = availWidth
--- a/reportlab/platypus/frames.py	Tue Jun 13 04:11:49 2000 +0000
+++ b/reportlab/platypus/frames.py	Tue Jun 13 13:03:31 2000 +0000
@@ -31,14 +31,27 @@
 #
 ###############################################################################
 #	$Log: frames.py,v $
+#	Revision 1.2  2000/06/13 13:03:31  aaron_watters
+#	more documentation changes
+#
 #	Revision 1.1  2000/06/01 15:23:06  rgbecker
 #	Platypus re-organisation
-#
-__version__=''' $Id: frames.py,v 1.1 2000/06/01 15:23:06 rgbecker Exp $ '''
+#	
+__version__=''' $Id: frames.py,v 1.2 2000/06/13 13:03:31 aaron_watters Exp $ '''
 __doc__="""
 """
 class Frame:
-	'''Abstraction for the definitional part of a Frame
+	'''
+	A Frame is a piece of space in a document that is filled by the
+	"flowables" in the story.  For example in a book like document most
+	pages have the text paragraphs in one or two frames.  For generality
+	a page might have several frames (for example for 3 column text or
+	for text that wraps around a graphic).
+	
+	After creation a Frame is not usually manipulated directly by the
+	applications program -- it is used internally by the platypus modules.
+	
+	Here is a diagramatid abstraction for the definitional part of a Frame
 
                 width                    x2,y2
     	+---------------------------------+
@@ -54,7 +67,10 @@
     	|   +-------------------------+   |
     	|    bottom padding				  |
     	+---------------------------------+
-    	(x1,y1)
+    	(x1,y1) <-- lower left corner
+    	
+        NOTE!! Frames are stateful objects.  No single frame should be used in
+        two documents at the same time (especially in the presence of multithreading.
 	'''
 	def __init__(self, x1, y1, width,height, leftPadding=6, bottomPadding=6,
 			rightPadding=6, topPadding=6, id=None, showBoundary=0):
@@ -123,7 +139,7 @@
 	add = _add
 
 	def split(self,flowable):
-		'''calls split on the flowable'''
+		'''As the flowable to split using up the available space.'''
 		y = self.y
 		p = self.y1p
 		s = self.atTop and 0 or flowable.getSpaceBefore()
@@ -131,6 +147,7 @@
 
 
 	def drawBoundary(self,canv):
+		"draw the frame boundary as a rectangle (primarily for debugging)."
 		canv.rect(
 				self.x1,
 				self.y1,
--- a/reportlab/platypus/paragraph.py	Tue Jun 13 04:11:49 2000 +0000
+++ b/reportlab/platypus/paragraph.py	Tue Jun 13 13:03:31 2000 +0000
@@ -31,9 +31,12 @@
 #
 ###############################################################################
 #	$Log: paragraph.py,v $
+#	Revision 1.12  2000/06/13 13:03:31  aaron_watters
+#	more documentation changes
+#
 #	Revision 1.11  2000/06/01 15:23:06  rgbecker
 #	Platypus re-organisation
-#
+#	
 #	Revision 1.10  2000/05/31 10:12:20  rgbecker
 #	<bullet> xml tag added
 #	
@@ -64,7 +67,7 @@
 #	Revision 1.1  2000/04/14 13:21:52  rgbecker
 #	Removed from layout.py
 #	
-__version__=''' $Id: paragraph.py,v 1.11 2000/06/01 15:23:06 rgbecker Exp $ '''
+__version__=''' $Id: paragraph.py,v 1.12 2000/06/13 13:03:31 aaron_watters Exp $ '''
 import string
 import types
 from reportlab.pdfbase.pdfmetrics import stringWidth
@@ -75,6 +78,7 @@
 from copy import deepcopy
 
 #our one and only parser
+# XXXXX if the parser has any internal state using only one is probably a BAD idea!
 _parser=ParaParser()
 
 def cleanBlockQuotedText(text):
@@ -245,7 +249,23 @@
 	return offset
 
 class Paragraph(Flowable):
+	"""format a block of text into a paragraph with a given style
+	
+	   The paragraph Text can contain XML-like markup including the 
+	   tags:
+	   <b> ... </b> - bold
+	   <i> ... </i> - italics
+	   <u> ... </u> - underline
+	   <super> ... </super> - superscript
+	   <sub> ... </sub> - subscript
+	   <font name=fontfamily/fontname color=colorname size=float>
+
+		The whole may be surrounded by <para> </para> tags
+
+	 It will also be able to handle any MathML specified Greek characters.
+	"""
 	def __init__(self, text, style, bulletText = None, frags=None):
+		
 		if frags is None:
 			text = cleanBlockQuotedText(text)
 			style, frags, bFrags = _parser.parse(text,style)
--- a/reportlab/platypus/tables.py	Tue Jun 13 04:11:49 2000 +0000
+++ b/reportlab/platypus/tables.py	Tue Jun 13 13:03:31 2000 +0000
@@ -31,9 +31,12 @@
 #
 ###############################################################################
 #	$Log: tables.py,v $
+#	Revision 1.12  2000/06/13 13:03:31  aaron_watters
+#	more documentation changes
+#
 #	Revision 1.11  2000/06/01 15:23:06  rgbecker
 #	Platypus re-organisation
-#
+#	
 #	Revision 1.10  2000/05/26 09:49:23  rgbecker
 #	Color fixes; thanks to J Alet
 #	
@@ -62,11 +65,14 @@
 #	Revision 1.2  2000/02/15 15:47:09  rgbecker
 #	Added license, __version__ and Logi comment
 #	
-__version__=''' $Id: tables.py,v 1.11 2000/06/01 15:23:06 rgbecker Exp $ '''
+__version__=''' $Id: tables.py,v 1.12 2000/06/13 13:03:31 aaron_watters Exp $ '''
 __doc__="""
 Tables are created by passing the constructor a tuple of column widths, a tuple of row heights and the data in
 row order. Drawing of the table can be controlled by using a TableStyle instance. This allows control of the
 color and weight of the lines (if any), and the font, alignment and padding of the text.
+
+See the test output from running this module as a script for a discussion of the method for constructing
+tables and table styles.
 """
 from reportlab.platypus import *
 from reportlab.lib.styles import PropertySet, getSampleStyleSheet