--- a/reportlab/platypus/doctemplate.py Fri Jul 21 08:48:41 2006 +0000
+++ b/reportlab/platypus/doctemplate.py Fri Jul 21 12:44:40 2006 +0000
@@ -586,7 +586,7 @@
n = len(flowables)
while i<n and flowables[i].getKeepWithNext(): i += 1
if i:
- if not getattr(flowables[i],'locChanger',None): i += 1
+ if i<n and not getattr(flowables[i],'locChanger',None): i += 1
K = KeepTogether(flowables[:i])
for f in K._content:
f.keepWithNext = 0
--- a/reportlab/platypus/paragraph.py Fri Jul 21 08:48:41 2006 +0000
+++ b/reportlab/platypus/paragraph.py Fri Jul 21 12:44:40 2006 +0000
@@ -212,7 +212,8 @@
#if you modify this you need to modify _rl_accel RGB
def _sameFrag(f,g):
'returns 1 if two ParaFrags map out the same'
- if hasattr(f,'cbDefn') or hasattr(g,'cbDefn'): return 0
+ if (hasattr(f,'cbDefn') or hasattr(g,'cbDefn')
+ or hasattr(f,'lineBreak') or hasattr(g,'lineBreak')): return 0
for a in ('fontName', 'fontSize', 'textColor', 'rise', 'underline', 'strike', 'link'):
if getattr(f,a)!=getattr(g,a): return 0
return 1
@@ -257,10 +258,14 @@
n = 0
elif hasattr(f,'cbDefn'):
W.append((f,''))
- elif getattr(f, 'lineBreak', False) == True:
+ elif hasattr(f, 'lineBreak'):
#pass the frag through. The line breaker will scan for it.
- W.append((f,''))
-
+ if W!=[]:
+ W.insert(0,n)
+ R.append(W)
+ W = []
+ n = 0
+ R.append([0,(f,'')])
if W!=[]:
W.insert(0,n)
@@ -638,7 +643,7 @@
#this underscores my feeling that Unicode throughout would be easier!
wordWidth = stringWidth(word, fontName, fontSize, self.encoding)
newWidth = currentWidth + spaceWidth + wordWidth
- if newWidth <= maxWidth or len(cLine) == 0:
+ if newWidth <= maxWidth or len(cLine) == 0:
# fit one more on this line
cLine.append(word)
currentWidth = newWidth
@@ -670,6 +675,7 @@
return self.blPara
n = 0
nSp = 0
+ lineBreakPrev = False
for w in _getFragWords(frags):
spaceWidth = stringWidth(' ',w[-1][0].fontName, w[-1][0].fontSize)
@@ -684,9 +690,14 @@
newWidth = currentWidth + spaceWidth + wordWidth
else:
newWidth = currentWidth
- #if (not getattr(f, 'lineBreak','False')) and (newWidth<=maxWidth or n==0):
- if newWidth<=maxWidth or n==0:
- # fit one more word on this line
+
+ #text to see if this frag is a line break. If it is and we will only act on it
+ #if the current width is non-negative or the previous thing was a deliberate lineBreak
+ lineBreak = hasattr(f,'lineBreak')
+ endLine = (newWidth>maxWidth and n>0) or (lineBreak and (currentWidth>0 or lineBreakPrev))
+ if not endLine:
+ lineBreakPrev = lineBreak
+ if lineBreak: continue #throw it away
n += 1
maxSize = max(maxSize,f.fontSize)
nText = w[1][1]
@@ -718,6 +729,11 @@
currentWidth = newWidth
else: #either it won't fit, or it's a lineBreak tag
+ if lineBreak and not len(words):
+ g = f.clone()
+ del g.lineBreak
+ words.append(g)
+
if currentWidth>self.width: self.width = currentWidth
#end of line
lines.append(FragLine(extraSpace=(maxWidth - currentWidth),wordCount=n,
@@ -729,6 +745,12 @@
maxWidth = maxWidths[lineno]
except IndexError:
maxWidth = maxWidths[-1] # use the last one
+
+ lineBreakPrev = lineBreak
+ if lineBreak:
+ n = 0
+ continue
+
currentWidth = wordWidth
n = 1
maxSize = f.fontSize
--- a/reportlab/platypus/paraparser.py Fri Jul 21 08:48:41 2006 +0000
+++ b/reportlab/platypus/paraparser.py Fri Jul 21 12:44:40 2006 +0000
@@ -465,7 +465,7 @@
v = '\0'
else:
v = None
- if attr:
+ if attr:
self._syntax_error('<unichar/> invalid attribute %s' % attr.keys()[0])
if v is not None:
@@ -483,12 +483,14 @@
def start_br(self, attr):
#just do the trick to make sure there is no content
- self._push(_selfClosingTag='br', lineBreak=True, text='')
+ self._push(_selfClosingTag='br',lineBreak=True,text='')
def end_br(self):
- frag = self._pop(_selfClosingTag='br', lineBreak=True)
- self.fragList.append(frag)
-
+ frag = self._stack[-1]
+ assert frag._selfClosingTag=='br' and frag.lineBreak,'Parser failure in <br/>'
+ del frag._selfClosingTag
+ self.handle_data('')
+ self._pop()
def _initial_frag(self,attr,attrMap,bullet=0):
style = self._style
@@ -760,7 +762,7 @@
if bFragList:
for frag in bFragList:
frag.text = unicode(frag.text, self._enc)
-
+
return style, fragList, bFragList
def _tt_parse(self,tt):
@@ -917,4 +919,4 @@
check_text('''Here comes <font face="Courier" size="3cm">Courier 3cm</font> and normal again.''')
#AR 14-Jul-2006: test <br/> tag
check_text('''Before the break <br/>the middle line <br/> and the last line.''')
-
\ No newline at end of file
+
--- a/reportlab/test/test_platypus_breaking.py Fri Jul 21 08:48:41 2006 +0000
+++ b/reportlab/test/test_platypus_breaking.py Fri Jul 21 12:44:40 2006 +0000
@@ -49,11 +49,27 @@
self.addPageTemplates(template)
+_text1='''Furthermore, the fundamental error of regarding functional notions as
+categorial delimits a general convention regarding the forms of the
+grammar. I suggested that these results would follow from the
+assumption that the descriptive power of the base component may remedy
+and, at the same time, eliminate a descriptive fact. Thus a subset of
+English sentences interesting on quite independent grounds raises
+serious doubts about the ultimate standard that determines the accuracy
+of any proposed grammar. Of course, the natural general principle that
+will subsume this case can be defined in such a way as to impose the
+strong generative capacity of the theory. By combining adjunctions and
+certain deformations, the descriptive power of the base component is not
+subject to the levels of acceptability from fairly high (e.g. (99a)) to
+virtual gibberish (e.g. (98d)).
+'''
def _test0(self):
"This makes one long multi-page paragraph."
# Build story.
story = []
+ a = story.append
+
styleSheet = getSampleStyleSheet()
h1 = styleSheet['Heading1']
@@ -69,27 +85,38 @@
h3.keepWithNext = 1
bt = styleSheet['BodyText']
-
- story.append(Paragraph("""
+ a(Paragraph("""
Subsequent pages test pageBreakBefore, frameBreakBefore and
keepTogether attributes. Generated at %s. The number in brackets
at the end of each paragraph is its position in the story. (%d)""" % (
time.ctime(time.time()), len(story)), bt))
for i in range(10):
- story.append(Paragraph('Heading 1 always starts a new page (%d)' % len(story), h1))
+ a(Paragraph('Heading 1 always starts a new page (%d)' % len(story), h1))
for j in range(3):
- story.append(Paragraph('Heading1 paragraphs should always'
+ a(Paragraph('Heading1 paragraphs should always'
'have a page break before. Heading 2 on the other hand'
'should always have a FRAME break before (%d)' % len(story), bt))
- story.append(Paragraph('Heading 2 always starts a new frame (%d)' % len(story), h2))
- story.append(Paragraph('Heading1 paragraphs should always'
+ a(Paragraph('Heading 2 always starts a new frame (%d)' % len(story), h2))
+ a(Paragraph('Heading1 paragraphs should always'
'have a page break before. Heading 2 on the other hand'
'should always have a FRAME break before (%d)' % len(story), bt))
for j in range(3):
- story.append(Paragraph(randomText(theme=PYTHON, sentences=2)+' (%d)' % len(story), bt))
- story.append(Paragraph('I should never be at the bottom of a frame (%d)' % len(story), h3))
- story.append(Paragraph(randomText(theme=PYTHON, sentences=1)+' (%d)' % len(story), bt))
+ a(Paragraph(randomText(theme=PYTHON, sentences=2)+' (%d)' % len(story), bt))
+ a(Paragraph('I should never be at the bottom of a frame (%d)' % len(story), h3))
+ a(Paragraph(randomText(theme=PYTHON, sentences=1)+' (%d)' % len(story), bt))
+
+ a(Paragraph('Now we do <br/> tests', h1))
+ a(Paragraph('First off no br tags',h3))
+ a(Paragraph(_text1,bt))
+ a(Paragraph("<br/> after 'the' in line 4",h3))
+ a(Paragraph(_text1.replace('forms of the','forms of the<br/>',1),bt))
+ a(Paragraph("2*<br/> after 'the' in line 4",h3))
+ a(Paragraph(_text1.replace('forms of the','forms of the<br/><br/>',1),bt))
+ a(Paragraph("<br/> after 'I suggested ' in line 5",h3))
+ a(Paragraph(_text1.replace('I suggested ','I suggested<br/>',1),bt))
+ a(Paragraph("2*<br/> after 'I suggested ' in line 5",h3))
+ a(Paragraph(_text1.replace('I suggested ','I suggested<br/><br/>',1),bt))
doc = MyDocTemplate(outputfile('test_platypus_breaking.pdf'))
doc.multiBuild(story)
--- a/reportlab/test/test_platypus_paraparser.py Fri Jul 21 08:48:41 2006 +0000
+++ b/reportlab/test/test_platypus_paraparser.py Fri Jul 21 12:44:40 2006 +0000
@@ -83,10 +83,8 @@
def testBr(self):
txt = u"Hello <br/> World"
fragList = ParaParser().parse(txt, self.style)[1]
- print fragList
-## self.assertEquals(map(lambda x:x.text, fragList), [u'Hello ',u'Bold',u' World'])
-## self.assertEquals(fragList[1].fontName, 'Times-Bold')
-
+ self.assertEquals(map(lambda x:x.text, fragList), [u'Hello ',u'',u' World'])
+ self.assertEquals(fragList[1].lineBreak, True)
def makeSuite():
return makeSuiteForClasses(ParaParserTestCase)