[reportlab-users] How to create multiple SimpleIndex in the same document?

Robin Becker robin at reportlab.com
Fri Jul 9 05:01:12 EDT 2010


On 08/07/2010 21:47, Billy Saelim wrote:

> Hi,

>

> I wonder how to include more than one SimpleIndex in the same document.

> Suppose in my code I have:

>

> doc_structure.append(Paragraph('IndexA', style['Heading3']))

> index_a = SimpleIndex(dot=' . ', name='index_a')

> doc_structure.append(index_a)

>

> doc_structure.append(Paragraph('IndexB', style['Heading3']))

> index_b = SimpleIndex(dot=' . ', name='index_b')

> doc_structure.append(index_b)

>

>

> And I use the name attribute to indicate to which index an item should

> go, for example:

>

> doc_structure.append(Paragraph('<b><index name="index_a"

> item="myterm" />My Term</b>', style['Heading5']))

>

>

> And suppose I have created an instance of BaseDocTemplate called doc and

> would like to call its multiBuild method, what should I specify for the

> canvasmaker parameter? If I do this:

>

> doc.multiBuild(list(doc_structure),

> canvasmaker=index_a.getCanvasMaker())

>

> It would throw an AttributeError.

>

> Please let me know what I have done incorrectly and if there is any

> example for creating multiple SimpleIndex in a document.

>

> Thanks.

>

> Billy

>

..........


The getCanvasMaker mechanism is a bit fake. In fact all that's required is for
the canvasmaker argument to return a Canvas object. However, because we actually
call this in the build method and don't get a chance to decorate the canvas
before the build starts (unless we override one of the SimpleDoc methods) then
the above is a short cut for the simple case with one index.

Try using the following (*WARNING* I haven't actually tried this so beware of
typos etc etc).

from reportlab.pdfgen.canvas import Canvas
def myCanvasMaker(indeces=[],canvasmaker=canvas.Canvas):
def newcanvasmaker(*args, **kwargs):
from reportlab.pdfgen import canvas
c = canvasmaker(*args, **kwargs)
for ix in indeces: #here's where we put the index
setattr(c,ix.name,ix) #on the canvas
return c

return newcanvasmaker

then in the multibuild you can do

doc.multiBuild(list(doc_structure),
canvasmaker=myCanvasMaker(indeces=[index_a,index_b]),
)

Hope this isn't too confusing; probably we should generalize the SimpleDoc stuff
to allow direct passing in of a canvas. That would allow the initializations to
take place in a more rational way.
--
Robin Becker


More information about the reportlab-users mailing list