tests/test_platypus_toc.py
author andy
Wed, 12 May 2010 14:49:43 +0000
changeset 3374 348f9bcb4c11
parent 3326 ce725978d11c
child 3468 4a75ba27637d
permissions -rw-r--r--
added example of preloading table of contents
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2967
ea62529bd1df reportlab-2.2: first stage changes in on the trunk
rgbecker
parents: 2966
diff changeset
     1
#Copyright ReportLab Europe Ltd. 2000-2008
2963
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
     2
#see license.txt for license details
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
     3
"""Tests for the Platypus TableOfContents class.
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
     4
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
     5
Currently there is only one such test. Most such tests, like this
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
     6
one, will be generating a PDF document that needs to be eye-balled
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
     7
in order to find out if it is 'correct'.
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
     8
"""
2984
c63f149d55aa tests.utils --> reportlab.lib.testutils
rgbecker
parents: 2967
diff changeset
     9
__version__='''$Id$'''
c63f149d55aa tests.utils --> reportlab.lib.testutils
rgbecker
parents: 2967
diff changeset
    10
from reportlab.lib.testutils import setOutDir,makeSuiteForClasses, outputfile, printLocation
c63f149d55aa tests.utils --> reportlab.lib.testutils
rgbecker
parents: 2967
diff changeset
    11
setOutDir(__name__)
2963
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    12
import sys, os
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    13
from os.path import join, basename, splitext
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    14
from math import sqrt
3374
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
    15
import random
2966
c9df63ccabdf reportlab-2.2: major changes to make tests run
rgbecker
parents: 2963
diff changeset
    16
import unittest
2963
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    17
from reportlab.lib.units import inch, cm
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    18
from reportlab.lib.pagesizes import A4
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    19
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    20
from reportlab.platypus.paragraph import Paragraph
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    21
from reportlab.platypus.xpreformatted import XPreformatted
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    22
from reportlab.platypus.frames import Frame
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    23
from reportlab.platypus.doctemplate \
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    24
     import PageTemplate, BaseDocTemplate
3374
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
    25
from reportlab.platypus import tableofcontents, PageBreak
2963
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    26
from reportlab.lib import randomtext
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    27
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    28
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    29
def myMainPageFrame(canvas, doc):
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    30
    "The page frame used for all PDF documents."
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    31
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    32
    canvas.saveState()
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    33
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    34
    canvas.rect(2.5*cm, 2.5*cm, 15*cm, 25*cm)
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    35
    canvas.setFont('Times-Roman', 12)
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    36
    pageNumber = canvas.getPageNumber()
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    37
    canvas.drawString(10*cm, cm, str(pageNumber))
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    38
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    39
    canvas.restoreState()
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    40
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    41
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    42
class MyDocTemplate(BaseDocTemplate):
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    43
    "The document template used for all PDF documents."
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    44
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    45
    _invalidInitArgs = ('pageTemplates',)
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    46
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    47
    def __init__(self, filename, **kw):
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    48
        frame1 = Frame(2.5*cm, 2.5*cm, 15*cm, 25*cm, id='F1')
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    49
        self.allowSplitting = 0
3326
ce725978d11c Initial Python3 compatibility fixes
damian
parents: 3060
diff changeset
    50
        BaseDocTemplate.__init__(self, filename, **kw)
2963
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    51
        template = PageTemplate('normal', [frame1], myMainPageFrame)
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    52
        self.addPageTemplates(template)
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    53
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    54
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    55
    def afterFlowable(self, flowable):
3060
eeedb611fa67 Added feature to have clickable TableOfContents entries (ToDo 978).
jonas
parents: 3059
diff changeset
    56
        "Registers TOC entries."
2963
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    57
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    58
        if flowable.__class__.__name__ == 'Paragraph':
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    59
            styleName = flowable.style.name
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    60
            if styleName[:7] == 'Heading':
3060
eeedb611fa67 Added feature to have clickable TableOfContents entries (ToDo 978).
jonas
parents: 3059
diff changeset
    61
                key = str(hash(flowable))
eeedb611fa67 Added feature to have clickable TableOfContents entries (ToDo 978).
jonas
parents: 3059
diff changeset
    62
                self.canv.bookmarkPage(key)
eeedb611fa67 Added feature to have clickable TableOfContents entries (ToDo 978).
jonas
parents: 3059
diff changeset
    63
2963
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    64
                # Register TOC entries.
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    65
                level = int(styleName[7:])
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    66
                text = flowable.getPlainText()
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    67
                pageNum = self.page
3060
eeedb611fa67 Added feature to have clickable TableOfContents entries (ToDo 978).
jonas
parents: 3059
diff changeset
    68
                # Try calling this with and without a key to test both
eeedb611fa67 Added feature to have clickable TableOfContents entries (ToDo 978).
jonas
parents: 3059
diff changeset
    69
                # Entries of every second level will have links, others won't
eeedb611fa67 Added feature to have clickable TableOfContents entries (ToDo 978).
jonas
parents: 3059
diff changeset
    70
                if level % 2 == 1:
eeedb611fa67 Added feature to have clickable TableOfContents entries (ToDo 978).
jonas
parents: 3059
diff changeset
    71
                    self.notify('TOCEntry', (level, text, pageNum, key))
eeedb611fa67 Added feature to have clickable TableOfContents entries (ToDo 978).
jonas
parents: 3059
diff changeset
    72
                else:
eeedb611fa67 Added feature to have clickable TableOfContents entries (ToDo 978).
jonas
parents: 3059
diff changeset
    73
                    self.notify('TOCEntry', (level, text, pageNum))
2963
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    74
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    75
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    76
def makeHeaderStyle(level, fontName='Times-Roman'):
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    77
    "Make a header style for different levels."
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    78
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    79
    assert level >= 0, "Level must be >= 0."
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    80
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    81
    PS = ParagraphStyle
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    82
    size = 24.0 / sqrt(1+level)
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    83
    style = PS(name = 'Heading' + str(level),
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    84
               fontName = fontName,
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    85
               fontSize = size,
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    86
               leading = size*1.2,
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    87
               spaceBefore = size/4.0,
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    88
               spaceAfter = size/8.0)
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    89
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    90
    return style
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    91
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    92
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    93
def makeBodyStyle():
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    94
    "Body text style - the default will do"
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    95
    return ParagraphStyle('body')
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    96
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    97
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    98
def makeTocHeaderStyle(level, delta, epsilon, fontName='Times-Roman'):
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    99
    "Make a header style for different levels."
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   100
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   101
    assert level >= 0, "Level must be >= 0."
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   102
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   103
    PS = ParagraphStyle
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   104
    size = 12
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   105
    style = PS(name = 'Heading' + str(level),
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   106
               fontName = fontName,
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   107
               fontSize = size,
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   108
               leading = size*1.2,
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   109
               spaceBefore = size/4.0,
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   110
               spaceAfter = size/8.0,
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   111
               firstLineIndent = -epsilon,
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   112
               leftIndent = level*delta + epsilon)
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   113
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   114
    return style
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   115
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   116
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   117
class TocTestCase(unittest.TestCase):
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   118
    "Test TableOfContents class (eyeball-test)."
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   119
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   120
    def test0(self):
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   121
        """Test story with TOC and a cascaded header hierarchy.
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   122
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   123
        The story should contain exactly one table of contents that is
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   124
        immediatly followed by a list of of cascaded levels of header
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   125
        lines, each nested one level deeper than the previous one.
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   126
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   127
        Features to be visually confirmed by a human being are:
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   128
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   129
            1. TOC lines are indented in multiples of 1 cm.
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   130
            2. Wrapped TOC lines continue with additional 0.5 cm indentation.
3060
eeedb611fa67 Added feature to have clickable TableOfContents entries (ToDo 978).
jonas
parents: 3059
diff changeset
   131
            3. Only entries of every second level has links
eeedb611fa67 Added feature to have clickable TableOfContents entries (ToDo 978).
jonas
parents: 3059
diff changeset
   132
            ...
2963
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   133
        """
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   134
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   135
        maxLevels = 12
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   136
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   137
        # Create styles to be used for document headers
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   138
        # on differnet levels.
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   139
        headerLevelStyles = []
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   140
        for i in range(maxLevels):
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   141
            headerLevelStyles.append(makeHeaderStyle(i))
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   142
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   143
        # Create styles to be used for TOC entry lines
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   144
        # for headers on differnet levels.
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   145
        tocLevelStyles = []
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   146
        d, e = tableofcontents.delta, tableofcontents.epsilon
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   147
        for i in range(maxLevels):
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   148
            tocLevelStyles.append(makeTocHeaderStyle(i, d, e))
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   149
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   150
        # Build story.
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   151
        story = []
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   152
        styleSheet = getSampleStyleSheet()
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   153
        bt = styleSheet['BodyText']
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   154
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   155
        description = '<font color=red>%s</font>' % self.test0.__doc__
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   156
        story.append(XPreformatted(description, bt))
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   157
3059
3a6ff201e927 Added documentation for the table of contents to the userguide.
jonas
parents: 2984
diff changeset
   158
        toc = tableofcontents.TableOfContents()
2963
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   159
        toc.levelStyles = tocLevelStyles
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   160
        story.append(toc)
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   161
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   162
        for i in range(maxLevels):
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   163
            story.append(Paragraph('HEADER, LEVEL %d' % i,
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   164
                                   headerLevelStyles[i]))
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   165
            #now put some body stuff in.
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   166
            txt = randomtext.randomText(randomtext.PYTHON, 5)
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   167
            para = Paragraph(txt, makeBodyStyle())
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   168
            story.append(para)
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   169
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   170
        path = outputfile('test_platypus_toc.pdf')
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   171
        doc = MyDocTemplate(path)
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   172
        doc.multiBuild(story)
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   173
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   174
3374
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   175
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   176
    def test1(self):
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   177
        """This shows a table which would take more than one page,
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   178
        and need multiple passes to render.  But we preload it
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   179
        with the right headings to make it go faster.  We used
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   180
        a simple 100-chapter document with one level.
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   181
        """
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   182
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   183
        chapters = 30   #goes over one page
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   184
        
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   185
        headerStyle = makeHeaderStyle(0)
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   186
        d, e = tableofcontents.delta, tableofcontents.epsilon
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   187
        tocLevelStyle = makeTocHeaderStyle(0, d, e)
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   188
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   189
        # Build most of the story; we'll re-use it to 
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   190
        # make documents with different numbers of passes.
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   191
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   192
        story = []
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   193
        styleSheet = getSampleStyleSheet()
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   194
        bt = styleSheet['BodyText']
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   195
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   196
        description = '<font color=red>%s</font>' % self.test1.__doc__
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   197
        story.append(XPreformatted(description, bt))
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   198
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   199
        for i in range(chapters):
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   200
            story.append(PageBreak())
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   201
            story.append(Paragraph('This is chapter %d' % (i+1),
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   202
                                   headerStyle))
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   203
            #now put some lengthy body stuff in.  
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   204
            for paras in range(random.randint(1,3)):
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   205
                txt = randomtext.randomText(randomtext.PYTHON, 5)
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   206
                para = Paragraph(txt, makeBodyStyle())
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   207
                story.append(para)
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   208
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   209
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   210
        #try 1: empty TOC, 3 passes
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   211
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   212
        toc = tableofcontents.TableOfContents()
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   213
        toc.levelStyles = [tocLevelStyle]   #only need one
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   214
        story1 = [toc] + story
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   215
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   216
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   217
        path = outputfile('test_platypus_toc_preload.pdf')
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   218
        doc = MyDocTemplate(path)
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   219
        passes = doc.multiBuild(story1)
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   220
        self.assertEquals(passes, 3)
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   221
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   222
        #try 2: now preload the TOC with the entries
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   223
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   224
        toc = tableofcontents.TableOfContents()
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   225
        toc.levelStyles = [tocLevelStyle]   #only need one
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   226
        tocEntries = []
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   227
        for i in range(chapters):
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   228
            #add tuple of (level, text, pageNum, key)
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   229
            #with an initial guess of pageNum=0
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   230
            tocEntries.append((0, 'This is chapter %d' % (i+1), 0, None))
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   231
        toc.addEntries(tocEntries)
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   232
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   233
        story2 = [toc] + story
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   234
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   235
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   236
        path = outputfile('test_platypus_toc_preload.pdf')
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   237
        doc = MyDocTemplate(path)
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   238
        passes = doc.multiBuild(story2)
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   239
        self.assertEquals(passes, 2)
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   240
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   241
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   242
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   243
        #try 3: preload again but try to be really smart and work out
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   244
        #in advance what page everything starts on.  We cannot
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   245
        #use a random story for this.
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   246
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   247
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   248
        toc3 = tableofcontents.TableOfContents()
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   249
        toc3.levelStyles = [tocLevelStyle]   #only need one
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   250
        tocEntries = []
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   251
        for i in range(chapters):
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   252
            #add tuple of (level, text, pageNum, key)
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   253
            #with an initial guess of pageNum= 3
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   254
            tocEntries.append((0, 'This is chapter %d' % i, 2+i, None))
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   255
        toc3.addEntries(tocEntries)
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   256
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   257
        story3 = [toc3] 
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   258
        for i in range(chapters):
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   259
            story3.append(PageBreak())
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   260
            story3.append(Paragraph('This is chapter %d' % (i+1),
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   261
                                   headerStyle))
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   262
            txt = """
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   263
                The paragraphs in this are not at all random, because
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   264
                we need to be absolutely, totally certain they will fit 
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   265
                on one page.  Each chapter will be one page long.
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   266
            """
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   267
            para = Paragraph(txt, makeBodyStyle())
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   268
            story3.append(para)
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   269
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   270
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   271
        path = outputfile('test_platypus_toc_preload.pdf')
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   272
        doc = MyDocTemplate(path)
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   273
        passes = doc.multiBuild(story3)
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   274
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   275
        # I can't get one pass yet'
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   276
        #self.assertEquals(passes, 1)
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   277
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   278
348f9bcb4c11 added example of preloading table of contents
andy
parents: 3326
diff changeset
   279
2963
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   280
def makeSuite():
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   281
    return makeSuiteForClasses(TocTestCase)
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   282
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   283
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   284
#noruntests
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   285
if __name__ == "__main__":
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   286
    unittest.TextTestRunner().run(makeSuite())
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   287
    printLocation()