[reportlab-users] question about keepWithNext and multibuild
adam hyde
adam at flossmanuals.net
Tue Sep 23 13:47:03 EDT 2008
goodness...it appears to work :)
I patched reportlab 2.1 and it looks good. I will run some more tests
today and tomorrow and let confirm the situation, but from what I see
now it is holding the keepWithNext while building the TOC. Fantastic!
Many thanks for all your help!
adam
On Tue, 2008-09-23 at 18:03 +0100, Robin Becker wrote:
> adam hyde wrote:
> >........
> > So we are really needing to build a TOC without multipass. We just pick
> > up on h1 headings using Pisa as this is the only depth required in a
> > book TOC for our purposes. If anyone has a nice snippet for producing a
> > TOC without multipass we would very much appreciate it.
> >
> > adam
> .........
>
> At the moment the keepTogether style is handled thusly;
>
> in the main loop of the doctemplate build process at the start of the flowable
> handling the head of the list is examined for flowables with keepWithNext style.
> If any are found these are bundled together and replaced by a single
> KeepTogether flowable; to avoid doing this recursively we force the keepWithNext
> value for each flowable to be zero.
>
> KeepTogether has just enough intelligence to try and ensure its contents stay on
> a single page and when wrapped it always fails first time inorder to allow the
> split method a chance to force a frame throw.
>
> Even though we've messed about with the current passed story quite a bit the
> main problem is that we changed the keepWithNext attribute on each flowable we
> bundled together. The multiBuild method is careful to keep the original story
> list intact, but we have forgotten that flowables are mutable (in this case a
> structural property of the flowable was changed).
>
> It should be possible to just remember the flowables which have been modified by
> the handle_keepWithNext method and restore them at the end of the loop. After
> checking I see that we are already attempting to eliminate some side effects of
> the main loop.
>
>
> I have run all tests with this patch in place. It attempts to fix the
> keepWithNext values back to their original state. Can you give it a whirl? It is
> against current head, but the coding is not that hard so should apply to recent
> sources.
>
> C:\code\reportlab\platypus>svn diff doctemplate.py
> Index: doctemplate.py
> ===================================================================
> --- doctemplate.py (revision 3298)
> +++ doctemplate.py (working copy)
> @@ -600,8 +600,17 @@
> if i:
> if i<n and not getattr(flowables[i],'locChanger',None): i += 1
> K = KeepTogether(flowables[:i])
> - for f in K._content[:-1]:
> - f.__dict__['keepWithNext'] = 0
> + mbe = getattr(self,'_multiBuildEdits',None)
> + if mbe:
> + for f in K._content[:-1]:
> + if hasattr(f,'keepWithNext'):
> + mbe((setattr,f,'keepWithNext',f.keepWithNext))
> + else:
> + mbe((delattr,f,'keepWithNext')) #must get it from a style
> + f.__dict__['keepWithNext'] = 0
> + else:
> + for f in K._content[:-1]:
> + f.__dict__['keepWithNext'] = 0
> del flowables[:i]
> flowables.insert(0,K)
>
> @@ -818,6 +827,8 @@
> #better fix for filename is a 'file' problem
> self._doSave = 0
> passes = 0
> + mbe = []
> + self._multiBuildEdits = mbe.append
> while 1:
> passes += 1
> if self._onProgress:
> @@ -832,12 +843,6 @@
> self.build(tempStory, filename, canvasmaker)
> #self.notify('debug',None)
>
> - #clean up so multi-build does not go wrong - the frame
> - #packer might have tacked an attribute onto some flowables
> - for elem in story:
> - if hasattr(elem, '_postponed'):
> - del elem._postponed
> -
> for fl in self._indexingFlowables:
> fl.afterBuild()
>
> @@ -850,6 +855,18 @@
> if passes > maxPasses:
> raise IndexError, "Index entries not resolved after %d passes"
> % maxPasses
>
> + #clean up so multi-build does not go wrong - the frame
> + #packer might have tacked an attribute onto some flowables
> + for elem in story:
> + if hasattr(elem, '_postponed'):
> + del elem._postponed
> +
> + #work through any edits
> + while mbe:
> + e = mbe.pop(0)
> + e[0](*e[1:])
> +
> + del self._multiBuildEdits
> if verbose: print 'saved'
>
> #these are pure virtuals override in derived classes
>
> plain text document attachment (mbe.patch)
> Index: doctemplate.py
> ===================================================================
> --- doctemplate.py (revision 3298)
> +++ doctemplate.py (working copy)
> @@ -600,8 +600,17 @@
> if i:
> if i<n and not getattr(flowables[i],'locChanger',None): i += 1
> K = KeepTogether(flowables[:i])
> - for f in K._content[:-1]:
> - f.__dict__['keepWithNext'] = 0
> + mbe = getattr(self,'_multiBuildEdits',None)
> + if mbe:
> + for f in K._content[:-1]:
> + if hasattr(f,'keepWithNext'):
> + mbe((setattr,f,'keepWithNext',f.keepWithNext))
> + else:
> + mbe((delattr,f,'keepWithNext')) #must get it from a style
> + f.__dict__['keepWithNext'] = 0
> + else:
> + for f in K._content[:-1]:
> + f.__dict__['keepWithNext'] = 0
> del flowables[:i]
> flowables.insert(0,K)
>
> @@ -818,6 +827,8 @@
> #better fix for filename is a 'file' problem
> self._doSave = 0
> passes = 0
> + mbe = []
> + self._multiBuildEdits = mbe.append
> while 1:
> passes += 1
> if self._onProgress:
> @@ -832,12 +843,6 @@
> self.build(tempStory, filename, canvasmaker)
> #self.notify('debug',None)
>
> - #clean up so multi-build does not go wrong - the frame
> - #packer might have tacked an attribute onto some flowables
> - for elem in story:
> - if hasattr(elem, '_postponed'):
> - del elem._postponed
> -
> for fl in self._indexingFlowables:
> fl.afterBuild()
>
> @@ -850,6 +855,18 @@
> if passes > maxPasses:
> raise IndexError, "Index entries not resolved after %d passes" % maxPasses
>
> + #clean up so multi-build does not go wrong - the frame
> + #packer might have tacked an attribute onto some flowables
> + for elem in story:
> + if hasattr(elem, '_postponed'):
> + del elem._postponed
> +
> + #work through any edits
> + while mbe:
> + e = mbe.pop(0)
> + e[0](*e[1:])
> +
> + del self._multiBuildEdits
> if verbose: print 'saved'
>
> #these are pure virtuals override in derived classes
> _______________________________________________
> reportlab-users mailing list
> reportlab-users at reportlab.com
> http://two.pairlist.net/mailman/listinfo/reportlab-users
--
Adam Hyde
Founder FLOSS Manuals
http://www.flossmanuals.net
More information about the reportlab-users
mailing list