--- a/docs/userguide/ch6_tables.py Thu Jan 15 10:34:53 2009 +0000
+++ b/docs/userguide/ch6_tables.py Thu Jan 15 16:59:35 2009 +0000
@@ -415,3 +415,112 @@
If the total height of the $Flowables$ in the list $flowables$ exceeds the current frame's available
space then all the space is used and a frame break is forced.
""")
+CPage(1)
+heading2("""$TableOfContents()$""")
+disc("""
+A table of contents can be generated by using the $TableOfContents$ flowable.
+
+The following steps are needed to add a table of contents to your document:
+""")
+
+disc("""Create an instance of $TableOfContents$. Override the level styles (optional) and add the object to the story:""")
+
+eg("""
+toc = TableOfContents()
+PS = ParagraphStyle
+toc.levelStyles = [
+ PS(fontName='Times-Bold', fontSize=14, name='TOCHeading1',
+ leftIndent=20, firstLineIndent=-20, spaceBefore=5, leading=16),
+ PS(fontSize=12, name='TOCHeading2',
+ leftIndent=40, firstLineIndent=-20, spaceBefore=0, leading=12),
+ PS(fontSize=10, name='TOCHeading3',
+ leftIndent=60, firstLineIndent=-20, spaceBefore=0, leading=12),
+ PS(fontSize=10, name='TOCHeading4',
+ leftIndent=100, firstLineIndent=-20, spaceBefore=0, leading=12),
+]
+story.append(toc)
+""")
+
+disc("""Entries to the table of contents can be done either manually by calling the $addEntry$ method on the $TableOfContents$ object
+or automatically by sending a $'TOCEntry'$ notification in the $afterFlowable$ method of the $DocTemplate$ you are using:""")
+
+eg('''
+def afterFlowable(self, flowable):
+ """Detect Level 1 and 2 headings, build outline,
+ and track chapter title."""
+ if isinstance(flowable, Paragraph):
+ txt = flowable.getPlainText()
+ if style == 'Heading1':
+ # ...
+ self.notify('TOCEntry', (0, txt, self.page))
+ elif style == 'Heading2':
+ # ...
+ self.notify('TOCEntry', (1, txt, self.page))
+ # ...
+''')
+
+disc("""This way, whenever a paragraph of style $'Heading1'$ or $'Heading2'$ is added to the story, it will appear in the table of contents.""")
+
+disc("""Finally you need to use the $multiBuild$ method of the DocTemplate because tables of contents need several passes to be generated:""")
+
+eg("""
+doc.multiBuild(story)
+""")
+
+disc("""Below is a simple but working example of a document with a table of contents:""")
+
+eg('''
+from reportlab.lib.styles import ParagraphStyle as PS
+from reportlab.platypus import PageBreak
+from reportlab.platypus.paragraph import Paragraph
+from reportlab.platypus.doctemplate import PageTemplate, BaseDocTemplate
+from reportlab.platypus.tableofcontents import TableOfContents
+from reportlab.platypus.frames import Frame
+from reportlab.lib.units import cm
+
+class MyDocTemplate(BaseDocTemplate):
+
+ def __init__(self, filename, **kw):
+ self.allowSplitting = 0
+ apply(BaseDocTemplate.__init__, (self, filename), kw)
+ template = PageTemplate('normal', [Frame(2.5*cm, 2.5*cm, 15*cm, 25*cm, id='F1')])
+ self.addPageTemplates(template)
+
+ def afterFlowable(self, flowable):
+ "Registers TOC entries."
+ if flowable.__class__.__name__ == 'Paragraph':
+ text = flowable.getPlainText()
+ style = flowable.style.name
+ if style == 'Heading1':
+ self.notify('TOCEntry', (0, text, self.page))
+ if style == 'Heading2':
+ self.notify('TOCEntry', (1, text, self.page))
+
+h1 = PS(name = 'Heading1',
+ fontSize = 14,
+ leading = 16)
+
+h2 = PS(name = 'Heading2',
+ fontSize = 12,
+ leading = 14,
+ leftIndent = delta)
+
+# Build story.
+story = []
+toc = TableOfContents()
+# For conciseness we use the same styles for headings and TOC entries
+toc.levelStyles = [h1, h2]
+story.append(toc)
+story.append(PageBreak())
+story.append(Paragraph('First heading', h1))
+story.append(Paragraph('Text in first heading', PS('body')))
+story.append(Paragraph('First sub heading', h2))
+story.append(Paragraph('Text in first sub heading', PS('body')))
+story.append(PageBreak())
+story.append(Paragraph('Second sub heading', h2))
+story.append(Paragraph('Text in second sub heading', PS('body')))
+story.append(Paragraph('Last heading', h1))
+
+doc = MyDocTemplate('mintoc.pdf')
+doc.multiBuild(story)
+''')