src/reportlab/platypus/tableofcontents.py
author robin <robin@reportlab.com>
Tue, 07 Mar 2017 10:00:34 +0000
changeset 4330 617ffa6bbdc8
parent 4252 fe660f227cac
child 4338 6223e7fa13f6
permissions -rw-r--r--
changes for release 3.4.0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
4330
617ffa6bbdc8 changes for release 3.4.0
robin <robin@reportlab.com>
parents: 4252
diff changeset
     1
#Copyright ReportLab Europe Ltd. 2000-2017
817
8c3a399effda License text changes
rgbecker
parents: 754
diff changeset
     2
#see license.txt for license details
2332
2a7ab4405e18 Remove $Header:, fix CopyRight & history
rgbecker
parents: 1683
diff changeset
     3
#history http://www.reportlab.co.uk/cgi-bin/viewcvs.cgi/public/reportlab/trunk/reportlab/platypus/tableofcontents.py
3032
22224b1b4d24 New docstrings mainly for module titles
damian
parents: 2964
diff changeset
     4
4252
fe660f227cac changes for release 3.3.0
robin
parents: 4180
diff changeset
     5
__version__='3.3.0'
3032
22224b1b4d24 New docstrings mainly for module titles
damian
parents: 2964
diff changeset
     6
__doc__="""Experimental class to generate Tables of Contents easily
22224b1b4d24 New docstrings mainly for module titles
damian
parents: 2964
diff changeset
     7
1440
243d35446390 Removed 0 from multiBuild stuff prior to further changes;
andy_robinson
parents: 817
diff changeset
     8
This module defines a single TableOfContents() class that can be used to
754
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
     9
create automatically a table of tontents for Platypus documents like
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
    10
this:
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
    11
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
    12
    story = []
1440
243d35446390 Removed 0 from multiBuild stuff prior to further changes;
andy_robinson
parents: 817
diff changeset
    13
    toc = TableOfContents()
754
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
    14
    story.append(toc)
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
    15
    # some heading paragraphs here...
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
    16
    doc = MyTemplate(path)
1440
243d35446390 Removed 0 from multiBuild stuff prior to further changes;
andy_robinson
parents: 817
diff changeset
    17
    doc.multiBuild(story)
754
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
    18
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
    19
The data needed to create the table is a list of (level, text, pageNum)
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
    20
triplets, plus some paragraph styles for each level of the table itself.
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
    21
The triplets will usually be created in a document template's method
1440
243d35446390 Removed 0 from multiBuild stuff prior to further changes;
andy_robinson
parents: 817
diff changeset
    22
like afterFlowable(), making notification calls using the notify()
754
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
    23
method with appropriate data like this:
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
    24
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
    25
    (level, text, pageNum) = ...
1440
243d35446390 Removed 0 from multiBuild stuff prior to further changes;
andy_robinson
parents: 817
diff changeset
    26
    self.notify('TOCEntry', (level, text, pageNum))
754
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
    27
3060
eeedb611fa67 Added feature to have clickable TableOfContents entries (ToDo 978).
jonas
parents: 3049
diff changeset
    28
Optionally the list can contain four items in which case the last item
eeedb611fa67 Added feature to have clickable TableOfContents entries (ToDo 978).
jonas
parents: 3049
diff changeset
    29
is a destination key which the entry should point to. A bookmark
eeedb611fa67 Added feature to have clickable TableOfContents entries (ToDo 978).
jonas
parents: 3049
diff changeset
    30
with this key needs to be created first like this:
eeedb611fa67 Added feature to have clickable TableOfContents entries (ToDo 978).
jonas
parents: 3049
diff changeset
    31
eeedb611fa67 Added feature to have clickable TableOfContents entries (ToDo 978).
jonas
parents: 3049
diff changeset
    32
    key = 'ch%s' % self.seq.nextf('chapter')
eeedb611fa67 Added feature to have clickable TableOfContents entries (ToDo 978).
jonas
parents: 3049
diff changeset
    33
    self.canv.bookmarkPage(key)
eeedb611fa67 Added feature to have clickable TableOfContents entries (ToDo 978).
jonas
parents: 3049
diff changeset
    34
    self.notify('TOCEntry', (level, text, pageNum, key))
eeedb611fa67 Added feature to have clickable TableOfContents entries (ToDo 978).
jonas
parents: 3049
diff changeset
    35
754
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
    36
As the table of contents need at least two passes over the Platypus
4180
2ee5e4cd860f add formatter and argument processing to tabelOfContents; version-->3.1.52
robin
parents: 4178
diff changeset
    37
story which is why the multiBuild() method must be called.
754
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
    38
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
    39
The level<NUMBER>ParaStyle variables are the paragraph styles used
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
    40
to format the entries in the table of contents. Their indentation
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
    41
is calculated like this: each entry starts at a multiple of some
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
    42
constant named delta. If one entry spans more than one line, all
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
    43
lines after the first are indented by the same constant named
1683
7fa753e4420a Removed all trailing whitespace
andy_robinson
parents: 1559
diff changeset
    44
epsilon.
754
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
    45
"""
3032
22224b1b4d24 New docstrings mainly for module titles
damian
parents: 2964
diff changeset
    46
754
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
    47
from reportlab.lib import enums
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
    48
from reportlab.lib.units import cm
4178
b2c73e04465c fix indexing for accented stuff contributed by alexandrel_sgi @ bitbucket, version-->3.1.50
robin
parents: 4121
diff changeset
    49
from reportlab.lib.utils import commasplit, escapeOnce, encode_label, decode_label, strTypes, asUnicode
3368
afa025c34493 reportlab: new base font mechanism more fully applied
rgbecker
parents: 3349
diff changeset
    50
from reportlab.lib.styles import ParagraphStyle, _baseFontName
754
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
    51
from reportlab.platypus.paragraph import Paragraph
1440
243d35446390 Removed 0 from multiBuild stuff prior to further changes;
andy_robinson
parents: 817
diff changeset
    52
from reportlab.platypus.doctemplate import IndexingFlowable
754
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
    53
from reportlab.platypus.tables import TableStyle, Table
3111
86a3158c50bd reportlab: improved support for onDraw and SimpleIndex
rgbecker
parents: 3060
diff changeset
    54
from reportlab.platypus.flowables import Spacer, Flowable
3049
6e9ca03c4dbe Added dotted lines to TableOfContents.
jonas
parents: 3045
diff changeset
    55
from reportlab.pdfbase.pdfmetrics import stringWidth
3162
77afde998aa9 Made Index entries clickable.
jonas
parents: 3146
diff changeset
    56
from reportlab.pdfgen import canvas
4178
b2c73e04465c fix indexing for accented stuff contributed by alexandrel_sgi @ bitbucket, version-->3.1.50
robin
parents: 4121
diff changeset
    57
import unicodedata
3162
77afde998aa9 Made Index entries clickable.
jonas
parents: 3146
diff changeset
    58
77afde998aa9 Made Index entries clickable.
jonas
parents: 3146
diff changeset
    59
def unquote(txt):
3170
91786d2240d0 Using base 64 encoding to make sure sgmllib does not mess with the whitespace in the attribute.
jonas
parents: 3167
diff changeset
    60
    from xml.sax.saxutils import unescape
3162
77afde998aa9 Made Index entries clickable.
jonas
parents: 3146
diff changeset
    61
    return unescape(txt, {"&apos;": "'", "&quot;": '"'})
77afde998aa9 Made Index entries clickable.
jonas
parents: 3146
diff changeset
    62
3111
86a3158c50bd reportlab: improved support for onDraw and SimpleIndex
rgbecker
parents: 3060
diff changeset
    63
try:
86a3158c50bd reportlab: improved support for onDraw and SimpleIndex
rgbecker
parents: 3060
diff changeset
    64
    set
86a3158c50bd reportlab: improved support for onDraw and SimpleIndex
rgbecker
parents: 3060
diff changeset
    65
except:
86a3158c50bd reportlab: improved support for onDraw and SimpleIndex
rgbecker
parents: 3060
diff changeset
    66
    class set(list):
86a3158c50bd reportlab: improved support for onDraw and SimpleIndex
rgbecker
parents: 3060
diff changeset
    67
        def add(self,x):
86a3158c50bd reportlab: improved support for onDraw and SimpleIndex
rgbecker
parents: 3060
diff changeset
    68
            if x not in self:
86a3158c50bd reportlab: improved support for onDraw and SimpleIndex
rgbecker
parents: 3060
diff changeset
    69
                list.append(self,x)
3165
cbda9e7d0ee3 reportlab: new index support
rgbecker
parents: 3164
diff changeset
    70
4180
2ee5e4cd860f add formatter and argument processing to tabelOfContents; version-->3.1.52
robin
parents: 4178
diff changeset
    71
def drawPageNumbers(canvas, style, pages, availWidth, availHeight, dot=' . ', formatter=None):
3135
3a2a8a52c1c1 reportlab.platypus: Fixes for SimpleIndex and TableOfContents.
jonas
parents: 3111
diff changeset
    72
    '''
3136
3a4e339ebac8 platypus.tableofcontents: allow more flexibility for drawing dots in Index and TableOfContents. Set default for Index back to none.
jonas
parents: 3135
diff changeset
    73
    Draws pagestr on the canvas using the given style.
3a4e339ebac8 platypus.tableofcontents: allow more flexibility for drawing dots in Index and TableOfContents. Set default for Index back to none.
jonas
parents: 3135
diff changeset
    74
    If dot is None, pagestr is drawn at the current position in the canvas.
3a4e339ebac8 platypus.tableofcontents: allow more flexibility for drawing dots in Index and TableOfContents. Set default for Index back to none.
jonas
parents: 3135
diff changeset
    75
    If dot is a string, pagestr is drawn right-aligned. If the string is not empty,
3a4e339ebac8 platypus.tableofcontents: allow more flexibility for drawing dots in Index and TableOfContents. Set default for Index back to none.
jonas
parents: 3135
diff changeset
    76
    the gap is filled with it.
3135
3a2a8a52c1c1 reportlab.platypus: Fixes for SimpleIndex and TableOfContents.
jonas
parents: 3111
diff changeset
    77
    '''
3166
93e3203eab88 Removed some post python 2.3 constructs.
jonas
parents: 3165
diff changeset
    78
    pagestr = ', '.join([str(p) for p, _ in pages])
3135
3a2a8a52c1c1 reportlab.platypus: Fixes for SimpleIndex and TableOfContents.
jonas
parents: 3111
diff changeset
    79
    x, y = canvas._curr_tx_info['cur_x'], canvas._curr_tx_info['cur_y']
4121
3b9e6fa286ad tableofcontents.py, doctemplate.py: fix indexing page number ordering bug found by Greg Jones bitbucket issue #40
robin
parents: 4058
diff changeset
    80
3348
d44de6313b58 workaround for widow/orphan control in simpleindex
andy
parents: 3327
diff changeset
    81
    fontSize = style.fontSize
d44de6313b58 workaround for widow/orphan control in simpleindex
andy
parents: 3327
diff changeset
    82
    pagestrw = stringWidth(pagestr, style.fontName, fontSize)
4121
3b9e6fa286ad tableofcontents.py, doctemplate.py: fix indexing page number ordering bug found by Greg Jones bitbucket issue #40
robin
parents: 4058
diff changeset
    83
3348
d44de6313b58 workaround for widow/orphan control in simpleindex
andy
parents: 3327
diff changeset
    84
    #if it's too long to fit, we need to shrink to fit in 10% increments.
d44de6313b58 workaround for widow/orphan control in simpleindex
andy
parents: 3327
diff changeset
    85
    #it would be very hard to output multiline entries.
d44de6313b58 workaround for widow/orphan control in simpleindex
andy
parents: 3327
diff changeset
    86
    #however, we impose a minimum size of 1 point as we don't want an
d44de6313b58 workaround for widow/orphan control in simpleindex
andy
parents: 3327
diff changeset
    87
    #infinite loop.   Ultimately we should allow a TOC entry to spill
d44de6313b58 workaround for widow/orphan control in simpleindex
andy
parents: 3327
diff changeset
    88
    #over onto a second line if needed.
d44de6313b58 workaround for widow/orphan control in simpleindex
andy
parents: 3327
diff changeset
    89
    freeWidth = availWidth-x
d44de6313b58 workaround for widow/orphan control in simpleindex
andy
parents: 3327
diff changeset
    90
    while pagestrw > freeWidth and fontSize >= 1.0:
d44de6313b58 workaround for widow/orphan control in simpleindex
andy
parents: 3327
diff changeset
    91
        fontSize = 0.9 * fontSize
d44de6313b58 workaround for widow/orphan control in simpleindex
andy
parents: 3327
diff changeset
    92
        pagestrw = stringWidth(pagestr, style.fontName, fontSize)
4121
3b9e6fa286ad tableofcontents.py, doctemplate.py: fix indexing page number ordering bug found by Greg Jones bitbucket issue #40
robin
parents: 4058
diff changeset
    93
3b9e6fa286ad tableofcontents.py, doctemplate.py: fix indexing page number ordering bug found by Greg Jones bitbucket issue #40
robin
parents: 4058
diff changeset
    94
4058
a97a88afcfe8 tableofcontents.py: try and allow for differecnt dot kinds
robin
parents: 3853
diff changeset
    95
    if isinstance(dot, strTypes):
3136
3a4e339ebac8 platypus.tableofcontents: allow more flexibility for drawing dots in Index and TableOfContents. Set default for Index back to none.
jonas
parents: 3135
diff changeset
    96
        if dot:
3348
d44de6313b58 workaround for widow/orphan control in simpleindex
andy
parents: 3327
diff changeset
    97
            dotw = stringWidth(dot, style.fontName, fontSize)
3136
3a4e339ebac8 platypus.tableofcontents: allow more flexibility for drawing dots in Index and TableOfContents. Set default for Index back to none.
jonas
parents: 3135
diff changeset
    98
            dotsn = int((availWidth-x-pagestrw)/dotw)
3a4e339ebac8 platypus.tableofcontents: allow more flexibility for drawing dots in Index and TableOfContents. Set default for Index back to none.
jonas
parents: 3135
diff changeset
    99
        else:
3a4e339ebac8 platypus.tableofcontents: allow more flexibility for drawing dots in Index and TableOfContents. Set default for Index back to none.
jonas
parents: 3135
diff changeset
   100
            dotsn = dotw = 0
3a4e339ebac8 platypus.tableofcontents: allow more flexibility for drawing dots in Index and TableOfContents. Set default for Index back to none.
jonas
parents: 3135
diff changeset
   101
        text = '%s%s' % (dotsn * dot, pagestr)
3162
77afde998aa9 Made Index entries clickable.
jonas
parents: 3146
diff changeset
   102
        newx = availWidth - dotsn*dotw - pagestrw
77afde998aa9 Made Index entries clickable.
jonas
parents: 3146
diff changeset
   103
        pagex = availWidth - pagestrw
3136
3a4e339ebac8 platypus.tableofcontents: allow more flexibility for drawing dots in Index and TableOfContents. Set default for Index back to none.
jonas
parents: 3135
diff changeset
   104
    elif dot is None:
3143
c704253bc72a Added support for multi-level and alphabetical indexes.
jonas
parents: 3141
diff changeset
   105
        text = ',  ' + pagestr
3136
3a4e339ebac8 platypus.tableofcontents: allow more flexibility for drawing dots in Index and TableOfContents. Set default for Index back to none.
jonas
parents: 3135
diff changeset
   106
        newx = x
3162
77afde998aa9 Made Index entries clickable.
jonas
parents: 3146
diff changeset
   107
        pagex = newx
3135
3a2a8a52c1c1 reportlab.platypus: Fixes for SimpleIndex and TableOfContents.
jonas
parents: 3111
diff changeset
   108
    else:
3136
3a4e339ebac8 platypus.tableofcontents: allow more flexibility for drawing dots in Index and TableOfContents. Set default for Index back to none.
jonas
parents: 3135
diff changeset
   109
        raise TypeError('Argument dot should either be None or an instance of basestring.')
3135
3a2a8a52c1c1 reportlab.platypus: Fixes for SimpleIndex and TableOfContents.
jonas
parents: 3111
diff changeset
   110
3136
3a4e339ebac8 platypus.tableofcontents: allow more flexibility for drawing dots in Index and TableOfContents. Set default for Index back to none.
jonas
parents: 3135
diff changeset
   111
    tx = canvas.beginText(newx, y)
3348
d44de6313b58 workaround for widow/orphan control in simpleindex
andy
parents: 3327
diff changeset
   112
    tx.setFont(style.fontName, fontSize)
3135
3a2a8a52c1c1 reportlab.platypus: Fixes for SimpleIndex and TableOfContents.
jonas
parents: 3111
diff changeset
   113
    tx.setFillColor(style.textColor)
3a2a8a52c1c1 reportlab.platypus: Fixes for SimpleIndex and TableOfContents.
jonas
parents: 3111
diff changeset
   114
    tx.textLine(text)
3a2a8a52c1c1 reportlab.platypus: Fixes for SimpleIndex and TableOfContents.
jonas
parents: 3111
diff changeset
   115
    canvas.drawText(tx)
3165
cbda9e7d0ee3 reportlab: new index support
rgbecker
parents: 3164
diff changeset
   116
3348
d44de6313b58 workaround for widow/orphan control in simpleindex
andy
parents: 3327
diff changeset
   117
    commaw = stringWidth(', ', style.fontName, fontSize)
3162
77afde998aa9 Made Index entries clickable.
jonas
parents: 3146
diff changeset
   118
    for p, key in pages:
77afde998aa9 Made Index entries clickable.
jonas
parents: 3146
diff changeset
   119
        if not key:
77afde998aa9 Made Index entries clickable.
jonas
parents: 3146
diff changeset
   120
            continue
3348
d44de6313b58 workaround for widow/orphan control in simpleindex
andy
parents: 3327
diff changeset
   121
        w = stringWidth(str(p), style.fontName, fontSize)
3162
77afde998aa9 Made Index entries clickable.
jonas
parents: 3146
diff changeset
   122
        canvas.linkRect('', key, (pagex, y, pagex+w, y+style.leading), relative=1)
77afde998aa9 Made Index entries clickable.
jonas
parents: 3146
diff changeset
   123
        pagex += w + commaw
3135
3a2a8a52c1c1 reportlab.platypus: Fixes for SimpleIndex and TableOfContents.
jonas
parents: 3111
diff changeset
   124
754
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   125
# Default paragraph styles for tables of contents.
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   126
# (This could also be generated automatically or even
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   127
# on-demand if it is not known how many levels the
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   128
# TOC will finally need to display...)
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   129
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   130
delta = 1*cm
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   131
epsilon = 0.5*cm
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   132
3146
4732d02eae94 Added support for an unlimited number of TOC levels with default styles.
jonas
parents: 3145
diff changeset
   133
defaultLevelStyles = [
4732d02eae94 Added support for an unlimited number of TOC levels with default styles.
jonas
parents: 3145
diff changeset
   134
    ParagraphStyle(
4732d02eae94 Added support for an unlimited number of TOC levels with default styles.
jonas
parents: 3145
diff changeset
   135
        name='Level 0',
3368
afa025c34493 reportlab: new base font mechanism more fully applied
rgbecker
parents: 3349
diff changeset
   136
        fontName=_baseFontName,
3146
4732d02eae94 Added support for an unlimited number of TOC levels with default styles.
jonas
parents: 3145
diff changeset
   137
        fontSize=10,
4732d02eae94 Added support for an unlimited number of TOC levels with default styles.
jonas
parents: 3145
diff changeset
   138
        leading=11,
4732d02eae94 Added support for an unlimited number of TOC levels with default styles.
jonas
parents: 3145
diff changeset
   139
        firstLineIndent = 0,
4732d02eae94 Added support for an unlimited number of TOC levels with default styles.
jonas
parents: 3145
diff changeset
   140
        leftIndent = epsilon)]
754
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   141
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   142
defaultTableStyle = \
3135
3a2a8a52c1c1 reportlab.platypus: Fixes for SimpleIndex and TableOfContents.
jonas
parents: 3111
diff changeset
   143
    TableStyle([
3a2a8a52c1c1 reportlab.platypus: Fixes for SimpleIndex and TableOfContents.
jonas
parents: 3111
diff changeset
   144
        ('VALIGN', (0,0), (-1,-1), 'TOP'),
3a2a8a52c1c1 reportlab.platypus: Fixes for SimpleIndex and TableOfContents.
jonas
parents: 3111
diff changeset
   145
        ('RIGHTPADDING', (0,0), (-1,-1), 0),
3a2a8a52c1c1 reportlab.platypus: Fixes for SimpleIndex and TableOfContents.
jonas
parents: 3111
diff changeset
   146
        ('LEFTPADDING', (0,0), (-1,-1), 0),
3a2a8a52c1c1 reportlab.platypus: Fixes for SimpleIndex and TableOfContents.
jonas
parents: 3111
diff changeset
   147
    ])
754
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   148
1440
243d35446390 Removed 0 from multiBuild stuff prior to further changes;
andy_robinson
parents: 817
diff changeset
   149
class TableOfContents(IndexingFlowable):
754
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   150
    """This creates a formatted table of contents.
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   151
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   152
    It presumes a correct block of data is passed in.
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   153
    The data block contains a list of (level, text, pageNumber)
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   154
    triplets.  You can supply a paragraph style for each level
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   155
    (starting at zero).
3049
6e9ca03c4dbe Added dotted lines to TableOfContents.
jonas
parents: 3045
diff changeset
   156
    Set dotsMinLevel to determine from which level on a line of
6e9ca03c4dbe Added dotted lines to TableOfContents.
jonas
parents: 3045
diff changeset
   157
    dots should be drawn between the text and the page number.
6e9ca03c4dbe Added dotted lines to TableOfContents.
jonas
parents: 3045
diff changeset
   158
    If dotsMinLevel is set to a negative value, no dotted lines are drawn.
754
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   159
    """
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   160
4180
2ee5e4cd860f add formatter and argument processing to tabelOfContents; version-->3.1.52
robin
parents: 4178
diff changeset
   161
    def __init__(self,**kwds):
2ee5e4cd860f add formatter and argument processing to tabelOfContents; version-->3.1.52
robin
parents: 4178
diff changeset
   162
        self.rightColumnWidth = kwds.get('rightColumnWidth',72)
2ee5e4cd860f add formatter and argument processing to tabelOfContents; version-->3.1.52
robin
parents: 4178
diff changeset
   163
        self.levelStyles = kwds.get('levelStyles',defaultLevelStyles)
2ee5e4cd860f add formatter and argument processing to tabelOfContents; version-->3.1.52
robin
parents: 4178
diff changeset
   164
        self.tableStyle = kwds.get('tableStyle',defaultTableStyle)
2ee5e4cd860f add formatter and argument processing to tabelOfContents; version-->3.1.52
robin
parents: 4178
diff changeset
   165
        self.dotsMinLevel = kwds.get('dotsMinLevel',1)
2ee5e4cd860f add formatter and argument processing to tabelOfContents; version-->3.1.52
robin
parents: 4178
diff changeset
   166
        self.formatter = kwds.get('formatter',None)
2ee5e4cd860f add formatter and argument processing to tabelOfContents; version-->3.1.52
robin
parents: 4178
diff changeset
   167
        if kwds: raise ValueError('unexpected keyword arguments %s' % ', '.join(kwds.keys()))
754
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   168
        self._table = None
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   169
        self._entries = []
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   170
        self._lastEntries = []
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   171
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   172
    def beforeBuild(self):
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   173
        # keep track of the last run
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   174
        self._lastEntries = self._entries[:]
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   175
        self.clearEntries()
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   176
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   177
    def isIndexing(self):
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   178
        return 1
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   179
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   180
    def isSatisfied(self):
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   181
        return (self._entries == self._lastEntries)
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   182
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   183
    def notify(self, kind, stuff):
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   184
        """The notification hook called to register all kinds of events.
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   185
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   186
        Here we are interested in 'TOCEntry' events only.
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   187
        """
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   188
        if kind == 'TOCEntry':
3060
eeedb611fa67 Added feature to have clickable TableOfContents entries (ToDo 978).
jonas
parents: 3049
diff changeset
   189
            self.addEntry(*stuff)
754
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   190
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   191
    def clearEntries(self):
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   192
        self._entries = []
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   193
3146
4732d02eae94 Added support for an unlimited number of TOC levels with default styles.
jonas
parents: 3145
diff changeset
   194
    def getLevelStyle(self, n):
4732d02eae94 Added support for an unlimited number of TOC levels with default styles.
jonas
parents: 3145
diff changeset
   195
        '''Returns the style for level n, generating and caching styles on demand if not present.'''
4732d02eae94 Added support for an unlimited number of TOC levels with default styles.
jonas
parents: 3145
diff changeset
   196
        try:
4732d02eae94 Added support for an unlimited number of TOC levels with default styles.
jonas
parents: 3145
diff changeset
   197
            return self.levelStyles[n]
4732d02eae94 Added support for an unlimited number of TOC levels with default styles.
jonas
parents: 3145
diff changeset
   198
        except IndexError:
4732d02eae94 Added support for an unlimited number of TOC levels with default styles.
jonas
parents: 3145
diff changeset
   199
            prevstyle = self.getLevelStyle(n-1)
4732d02eae94 Added support for an unlimited number of TOC levels with default styles.
jonas
parents: 3145
diff changeset
   200
            self.levelStyles.append(ParagraphStyle(
4732d02eae94 Added support for an unlimited number of TOC levels with default styles.
jonas
parents: 3145
diff changeset
   201
                    name='%s-%d-indented' % (prevstyle.name, n),
4732d02eae94 Added support for an unlimited number of TOC levels with default styles.
jonas
parents: 3145
diff changeset
   202
                    parent=prevstyle,
4732d02eae94 Added support for an unlimited number of TOC levels with default styles.
jonas
parents: 3145
diff changeset
   203
                    firstLineIndent = prevstyle.firstLineIndent+delta,
4732d02eae94 Added support for an unlimited number of TOC levels with default styles.
jonas
parents: 3145
diff changeset
   204
                    leftIndent = prevstyle.leftIndent+delta))
4732d02eae94 Added support for an unlimited number of TOC levels with default styles.
jonas
parents: 3145
diff changeset
   205
            return self.levelStyles[n]
754
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   206
3060
eeedb611fa67 Added feature to have clickable TableOfContents entries (ToDo 978).
jonas
parents: 3049
diff changeset
   207
    def addEntry(self, level, text, pageNum, key=None):
754
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   208
        """Adds one entry to the table of contents.
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   209
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   210
        This allows incremental buildup by a doctemplate.
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   211
        Requires that enough styles are defined."""
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   212
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   213
        assert type(level) == type(1), "Level must be an integer"
3060
eeedb611fa67 Added feature to have clickable TableOfContents entries (ToDo 978).
jonas
parents: 3049
diff changeset
   214
        self._entries.append((level, text, pageNum, key))
754
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   215
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   216
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   217
    def addEntries(self, listOfEntries):
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   218
        """Bulk creation of entries in the table of contents.
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   219
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   220
        If you knew the titles but not the page numbers, you could
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   221
        supply them to get sensible output on the first run."""
1683
7fa753e4420a Removed all trailing whitespace
andy_robinson
parents: 1559
diff changeset
   222
3060
eeedb611fa67 Added feature to have clickable TableOfContents entries (ToDo 978).
jonas
parents: 3049
diff changeset
   223
        for entryargs in listOfEntries:
eeedb611fa67 Added feature to have clickable TableOfContents entries (ToDo 978).
jonas
parents: 3049
diff changeset
   224
            self.addEntry(*entryargs)
754
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   225
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   226
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   227
    def wrap(self, availWidth, availHeight):
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   228
        "All table properties should be known by now."
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   229
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   230
        # makes an internal table which does all the work.
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   231
        # we draw the LAST RUN's entries!  If there are
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   232
        # none, we make some dummy data to keep the table
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   233
        # from complaining
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   234
        if len(self._lastEntries) == 0:
3060
eeedb611fa67 Added feature to have clickable TableOfContents entries (ToDo 978).
jonas
parents: 3049
diff changeset
   235
            _tempEntries = [(0,'Placeholder for table of contents',0,None)]
754
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   236
        else:
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   237
            _tempEntries = self._lastEntries
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   238
3049
6e9ca03c4dbe Added dotted lines to TableOfContents.
jonas
parents: 3045
diff changeset
   239
        def drawTOCEntryEnd(canvas, kind, label):
6e9ca03c4dbe Added dotted lines to TableOfContents.
jonas
parents: 3045
diff changeset
   240
            '''Callback to draw dots and page numbers after each entry.'''
3294
f60b7cb499aa tableofcontents.py: fix passing of key to onDraw for TOC
rgbecker
parents: 3187
diff changeset
   241
            label = label.split(',')
f60b7cb499aa tableofcontents.py: fix passing of key to onDraw for TOC
rgbecker
parents: 3187
diff changeset
   242
            page, level, key = int(label[0]), int(label[1]), eval(label[2],{})
3146
4732d02eae94 Added support for an unlimited number of TOC levels with default styles.
jonas
parents: 3145
diff changeset
   243
            style = self.getLevelStyle(level)
3145
afc8212b1ed8 fixed 2.6-ism
andy
parents: 3143
diff changeset
   244
            if self.dotsMinLevel >= 0 and level >= self.dotsMinLevel:
3165
cbda9e7d0ee3 reportlab: new index support
rgbecker
parents: 3164
diff changeset
   245
                dot = ' . '
cbda9e7d0ee3 reportlab: new index support
rgbecker
parents: 3164
diff changeset
   246
            else:
3145
afc8212b1ed8 fixed 2.6-ism
andy
parents: 3143
diff changeset
   247
                dot = ''
4180
2ee5e4cd860f add formatter and argument processing to tabelOfContents; version-->3.1.52
robin
parents: 4178
diff changeset
   248
            if self.formatter: page = self.formatter(page)
3294
f60b7cb499aa tableofcontents.py: fix passing of key to onDraw for TOC
rgbecker
parents: 3187
diff changeset
   249
            drawPageNumbers(canvas, style, [(page, key)], availWidth, availHeight, dot)
3049
6e9ca03c4dbe Added dotted lines to TableOfContents.
jonas
parents: 3045
diff changeset
   250
        self.canv.drawTOCEntryEnd = drawTOCEntryEnd
6e9ca03c4dbe Added dotted lines to TableOfContents.
jonas
parents: 3045
diff changeset
   251
754
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   252
        tableData = []
3060
eeedb611fa67 Added feature to have clickable TableOfContents entries (ToDo 978).
jonas
parents: 3049
diff changeset
   253
        for (level, text, pageNum, key) in _tempEntries:
3146
4732d02eae94 Added support for an unlimited number of TOC levels with default styles.
jonas
parents: 3145
diff changeset
   254
            style = self.getLevelStyle(level)
3060
eeedb611fa67 Added feature to have clickable TableOfContents entries (ToDo 978).
jonas
parents: 3049
diff changeset
   255
            if key:
eeedb611fa67 Added feature to have clickable TableOfContents entries (ToDo 978).
jonas
parents: 3049
diff changeset
   256
                text = '<a href="#%s">%s</a>' % (key, text)
3294
f60b7cb499aa tableofcontents.py: fix passing of key to onDraw for TOC
rgbecker
parents: 3187
diff changeset
   257
                keyVal = repr(key).replace(',','\\x2c').replace('"','\\x2c')
f60b7cb499aa tableofcontents.py: fix passing of key to onDraw for TOC
rgbecker
parents: 3187
diff changeset
   258
            else:
f60b7cb499aa tableofcontents.py: fix passing of key to onDraw for TOC
rgbecker
parents: 3187
diff changeset
   259
                keyVal = None
f60b7cb499aa tableofcontents.py: fix passing of key to onDraw for TOC
rgbecker
parents: 3187
diff changeset
   260
            para = Paragraph('%s<onDraw name="drawTOCEntryEnd" label="%d,%d,%s"/>' % (text, pageNum, level, keyVal), style)
3049
6e9ca03c4dbe Added dotted lines to TableOfContents.
jonas
parents: 3045
diff changeset
   261
            if style.spaceBefore:
6e9ca03c4dbe Added dotted lines to TableOfContents.
jonas
parents: 3045
diff changeset
   262
                tableData.append([Spacer(1, style.spaceBefore),])
6e9ca03c4dbe Added dotted lines to TableOfContents.
jonas
parents: 3045
diff changeset
   263
            tableData.append([para,])
754
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   264
3135
3a2a8a52c1c1 reportlab.platypus: Fixes for SimpleIndex and TableOfContents.
jonas
parents: 3111
diff changeset
   265
        self._table = Table(tableData, colWidths=(availWidth,), style=self.tableStyle)
754
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   266
1493
bfcdeed2f9e7 Propogate the canvas
rgbecker
parents: 1444
diff changeset
   267
        self.width, self.height = self._table.wrapOn(self.canv,availWidth, availHeight)
754
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   268
        return (self.width, self.height)
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   269
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   270
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   271
    def split(self, availWidth, availHeight):
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   272
        """At this stage we do not care about splitting the entries,
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   273
        we will just return a list of platypus tables.  Presumably the
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   274
        calling app has a pointer to the original TableOfContents object;
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   275
        Platypus just sees tables.
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   276
        """
1493
bfcdeed2f9e7 Propogate the canvas
rgbecker
parents: 1444
diff changeset
   277
        return self._table.splitOn(self.canv,availWidth, availHeight)
754
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   278
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   279
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   280
    def drawOn(self, canvas, x, y, _sW=0):
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   281
        """Don't do this at home!  The standard calls for implementing
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   282
        draw(); we are hooking this in order to delegate ALL the drawing
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   283
        work to the embedded table object.
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   284
        """
ac7d1e99bd3e Replaced trailing digit file.
dinu_gherman
parents:
diff changeset
   285
        self._table.drawOn(canvas, x, y, _sW)
3165
cbda9e7d0ee3 reportlab: new index support
rgbecker
parents: 3164
diff changeset
   286
3143
c704253bc72a Added support for multi-level and alphabetical indexes.
jonas
parents: 3141
diff changeset
   287
def makeTuple(x):
c704253bc72a Added support for multi-level and alphabetical indexes.
jonas
parents: 3141
diff changeset
   288
    if hasattr(x, '__iter__'):
c704253bc72a Added support for multi-level and alphabetical indexes.
jonas
parents: 3141
diff changeset
   289
        return tuple(x)
c704253bc72a Added support for multi-level and alphabetical indexes.
jonas
parents: 3141
diff changeset
   290
    return (x,)
1444
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   291
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   292
class SimpleIndex(IndexingFlowable):
3173
ded6e2bbf425 More documentation for SimpleIndex.
jonas
parents: 3171
diff changeset
   293
    """Creates multi level indexes.
ded6e2bbf425 More documentation for SimpleIndex.
jonas
parents: 3171
diff changeset
   294
    The styling can be cutomized and alphabetic headers turned on and off.
ded6e2bbf425 More documentation for SimpleIndex.
jonas
parents: 3171
diff changeset
   295
    """
1444
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   296
3164
0c60143b507e Added setup method and headers parameter. AlphabeticalIndex is now deprecated.
jonas
parents: 3162
diff changeset
   297
    def __init__(self, **kwargs):
3173
ded6e2bbf425 More documentation for SimpleIndex.
jonas
parents: 3171
diff changeset
   298
        """
ded6e2bbf425 More documentation for SimpleIndex.
jonas
parents: 3171
diff changeset
   299
        Constructor of SimpleIndex.
ded6e2bbf425 More documentation for SimpleIndex.
jonas
parents: 3171
diff changeset
   300
        Accepts the same arguments as the setup method.
ded6e2bbf425 More documentation for SimpleIndex.
jonas
parents: 3171
diff changeset
   301
        """
1444
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   302
        #keep stuff in a dictionary while building
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   303
        self._entries = {}
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   304
        self._lastEntries = {}
3140
c79e6a56495d tableofcontents: add support for index tableStyle
rgbecker
parents: 3136
diff changeset
   305
        self._flowable = None
3164
0c60143b507e Added setup method and headers parameter. AlphabeticalIndex is now deprecated.
jonas
parents: 3162
diff changeset
   306
        self.setup(**kwargs)
3165
cbda9e7d0ee3 reportlab: new index support
rgbecker
parents: 3164
diff changeset
   307
3187
2d5a6655556e tableofcontents/paraparser: allow for format and offset parameters
rgbecker
parents: 3173
diff changeset
   308
    def getFormatFunc(self,format):
2d5a6655556e tableofcontents/paraparser: allow for format and offset parameters
rgbecker
parents: 3173
diff changeset
   309
        try:
3853
b0e7b6056117 tableofcontents.py: fix getFormatFunc
robin
parents: 3850
diff changeset
   310
            D = {}
b0e7b6056117 tableofcontents.py: fix getFormatFunc
robin
parents: 3850
diff changeset
   311
            exec('from reportlab.lib.sequencer import _format_%s as formatFunc' % format, D)
b0e7b6056117 tableofcontents.py: fix getFormatFunc
robin
parents: 3850
diff changeset
   312
            return D['formatFunc']
3187
2d5a6655556e tableofcontents/paraparser: allow for format and offset parameters
rgbecker
parents: 3173
diff changeset
   313
        except ImportError:
2d5a6655556e tableofcontents/paraparser: allow for format and offset parameters
rgbecker
parents: 3173
diff changeset
   314
            raise ValueError('Unknown format %r' % format)
2d5a6655556e tableofcontents/paraparser: allow for format and offset parameters
rgbecker
parents: 3173
diff changeset
   315
2d5a6655556e tableofcontents/paraparser: allow for format and offset parameters
rgbecker
parents: 3173
diff changeset
   316
    def setup(self, style=None, dot=None, tableStyle=None, headers=True, name=None, format='123', offset=0):
3173
ded6e2bbf425 More documentation for SimpleIndex.
jonas
parents: 3171
diff changeset
   317
        """
ded6e2bbf425 More documentation for SimpleIndex.
jonas
parents: 3171
diff changeset
   318
        This method makes it possible to change styling and other parameters on an existing object.
4121
3b9e6fa286ad tableofcontents.py, doctemplate.py: fix indexing page number ordering bug found by Greg Jones bitbucket issue #40
robin
parents: 4058
diff changeset
   319
3173
ded6e2bbf425 More documentation for SimpleIndex.
jonas
parents: 3171
diff changeset
   320
        style is the paragraph style to use for index entries.
ded6e2bbf425 More documentation for SimpleIndex.
jonas
parents: 3171
diff changeset
   321
        dot can either be None or a string. If it's None, entries are immediatly followed by their
ded6e2bbf425 More documentation for SimpleIndex.
jonas
parents: 3171
diff changeset
   322
            corresponding page numbers. If it's a string, page numbers are aligned on the right side
ded6e2bbf425 More documentation for SimpleIndex.
jonas
parents: 3171
diff changeset
   323
            of the document and the gap filled with a repeating sequence of the string.
ded6e2bbf425 More documentation for SimpleIndex.
jonas
parents: 3171
diff changeset
   324
        tableStyle is the style used by the table which the index uses to draw itself. Use this to
ded6e2bbf425 More documentation for SimpleIndex.
jonas
parents: 3171
diff changeset
   325
            change properties like spacing between elements.
3348
d44de6313b58 workaround for widow/orphan control in simpleindex
andy
parents: 3327
diff changeset
   326
        headers is a boolean. If it is True, alphabetic headers are displayed in the Index when the first
4121
3b9e6fa286ad tableofcontents.py, doctemplate.py: fix indexing page number ordering bug found by Greg Jones bitbucket issue #40
robin
parents: 4058
diff changeset
   327
        letter changes. If False, we just output some extra space before the next item
3173
ded6e2bbf425 More documentation for SimpleIndex.
jonas
parents: 3171
diff changeset
   328
        name makes it possible to use several indexes in one document. If you want this use this
ded6e2bbf425 More documentation for SimpleIndex.
jonas
parents: 3171
diff changeset
   329
            parameter to give each index a unique name. You can then index a term by refering to the
ded6e2bbf425 More documentation for SimpleIndex.
jonas
parents: 3171
diff changeset
   330
            name of the index which it should appear in:
4121
3b9e6fa286ad tableofcontents.py, doctemplate.py: fix indexing page number ordering bug found by Greg Jones bitbucket issue #40
robin
parents: 4058
diff changeset
   331
3173
ded6e2bbf425 More documentation for SimpleIndex.
jonas
parents: 3171
diff changeset
   332
                <index item="term" name="myindex" />
3187
2d5a6655556e tableofcontents/paraparser: allow for format and offset parameters
rgbecker
parents: 3173
diff changeset
   333
2d5a6655556e tableofcontents/paraparser: allow for format and offset parameters
rgbecker
parents: 3173
diff changeset
   334
        format can be 'I', 'i', '123',  'ABC', 'abc'
3173
ded6e2bbf425 More documentation for SimpleIndex.
jonas
parents: 3171
diff changeset
   335
        """
4121
3b9e6fa286ad tableofcontents.py, doctemplate.py: fix indexing page number ordering bug found by Greg Jones bitbucket issue #40
robin
parents: 4058
diff changeset
   336
3135
3a2a8a52c1c1 reportlab.platypus: Fixes for SimpleIndex and TableOfContents.
jonas
parents: 3111
diff changeset
   337
        if style is None:
3a2a8a52c1c1 reportlab.platypus: Fixes for SimpleIndex and TableOfContents.
jonas
parents: 3111
diff changeset
   338
            style = ParagraphStyle(name='index',
3368
afa025c34493 reportlab: new base font mechanism more fully applied
rgbecker
parents: 3349
diff changeset
   339
                                        fontName=_baseFontName,
3135
3a2a8a52c1c1 reportlab.platypus: Fixes for SimpleIndex and TableOfContents.
jonas
parents: 3111
diff changeset
   340
                                        fontSize=11)
3a2a8a52c1c1 reportlab.platypus: Fixes for SimpleIndex and TableOfContents.
jonas
parents: 3111
diff changeset
   341
        self.textStyle = style
3140
c79e6a56495d tableofcontents: add support for index tableStyle
rgbecker
parents: 3136
diff changeset
   342
        self.tableStyle = tableStyle or defaultTableStyle
3136
3a4e339ebac8 platypus.tableofcontents: allow more flexibility for drawing dots in Index and TableOfContents. Set default for Index back to none.
jonas
parents: 3135
diff changeset
   343
        self.dot = dot
3164
0c60143b507e Added setup method and headers parameter. AlphabeticalIndex is now deprecated.
jonas
parents: 3162
diff changeset
   344
        self.headers = headers
3165
cbda9e7d0ee3 reportlab: new index support
rgbecker
parents: 3164
diff changeset
   345
        if name is None:
cbda9e7d0ee3 reportlab: new index support
rgbecker
parents: 3164
diff changeset
   346
            from reportlab.platypus.paraparser import DEFAULT_INDEX_NAME as name
cbda9e7d0ee3 reportlab: new index support
rgbecker
parents: 3164
diff changeset
   347
        self.name = name
3187
2d5a6655556e tableofcontents/paraparser: allow for format and offset parameters
rgbecker
parents: 3173
diff changeset
   348
        self.formatFunc = self.getFormatFunc(format)
2d5a6655556e tableofcontents/paraparser: allow for format and offset parameters
rgbecker
parents: 3173
diff changeset
   349
        self.offset = offset
3165
cbda9e7d0ee3 reportlab: new index support
rgbecker
parents: 3164
diff changeset
   350
cbda9e7d0ee3 reportlab: new index support
rgbecker
parents: 3164
diff changeset
   351
    def __call__(self,canv,kind,label):
3187
2d5a6655556e tableofcontents/paraparser: allow for format and offset parameters
rgbecker
parents: 3173
diff changeset
   352
        try:
3850
52c3600611ec utils.py: fix encode/decode_label
robin
parents: 3818
diff changeset
   353
            terms, format, offset = decode_label(label)
3187
2d5a6655556e tableofcontents/paraparser: allow for format and offset parameters
rgbecker
parents: 3173
diff changeset
   354
        except:
2d5a6655556e tableofcontents/paraparser: allow for format and offset parameters
rgbecker
parents: 3173
diff changeset
   355
            terms = label
2d5a6655556e tableofcontents/paraparser: allow for format and offset parameters
rgbecker
parents: 3173
diff changeset
   356
            format = offset = None
2d5a6655556e tableofcontents/paraparser: allow for format and offset parameters
rgbecker
parents: 3173
diff changeset
   357
        if format is None:
2d5a6655556e tableofcontents/paraparser: allow for format and offset parameters
rgbecker
parents: 3173
diff changeset
   358
            formatFunc = self.formatFunc
2d5a6655556e tableofcontents/paraparser: allow for format and offset parameters
rgbecker
parents: 3173
diff changeset
   359
        else:
2d5a6655556e tableofcontents/paraparser: allow for format and offset parameters
rgbecker
parents: 3173
diff changeset
   360
            formatFunc = self.getFormatFunc(format)
2d5a6655556e tableofcontents/paraparser: allow for format and offset parameters
rgbecker
parents: 3173
diff changeset
   361
        if offset is None:
2d5a6655556e tableofcontents/paraparser: allow for format and offset parameters
rgbecker
parents: 3173
diff changeset
   362
            offset = self.offset
2d5a6655556e tableofcontents/paraparser: allow for format and offset parameters
rgbecker
parents: 3173
diff changeset
   363
2d5a6655556e tableofcontents/paraparser: allow for format and offset parameters
rgbecker
parents: 3173
diff changeset
   364
        terms = commasplit(terms)
4121
3b9e6fa286ad tableofcontents.py, doctemplate.py: fix indexing page number ordering bug found by Greg Jones bitbucket issue #40
robin
parents: 4058
diff changeset
   365
        cPN = canv.getPageNumber()
3b9e6fa286ad tableofcontents.py, doctemplate.py: fix indexing page number ordering bug found by Greg Jones bitbucket issue #40
robin
parents: 4058
diff changeset
   366
        pns = formatFunc(cPN-offset)
3187
2d5a6655556e tableofcontents/paraparser: allow for format and offset parameters
rgbecker
parents: 3173
diff changeset
   367
        key = 'ix_%s_%s_p_%s' % (self.name, label, pns)
3165
cbda9e7d0ee3 reportlab: new index support
rgbecker
parents: 3164
diff changeset
   368
cbda9e7d0ee3 reportlab: new index support
rgbecker
parents: 3164
diff changeset
   369
        info = canv._curr_tx_info
cbda9e7d0ee3 reportlab: new index support
rgbecker
parents: 3164
diff changeset
   370
        canv.bookmarkHorizontal(key, info['cur_x'], info['cur_y'] + info['leading'])
4121
3b9e6fa286ad tableofcontents.py, doctemplate.py: fix indexing page number ordering bug found by Greg Jones bitbucket issue #40
robin
parents: 4058
diff changeset
   371
        self.addEntry(terms, (cPN,pns), key)
3165
cbda9e7d0ee3 reportlab: new index support
rgbecker
parents: 3164
diff changeset
   372
3162
77afde998aa9 Made Index entries clickable.
jonas
parents: 3146
diff changeset
   373
    def getCanvasMaker(self, canvasmaker=canvas.Canvas):
3165
cbda9e7d0ee3 reportlab: new index support
rgbecker
parents: 3164
diff changeset
   374
3162
77afde998aa9 Made Index entries clickable.
jonas
parents: 3146
diff changeset
   375
        def newcanvasmaker(*args, **kwargs):
77afde998aa9 Made Index entries clickable.
jonas
parents: 3146
diff changeset
   376
            from reportlab.pdfgen import canvas
77afde998aa9 Made Index entries clickable.
jonas
parents: 3146
diff changeset
   377
            c = canvasmaker(*args, **kwargs)
3165
cbda9e7d0ee3 reportlab: new index support
rgbecker
parents: 3164
diff changeset
   378
            setattr(c,self.name,self)
3162
77afde998aa9 Made Index entries clickable.
jonas
parents: 3146
diff changeset
   379
            return c
3165
cbda9e7d0ee3 reportlab: new index support
rgbecker
parents: 3164
diff changeset
   380
3162
77afde998aa9 Made Index entries clickable.
jonas
parents: 3146
diff changeset
   381
        return newcanvasmaker
3135
3a2a8a52c1c1 reportlab.platypus: Fixes for SimpleIndex and TableOfContents.
jonas
parents: 3111
diff changeset
   382
1444
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   383
    def isIndexing(self):
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   384
        return 1
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   385
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   386
    def isSatisfied(self):
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   387
        return (self._entries == self._lastEntries)
1683
7fa753e4420a Removed all trailing whitespace
andy_robinson
parents: 1559
diff changeset
   388
1444
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   389
    def beforeBuild(self):
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   390
        # keep track of the last run
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   391
        self._lastEntries = self._entries.copy()
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   392
        self.clearEntries()
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   393
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   394
    def clearEntries(self):
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   395
        self._entries = {}
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   396
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   397
    def notify(self, kind, stuff):
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   398
        """The notification hook called to register all kinds of events.
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   399
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   400
        Here we are interested in 'IndexEntry' events only.
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   401
        """
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   402
        if kind == 'IndexEntry':
4121
3b9e6fa286ad tableofcontents.py, doctemplate.py: fix indexing page number ordering bug found by Greg Jones bitbucket issue #40
robin
parents: 4058
diff changeset
   403
            text, pageNum = stuff
3b9e6fa286ad tableofcontents.py, doctemplate.py: fix indexing page number ordering bug found by Greg Jones bitbucket issue #40
robin
parents: 4058
diff changeset
   404
            self.addEntry(text, (self._canv.getPageNumber(),pageNum))
1444
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   405
3162
77afde998aa9 Made Index entries clickable.
jonas
parents: 3146
diff changeset
   406
    def addEntry(self, text, pageNum, key=None):
1444
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   407
        """Allows incremental buildup"""
3162
77afde998aa9 Made Index entries clickable.
jonas
parents: 3146
diff changeset
   408
        self._entries.setdefault(makeTuple(text),set([])).add((pageNum, key))
1444
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   409
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   410
    def split(self, availWidth, availHeight):
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   411
        """At this stage we do not care about splitting the entries,
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   412
        we will just return a list of platypus tables.  Presumably the
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   413
        calling app has a pointer to the original TableOfContents object;
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   414
        Platypus just sees tables.
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   415
        """
3140
c79e6a56495d tableofcontents: add support for index tableStyle
rgbecker
parents: 3136
diff changeset
   416
        return self._flowable.splitOn(self.canv,availWidth, availHeight)
1444
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   417
3162
77afde998aa9 Made Index entries clickable.
jonas
parents: 3146
diff changeset
   418
    def _getlastEntries(self, dummy=[(['Placeholder for index'],enumerate((None,)*3))]):
3143
c704253bc72a Added support for multi-level and alphabetical indexes.
jonas
parents: 3141
diff changeset
   419
        '''Return the last run's entries!  If there are none, returns dummy.'''
c704253bc72a Added support for multi-level and alphabetical indexes.
jonas
parents: 3141
diff changeset
   420
        if not self._lastEntries:
c704253bc72a Added support for multi-level and alphabetical indexes.
jonas
parents: 3141
diff changeset
   421
            if self._entries:
3721
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3617
diff changeset
   422
                return list(self._entries.items())
3143
c704253bc72a Added support for multi-level and alphabetical indexes.
jonas
parents: 3141
diff changeset
   423
            return dummy
3721
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3617
diff changeset
   424
        return list(self._lastEntries.items())
3165
cbda9e7d0ee3 reportlab: new index support
rgbecker
parents: 3164
diff changeset
   425
3140
c79e6a56495d tableofcontents: add support for index tableStyle
rgbecker
parents: 3136
diff changeset
   426
    def _build(self,availWidth,availHeight):
4178
b2c73e04465c fix indexing for accented stuff contributed by alexandrel_sgi @ bitbucket, version-->3.1.50
robin
parents: 4121
diff changeset
   427
        _tempEntries = [(tuple(asUnicode(t) for t in texts),pageNumbers)
b2c73e04465c fix indexing for accented stuff contributed by alexandrel_sgi @ bitbucket, version-->3.1.50
robin
parents: 4121
diff changeset
   428
                            for texts, pageNumbers in self._getlastEntries()]
3327
512eb20b0c3d more 2to3ing
andy
parents: 3294
diff changeset
   429
        def getkey(seq):
4178
b2c73e04465c fix indexing for accented stuff contributed by alexandrel_sgi @ bitbucket, version-->3.1.50
robin
parents: 4121
diff changeset
   430
            return [''.join((c for c in unicodedata.normalize('NFD', x.upper()) if unicodedata.category(c) != 'Mn')) for x in seq[0]]
3327
512eb20b0c3d more 2to3ing
andy
parents: 3294
diff changeset
   431
        _tempEntries.sort(key=getkey)
3164
0c60143b507e Added setup method and headers parameter. AlphabeticalIndex is now deprecated.
jonas
parents: 3162
diff changeset
   432
        leveloffset = self.headers and 1 or 0
1444
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   433
3135
3a2a8a52c1c1 reportlab.platypus: Fixes for SimpleIndex and TableOfContents.
jonas
parents: 3111
diff changeset
   434
        def drawIndexEntryEnd(canvas, kind, label):
3a2a8a52c1c1 reportlab.platypus: Fixes for SimpleIndex and TableOfContents.
jonas
parents: 3111
diff changeset
   435
            '''Callback to draw dots and page numbers after each entry.'''
3164
0c60143b507e Added setup method and headers parameter. AlphabeticalIndex is now deprecated.
jonas
parents: 3162
diff changeset
   436
            style = self.getLevelStyle(leveloffset)
4121
3b9e6fa286ad tableofcontents.py, doctemplate.py: fix indexing page number ordering bug found by Greg Jones bitbucket issue #40
robin
parents: 4058
diff changeset
   437
            pages = [(p[1],k) for p,k in sorted(decode_label(label))]
3162
77afde998aa9 Made Index entries clickable.
jonas
parents: 3146
diff changeset
   438
            drawPageNumbers(canvas, style, pages, availWidth, availHeight, self.dot)
3135
3a2a8a52c1c1 reportlab.platypus: Fixes for SimpleIndex and TableOfContents.
jonas
parents: 3111
diff changeset
   439
        self.canv.drawIndexEntryEnd = drawIndexEntryEnd
3a2a8a52c1c1 reportlab.platypus: Fixes for SimpleIndex and TableOfContents.
jonas
parents: 3111
diff changeset
   440
3164
0c60143b507e Added setup method and headers parameter. AlphabeticalIndex is now deprecated.
jonas
parents: 3162
diff changeset
   441
        alpha = ''
1444
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   442
        tableData = []
3143
c704253bc72a Added support for multi-level and alphabetical indexes.
jonas
parents: 3141
diff changeset
   443
        lastTexts = []
3348
d44de6313b58 workaround for widow/orphan control in simpleindex
andy
parents: 3327
diff changeset
   444
        alphaStyle = self.getLevelStyle(0)
3143
c704253bc72a Added support for multi-level and alphabetical indexes.
jonas
parents: 3141
diff changeset
   445
        for texts, pageNumbers in _tempEntries:
c704253bc72a Added support for multi-level and alphabetical indexes.
jonas
parents: 3141
diff changeset
   446
            texts = list(texts)
3348
d44de6313b58 workaround for widow/orphan control in simpleindex
andy
parents: 3327
diff changeset
   447
            #track when the first character changes; either output some extra
d44de6313b58 workaround for widow/orphan control in simpleindex
andy
parents: 3327
diff changeset
   448
            #space, or the first letter on a row of its own.  We cannot do
d44de6313b58 workaround for widow/orphan control in simpleindex
andy
parents: 3327
diff changeset
   449
            #widow/orphan control, sadly.
4178
b2c73e04465c fix indexing for accented stuff contributed by alexandrel_sgi @ bitbucket, version-->3.1.50
robin
parents: 4121
diff changeset
   450
            nalpha = ''.join((c for c in unicodedata.normalize('NFD', texts[0][0].upper()) if unicodedata.category(c) != 'Mn'))
3348
d44de6313b58 workaround for widow/orphan control in simpleindex
andy
parents: 3327
diff changeset
   451
            if alpha != nalpha:
d44de6313b58 workaround for widow/orphan control in simpleindex
andy
parents: 3327
diff changeset
   452
                alpha = nalpha
d44de6313b58 workaround for widow/orphan control in simpleindex
andy
parents: 3327
diff changeset
   453
                if self.headers:
d44de6313b58 workaround for widow/orphan control in simpleindex
andy
parents: 3327
diff changeset
   454
                    header = alpha
d44de6313b58 workaround for widow/orphan control in simpleindex
andy
parents: 3327
diff changeset
   455
                else:
d44de6313b58 workaround for widow/orphan control in simpleindex
andy
parents: 3327
diff changeset
   456
                    header = ' '
d44de6313b58 workaround for widow/orphan control in simpleindex
andy
parents: 3327
diff changeset
   457
                tableData.append([Spacer(1, alphaStyle.spaceBefore),])
d44de6313b58 workaround for widow/orphan control in simpleindex
andy
parents: 3327
diff changeset
   458
                tableData.append([Paragraph(header, alphaStyle),])
d44de6313b58 workaround for widow/orphan control in simpleindex
andy
parents: 3327
diff changeset
   459
                tableData.append([Spacer(1, alphaStyle.spaceAfter),])
3164
0c60143b507e Added setup method and headers parameter. AlphabeticalIndex is now deprecated.
jonas
parents: 3162
diff changeset
   460
4121
3b9e6fa286ad tableofcontents.py, doctemplate.py: fix indexing page number ordering bug found by Greg Jones bitbucket issue #40
robin
parents: 4058
diff changeset
   461
3143
c704253bc72a Added support for multi-level and alphabetical indexes.
jonas
parents: 3141
diff changeset
   462
            i, diff = listdiff(lastTexts, texts)
c704253bc72a Added support for multi-level and alphabetical indexes.
jonas
parents: 3141
diff changeset
   463
            if diff:
c704253bc72a Added support for multi-level and alphabetical indexes.
jonas
parents: 3141
diff changeset
   464
                lastTexts = texts
c704253bc72a Added support for multi-level and alphabetical indexes.
jonas
parents: 3141
diff changeset
   465
                texts = texts[i:]
3850
52c3600611ec utils.py: fix encode/decode_label
robin
parents: 3818
diff changeset
   466
            label = encode_label(list(pageNumbers))
3170
91786d2240d0 Using base 64 encoding to make sure sgmllib does not mess with the whitespace in the attribute.
jonas
parents: 3167
diff changeset
   467
            texts[-1] = '%s<onDraw name="drawIndexEntryEnd" label="%s"/>' % (texts[-1], label)
3143
c704253bc72a Added support for multi-level and alphabetical indexes.
jonas
parents: 3141
diff changeset
   468
            for text in texts:
4121
3b9e6fa286ad tableofcontents.py, doctemplate.py: fix indexing page number ordering bug found by Greg Jones bitbucket issue #40
robin
parents: 4058
diff changeset
   469
                #Platypus and RML differ on how parsed XML attributes are escaped.
3349
b67514b01536 Index display code now handles 'M&S'-like attributes however they are escaped
andy
parents: 3348
diff changeset
   470
                #e.g. <index item="M&S"/>.  The only place this seems to bite us is in
b67514b01536 Index display code now handles 'M&S'-like attributes however they are escaped
andy
parents: 3348
diff changeset
   471
                #the index entries so work around it here.
4121
3b9e6fa286ad tableofcontents.py, doctemplate.py: fix indexing page number ordering bug found by Greg Jones bitbucket issue #40
robin
parents: 4058
diff changeset
   472
                text = escapeOnce(text)
3b9e6fa286ad tableofcontents.py, doctemplate.py: fix indexing page number ordering bug found by Greg Jones bitbucket issue #40
robin
parents: 4058
diff changeset
   473
3164
0c60143b507e Added setup method and headers parameter. AlphabeticalIndex is now deprecated.
jonas
parents: 3162
diff changeset
   474
                style = self.getLevelStyle(i+leveloffset)
3143
c704253bc72a Added support for multi-level and alphabetical indexes.
jonas
parents: 3141
diff changeset
   475
                para = Paragraph(text, style)
c704253bc72a Added support for multi-level and alphabetical indexes.
jonas
parents: 3141
diff changeset
   476
                if style.spaceBefore:
c704253bc72a Added support for multi-level and alphabetical indexes.
jonas
parents: 3141
diff changeset
   477
                    tableData.append([Spacer(1, style.spaceBefore),])
c704253bc72a Added support for multi-level and alphabetical indexes.
jonas
parents: 3141
diff changeset
   478
                tableData.append([para,])
c704253bc72a Added support for multi-level and alphabetical indexes.
jonas
parents: 3141
diff changeset
   479
                i += 1
3164
0c60143b507e Added setup method and headers parameter. AlphabeticalIndex is now deprecated.
jonas
parents: 3162
diff changeset
   480
3140
c79e6a56495d tableofcontents: add support for index tableStyle
rgbecker
parents: 3136
diff changeset
   481
        self._flowable = Table(tableData, colWidths=[availWidth], style=self.tableStyle)
1444
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   482
3140
c79e6a56495d tableofcontents: add support for index tableStyle
rgbecker
parents: 3136
diff changeset
   483
    def wrap(self, availWidth, availHeight):
c79e6a56495d tableofcontents: add support for index tableStyle
rgbecker
parents: 3136
diff changeset
   484
        "All table properties should be known by now."
c79e6a56495d tableofcontents: add support for index tableStyle
rgbecker
parents: 3136
diff changeset
   485
        self._build(availWidth,availHeight)
c79e6a56495d tableofcontents: add support for index tableStyle
rgbecker
parents: 3136
diff changeset
   486
        self.width, self.height = self._flowable.wrapOn(self.canv,availWidth, availHeight)
3111
86a3158c50bd reportlab: improved support for onDraw and SimpleIndex
rgbecker
parents: 3060
diff changeset
   487
        return self.width, self.height
1444
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   488
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   489
    def drawOn(self, canvas, x, y, _sW=0):
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   490
        """Don't do this at home!  The standard calls for implementing
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   491
        draw(); we are hooking this in order to delegate ALL the drawing
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   492
        work to the embedded table object.
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   493
        """
3140
c79e6a56495d tableofcontents: add support for index tableStyle
rgbecker
parents: 3136
diff changeset
   494
        self._flowable.drawOn(canvas, x, y, _sW)
1444
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   495
3111
86a3158c50bd reportlab: improved support for onDraw and SimpleIndex
rgbecker
parents: 3060
diff changeset
   496
    def draw(self):
3140
c79e6a56495d tableofcontents: add support for index tableStyle
rgbecker
parents: 3136
diff changeset
   497
        t = self._flowable
3111
86a3158c50bd reportlab: improved support for onDraw and SimpleIndex
rgbecker
parents: 3060
diff changeset
   498
        ocanv = getattr(t,'canv',None)
86a3158c50bd reportlab: improved support for onDraw and SimpleIndex
rgbecker
parents: 3060
diff changeset
   499
        if not ocanv:
86a3158c50bd reportlab: improved support for onDraw and SimpleIndex
rgbecker
parents: 3060
diff changeset
   500
            t.canv = self.canv
86a3158c50bd reportlab: improved support for onDraw and SimpleIndex
rgbecker
parents: 3060
diff changeset
   501
        try:
86a3158c50bd reportlab: improved support for onDraw and SimpleIndex
rgbecker
parents: 3060
diff changeset
   502
            t.draw()
86a3158c50bd reportlab: improved support for onDraw and SimpleIndex
rgbecker
parents: 3060
diff changeset
   503
        finally:
86a3158c50bd reportlab: improved support for onDraw and SimpleIndex
rgbecker
parents: 3060
diff changeset
   504
            if not ocanv:
86a3158c50bd reportlab: improved support for onDraw and SimpleIndex
rgbecker
parents: 3060
diff changeset
   505
                del t.canv
86a3158c50bd reportlab: improved support for onDraw and SimpleIndex
rgbecker
parents: 3060
diff changeset
   506
3143
c704253bc72a Added support for multi-level and alphabetical indexes.
jonas
parents: 3141
diff changeset
   507
    def getLevelStyle(self, n):
c704253bc72a Added support for multi-level and alphabetical indexes.
jonas
parents: 3141
diff changeset
   508
        '''Returns the style for level n, generating and caching styles on demand if not present.'''
c704253bc72a Added support for multi-level and alphabetical indexes.
jonas
parents: 3141
diff changeset
   509
        if not hasattr(self.textStyle, '__iter__'):
c704253bc72a Added support for multi-level and alphabetical indexes.
jonas
parents: 3141
diff changeset
   510
            self.textStyle = [self.textStyle]
c704253bc72a Added support for multi-level and alphabetical indexes.
jonas
parents: 3141
diff changeset
   511
        try:
c704253bc72a Added support for multi-level and alphabetical indexes.
jonas
parents: 3141
diff changeset
   512
            return self.textStyle[n]
c704253bc72a Added support for multi-level and alphabetical indexes.
jonas
parents: 3141
diff changeset
   513
        except IndexError:
c704253bc72a Added support for multi-level and alphabetical indexes.
jonas
parents: 3141
diff changeset
   514
            self.textStyle = list(self.textStyle)
c704253bc72a Added support for multi-level and alphabetical indexes.
jonas
parents: 3141
diff changeset
   515
            prevstyle = self.getLevelStyle(n-1)
c704253bc72a Added support for multi-level and alphabetical indexes.
jonas
parents: 3141
diff changeset
   516
            self.textStyle.append(ParagraphStyle(
c704253bc72a Added support for multi-level and alphabetical indexes.
jonas
parents: 3141
diff changeset
   517
                    name='%s-%d-indented' % (prevstyle.name, n),
c704253bc72a Added support for multi-level and alphabetical indexes.
jonas
parents: 3141
diff changeset
   518
                    parent=prevstyle,
3146
4732d02eae94 Added support for an unlimited number of TOC levels with default styles.
jonas
parents: 3145
diff changeset
   519
                    firstLineIndent = prevstyle.firstLineIndent+.2*cm,
4732d02eae94 Added support for an unlimited number of TOC levels with default styles.
jonas
parents: 3145
diff changeset
   520
                    leftIndent = prevstyle.leftIndent+.2*cm))
3143
c704253bc72a Added support for multi-level and alphabetical indexes.
jonas
parents: 3141
diff changeset
   521
            return self.textStyle[n]
c704253bc72a Added support for multi-level and alphabetical indexes.
jonas
parents: 3141
diff changeset
   522
3164
0c60143b507e Added setup method and headers parameter. AlphabeticalIndex is now deprecated.
jonas
parents: 3162
diff changeset
   523
AlphabeticIndex =  SimpleIndex
3141
e080fe8ab372 platypus.tableofcontents: Added an alphabetic grouping indexing class.
jonas
parents: 3140
diff changeset
   524
3143
c704253bc72a Added support for multi-level and alphabetical indexes.
jonas
parents: 3141
diff changeset
   525
def listdiff(l1, l2):
c704253bc72a Added support for multi-level and alphabetical indexes.
jonas
parents: 3141
diff changeset
   526
    m = min(len(l1), len(l2))
c704253bc72a Added support for multi-level and alphabetical indexes.
jonas
parents: 3141
diff changeset
   527
    for i in range(m):
c704253bc72a Added support for multi-level and alphabetical indexes.
jonas
parents: 3141
diff changeset
   528
        if l1[i] != l2[i]:
c704253bc72a Added support for multi-level and alphabetical indexes.
jonas
parents: 3141
diff changeset
   529
            return i, l2[i:]
c704253bc72a Added support for multi-level and alphabetical indexes.
jonas
parents: 3141
diff changeset
   530
    return m, l2[m:]
c704253bc72a Added support for multi-level and alphabetical indexes.
jonas
parents: 3141
diff changeset
   531
1444
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   532
class ReferenceText(IndexingFlowable):
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   533
    """Fakery to illustrate how a reference would work if we could
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   534
    put it in a paragraph."""
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   535
    def __init__(self, textPattern, targetKey):
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   536
        self.textPattern = textPattern
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   537
        self.target = targetKey
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   538
        self.paraStyle = ParagraphStyle('tmp')
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   539
        self._lastPageNum = None
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   540
        self._pageNum = -999
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   541
        self._para = None
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   542
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   543
    def beforeBuild(self):
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   544
        self._lastPageNum = self._pageNum
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   545
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   546
    def notify(self, kind, stuff):
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   547
        if kind == 'Target':
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   548
            (key, pageNum) = stuff
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   549
            if key == self.target:
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   550
                self._pageNum = pageNum
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   551
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   552
    def wrap(self, availWidth, availHeight):
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   553
        text = self.textPattern % self._lastPageNum
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   554
        self._para = Paragraph(text, self.paraStyle)
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   555
        return self._para.wrap(availWidth, availHeight)
1683
7fa753e4420a Removed all trailing whitespace
andy_robinson
parents: 1559
diff changeset
   556
1444
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   557
    def drawOn(self, canvas, x, y, _sW=0):
454d117af3a5 Missed a checkin
andy_robinson
parents: 1440
diff changeset
   558
        self._para.drawOn(canvas, x, y, _sW)