reportlab/platypus/xpreformatted.py
author andy_robinson
Mon, 26 Nov 2001 21:49:01 +0000
changeset 1440 243d35446390
parent 1138 9dd6ee76c791
child 1677 1450177dd19e
permissions -rw-r--r--
Removed 0 from multiBuild stuff prior to further changes; ensured test suite really does run silently when making manuals.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
494
54257447cfe9 Changed to indirect copyright
rgbecker
parents: 473
diff changeset
     1
#copyright ReportLab Inc. 2000
54257447cfe9 Changed to indirect copyright
rgbecker
parents: 473
diff changeset
     2
#see license.txt for license details
54257447cfe9 Changed to indirect copyright
rgbecker
parents: 473
diff changeset
     3
#history http://cvs.sourceforge.net/cgi-bin/cvsweb.cgi/reportlab/platypus/xpreformatted.py?cvsroot=reportlab
1138
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
     4
#$Header: /tmp/reportlab/reportlab/platypus/xpreformatted.py,v 1.14 2001/08/17 10:35:30 dinu_gherman Exp $
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
     5
__version__=''' $Id: xpreformatted.py,v 1.14 2001/08/17 10:35:30 dinu_gherman Exp $ '''
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
     6
439
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
     7
import string
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
     8
from types import StringType, ListType
1138
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
     9
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
    10
from reportlab.lib import PyFontify
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
    11
from paragraph import Paragraph, cleanBlockQuotedText, _handleBulletWidth, \
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
    12
	 ParaLines, _getFragWords, stringWidth, _sameFrag
442
e3eac15cddbd XPreformatted first fixes; now runs
rgbecker
parents: 439
diff changeset
    13
from flowables import _dedenter
439
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
    14
1138
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
    15
439
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
    16
def _getFragLines(frags):
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
    17
	lines = []
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
    18
	cline = []
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
    19
	W = frags[:]
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
    20
	while W != []:
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
    21
		w = W[0]
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
    22
		t = w.text
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
    23
		del W[0]
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
    24
		i = string.find(t,'\n')
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
    25
		if i>=0:
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
    26
			tleft = t[i+1:]
473
e484f898b9cc Fixed copying bug
rgbecker
parents: 468
diff changeset
    27
			cline.append(w.clone(text=t[:i]))
439
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
    28
			lines.append(cline)
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
    29
			cline = []
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
    30
			if tleft!='':
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
    31
				W.insert(0,w.clone(text=tleft))
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
    32
		else:
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
    33
			cline.append(w)
449
1ba0d6fb0f9e XPreformatted fixed empty lines and leading space
rgbecker
parents: 445
diff changeset
    34
	if cline!=[]:
1ba0d6fb0f9e XPreformatted fixed empty lines and leading space
rgbecker
parents: 445
diff changeset
    35
		lines.append(cline)
439
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
    36
	return lines
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
    37
518
5be3fcb26c78 Semantic Name changes
rgbecker
parents: 494
diff changeset
    38
def	_split_blPara(blPara,start,stop):
5be3fcb26c78 Semantic Name changes
rgbecker
parents: 494
diff changeset
    39
	f = blPara.clone()
467
34593cc102de Splitting fixes. Mostly caused by XPreformatted not doing it right.
rgbecker
parents: 465
diff changeset
    40
	for a in ('lines', 'text'):
34593cc102de Splitting fixes. Mostly caused by XPreformatted not doing it right.
rgbecker
parents: 465
diff changeset
    41
		if hasattr(f,a): delattr(f,a)
518
5be3fcb26c78 Semantic Name changes
rgbecker
parents: 494
diff changeset
    42
	f.lines = blPara.lines[start:stop]
467
34593cc102de Splitting fixes. Mostly caused by XPreformatted not doing it right.
rgbecker
parents: 465
diff changeset
    43
	return [f]
34593cc102de Splitting fixes. Mostly caused by XPreformatted not doing it right.
rgbecker
parents: 465
diff changeset
    44
629
0252c3741f7c Commented _countSpaces() and replaced with string.count().
dinu_gherman
parents: 518
diff changeset
    45
# Will be removed shortly.
465
04ff7ff8868a Cleaning up XPreformatted
rgbecker
parents: 464
diff changeset
    46
def _countSpaces(text):
629
0252c3741f7c Commented _countSpaces() and replaced with string.count().
dinu_gherman
parents: 518
diff changeset
    47
	return string.count(text, ' ')
0252c3741f7c Commented _countSpaces() and replaced with string.count().
dinu_gherman
parents: 518
diff changeset
    48
##	i = 0
0252c3741f7c Commented _countSpaces() and replaced with string.count().
dinu_gherman
parents: 518
diff changeset
    49
##	s = 0
0252c3741f7c Commented _countSpaces() and replaced with string.count().
dinu_gherman
parents: 518
diff changeset
    50
##	while 1:
0252c3741f7c Commented _countSpaces() and replaced with string.count().
dinu_gherman
parents: 518
diff changeset
    51
##		j = string.find(text,' ',i)
0252c3741f7c Commented _countSpaces() and replaced with string.count().
dinu_gherman
parents: 518
diff changeset
    52
##		if j<0: return s
0252c3741f7c Commented _countSpaces() and replaced with string.count().
dinu_gherman
parents: 518
diff changeset
    53
##		s = s + 1
0252c3741f7c Commented _countSpaces() and replaced with string.count().
dinu_gherman
parents: 518
diff changeset
    54
##		i = j + 1
465
04ff7ff8868a Cleaning up XPreformatted
rgbecker
parents: 464
diff changeset
    55
04ff7ff8868a Cleaning up XPreformatted
rgbecker
parents: 464
diff changeset
    56
def _getFragWord(frags):
464
15d748bfbf6f Removed space split and readding
rgbecker
parents: 450
diff changeset
    57
	'''	given a fragment list return a list of lists
465
04ff7ff8868a Cleaning up XPreformatted
rgbecker
parents: 464
diff changeset
    58
		[size, spaces, (f00,w00), ..., (f0n,w0n)]
464
15d748bfbf6f Removed space split and readding
rgbecker
parents: 450
diff changeset
    59
		each pair f,w represents a style and some string
15d748bfbf6f Removed space split and readding
rgbecker
parents: 450
diff changeset
    60
	'''
15d748bfbf6f Removed space split and readding
rgbecker
parents: 450
diff changeset
    61
	W = []
15d748bfbf6f Removed space split and readding
rgbecker
parents: 450
diff changeset
    62
	n = 0
465
04ff7ff8868a Cleaning up XPreformatted
rgbecker
parents: 464
diff changeset
    63
	s = 0
464
15d748bfbf6f Removed space split and readding
rgbecker
parents: 450
diff changeset
    64
	for f in frags:
15d748bfbf6f Removed space split and readding
rgbecker
parents: 450
diff changeset
    65
		text = f.text[:]
15d748bfbf6f Removed space split and readding
rgbecker
parents: 450
diff changeset
    66
		W.append((f,text))
15d748bfbf6f Removed space split and readding
rgbecker
parents: 450
diff changeset
    67
		n = n + stringWidth(text, f.fontName, f.fontSize)
629
0252c3741f7c Commented _countSpaces() and replaced with string.count().
dinu_gherman
parents: 518
diff changeset
    68
0252c3741f7c Commented _countSpaces() and replaced with string.count().
dinu_gherman
parents: 518
diff changeset
    69
		#s = s + _countSpaces(text)
0252c3741f7c Commented _countSpaces() and replaced with string.count().
dinu_gherman
parents: 518
diff changeset
    70
		s = s + string.count(text, ' ') # much faster for many blanks
0252c3741f7c Commented _countSpaces() and replaced with string.count().
dinu_gherman
parents: 518
diff changeset
    71
		
464
15d748bfbf6f Removed space split and readding
rgbecker
parents: 450
diff changeset
    72
		#del f.text	# we can't do this until we sort out splitting
15d748bfbf6f Removed space split and readding
rgbecker
parents: 450
diff changeset
    73
					# of paragraphs
465
04ff7ff8868a Cleaning up XPreformatted
rgbecker
parents: 464
diff changeset
    74
	return n, s, W
464
15d748bfbf6f Removed space split and readding
rgbecker
parents: 450
diff changeset
    75
1138
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
    76
439
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
    77
class XPreformatted(Paragraph):
442
e3eac15cddbd XPreformatted first fixes; now runs
rgbecker
parents: 439
diff changeset
    78
	def __init__(self, text, style, bulletText = None, dedent=0, frags=None):
e3eac15cddbd XPreformatted first fixes; now runs
rgbecker
parents: 439
diff changeset
    79
		cleaner = lambda text, dedent=dedent: string.join(_dedenter(text,dedent),'\n')
e3eac15cddbd XPreformatted first fixes; now runs
rgbecker
parents: 439
diff changeset
    80
		self._setup(text, style, bulletText, frags, cleaner)
439
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
    81
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
    82
	def breakLines(self, width):
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
    83
		"""
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
    84
		Returns a broken line structure. There are two cases
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
    85
		
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
    86
		A) For the simple case of a single formatting input fragment the output is
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
    87
			A fragment specifier with
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
    88
				kind = 0
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
    89
				fontName, fontSize, leading, textColor
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
    90
				lines=	A list of lines
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
    91
						Each line has two items.
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
    92
						1) unused width in points
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
    93
						2) a list of words
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
    94
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
    95
		B) When there is more than one input formatting fragment the out put is
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
    96
			A fragment specifier with
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
    97
				kind = 1
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
    98
				lines=	A list of fragments each having fields
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
    99
							extraspace (needed for justified)
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   100
							fontSize
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   101
							words=word list
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   102
								each word is itself a fragment with
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   103
								various settings
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   104
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   105
		This structure can be used to easily draw paragraphs with the various alignments.
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   106
		You can supply either a single width or a list of widths; the latter will have its
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   107
		last item repeated until necessary. A 2-element list is useful when there is a
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   108
		different first line indent; a longer list could be created to facilitate custom wraps
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   109
		around irregular objects."""
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   110
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   111
		if type(width) <> ListType: maxWidths = [width]
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   112
		else: maxWidths = width
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   113
		lines = []
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   114
		lineno = 0
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   115
		maxWidth = maxWidths[lineno]
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   116
		style = self.style
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   117
		fFontSize = float(style.fontSize)
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   118
		requiredWidth = 0
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   119
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   120
		#for bullets, work out width and ensure we wrap the right amount onto line one
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   121
		_handleBulletWidth(self.bulletText,style,maxWidths)
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   122
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   123
		self.height = 0
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   124
		frags = self.frags
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   125
		nFrags= len(frags)
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   126
		if nFrags==1:
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   127
			f = frags[0]
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   128
			if hasattr(f,'text'):
467
34593cc102de Splitting fixes. Mostly caused by XPreformatted not doing it right.
rgbecker
parents: 465
diff changeset
   129
				fontSize = f.fontSize
34593cc102de Splitting fixes. Mostly caused by XPreformatted not doing it right.
rgbecker
parents: 465
diff changeset
   130
				fontName = f.fontName
34593cc102de Splitting fixes. Mostly caused by XPreformatted not doing it right.
rgbecker
parents: 465
diff changeset
   131
				kind = 0
439
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   132
				L=string.split(f.text, '\n')
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   133
				for l in L:
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   134
					currentWidth = stringWidth(l,fontName,fontSize)
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   135
					requiredWidth = max(currentWidth,requiredWidth)
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   136
					extraSpace = maxWidth-currentWidth
467
34593cc102de Splitting fixes. Mostly caused by XPreformatted not doing it right.
rgbecker
parents: 465
diff changeset
   137
					lines.append((extraSpace,string.split(l,' '),currentWidth))
439
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   138
					lineno = lineno+1
442
e3eac15cddbd XPreformatted first fixes; now runs
rgbecker
parents: 439
diff changeset
   139
					maxWidth = lineno<len(maxWidths) and maxWidths[lineno] or maxWidths[-1]
439
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   140
			else:
467
34593cc102de Splitting fixes. Mostly caused by XPreformatted not doing it right.
rgbecker
parents: 465
diff changeset
   141
				kind = f.kind
34593cc102de Splitting fixes. Mostly caused by XPreformatted not doing it right.
rgbecker
parents: 465
diff changeset
   142
				lines = f.lines
34593cc102de Splitting fixes. Mostly caused by XPreformatted not doing it right.
rgbecker
parents: 465
diff changeset
   143
				for L in lines:
34593cc102de Splitting fixes. Mostly caused by XPreformatted not doing it right.
rgbecker
parents: 465
diff changeset
   144
					if kind==0:
34593cc102de Splitting fixes. Mostly caused by XPreformatted not doing it right.
rgbecker
parents: 465
diff changeset
   145
						currentWidth = L[2]
34593cc102de Splitting fixes. Mostly caused by XPreformatted not doing it right.
rgbecker
parents: 465
diff changeset
   146
					else:
34593cc102de Splitting fixes. Mostly caused by XPreformatted not doing it right.
rgbecker
parents: 465
diff changeset
   147
						currentWidth = L.currentWidth
34593cc102de Splitting fixes. Mostly caused by XPreformatted not doing it right.
rgbecker
parents: 465
diff changeset
   148
					requiredWidth = max(currentWidth,requiredWidth)
439
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   149
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   150
			self.width = max(self.width,requiredWidth)
467
34593cc102de Splitting fixes. Mostly caused by XPreformatted not doing it right.
rgbecker
parents: 465
diff changeset
   151
			return f.clone(kind=kind, lines=lines)
439
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   152
		elif nFrags<=0:
518
5be3fcb26c78 Semantic Name changes
rgbecker
parents: 494
diff changeset
   153
			return ParaLines(kind=0, fontSize=style.fontSize, fontName=style.fontName,
439
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   154
							textColor=style.textColor, lines=[])
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   155
		else:
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   156
			for L in _getFragLines(frags):
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   157
				maxSize = 0
465
04ff7ff8868a Cleaning up XPreformatted
rgbecker
parents: 464
diff changeset
   158
				currentWidth, n, w = _getFragWord(L)
04ff7ff8868a Cleaning up XPreformatted
rgbecker
parents: 464
diff changeset
   159
				f = w[0][0]
04ff7ff8868a Cleaning up XPreformatted
rgbecker
parents: 464
diff changeset
   160
				maxSize = max(maxSize,f.fontSize)
04ff7ff8868a Cleaning up XPreformatted
rgbecker
parents: 464
diff changeset
   161
				words = [f.clone()]
04ff7ff8868a Cleaning up XPreformatted
rgbecker
parents: 464
diff changeset
   162
				words[-1].text = w[0][1]
04ff7ff8868a Cleaning up XPreformatted
rgbecker
parents: 464
diff changeset
   163
				for i in w[1:]:
04ff7ff8868a Cleaning up XPreformatted
rgbecker
parents: 464
diff changeset
   164
					f = i[0].clone()
04ff7ff8868a Cleaning up XPreformatted
rgbecker
parents: 464
diff changeset
   165
					f.text=i[1]
04ff7ff8868a Cleaning up XPreformatted
rgbecker
parents: 464
diff changeset
   166
					words.append(f)
439
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   167
					maxSize = max(maxSize,f.fontSize)
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   168
442
e3eac15cddbd XPreformatted first fixes; now runs
rgbecker
parents: 439
diff changeset
   169
				lineno = lineno+1
e3eac15cddbd XPreformatted first fixes; now runs
rgbecker
parents: 439
diff changeset
   170
				maxWidth = lineno<len(maxWidths) and maxWidths[lineno] or maxWidths[-1]
439
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   171
				requiredWidth = max(currentWidth,requiredWidth)
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   172
				extraSpace = maxWidth - currentWidth
518
5be3fcb26c78 Semantic Name changes
rgbecker
parents: 494
diff changeset
   173
				lines.append(ParaLines(extraSpace=extraSpace,wordCount=n, words=words, fontSize=maxSize, currentWidth=currentWidth))
439
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   174
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   175
			self.width = max(self.width,requiredWidth)
518
5be3fcb26c78 Semantic Name changes
rgbecker
parents: 494
diff changeset
   176
			return ParaLines(kind=1, lines=lines)
439
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   177
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   178
		return lines
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   179
467
34593cc102de Splitting fixes. Mostly caused by XPreformatted not doing it right.
rgbecker
parents: 465
diff changeset
   180
	# we need this her to get the right splitter
518
5be3fcb26c78 Semantic Name changes
rgbecker
parents: 494
diff changeset
   181
	def _get_split_blParaFunc(self):
5be3fcb26c78 Semantic Name changes
rgbecker
parents: 494
diff changeset
   182
		return _split_blPara
467
34593cc102de Splitting fixes. Mostly caused by XPreformatted not doing it right.
rgbecker
parents: 465
diff changeset
   183
1138
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
   184
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
   185
class PythonPreformatted(XPreformatted):
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
   186
	"""Used for syntax-colored Python code, otherwise like XPreformatted.  
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
   187
	"""
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
   188
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
   189
	formats = {
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
   190
		'rest'       : ('', ''),
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
   191
		'comment'    : ('<font color="green">', '</font>'),
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
   192
		'keyword'    : ('<font color="blue"><b>', '</b></font>'),
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
   193
		'parameter'  : ('<font color="black">', '</font>'),
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
   194
		'identifier' : ('<font color="red">', '</font>'),
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
   195
		'string'     : ('<font color="gray">', '</font>') }
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
   196
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
   197
	def __init__(self, text, style, bulletText = None, dedent=0, frags=None):
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
   198
		if text:
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
   199
			text = self.fontify(self.escapeHtml(text))
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
   200
		apply(XPreformatted.__init__,
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
   201
			  (self, text, style),
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
   202
			  {'bulletText':bulletText, 'dedent':dedent, 'frags':frags})
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
   203
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
   204
	def escapeHtml(self, text):
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
   205
		s = string.replace(text, '&', '&amp;')
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
   206
		s = string.replace(s, '<', '&lt;')
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
   207
		s = string.replace(s, '>', '&gt;')
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
   208
		return s
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
   209
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
   210
	def fontify(self, code):
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
   211
		"Return a fontified version of some Python code."
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
   212
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
   213
		if code[0] == '\n':
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
   214
			code = code[1:]
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
   215
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
   216
		tags = PyFontify.fontify(code)
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
   217
		fontifiedCode = ''
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
   218
		pos = 0
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
   219
		for k, i, j, dummy in tags:
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
   220
			fontifiedCode = fontifiedCode + code[pos:i]
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
   221
			s, e = self.formats[k]
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
   222
			fontifiedCode = fontifiedCode + s + code[i:j] + e
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
   223
			pos = j
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
   224
			
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
   225
		fontifiedCode = fontifiedCode + code[pos:]
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
   226
		
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
   227
		return fontifiedCode
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
   228
	
9dd6ee76c791 Added PythonPreformatted class.
dinu_gherman
parents: 629
diff changeset
   229
439
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   230
if __name__=='__main__':	#NORUNTESTS
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   231
	def dumpXPreformattedLines(P):
473
e484f898b9cc Fixed copying bug
rgbecker
parents: 468
diff changeset
   232
		print '\n############dumpXPreforemattedLines(%s)' % str(P)
518
5be3fcb26c78 Semantic Name changes
rgbecker
parents: 494
diff changeset
   233
		lines = P.blPara.lines
439
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   234
		n =len(lines)
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   235
		for l in range(n):
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   236
			line = lines[l]
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   237
			words = line.words
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   238
			nwords = len(words)
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   239
			print 'line%d: %d(%d)\n  ' % (l,nwords,line.wordCount),
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   240
			for w in range(nwords):
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   241
				print "%d:'%s'"%(w,words[w].text),
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   242
			print
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   243
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   244
	def dumpXPreformattedFrags(P):
473
e484f898b9cc Fixed copying bug
rgbecker
parents: 468
diff changeset
   245
		print '\n############dumpXPreforemattedFrags(%s)' % str(P)
439
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   246
		frags = P.frags
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   247
		n =len(frags)
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   248
		for l in range(n):
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   249
			print "frag%d: '%s'" % (l, frags[l].text)
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   250
	
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   251
		l = 0
449
1ba0d6fb0f9e XPreformatted fixed empty lines and leading space
rgbecker
parents: 445
diff changeset
   252
		for L in _getFragLines(frags):
1ba0d6fb0f9e XPreformatted fixed empty lines and leading space
rgbecker
parents: 445
diff changeset
   253
			n=0
1ba0d6fb0f9e XPreformatted fixed empty lines and leading space
rgbecker
parents: 445
diff changeset
   254
			for W in _getFragWords(L):
1ba0d6fb0f9e XPreformatted fixed empty lines and leading space
rgbecker
parents: 445
diff changeset
   255
				print "frag%d.%d: size=%d" % (l, n, W[0]),
1ba0d6fb0f9e XPreformatted fixed empty lines and leading space
rgbecker
parents: 445
diff changeset
   256
				n = n + 1
1ba0d6fb0f9e XPreformatted fixed empty lines and leading space
rgbecker
parents: 445
diff changeset
   257
				for w in W[1:]:
1ba0d6fb0f9e XPreformatted fixed empty lines and leading space
rgbecker
parents: 445
diff changeset
   258
					print "'%s'" % w[1],
1ba0d6fb0f9e XPreformatted fixed empty lines and leading space
rgbecker
parents: 445
diff changeset
   259
				print
439
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   260
			l = l + 1
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   261
473
e484f898b9cc Fixed copying bug
rgbecker
parents: 468
diff changeset
   262
	def try_it(text,style,dedent,aW,aH):
449
1ba0d6fb0f9e XPreformatted fixed empty lines and leading space
rgbecker
parents: 445
diff changeset
   263
		P=XPreformatted(text,style,dedent=dedent)
1ba0d6fb0f9e XPreformatted fixed empty lines and leading space
rgbecker
parents: 445
diff changeset
   264
		dumpXPreformattedFrags(P)
1ba0d6fb0f9e XPreformatted fixed empty lines and leading space
rgbecker
parents: 445
diff changeset
   265
		w,h = P.wrap(aW, aH)
1ba0d6fb0f9e XPreformatted fixed empty lines and leading space
rgbecker
parents: 445
diff changeset
   266
		dumpXPreformattedLines(P)
1ba0d6fb0f9e XPreformatted fixed empty lines and leading space
rgbecker
parents: 445
diff changeset
   267
		S = P.split(aW,aH)
473
e484f898b9cc Fixed copying bug
rgbecker
parents: 468
diff changeset
   268
		dumpXPreformattedLines(P)
449
1ba0d6fb0f9e XPreformatted fixed empty lines and leading space
rgbecker
parents: 445
diff changeset
   269
		for s in S:
1ba0d6fb0f9e XPreformatted fixed empty lines and leading space
rgbecker
parents: 445
diff changeset
   270
			s.wrap(aW,aH)
1ba0d6fb0f9e XPreformatted fixed empty lines and leading space
rgbecker
parents: 445
diff changeset
   271
			dumpXPreformattedLines(s)
1ba0d6fb0f9e XPreformatted fixed empty lines and leading space
rgbecker
parents: 445
diff changeset
   272
			aH = 500
1ba0d6fb0f9e XPreformatted fixed empty lines and leading space
rgbecker
parents: 445
diff changeset
   273
439
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   274
	from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   275
	styleSheet = getSampleStyleSheet()
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   276
	B = styleSheet['BodyText']
467
34593cc102de Splitting fixes. Mostly caused by XPreformatted not doing it right.
rgbecker
parents: 465
diff changeset
   277
	DTstyle = ParagraphStyle("discussiontext", parent=B)
34593cc102de Splitting fixes. Mostly caused by XPreformatted not doing it right.
rgbecker
parents: 465
diff changeset
   278
	DTstyle.fontName= 'Helvetica'
473
e484f898b9cc Fixed copying bug
rgbecker
parents: 468
diff changeset
   279
	for (text,dedent,style, aW, aH, active) in [('''
445
8b64b9812ca6 Fixes to _dedenter
rgbecker
parents: 442
diff changeset
   280
8b64b9812ca6 Fixes to _dedenter
rgbecker
parents: 442
diff changeset
   281
8b64b9812ca6 Fixes to _dedenter
rgbecker
parents: 442
diff changeset
   282
The <font name=courier color=green>CMYK</font> or subtractive
8b64b9812ca6 Fixes to _dedenter
rgbecker
parents: 442
diff changeset
   283
8b64b9812ca6 Fixes to _dedenter
rgbecker
parents: 442
diff changeset
   284
method follows the way a printer
439
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   285
mixes three pigments (cyan, magenta, and yellow) to form colors.
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   286
Because mixing chemicals is more difficult than combining light there
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   287
is a fourth parameter for darkness.  For example a chemical
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   288
combination of the <font name=courier color=green>CMY</font> pigments generally never makes a perfect
445
8b64b9812ca6 Fixes to _dedenter
rgbecker
parents: 442
diff changeset
   289
439
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   290
black -- instead producing a muddy color -- so, to get black printers
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   291
don't use the <font name=courier color=green>CMY</font> pigments but use a direct black ink.  Because
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   292
<font name=courier color=green>CMYK</font> maps more directly to the way printer hardware works it may
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   293
be the case that &amp;| &amp; | colors specified in <font name=courier color=green>CMYK</font> will provide better fidelity
428c55ed2276 Initial semi working version
rgbecker
parents:
diff changeset
   294
and better control when printed.
445
8b64b9812ca6 Fixes to _dedenter
rgbecker
parents: 442
diff changeset
   295
8b64b9812ca6 Fixes to _dedenter
rgbecker
parents: 442
diff changeset
   296
473
e484f898b9cc Fixed copying bug
rgbecker
parents: 468
diff changeset
   297
''',0,DTstyle, 456.0, 42.8, 0),
449
1ba0d6fb0f9e XPreformatted fixed empty lines and leading space
rgbecker
parents: 445
diff changeset
   298
('''
1ba0d6fb0f9e XPreformatted fixed empty lines and leading space
rgbecker
parents: 445
diff changeset
   299
1ba0d6fb0f9e XPreformatted fixed empty lines and leading space
rgbecker
parents: 445
diff changeset
   300
   This is a non rearranging form of the <b>Paragraph</b> class;
1ba0d6fb0f9e XPreformatted fixed empty lines and leading space
rgbecker
parents: 445
diff changeset
   301
   <b><font color=red>XML</font></b> tags are allowed in <i>text</i> and have the same
450
37919675ea28 Further tweaks of XPreformatted
rgbecker
parents: 449
diff changeset
   302
449
1ba0d6fb0f9e XPreformatted fixed empty lines and leading space
rgbecker
parents: 445
diff changeset
   303
      meanings as for the <b>Paragraph</b> class.
1ba0d6fb0f9e XPreformatted fixed empty lines and leading space
rgbecker
parents: 445
diff changeset
   304
   As for <b>Preformatted</b>, if dedent is non zero <font color=red size=+1>dedent</font>
1ba0d6fb0f9e XPreformatted fixed empty lines and leading space
rgbecker
parents: 445
diff changeset
   305
       common leading spaces will be removed from the
1ba0d6fb0f9e XPreformatted fixed empty lines and leading space
rgbecker
parents: 445
diff changeset
   306
   front of each line.
1ba0d6fb0f9e XPreformatted fixed empty lines and leading space
rgbecker
parents: 445
diff changeset
   307
473
e484f898b9cc Fixed copying bug
rgbecker
parents: 468
diff changeset
   308
''',3, DTstyle, 456.0, 42.8, 0),
e484f898b9cc Fixed copying bug
rgbecker
parents: 468
diff changeset
   309
("""\
e484f898b9cc Fixed copying bug
rgbecker
parents: 468
diff changeset
   310
    <font color=blue>class </font><font color=red>FastXMLParser</font>:
e484f898b9cc Fixed copying bug
rgbecker
parents: 468
diff changeset
   311
        # Nonsense method
e484f898b9cc Fixed copying bug
rgbecker
parents: 468
diff changeset
   312
        def nonsense(self):
e484f898b9cc Fixed copying bug
rgbecker
parents: 468
diff changeset
   313
            self.foo = 'bar'
e484f898b9cc Fixed copying bug
rgbecker
parents: 468
diff changeset
   314
""",0, styleSheet['Code'], 456.0, 4.8, 1),
467
34593cc102de Splitting fixes. Mostly caused by XPreformatted not doing it right.
rgbecker
parents: 465
diff changeset
   315
]:
473
e484f898b9cc Fixed copying bug
rgbecker
parents: 468
diff changeset
   316
		if active: try_it(text,style,dedent,aW,aH)