[reportlab-users] patch to do no PageBreak on an otherwise empty page + suggested refactoring of BaseDocTemplate.handle_pageBreak

Massa, Harald Armin chef at ghum.de
Mon Sep 3 04:22:32 EDT 2012


Hello,

the content of the pages within my application is dynamic. Certain
section need to start on a new page.

The obvious platypus solution is to:

story.append(PageBreak())
story.append(HeadOfNewSection())

now it happens that the page right before the new section was filled
up completely, and a new page has just begun.
So the PageBreak() will insert an empty page - which is not wanted.

CondPageBreak(height) does not work, as it is "a page break that only
happens if there is less then (height) available".

My solution: in the subclassing of BaseDocTemplate, I patched the
handle_pageBreak as follows:

def handle_pageBreak(self,slow=None):
'''ignore page break on empty page'''
if self._curPageFlowableCount == 0:
return

if self._pageBreakQuick and not slow:
self.handle_pageEnd()
else:
n = len(self._hanging)
while len(self._hanging)==n:
self.handle_frameEnd()


So, if handle_flowable is called with a PageBreak on an otherwise
empty page (i.e. no flowable there), it is ignored.

Which solves my problem so far, and is hereby published for others
dealing with the same challenge.

DRAWBACK: this will counteract to an empty page that is created on purpose.

So my solution is the following refactoring of BaseDocTemplate:

def handle_flowable(self,flowables):
'''try to handle one flowable from the front of list flowables.'''

#allow document a chance to look at, modify or ignore
#the object(s) about to be processed
self.filterFlowables(flowables)

self.handle_breakBefore(flowables)
self.handle_keepWithNext(flowables)
f = flowables[0]
del flowables[0]
if f is None:
return

if isinstance(f,PageBreak):
# pass the PageBreak object to the handle_pageBreak method
self.handle_pageBreak(page_break_object=f)
self.afterFlowable(f)
elif isinstance(f,ActionFlowable):
f.apply(self)
self.afterFlowable(f)
[...]
#---------------------------

def handle_pageBreak(self,slow=None, page_break_flowable=None):
'''ignore page break on empty page'''

if self._curPageFlowableCount == 0 and
isinstance(page_break_flowable,PageBreakNotOnEmptyPage):
return

if self._pageBreakQuick and not isinstance(
page_break_flowable ,SlowPageBreak):
self.handle_pageEnd()
else:
n = len(self._hanging)
while len(self._hanging)==n:
self.handle_frameEnd()

This allows to plug-in more various pageBreak-Handlers into the system
without to much patching. The "slow"-parameter is kept, so existing
code relying on it will continue to function.

This patch is made available to integrate into reportlab or use by
anyone/ if you need a code contribution agreement, please let me know.

Best wishes,

Harald

--

GHUM GmbH
Harald Armin Massa
Spielberger Straße 49
70435 Stuttgart
0173/9409607

Amtsgericht Stuttgart, HRB 734971


More information about the reportlab-users mailing list