docs/userguide/ch6_tables.py
changeset 3059 3a6ff201e927
parent 3044 7e5a05f30245
child 3061 ecd4963cc832
--- 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)
+''')