[reportlab-users] How are split, wrap, wrapOn supposed to work?
Henning von Bargen
H.vonBargen at t-p.com
Wed Oct 29 12:25:44 EDT 2014
Hi all,
after a long, long time I'm finally trying to make Wordaxe work with
ReportLab again (RL 3.1.8),
mainly because I'm going to use it in a commercial application.
The test case "test1" from the file
c:\wordaxe\trunk\tests\test_platypus_paragraphs.py
runs into an endless loop and I think this could be a bug in RL.
Adding print statements like """print "_listWrapOn", availWidth"""
in several places the ReportLab code (mainly in platypus\flowables.py)
and raising an exception in c:\wordaxe-svn\trunk\rl\NewParagraph.py
in the i_wrap method like this:
...
def iter_widths(max_widths=max_widths):
# an iterator that repeats the last element infinitely
for w in max_widths: yield w
while True: yield w
width_iter = iter_widths()
max_width = width_iter.next()
if max_width < 0:
raise ValueError("Paragraph id %s: Max width is < 0: %s.
Text: %s" % (id(self), max_width, self.text[:200]))
...
I could see this output for the test case:
ImageAndFlowables wrap returning 298.0 123
67246472 wrap 55.0 268435455
65397704 wrap 298.0 696.661417323
65397704 i_wrap 298.0 696.661417323 [298.0, 298.0]
ImageAndFlowables wrap 298.0 673.161417323
ImageAndFlowables _findSplit -3.0 122.2
65388360 wrap -3.0 268435455
65388360 i_wrap -3.0 268435455 [-3.0, -3.0]
E
======================================================================
ERROR: test1 (__main__.ParagraphSplitTestCase)
This makes one long multi-page paragraph.
----------------------------------------------------------------------
Traceback (most recent call last):
File "test_platypus_paragraphs.py", line 317, in test1
doc.multiBuild(story)
File
"c:\Python27\lib\site-packages\reportlab\platypus\doctemplate.py", line
970, in multiBuild
self.build(tempStory, **buildKwds)
File
"c:\Python27\lib\site-packages\reportlab\platypus\doctemplate.py", line
890, in build
self.handle_flowable(flowables)
File
"c:\Python27\lib\site-packages\reportlab\platypus\doctemplate.py", line
773, in handle_flowab
le
if frame.add(f, canv, trySplit=self.allowSplitting):
File "c:\Python27\lib\site-packages\reportlab\platypus\frames.py",
line 161, in _add
w, h = flowable.wrap(aW, h)
File "c:\Python27\lib\site-packages\reportlab\platypus\flowables.py",
line 1195, in wrap
W,H0,self._C0,self._C1 = self._findSplit(canv,self._iW,aH)
File "c:\Python27\lib\site-packages\reportlab\platypus\flowables.py",
line 1266, in _findSplit
w,h = f.wrapOn(canv,availWidth,0xfffffff)
File "c:\Python27\lib\site-packages\reportlab\platypus\flowables.py",
line 121, in wrapOn
w, h = self.wrap(aW,aH)
File "c:\wordaxe-svn\wordaxe\rl\NewParagraph.py", line 536, in wrap
return self.i_wrap(availW, availH, max_widths)
File "c:\wordaxe-svn\wordaxe\rl\NewParagraph.py", line 563, in i_wrap
raise ValueError("Paragraph id %s: Max width is < 0: %s. Text: %s" %
(id(self), max_width, self.
text[:200]))
ValueError: Paragraph id 65388360: Max width is < 0: -3.0. Text: The
CCCC of an integrated one box s
olution for advanced voice and data applications began with the
introduction of the IMACS. The IMACS
200 carries on that tradition with an integrated solution optimi
The long numbers are from id(self), the numbers after the description
are usually availWidth/availHeight
Note: I changed the test data text a bit to see that the story fragment
caused the endless loop:
story.append(Paragraph('Image larger than the frame',h3))
---> story.append(ImageAndFlowables(... <---- causing the loop
It is remarkable that ImageAndFlowables calls _findSplit with a negative
availWidth,
which in turns calls the flowable's wrap method (here: of the WordAxe
Paragraph instance)
with a negative instance:
ImageAndFlowables _findSplit -3.0 122.2
65388360 wrap -3.0 268435455
My gut feeling tells me that this is either a bug in RL or that I am
misunderstanding
something here.
So my main question is:
****************************************
How is a flowable's wrap method supposed to react when availWidth or
availHeight is <= 0?
****************************************
Running into an endless loop (as WordAxe does) is for sure not the best
solution.
I always assumed that wrap is only called after it has been assured that
everything fits.
And if this case is not expected, then it's a bug in ImageAndFlowable,
isn't it?
Furthermore, there are some bits in flowables.py that seem possibly
wrong:
1) In class Image:
def identity(self,maxLen=None):
r = Flowable.identity(self,maxLen)
if r[-4:]=='>...' and isinstance(self.filename,str):
r = "%s filename=%s>" % (r[:-4],self.filename)
return r
Shouldn't isinstance be used with basestr instead of str?
2) In ImageAndFlowables _findSplit method:
if H>availHeight:
from reportlab.platypus.paragraph import Paragraph
aH = availHeight-(H-h)
if isinstance(f,(Paragraph,Preformatted)):
leading = f.style.leading
Using isinstance here doesn't look very pythonish
and at the moment prevents this to work correctly with Wordaxe.
Best regards
Henning von Bargen
More information about the reportlab-users
mailing list