Splitting layout.py
authorrgbecker
Fri, 14 Apr 2000 11:54:57 +0000
changeset 128 a0676f013314
parent 127 44912033ce1b
child 129 623baa767856
Splitting layout.py
reportlab/lib/styles.py
reportlab/platypus/layout.py
reportlab/platypus/paraparser.py
reportlab/platypus/tables.py
reportlab/platypus/test/testplatypus.py
--- a/reportlab/lib/styles.py	Fri Apr 14 11:28:32 2000 +0000
+++ b/reportlab/lib/styles.py	Fri Apr 14 11:54:57 2000 +0000
@@ -31,11 +31,16 @@
 #
 ###############################################################################
 #	$Log: styles.py,v $
+#	Revision 1.2  2000/04/14 11:54:56  rgbecker
+#	Splitting layout.py
+#
 #	Revision 1.1  2000/04/14 10:51:56  rgbecker
 #	Moved out of layout.py
-#
-__version__=''' $Id: styles.py,v 1.1 2000/04/14 10:51:56 rgbecker Exp $ '''
+#	
+__version__=''' $Id: styles.py,v 1.2 2000/04/14 11:54:56 rgbecker Exp $ '''
 
+from reportlab.lib.colors import white, black
+from reportlab.lib.enums import TA_LEFT
 
 ###########################################################
 # This class provides an 'instance inheritance'
--- a/reportlab/platypus/layout.py	Fri Apr 14 11:28:32 2000 +0000
+++ b/reportlab/platypus/layout.py	Fri Apr 14 11:54:57 2000 +0000
@@ -31,9 +31,12 @@
 #
 ###############################################################################
 #	$Log: layout.py,v $
+#	Revision 1.16  2000/04/14 11:54:57  rgbecker
+#	Splitting layout.py
+#
 #	Revision 1.15  2000/04/14 08:56:20  rgbecker
 #	Drawable ==> Flowable
-#
+#	
 #	Revision 1.14  2000/04/13 17:06:40  rgbecker
 #	Fixed SimpleFrame.add
 #	
@@ -73,7 +76,7 @@
 #	Revision 1.2  2000/02/15 15:47:09  rgbecker
 #	Added license, __version__ and Logi comment
 #	
-__version__=''' $Id: layout.py,v 1.15 2000/04/14 08:56:20 rgbecker Exp $ '''
+__version__=''' $Id: layout.py,v 1.16 2000/04/14 11:54:57 rgbecker Exp $ '''
 __doc__="""
 Page Layout And TYPography Using Scripts
 a page layout API on top of PDFgen
@@ -87,200 +90,12 @@
 import string
 import types
 
-from reportlab.pdfbase.pdfmetrics import stringWidth
 from reportlab.pdfgen import canvas
 from reportlab.lib.units import inch
-from reportlab.lib.colors import white, black, red, Color
-from reportlab.platypus.paraparser import ParaParser, ParaFrag
-
-#our one and only parser
-_parser=ParaParser()
+from reportlab.lib.colors import red
 
 from reportlab.lib.pagesizes import DEFAULT_PAGE_SIZE
 PAGE_HEIGHT = DEFAULT_PAGE_SIZE[1]
-from reportlab.lib.enums import TA_LEFT, TA_RIGHT, TA_CENTER, TA_JUSTIFY
-
-###########################################################
-#	Styles.  This class provides an 'instance inheritance'
-# mechanism for its descendants, simpler than acquisition
-# but not as far-reaching
-###########################################################
-class PropertySet:
-	defaults = {}
-
-	def __init__(self, name, parent=None):
-		self.name = name
-		self.parent = parent
-		self.attributes = {}
-
-	def __setattr__(self, key, value):
-		if self.defaults.has_key(key):
-			self.attributes[key] = value
-		else:
-			self.__dict__[key] = value
-
-	def __getattr__(self, key):
-		if self.defaults.has_key(key):
-			if self.attributes.has_key(key):
-				found = self.attributes[key]
-			elif self.parent:
-				found = getattr(self.parent, key)
-			else:  #take the class default
-				found = self.defaults[key]
-		else:
-			found = self.__dict__[key]
-		return found
-
-	def __repr__(self):
-		return "<%s '%s'>" % (self.__class__.__name__, self.name)
-
-	def listAttrs(self):
-		print 'name =', self.name
-		print 'parent =', self.parent
-		keylist = self.defaults.keys()
-		keylist.sort()
-		for key in keylist:
-			value = self.attributes.get(key, None)
-			if value:
-				print '%s = %s (direct)' % (key, value)
-			else: #try for inherited
-				value = getattr(self.parent, key, None)
-				if value:
-					print '%s = %s (inherited)' % (key, value)
-				else:
-					value = self.defaults[key]
-					print '%s = %s (class default)' % (key, value)
-
-
-
-class ParagraphStyle(PropertySet):
-	defaults = {
-		'fontName':'Times-Roman',
-		'fontSize':10,
-		'leading':12,
-		'leftIndent':0,
-		'rightIndent':0,
-		'firstLineIndent':0,
-		'alignment':TA_LEFT,
-		'spaceBefore':0,
-		'spaceAfter':0,
-		'bulletFontName':'Times-Roman',
-		'bulletFontSize':10,
-		'bulletIndent':0,
-		'textColor': black
-		}
-
-class LineStyle(PropertySet):
-	defaults = {
-		'width':1,
-		'color': black
-		}
-	def prepareCanvas(self, canvas):
-		"""You can ask a LineStyle to set up the canvas for drawing
-		the lines."""
-		canvas.setLineWidth(1)
-		#etc. etc.
-
-class CellStyle(PropertySet):
-	defaults = {
-		'fontname':'Times-Roman',
-		'fontsize':10,
-		'leading':12,
-		'leftPadding':6,
-		'rightPadding':6,
-		'topPadding':3,
-		'bottomPadding':3,
-		'firstLineIndent':0,
-		'color':white,
-		'alignment': 'LEFT',
-		}
-
-def testStyles():
-	pNormal = ParagraphStyle('Normal',None)
-	pNormal.fontName = 'Times-Roman'
-	pNormal.fontSize = 12
-	pNormal.leading = 14.4
-
-	pNormal.listAttrs()
-	print
-	pPre = ParagraphStyle('Literal', pNormal)
-	pPre.fontName = 'Courier'
-	pPre.listAttrs()
-	return pNormal, pPre
-
-def getSampleStyleSheet():
-	"""Returns a dictionary of styles to get you started.  Should be
-	usable for fairly basic word processing tasks.	We should really have
-	a class for StyleSheets, which can list itself and avoid the
-	duplication of item names seen below."""
-	stylesheet = {}
-
-	para = ParagraphStyle('Normal', None)	#the ancestor of all
-	para.fontName = 'Times-Roman'
-	para.fontSize = 10
-	para.leading = 12
-	stylesheet['Normal'] = para
-
-	para = ParagraphStyle('BodyText', stylesheet['Normal'])
-	para.spaceBefore = 6
-	stylesheet['BodyText'] = para
-
-	para = ParagraphStyle('Italic', stylesheet['BodyText'])
-	para.fontName = 'Times-Italic'
-	stylesheet['Italic'] = para
-
-	para = ParagraphStyle('Heading1', stylesheet['Normal'])
-	para.fontName = 'Times-Bold'
-	para.fontSize = 18
-	para.spaceAfter = 6
-	stylesheet['Heading1'] = para
-
-	para = ParagraphStyle('Heading2', stylesheet['Normal'])
-	para.fontName = 'Times-Bold'
-	para.fontSize = 14
-	para.spaceBefore = 12
-	para.spaceAfter = 6
-	stylesheet['Heading2'] = para
-
-	para = ParagraphStyle('Heading3', stylesheet['Normal'])
-	para.fontName = 'Times-BoldItalic'
-	para.fontSize = 12
-	para.spaceBefore = 12
-	para.spaceAfter = 6
-	stylesheet['Heading3'] = para
-
-	para = ParagraphStyle('Bullet', stylesheet['Normal'])
-	para.firstLineIndent = 36
-	para.leftIndent = 36
-	para.spaceBefore = 3
-	stylesheet['Bullet'] = para
-
-	para = ParagraphStyle('Definition', stylesheet['Normal'])
-	#use this for definition lists
-	para.firstLineIndent = 36
-	para.leftIndent = 36
-	para.bulletIndent = 0
-	para.spaceBefore = 6
-	para.bulletFontName = 'Times-BoldItalic'
-	stylesheet['Definition'] = para
-
-	para = ParagraphStyle('Code', stylesheet['Normal'])
-	para.fontName = 'Courier'
-	para.fontSize = 8
-	para.leading = 8.8
-	para.leftIndent = 36
-	stylesheet['Code'] = para
-
-	return stylesheet
-
-def cleanBlockQuotedText(text):
-	"""This is an internal utility which takes triple-
-	quoted text form within the document and returns
-	(hopefully) the paragraph the user intended originally."""
-	stripped = string.strip(text)
-	lines = string.split(stripped, '\n')
-	trimmed_lines = map(string.lstrip, lines)
-	return string.join(trimmed_lines, ' ')
 
 #############################################################
 #	Flowable Objects - a base class and a few examples.
@@ -334,413 +149,6 @@
 		self.canv.setFont('Times-Roman',12)
 		self.canv.drawCentredString(0.5*self.width, 0.5*self.height, self.text)
 
-def	_leftDrawParaLine( tx, offset, extraspace, words, last=0):
-	tx.moveCursor(offset, 0)
-	tx._textOut(string.join(words),1)
-	tx.moveCursor(-offset, 0)
-
-def	_centerDrawParaLine( tx, offset, extraspace, words, last=0):
-	tx.moveCursor(offset + 0.5 * extraspace, 0)
-	tx._textOut(string.join(words),1)
-	tx.moveCursor(-offset + 0.5 * extraspace, 0)
-
-def	_rightDrawParaLine( tx, offset, extraspace, words, last=0):
-	tx.moveCursor(offset + extraspace, 0)
-	tx._textOut(string.join(words),1)
-	tx.moveCursor(-offset + extraspace, 0)
-
-def	_justifyDrawParaLine( tx, offset, extraspace, words, last=0):
-	tx.moveCursor(offset, 0)
-	text  = string.join(words)
-	if last:
-		#last one, left align
-		tx._textOut(text,1)
-	else:
-		tx.setWordSpace(extraspace / float(len(words)-1))
-		tx._textOut(text,1)
-		tx.setWordSpace(0)
-	tx.moveCursor(-offset, 0)
-
-def	_putFragLine(tx,words):
-	for f in words:
-		if (tx._fontname,tx._fontsize)!=(f.fontName,f.fontSize):
-			tx._setFont(f.fontName, f.fontSize)
-		if tx.XtraState.textColor!=f.textColor:
-			tx.XtraState.textColor = f.textColor
-			tx.setFillColor(f.textColor)
-		if tx.XtraState.rise!=f.rise:
-			tx.XtraState.rise=f.rise
-			tx.setRise(f.rise)
-		tx._textOut(f.text,f is words[-1])	# cheap textOut
-
-def	_leftDrawParaLineX( tx, offset, line, last=0):
-	tx.moveCursor(offset, 0)
-	_putFragLine(tx, line.words)
-	tx.moveCursor(-offset, 0)
-
-def	_centerDrawParaLineX( tx, offset, line, last=0):
-	tx.moveCursor(offset + 0.5 * line.extraSpace, 0)
-	_putFragLine(tx, line.words)
-	tx.moveCursor(-offset + 0.5 * line.extraSpace, 0)
-
-def	_rightDrawParaLineX( tx, offset, line, last=0):
-	tx.moveCursor(offset + line.extraSpace, 0)
-	_putFragLine(tx, line.words)
-	tx.moveCursor(-offset + line.extraSpace, 0)
-
-def	_justifyDrawParaLineX( tx, offset, line, last=0):
-	tx.moveCursor(offset, 0)
-	if last:
-		#last one, left align
-		tx.moveCursor(offset, 0)
-		_putFragLine(tx, line.words)
-		tx.moveCursor(-offset, 0)
-	else:
-		tx.setWordSpace(line.extraSpace / float(line.wordCount-1))
-		_putFragLine(tx, line.words)
-		tx.setWordSpace(0)
-	tx.moveCursor(-offset, 0)
-
-def	_sameFrag(f,g):
-	'returns 1 if two frags map out the same'
-	for a in ('fontName', 'fontSize', 'textColor', 'rise'):
-		if getattr(f,a)!=getattr(g,a): return 0
-	return 1
-
-def _getFragWords(frags):
-	'''	given a fragment list return a list of lists
-		[[size, (f00,w00), ..., (f0n,w0n)],....,[size, (fm0,wm0), ..., (f0n,wmn)]]
-		each pair f,w represents a style and some string
-		each sublist represents a word
-	'''
-	R = []
-	W = []
-	n = 0
-	for f in frags:
-		text = f.text
-		del f.text
-		if text!='':
-			S = string.split(text,' ')
-			if W!=[] and text[0] in [' ','\t']:
-				W.insert(0,n)
-				R.append(W)
-				W = []
-				n = 0
-
-			for w in S[:-1]:
-				W.append((f,w))
-				n = n + stringWidth(w, f.fontName, f.fontSize)
-				W.insert(0,n)
-				R.append(W)
-				W = []
-				n = 0
-
-			w = S[-1]
-			W.append((f,w))
-			n = n + stringWidth(w, f.fontName, f.fontSize)
-			if text[-1] in [' ','\t']:
-				W.insert(0,n)
-				R.append(W)
-				W = []
-				n = 0
-	if W!=[]:
-		W.insert(0,n)
-		R.append(W)
-
-	for r in R:
-		f = r[1][0]
-	return R
-
-class Paragraph(Flowable):
-	def __init__(self, text, style, bulletText = None):
-		text = cleanBlockQuotedText(text)
-		style, rv = _parser.parse(text,style)
-		if rv is None:
-			raise "xml parser error (%s) in paragraph beginning\n'%s'"\
-					% (_parser.errors[0],text[:min(30,len(text))])
-		self.frags = rv
-		self.style = style
-		self.bulletText = bulletText
-		self.debug = 0	 #turn this on to see a pretty one with all the margins etc.
-
-	def wrap(self, availWidth, availHeight):
-		# work out widths array for breaking
-		self.width = availWidth
-		first_line_width = availWidth - self.style.firstLineIndent - self.style.rightIndent
-		later_widths = availWidth - self.style.leftIndent - self.style.rightIndent
-		self.bfrags = self.breakLines([first_line_width, later_widths])
-
-		#estimate the size
-		return (self.width, self.height)
-
-	def draw(self):
-		#call another method for historical reasons.  Besides, I
-		#suspect I will be playing with alternate drawing routines
-		#so not doing it here makes it easier to switch.
-		self.drawPara(self.debug)
-
-	def breakLines(self, width):
-		"""
-		Returns a broken line structure. There are two cases
-		
-		A) For the simple case of a single formatting input fragment the output is
-			A fragment specifier with
-				kind = 0
-				fontName, fontSize, leading, textColor
-				lines=	A list of lines
-						Each line has two items.
-						1) unused width in points
-						2) word list
-
-		B) When there is more than one input formatting fragment the out put is
-			A fragment specifier with
-				kind = 1
-				lines=	A list of fragments
-							1) extraspace (needed for justified)
-							2) fontSize
-							3) leading
-							4) words=word list
-								each word is itself a fragment with
-								various settings
-
-		This structure can be used to easily draw paragraphs with the various alignments.
-		You can supply either a single width or a list of widths; the latter will have its
-		last item repeated until necessary. A 2-element list is useful when there is a
-		different first line indent; a longer list could be created to facilitate custom wraps
-		around irregular objects."""
-
-		if type(width) <> types.ListType: maxwidths = [width]
-		else: maxwidths = width
-		lines = []
-		lineno = 0
-		maxwidth = maxwidths[lineno]
-		style = self.style
-		fFontSize = float(style.fontSize)
-		sLeading = style.leading
-
-		#for bullets, work out width and ensure we wrap the right amount onto line one
-		if self.bulletText <> None:
-			bulletWidth = stringWidth(
-				self.bulletText,
-				style.bulletFontName, style.bulletFontSize)
-			bulletRight = style.bulletIndent + bulletWidth
-			if bulletRight > style.firstLineIndent:
-				#..then it overruns, and we have less space available on line 1
-				maxwidths[0] = maxwidths[0] - (bulletRight - style.firstLineIndent)
-
-		self.height = style.spaceBefore + style.spaceAfter
-		frags = self.frags
-		nFrags= len(frags)
-		if nFrags==1:
-			f = frags[0]
-			fontSize = f.fontSize
-			fontName = f.fontName
-			words = string.split(f.text, ' ')
-			spacewidth = stringWidth(' ', fontName, fontSize)
-			cLine = []
-			currentwidth = - spacewidth   # hack to get around extra space for word 1
-			for word in words:
-				wordwidth = stringWidth(word, fontName, fontSize)
-				space_available = maxwidth - (currentwidth + spacewidth + wordwidth)
-				if	space_available > 0:
-					# fit one more on this line
-					cLine.append(word)
-					currentwidth = currentwidth + spacewidth + wordwidth
-				else:
-					#end of line
-					lines.append((maxwidth - currentwidth, cLine))
-					cLine = [word]
-					currentwidth = wordwidth
-					lineno = lineno + 1
-					try:
-						maxwidth = maxwidths[lineno]
-					except IndexError:
-						maxwidth = maxwidths[-1]  # use the last one
-
-			#deal with any leftovers on the final line
-			if cLine!=[]: lines.append((space_available, cLine))
-			self.height = self.height + len(lines) * sLeading
-			return f.clone(kind=0, lines=lines)
-		elif nFrags<=0:
-			return ParaFrag(kind=0, fontSize=style.fontSize, fontName=style.fontName,
-							textColor=style.textColor, lines=[])
-		else:
-			n = 0
-			for w in _getFragWords(frags):
-				spacewidth = stringWidth(' ',w[-1][0].fontName, w[-1][0].fontSize)
-
-				if n==0:
-					currentwidth = -spacewidth	 # hack to get around extra space for word 1
-					words = []
-					maxSize = 0
-
-				wordwidth = w[0]
-				f = w[1][0]
-				space_available = maxwidth - (currentwidth + spacewidth + wordwidth)
-				if	space_available > 0:
-					# fit one more on this line
-					n = n + 1
-					maxSize = max(maxSize,f.fontSize)
-					if words==[]:
-						words = [f.clone()]
-						words[-1].text = w[1][1]
-					elif not _sameFrag(words[-1],f):
-						words[-1].text = words[-1].text+' '
-						words.append(f.clone())
-						words[-1].text = w[1][1]
-					else:
-						words[-1].text = words[-1].text + ' ' + w[1][1]
-
-					for i in w[2:]:
-						f = i[0].clone()
-						f.text=i[1]
-						words.append(f)
-						maxSize = max(maxSize,f.fontSize)
-						
-					currentwidth = currentwidth + spacewidth + wordwidth
-				else:
-					#end of line
-					lines.append(ParaFrag(extraSpace=(maxwidth - currentwidth),wordCount=n,
-										words=words, fontSize=maxSize))
-
-					#start new line
-					lineno = lineno + 1
-					try:
-						maxwidth = maxwidths[lineno]
-					except IndexError:
-						maxwidth = maxwidths[-1]  # use the last one
-					currentwidth = wordwidth
-					n = 1
-					maxSize = f.fontSize
-					words = [f.clone()]
-					words[-1].text = w[1][1]
-
-					for i in w[2:]:
-						f = i[0].clone()
-						f.text=i[1]
-						words.append(f)
-						maxSize = max(maxSize,f.fontSize)
-
-			#deal with any leftovers on the final line
-			if words<>[]:
-				lines.append(ParaFrag(extraSpace=(maxwidth - currentwidth),wordCount=n,
-									words=words, fontSize=maxSize))
-			self.height = self.height + len(lines) * sLeading
-			return ParaFrag(kind=1, lines=lines)
-
-		return lines
-
-	def drawPara(self,debug=0):
-		"""Draws a paragraph according to the given style.
-		Returns the final y position at the bottom. Not safe for
-		paragraphs without spaces e.g. Japanese; wrapping
-		algorithm will go infinite."""
-
-		#stash the key facts locally for speed
-		canvas = self.canv
-		style = self.style
-		bfrags = self.bfrags
-		lines = bfrags.lines
-
-		#work out the origin for line 1
-		cur_x = style.leftIndent
-
-
-		if debug:
-			# This boxes and shades stuff to show how the paragraph
-			# uses its space.  Useful for self-documentation so
-			# the debug code stays!
-			# box the lot
-			canvas.rect(0, 0, self.width, self.height)
-			#left and right margins
-			canvas.saveState()
-			canvas.setFillColor(Color(0.9,0.9,0.9))
-			canvas.rect(0, 0, style.leftIndent, self.height)
-			canvas.rect(self.width - style.rightIndent, 0, style.rightIndent, self.height)
-			# shade above and below
-			canvas.setFillColor(Color(1.0,1.0,0.0))
-			canvas.rect(0, self.height - style.spaceBefore, self.width,  style.spaceBefore)
-			canvas.rect(0, 0, self.width, style.spaceAfter)
-			canvas.restoreState()
-			#self.drawLine(x + style.leftIndent, y, x + style.leftIndent, cur_y)
-
-		nLines = len(lines)
-		if nLines > 0:
-			canvas.saveState()
-			canvas.addLiteral('% textcanvas.drawParagraph()')
-			alignment = style.alignment
-			#is there a bullet?  if so, draw it first
-			offset = style.firstLineIndent - style.leftIndent
-			lim = nLines-1
-
-			if bfrags.kind==0:
-				if alignment == TA_LEFT:
-					dpl = _leftDrawParaLine
-				elif alignment == TA_CENTER:
-					dpl = _centerDrawParaLine
-				elif self.style.alignment == TA_RIGHT:
-					dpl = _rightDrawParaLine
-				elif self.style.alignment == TA_JUSTIFY:
-					dpl = _justifyDrawParaLine
-				f = bfrags
-				cur_y = self.height - f.fontSize - style.spaceBefore
-
-				if self.bulletText <> None:
-					tx2 = canvas.beginText(style.bulletIndent, cur_y)
-					tx2.setFont(style.bulletFontName, style.bulletFontSize)
-					tx2.textOut(self.bulletText)
-					bulletEnd = tx2.getX()
-					offset = max(offset, bulletEnd - style.leftIndent)
-					canvas.drawText(tx2)
-
-				#set up the font etc.
-				canvas._code.append('%s %s %s rg' % (f.textColor.red, f.textColor.green, f.textColor.blue))
-
-				tx = canvas.beginText(cur_x, cur_y)
-
-				#now the font for the rest of the paragraph
-				tx.setFont(f.fontName, f.fontSize, style.leading)
-				dpl( tx, offset, lines[0][0], lines[0][1], nLines==1)
-
-				#now the middle of the paragraph, aligned with the left margin which is our origin.
-				for i in range(1, nLines):
-					dpl( tx, 0, lines[i][0], lines[i][1], i==lim)
-			else:
-				f = lines[0]
-				cur_y = self.height - f.fontSize - style.spaceBefore
-				if alignment == TA_LEFT:
-					dpl = _leftDrawParaLineX
-				elif alignment == TA_CENTER:
-					dpl = _centerDrawParaLineX
-				elif self.style.alignment == TA_RIGHT:
-					dpl = _rightDrawParaLineX
-				elif self.style.alignment == TA_JUSTIFY:
-					dpl = _justifyDrawParaLineX
-
-				if self.bulletText <> None:
-					tx2 = canvas.beginText(style.bulletIndent, cur_y)
-					tx2.setFont(style.bulletFontName, style.bulletFontSize)
-					tx2.textOut(self.bulletText)
-					bulletEnd = tx2.getX()
-					offset = max(offset, bulletEnd - style.leftIndent)
-					canvas.drawText(tx2)
-
-				#set up the font etc.
-				tx = canvas.beginText(cur_x, cur_y)
-				tx.XtraState=ParaFrag()
-				tx.XtraState.textColor=None
-				tx.XtraState.rise=0
-				tx.setLeading(style.leading)
-				dpl( tx, offset, lines[0], nLines==1)
-
-				#now the middle of the paragraph, aligned with the left margin which is our origin.
-				for i in range(1, nLines):
-					f = lines[i]
-					dpl( tx, 0, f, i==lim)
-
-			canvas.drawText(tx)
-			canvas.restoreState()
-
 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!"""
@@ -844,19 +252,6 @@
 
 	def draw(self):
 		pass
-		#
-		#self.canv.drawRect(0, 0, self.width, self.height)
-		#self.canv.drawLine(0, 0, self.width, self.height)
-		#self.canv.drawLine(0, self.height, self.width, 0)
-		#self.text = 'Page Break Object (%d x %d)' % (self.width, self.height)
-		##centre the text
-		#self.canv._currentFont = self.canv.defaultFont
-		#f = Font(size=24,bold=1)
-		#w = self.canv.stringWidth(self.text, f)
-		#x = 0.5 * (self.width - w)
-		#y = 0.33 * (self.height + f.size)
-
-		#self.canv.drawString(self.text, x, y, font=f)
 
 class Macro(Flowable):
 	"""This is not actually drawn (i.e. it has zero height)
@@ -902,10 +297,10 @@
 		#these say where it goes on the page
 		x2 = x1 + width
 		y2 = y1 + height
-		self.leftMargin = x1
-		self.bottomMargin = y1
-		self.rightMargin = x2
-		self.topMargin = y2
+		self.x1 = x1
+		self.y1 = y1
+		self.x2 = x2
+		self.y2 = y2
 
 		#these create some padding.
 		self.leftPadding = 6
@@ -930,7 +325,7 @@
 		or if it is too high for a totally empty frame,
 		to avoid infinite loops"""
 		y = self.y
-		p = self.bottomMargin + self.bottomPadding
+		p = self.y1 + self.bottomPadding
 		w, h = flowable.wrap(self.width, y - p )
 
 		if h > self.height:
@@ -954,10 +349,10 @@
 
 		if self.showBoundary:
 			self.canvas.rect(
-						self.leftMargin,
-						self.bottomMargin,
-						self.rightMargin - self.leftMargin,
-						self.topMargin - self.bottomMargin
+						self.x1,
+						self.y1,
+						self.x2 - self.x1,
+						self.y2 - self.y1
 						)
 
 		while len(drawlist) > 0:
@@ -967,6 +362,7 @@
 			else:
 				#leave it in the list for later
 				break
+
 class Sequencer:
 	"""Something to make it easy to number paragraphs, sections,
 	images and anything else. Usage:
@@ -1115,10 +511,10 @@
 	canvas.drawString(4 * inch, 0.75 * inch, "Page %d" % doc.page)
 	canvas.restoreState()
 
-
-
 def run():
 	objects_to_draw = []
+	from reportlab.lib.styles import ParagraphStyle
+	from reportlab.platypus.paragraph import Paragraph
 
 	#need a style
 	normal = ParagraphStyle('normal')
--- a/reportlab/platypus/paraparser.py	Fri Apr 14 11:28:32 2000 +0000
+++ b/reportlab/platypus/paraparser.py	Fri Apr 14 11:54:57 2000 +0000
@@ -396,4 +396,6 @@
 		for l in _parser.errors:
 			print l
 	else:
-		print l.fontName,l.fontSize,l.textColor,l.bold, l.rise, l.text[:25]
+		print 'ParaStyle', l.fontName,l.fontSize,l.textColor
+		for l in rv:
+			print l.fontName,l.fontSize,l.textColor,l.bold, l.rise, l.text[:25]
--- a/reportlab/platypus/tables.py	Fri Apr 14 11:28:32 2000 +0000
+++ b/reportlab/platypus/tables.py	Fri Apr 14 11:54:57 2000 +0000
@@ -31,9 +31,12 @@
 #
 ###############################################################################
 #	$Log: tables.py,v $
+#	Revision 1.6  2000/04/14 11:54:57  rgbecker
+#	Splitting layout.py
+#
 #	Revision 1.5  2000/04/14 08:56:20  rgbecker
 #	Drawable ==> Flowable
-#
+#	
 #	Revision 1.4  2000/02/17 02:09:05  rgbecker
 #	Docstring & other fixes
 #	
@@ -43,18 +46,19 @@
 #	Revision 1.2  2000/02/15 15:47:09  rgbecker
 #	Added license, __version__ and Logi comment
 #	
-__version__=''' $Id: tables.py,v 1.5 2000/04/14 08:56:20 rgbecker Exp $ '''
+__version__=''' $Id: tables.py,v 1.6 2000/04/14 11:54:57 rgbecker 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.
 """
 from reportlab.platypus import layout
+from reportlab.lib.styles import PropertySet
 import operator
 
 _stringtype = type('')
 
-class CellStyle(layout.PropertySet):
+class CellStyle(PropertySet):
     defaults = {
         'fontname':'Times-Roman',
         'fontsize':10,
--- a/reportlab/platypus/test/testplatypus.py	Fri Apr 14 11:28:32 2000 +0000
+++ b/reportlab/platypus/test/testplatypus.py	Fri Apr 14 11:54:57 2000 +0000
@@ -32,9 +32,12 @@
 #
 ###############################################################################
 #	$Log: testplatypus.py,v $
+#	Revision 1.12  2000/04/14 11:54:57  rgbecker
+#	Splitting layout.py
+#
 #	Revision 1.11  2000/04/14 08:56:20  rgbecker
 #	Drawable ==> Flowable
-#
+#	
 #	Revision 1.10  2000/04/13 17:10:38  rgbecker
 #	minor adjustments
 #	
@@ -62,7 +65,7 @@
 #	Revision 1.2  2000/02/15 15:47:10  rgbecker
 #	Added license, __version__ and Logi comment
 #	
-__version__=''' $Id: testplatypus.py,v 1.11 2000/04/14 08:56:20 rgbecker Exp $ '''
+__version__=''' $Id: testplatypus.py,v 1.12 2000/04/14 11:54:57 rgbecker Exp $ '''
 
 #tests and documents Page Layout API
 __doc__="""This is not obvious so here's a brief explanation.  This module is both
@@ -76,7 +79,9 @@
 import string, copy
 from reportlab.pdfgen import canvas
 from reportlab.platypus import layout, tables
+from reportlab.platypus.paragraph import Paragraph
 from reportlab.lib.units import inch, cm
+from reportlab.lib.styles import PropertySet, getSampleStyleSheet, ParagraphStyle
 
 #################################################################
 #
@@ -127,10 +132,10 @@
 def getCommentary():
     """Returns the story for the commentary - all the paragraphs."""
 
-    styleSheet = layout.getSampleStyleSheet()
+    styleSheet = getSampleStyleSheet()
     
     story = []
-    story.append(layout.Paragraph("""
+    story.append(Paragraph("""
         PLATYPUS User Guide and Test Script
         """, styleSheet['Heading1']))
 
@@ -153,12 +158,12 @@
     """    
 
     for text in getParagraphs(spam):
-        story.append(layout.Paragraph(text, styleSheet['BodyText']))
+        story.append(Paragraph(text, styleSheet['BodyText']))
 
-    story.append(layout.Paragraph("""
+    story.append(Paragraph("""
         What concepts does PLATYPUS deal with?
         """, styleSheet['Heading2']))
-    story.append(layout.Paragraph("""
+    story.append(Paragraph("""
         The central concepts in PLATYPUS are Flowable Objects, Frames, Flow
         Management, Styles and Style Sheets, Paragraphs and Tables.  This is
         best explained in contrast to PDFgen, the layer underneath PLATYPUS.
@@ -169,11 +174,11 @@
         objects and fit them onto the page.
         """, styleSheet['BodyText']))
 
-    story.append(layout.Paragraph("""
+    story.append(Paragraph("""
         How is this document organized?
         """, styleSheet['Heading2']))
 
-    story.append(layout.Paragraph("""
+    story.append(Paragraph("""
         Since this is a test script, we'll just note how it is organized.
         the top of each page contains commentary.  The bottom half contains
         example drawings and graphic elements to whicht he commentary will
@@ -187,7 +192,7 @@
     #     Commentary Page 2
     #######################################################################
     
-    story.append(layout.Paragraph("""
+    story.append(Paragraph("""
         Flowable Objects
         """, styleSheet['Heading2']))
     spam = """
@@ -232,14 +237,14 @@
         can be drawn anywhere on the page (possibly even scaled or rotated).
         """    
     for text in getParagraphs(spam):
-        story.append(layout.Paragraph(text, styleSheet['BodyText']))
+        story.append(Paragraph(text, styleSheet['BodyText']))
 
     story.append(layout.PageBreak())
     #######################################################################
     #     Commentary Page 3
     #######################################################################
 
-    story.append(layout.Paragraph("""
+    story.append(Paragraph("""
         Available Flowable Objects
         """, styleSheet['Heading2']))
 
@@ -247,21 +252,21 @@
 ##
 ##        """    
 ##    for text in getParagraphs(spam):
-##        story.append(layout.Paragraph(text, styleSheet['BodyText']))
+##        story.append(Paragraph(text, styleSheet['BodyText']))
 
-    story.append(layout.Paragraph("""
+    story.append(Paragraph("""
         Platypus comes with a basic set of flowable objects.  Here we list their
         class names and tell you what they do:
         """, styleSheet['BodyText']))
     #we can use the bullet feature to do a definition list
-    story.append(layout.Paragraph("""
+    story.append(Paragraph("""
         This is a contrived object to give an example of a Flowable -
         just a fixed-size box with an X through it and a centred string.""",
             styleSheet['Definition'],
             bulletText='XBox  '  #hack - spot the extra space after
             ))
         
-    story.append(layout.Paragraph("""
+    story.append(Paragraph("""
         This is the basic unit of a document.  Paragraphs can be finely
         tuned and offer a host of properties through their associated
         ParagraphStyle.""",
@@ -269,7 +274,7 @@
             bulletText='Paragraph  '  #hack - spot the extra space after
             ))
     
-    story.append(layout.Paragraph("""
+    story.append(Paragraph("""
         This is used for printing code and other preformatted text.
         There is no wrapping, and line breaks are taken where they occur.
         Many paragraph style properties do not apply.  You may supply
@@ -278,7 +283,7 @@
             styleSheet['Definition'],
             bulletText='Preformatted  '  #hack - spot the extra space after
             ))
-    story.append(layout.Paragraph("""
+    story.append(Paragraph("""
         This is a straight wrapper around an external image file.  By default
         the image will be drawn at a scale of one pixel equals one point, and
         centred in the frame.  You may supply an optional width and height.""",
@@ -286,14 +291,14 @@
             bulletText='Image  '  #hack - spot the extra space after
             ))
         
-    story.append(layout.Paragraph("""
+    story.append(Paragraph("""
         This is a base class for making grids.  It is really just a base for
         TextGrid below.""",
             styleSheet['Definition'],
             bulletText='BaseGrid  '  #hack - spot the extra space after
             ))
 
-    story.append(layout.Paragraph("""
+    story.append(Paragraph("""
         This is a table drawing class descended from BaseGrid.  It is intended to be simpler
         than a full HTML table model yet be able to draw attractive output,
         and behave intelligently when the numbers of rows and columns vary.
@@ -302,20 +307,20 @@
             bulletText='TextGrid  '  #hack - spot the extra space after
             ))
 
-    story.append(layout.Paragraph("""
+    story.append(Paragraph("""
         This is a 'null object' which merely takes up space on the page.
         Use it when you want some extra padding betweene elements.""",
             styleSheet['Definition'],
             bulletText='Spacer  '  #hack - spot the extra space after
             ))
 
-    story.append(layout.Paragraph("""
+    story.append(Paragraph("""
         A PageBreak consumes all the remaining space in a frame.""",
             styleSheet['Definition'],
             bulletText='PageBreak  '  #hack - spot the extra space after
             ))
 
-    story.append(layout.Paragraph("""
+    story.append(Paragraph("""
         This is in progress, but a macro is basically a chunk of Python code to
         be evaluated when it is drawn.  It could do lots of neat things.""",
             styleSheet['Definition'],
@@ -327,20 +332,20 @@
 
 def getExamples():
     """Returns all the example flowable objects"""
-    styleSheet = layout.getSampleStyleSheet()
+    styleSheet = getSampleStyleSheet()
     
     story = []
 
     #make a style with indents and spacing
-    sty = layout.ParagraphStyle('obvious', None)
+    sty = ParagraphStyle('obvious', None)
     sty.leftIndent = 18
     sty.rightIndent = 18
     sty.firstLineIndent = 36
     sty.spaceBefore = 6
     sty.spaceAfter = 6
-    story.append(layout.Paragraph("""Now for some demo stuff - we need some on this page,
+    story.append(Paragraph("""Now for some demo stuff - we need some on this page,
         even before we explain the concepts fully""", styleSheet['BodyText']))
-    p = layout.Paragraph("""
+    p = Paragraph("""
         Platypus is all about fitting objects into frames on the page.  You
         are looking at a fairly simple Platypus paragraph in Debug mode.
         It has some gridlines drawn around it to show the left and right indents,
@@ -353,8 +358,8 @@
     p.debug = 1   #show me the borders
     story.append(p)
 
-    story.append(layout.Paragraph("""Same but with justification .5 extra leading""", styleSheet['BodyText']))
-    p = layout.Paragraph("""
+    story.append(Paragraph("""Same but with justification .5 extra leading""", styleSheet['BodyText']))
+    p = Paragraph("""
         <para align=justify leading=+1><font color=red>Platypus</font> is all about fitting objects into frames on the page.  You
         are looking at a fairly simple Platypus paragraph in Debug mode.
         It has some gridlines drawn around it to show the left and right indents,
@@ -370,7 +375,7 @@
     story.append(layout.XBox(4*inch, 0.75*inch,
             'This is a box with a fixed size'))
 
-    story.append(layout.Paragraph("""
+    story.append(Paragraph("""
         All of this is being drawn within a text frame which was defined
         on the page.  This frame is in 'debug' mode so you can see the border,
         and also see the margins which it reserves.  A frame does not have
@@ -384,7 +389,7 @@
     #     Examples Page 2
     #######################################################################
     
-    story.append(layout.Paragraph("""
+    story.append(Paragraph("""
         Here's the base class for Flowable...
         """, styleSheet['Italic']))
     
@@ -423,27 +428,27 @@
     #     Examples Page 3
     #######################################################################
 
-    story.append(layout.Paragraph(
+    story.append(Paragraph(
                 "Here are some examples of the remaining objects above.",
                 styleSheet['Italic']))
     
-    story.append(layout.Paragraph("This is a bullet point", styleSheet['Bullet'], bulletText='O'))
-    story.append(layout.Paragraph("Another bullet point", styleSheet['Bullet'], bulletText='O'))
+    story.append(Paragraph("This is a bullet point", styleSheet['Bullet'], bulletText='O'))
+    story.append(Paragraph("Another bullet point", styleSheet['Bullet'], bulletText='O'))
     
-    story.append(layout.Paragraph(
+    story.append(Paragraph(
                 "Here is an Image.  For now, these are always centred in the frame.",
                 styleSheet['Italic']))
 
     story.append(layout.Image('pythonpowered.gif'))
 
-##    story.append(layout.Paragraph("""
+##    story.append(Paragraph("""
 ##                Next comes a grid.  class BaseGrid is the ancestor of Grid classes,
 ##                and doesn't do much more than this.  It, too, is centred.""",
 ##                styleSheet['Italic']))
 ##
 ##    story.append(layout.BaseGrid((36,36,36,36),(8,8,8)))
 
-    story.append(layout.Paragraph("""Here is a Table, which takes all kinds of formatting options...""",
+    story.append(Paragraph("""Here is a Table, which takes all kinds of formatting options...""",
                 styleSheet['Italic']))
     story.append(layout.Spacer(0, 12))