author | robin |
Thu, 24 Oct 2019 16:07:15 +0100 | |
changeset 4551 | d357e2acc856 |
parent 4528 | e09377955af8 |
child 4709 | 1dcf7b3f7127 |
permissions | -rw-r--r-- |
4330 | 1 |
#Copyright ReportLab Europe Ltd. 2000-2017 |
817 | 2 |
#see license.txt for license details |
4528 | 3 |
#history https://hg.reportlab.com/hg-public/reportlab/log/tip/src/reportlab/platypus/tableofcontents.py |
3032 | 4 |
|
4551 | 5 |
__version__='3.5.32' |
3032 | 6 |
__doc__="""Experimental class to generate Tables of Contents easily |
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 | 9 |
create automatically a table of tontents for Platypus documents like |
10 |
this: |
|
11 |
||
12 |
story = [] |
|
1440
243d35446390
Removed 0 from multiBuild stuff prior to further changes;
andy_robinson
parents:
817
diff
changeset
|
13 |
toc = TableOfContents() |
754 | 14 |
story.append(toc) |
15 |
# some heading paragraphs here... |
|
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 | 18 |
|
19 |
The data needed to create the table is a list of (level, text, pageNum) |
|
20 |
triplets, plus some paragraph styles for each level of the table itself. |
|
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 | 23 |
method with appropriate data like this: |
24 |
||
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 | 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 | 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 | 38 |
|
39 |
The level<NUMBER>ParaStyle variables are the paragraph styles used |
|
40 |
to format the entries in the table of contents. Their indentation |
|
41 |
is calculated like this: each entry starts at a multiple of some |
|
42 |
constant named delta. If one entry spans more than one line, all |
|
43 |
lines after the first are indented by the same constant named |
|
1683 | 44 |
epsilon. |
754 | 45 |
""" |
3032 | 46 |
|
754 | 47 |
from reportlab.lib import enums |
48 |
from reportlab.lib.units import cm |
|
4338
6223e7fa13f6
reproducibility fixes; version --> 3.4.3
robin <robin@reportlab.com>
parents:
4330
diff
changeset
|
49 |
from reportlab.lib.utils import commasplit, escapeOnce, encode_label, decode_label, strTypes, asUnicode, asNative |
3368
afa025c34493
reportlab: new base font mechanism more fully applied
rgbecker
parents:
3349
diff
changeset
|
50 |
from reportlab.lib.styles import ParagraphStyle, _baseFontName |
4551 | 51 |
from reportlab.lib import sequencer as rl_sequencer |
754 | 52 |
from reportlab.platypus.paragraph import Paragraph |
1440
243d35446390
Removed 0 from multiBuild stuff prior to further changes;
andy_robinson
parents:
817
diff
changeset
|
53 |
from reportlab.platypus.doctemplate import IndexingFlowable |
754 | 54 |
from reportlab.platypus.tables import TableStyle, Table |
3111
86a3158c50bd
reportlab: improved support for onDraw and SimpleIndex
rgbecker
parents:
3060
diff
changeset
|
55 |
from reportlab.platypus.flowables import Spacer, Flowable |
3049 | 56 |
from reportlab.pdfbase.pdfmetrics import stringWidth |
3162 | 57 |
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
|
58 |
import unicodedata |
4551 | 59 |
from ast import literal_eval |
3162 | 60 |
|
61 |
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
|
62 |
from xml.sax.saxutils import unescape |
3162 | 63 |
return unescape(txt, {"'": "'", """: '"'}) |
64 |
||
3111
86a3158c50bd
reportlab: improved support for onDraw and SimpleIndex
rgbecker
parents:
3060
diff
changeset
|
65 |
try: |
86a3158c50bd
reportlab: improved support for onDraw and SimpleIndex
rgbecker
parents:
3060
diff
changeset
|
66 |
set |
86a3158c50bd
reportlab: improved support for onDraw and SimpleIndex
rgbecker
parents:
3060
diff
changeset
|
67 |
except: |
86a3158c50bd
reportlab: improved support for onDraw and SimpleIndex
rgbecker
parents:
3060
diff
changeset
|
68 |
class set(list): |
86a3158c50bd
reportlab: improved support for onDraw and SimpleIndex
rgbecker
parents:
3060
diff
changeset
|
69 |
def add(self,x): |
86a3158c50bd
reportlab: improved support for onDraw and SimpleIndex
rgbecker
parents:
3060
diff
changeset
|
70 |
if x not in self: |
86a3158c50bd
reportlab: improved support for onDraw and SimpleIndex
rgbecker
parents:
3060
diff
changeset
|
71 |
list.append(self,x) |
3165 | 72 |
|
4180
2ee5e4cd860f
add formatter and argument processing to tabelOfContents; version-->3.1.52
robin
parents:
4178
diff
changeset
|
73 |
def drawPageNumbers(canvas, style, pages, availWidth, availHeight, dot=' . ', formatter=None): |
3135
3a2a8a52c1c1
reportlab.platypus: Fixes for SimpleIndex and TableOfContents.
jonas
parents:
3111
diff
changeset
|
74 |
''' |
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
|
75 |
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
|
76 |
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
|
77 |
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
|
78 |
the gap is filled with it. |
3135
3a2a8a52c1c1
reportlab.platypus: Fixes for SimpleIndex and TableOfContents.
jonas
parents:
3111
diff
changeset
|
79 |
''' |
3166 | 80 |
pagestr = ', '.join([str(p) for p, _ in pages]) |
3135
3a2a8a52c1c1
reportlab.platypus: Fixes for SimpleIndex and TableOfContents.
jonas
parents:
3111
diff
changeset
|
81 |
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
|
82 |
|
3348 | 83 |
fontSize = style.fontSize |
84 |
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
|
85 |
|
3348 | 86 |
#if it's too long to fit, we need to shrink to fit in 10% increments. |
87 |
#it would be very hard to output multiline entries. |
|
88 |
#however, we impose a minimum size of 1 point as we don't want an |
|
89 |
#infinite loop. Ultimately we should allow a TOC entry to spill |
|
90 |
#over onto a second line if needed. |
|
91 |
freeWidth = availWidth-x |
|
92 |
while pagestrw > freeWidth and fontSize >= 1.0: |
|
93 |
fontSize = 0.9 * fontSize |
|
94 |
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
|
95 |
|
3b9e6fa286ad
tableofcontents.py, doctemplate.py: fix indexing page number ordering bug found by Greg Jones bitbucket issue #40
robin
parents:
4058
diff
changeset
|
96 |
|
4058
a97a88afcfe8
tableofcontents.py: try and allow for differecnt dot kinds
robin
parents:
3853
diff
changeset
|
97 |
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
|
98 |
if dot: |
3348 | 99 |
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
|
100 |
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
|
101 |
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
|
102 |
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
|
103 |
text = '%s%s' % (dotsn * dot, pagestr) |
3162 | 104 |
newx = availWidth - dotsn*dotw - pagestrw |
105 |
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
|
106 |
elif dot is None: |
3143
c704253bc72a
Added support for multi-level and alphabetical indexes.
jonas
parents:
3141
diff
changeset
|
107 |
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
|
108 |
newx = x |
3162 | 109 |
pagex = newx |
3135
3a2a8a52c1c1
reportlab.platypus: Fixes for SimpleIndex and TableOfContents.
jonas
parents:
3111
diff
changeset
|
110 |
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
|
111 |
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
|
112 |
|
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
|
113 |
tx = canvas.beginText(newx, y) |
3348 | 114 |
tx.setFont(style.fontName, fontSize) |
3135
3a2a8a52c1c1
reportlab.platypus: Fixes for SimpleIndex and TableOfContents.
jonas
parents:
3111
diff
changeset
|
115 |
tx.setFillColor(style.textColor) |
3a2a8a52c1c1
reportlab.platypus: Fixes for SimpleIndex and TableOfContents.
jonas
parents:
3111
diff
changeset
|
116 |
tx.textLine(text) |
3a2a8a52c1c1
reportlab.platypus: Fixes for SimpleIndex and TableOfContents.
jonas
parents:
3111
diff
changeset
|
117 |
canvas.drawText(tx) |
3165 | 118 |
|
3348 | 119 |
commaw = stringWidth(', ', style.fontName, fontSize) |
3162 | 120 |
for p, key in pages: |
121 |
if not key: |
|
122 |
continue |
|
3348 | 123 |
w = stringWidth(str(p), style.fontName, fontSize) |
3162 | 124 |
canvas.linkRect('', key, (pagex, y, pagex+w, y+style.leading), relative=1) |
125 |
pagex += w + commaw |
|
3135
3a2a8a52c1c1
reportlab.platypus: Fixes for SimpleIndex and TableOfContents.
jonas
parents:
3111
diff
changeset
|
126 |
|
754 | 127 |
# Default paragraph styles for tables of contents. |
128 |
# (This could also be generated automatically or even |
|
129 |
# on-demand if it is not known how many levels the |
|
130 |
# TOC will finally need to display...) |
|
131 |
||
132 |
delta = 1*cm |
|
133 |
epsilon = 0.5*cm |
|
134 |
||
3146
4732d02eae94
Added support for an unlimited number of TOC levels with default styles.
jonas
parents:
3145
diff
changeset
|
135 |
defaultLevelStyles = [ |
4732d02eae94
Added support for an unlimited number of TOC levels with default styles.
jonas
parents:
3145
diff
changeset
|
136 |
ParagraphStyle( |
4732d02eae94
Added support for an unlimited number of TOC levels with default styles.
jonas
parents:
3145
diff
changeset
|
137 |
name='Level 0', |
3368
afa025c34493
reportlab: new base font mechanism more fully applied
rgbecker
parents:
3349
diff
changeset
|
138 |
fontName=_baseFontName, |
3146
4732d02eae94
Added support for an unlimited number of TOC levels with default styles.
jonas
parents:
3145
diff
changeset
|
139 |
fontSize=10, |
4732d02eae94
Added support for an unlimited number of TOC levels with default styles.
jonas
parents:
3145
diff
changeset
|
140 |
leading=11, |
4732d02eae94
Added support for an unlimited number of TOC levels with default styles.
jonas
parents:
3145
diff
changeset
|
141 |
firstLineIndent = 0, |
4732d02eae94
Added support for an unlimited number of TOC levels with default styles.
jonas
parents:
3145
diff
changeset
|
142 |
leftIndent = epsilon)] |
754 | 143 |
|
144 |
defaultTableStyle = \ |
|
3135
3a2a8a52c1c1
reportlab.platypus: Fixes for SimpleIndex and TableOfContents.
jonas
parents:
3111
diff
changeset
|
145 |
TableStyle([ |
3a2a8a52c1c1
reportlab.platypus: Fixes for SimpleIndex and TableOfContents.
jonas
parents:
3111
diff
changeset
|
146 |
('VALIGN', (0,0), (-1,-1), 'TOP'), |
3a2a8a52c1c1
reportlab.platypus: Fixes for SimpleIndex and TableOfContents.
jonas
parents:
3111
diff
changeset
|
147 |
('RIGHTPADDING', (0,0), (-1,-1), 0), |
3a2a8a52c1c1
reportlab.platypus: Fixes for SimpleIndex and TableOfContents.
jonas
parents:
3111
diff
changeset
|
148 |
('LEFTPADDING', (0,0), (-1,-1), 0), |
3a2a8a52c1c1
reportlab.platypus: Fixes for SimpleIndex and TableOfContents.
jonas
parents:
3111
diff
changeset
|
149 |
]) |
754 | 150 |
|
1440
243d35446390
Removed 0 from multiBuild stuff prior to further changes;
andy_robinson
parents:
817
diff
changeset
|
151 |
class TableOfContents(IndexingFlowable): |
754 | 152 |
"""This creates a formatted table of contents. |
153 |
||
154 |
It presumes a correct block of data is passed in. |
|
155 |
The data block contains a list of (level, text, pageNumber) |
|
156 |
triplets. You can supply a paragraph style for each level |
|
157 |
(starting at zero). |
|
3049 | 158 |
Set dotsMinLevel to determine from which level on a line of |
159 |
dots should be drawn between the text and the page number. |
|
160 |
If dotsMinLevel is set to a negative value, no dotted lines are drawn. |
|
754 | 161 |
""" |
162 |
||
4180
2ee5e4cd860f
add formatter and argument processing to tabelOfContents; version-->3.1.52
robin
parents:
4178
diff
changeset
|
163 |
def __init__(self,**kwds): |
4369
46b44c48cdc0
fix bug in TableOfContents.__init__ reported by danilovmy @ bitbucket
robin <robin@reportlab.com>
parents:
4339
diff
changeset
|
164 |
self.rightColumnWidth = kwds.pop('rightColumnWidth',72) |
46b44c48cdc0
fix bug in TableOfContents.__init__ reported by danilovmy @ bitbucket
robin <robin@reportlab.com>
parents:
4339
diff
changeset
|
165 |
self.levelStyles = kwds.pop('levelStyles',defaultLevelStyles) |
46b44c48cdc0
fix bug in TableOfContents.__init__ reported by danilovmy @ bitbucket
robin <robin@reportlab.com>
parents:
4339
diff
changeset
|
166 |
self.tableStyle = kwds.pop('tableStyle',defaultTableStyle) |
46b44c48cdc0
fix bug in TableOfContents.__init__ reported by danilovmy @ bitbucket
robin <robin@reportlab.com>
parents:
4339
diff
changeset
|
167 |
self.dotsMinLevel = kwds.pop('dotsMinLevel',1) |
46b44c48cdc0
fix bug in TableOfContents.__init__ reported by danilovmy @ bitbucket
robin <robin@reportlab.com>
parents:
4339
diff
changeset
|
168 |
self.formatter = kwds.pop('formatter',None) |
4180
2ee5e4cd860f
add formatter and argument processing to tabelOfContents; version-->3.1.52
robin
parents:
4178
diff
changeset
|
169 |
if kwds: raise ValueError('unexpected keyword arguments %s' % ', '.join(kwds.keys())) |
754 | 170 |
self._table = None |
171 |
self._entries = [] |
|
172 |
self._lastEntries = [] |
|
173 |
||
174 |
def beforeBuild(self): |
|
175 |
# keep track of the last run |
|
176 |
self._lastEntries = self._entries[:] |
|
177 |
self.clearEntries() |
|
178 |
||
179 |
def isIndexing(self): |
|
180 |
return 1 |
|
181 |
||
182 |
def isSatisfied(self): |
|
183 |
return (self._entries == self._lastEntries) |
|
184 |
||
185 |
def notify(self, kind, stuff): |
|
186 |
"""The notification hook called to register all kinds of events. |
|
187 |
||
188 |
Here we are interested in 'TOCEntry' events only. |
|
189 |
""" |
|
190 |
if kind == 'TOCEntry': |
|
3060
eeedb611fa67
Added feature to have clickable TableOfContents entries (ToDo 978).
jonas
parents:
3049
diff
changeset
|
191 |
self.addEntry(*stuff) |
754 | 192 |
|
193 |
def clearEntries(self): |
|
194 |
self._entries = [] |
|
195 |
||
3146
4732d02eae94
Added support for an unlimited number of TOC levels with default styles.
jonas
parents:
3145
diff
changeset
|
196 |
def getLevelStyle(self, n): |
4732d02eae94
Added support for an unlimited number of TOC levels with default styles.
jonas
parents:
3145
diff
changeset
|
197 |
'''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
|
198 |
try: |
4732d02eae94
Added support for an unlimited number of TOC levels with default styles.
jonas
parents:
3145
diff
changeset
|
199 |
return self.levelStyles[n] |
4732d02eae94
Added support for an unlimited number of TOC levels with default styles.
jonas
parents:
3145
diff
changeset
|
200 |
except IndexError: |
4732d02eae94
Added support for an unlimited number of TOC levels with default styles.
jonas
parents:
3145
diff
changeset
|
201 |
prevstyle = self.getLevelStyle(n-1) |
4732d02eae94
Added support for an unlimited number of TOC levels with default styles.
jonas
parents:
3145
diff
changeset
|
202 |
self.levelStyles.append(ParagraphStyle( |
4732d02eae94
Added support for an unlimited number of TOC levels with default styles.
jonas
parents:
3145
diff
changeset
|
203 |
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
|
204 |
parent=prevstyle, |
4732d02eae94
Added support for an unlimited number of TOC levels with default styles.
jonas
parents:
3145
diff
changeset
|
205 |
firstLineIndent = prevstyle.firstLineIndent+delta, |
4732d02eae94
Added support for an unlimited number of TOC levels with default styles.
jonas
parents:
3145
diff
changeset
|
206 |
leftIndent = prevstyle.leftIndent+delta)) |
4732d02eae94
Added support for an unlimited number of TOC levels with default styles.
jonas
parents:
3145
diff
changeset
|
207 |
return self.levelStyles[n] |
754 | 208 |
|
3060
eeedb611fa67
Added feature to have clickable TableOfContents entries (ToDo 978).
jonas
parents:
3049
diff
changeset
|
209 |
def addEntry(self, level, text, pageNum, key=None): |
754 | 210 |
"""Adds one entry to the table of contents. |
211 |
||
212 |
This allows incremental buildup by a doctemplate. |
|
213 |
Requires that enough styles are defined.""" |
|
214 |
||
215 |
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
|
216 |
self._entries.append((level, text, pageNum, key)) |
754 | 217 |
|
218 |
||
219 |
def addEntries(self, listOfEntries): |
|
220 |
"""Bulk creation of entries in the table of contents. |
|
221 |
||
222 |
If you knew the titles but not the page numbers, you could |
|
223 |
supply them to get sensible output on the first run.""" |
|
1683 | 224 |
|
3060
eeedb611fa67
Added feature to have clickable TableOfContents entries (ToDo 978).
jonas
parents:
3049
diff
changeset
|
225 |
for entryargs in listOfEntries: |
eeedb611fa67
Added feature to have clickable TableOfContents entries (ToDo 978).
jonas
parents:
3049
diff
changeset
|
226 |
self.addEntry(*entryargs) |
754 | 227 |
|
228 |
||
229 |
def wrap(self, availWidth, availHeight): |
|
230 |
"All table properties should be known by now." |
|
231 |
||
232 |
# makes an internal table which does all the work. |
|
233 |
# we draw the LAST RUN's entries! If there are |
|
234 |
# none, we make some dummy data to keep the table |
|
235 |
# from complaining |
|
236 |
if len(self._lastEntries) == 0: |
|
3060
eeedb611fa67
Added feature to have clickable TableOfContents entries (ToDo 978).
jonas
parents:
3049
diff
changeset
|
237 |
_tempEntries = [(0,'Placeholder for table of contents',0,None)] |
754 | 238 |
else: |
239 |
_tempEntries = self._lastEntries |
|
240 |
||
3049 | 241 |
def drawTOCEntryEnd(canvas, kind, label): |
242 |
'''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
|
243 |
label = label.split(',') |
4551 | 244 |
page, level, key = int(label[0]), int(label[1]), literal_eval(label[2]) |
3146
4732d02eae94
Added support for an unlimited number of TOC levels with default styles.
jonas
parents:
3145
diff
changeset
|
245 |
style = self.getLevelStyle(level) |
3145 | 246 |
if self.dotsMinLevel >= 0 and level >= self.dotsMinLevel: |
3165 | 247 |
dot = ' . ' |
248 |
else: |
|
3145 | 249 |
dot = '' |
4180
2ee5e4cd860f
add formatter and argument processing to tabelOfContents; version-->3.1.52
robin
parents:
4178
diff
changeset
|
250 |
if self.formatter: page = self.formatter(page) |
3294
f60b7cb499aa
tableofcontents.py: fix passing of key to onDraw for TOC
rgbecker
parents:
3187
diff
changeset
|
251 |
drawPageNumbers(canvas, style, [(page, key)], availWidth, availHeight, dot) |
3049 | 252 |
self.canv.drawTOCEntryEnd = drawTOCEntryEnd |
253 |
||
754 | 254 |
tableData = [] |
3060
eeedb611fa67
Added feature to have clickable TableOfContents entries (ToDo 978).
jonas
parents:
3049
diff
changeset
|
255 |
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
|
256 |
style = self.getLevelStyle(level) |
3060
eeedb611fa67
Added feature to have clickable TableOfContents entries (ToDo 978).
jonas
parents:
3049
diff
changeset
|
257 |
if key: |
eeedb611fa67
Added feature to have clickable TableOfContents entries (ToDo 978).
jonas
parents:
3049
diff
changeset
|
258 |
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
|
259 |
keyVal = repr(key).replace(',','\\x2c').replace('"','\\x2c') |
f60b7cb499aa
tableofcontents.py: fix passing of key to onDraw for TOC
rgbecker
parents:
3187
diff
changeset
|
260 |
else: |
f60b7cb499aa
tableofcontents.py: fix passing of key to onDraw for TOC
rgbecker
parents:
3187
diff
changeset
|
261 |
keyVal = None |
f60b7cb499aa
tableofcontents.py: fix passing of key to onDraw for TOC
rgbecker
parents:
3187
diff
changeset
|
262 |
para = Paragraph('%s<onDraw name="drawTOCEntryEnd" label="%d,%d,%s"/>' % (text, pageNum, level, keyVal), style) |
3049 | 263 |
if style.spaceBefore: |
264 |
tableData.append([Spacer(1, style.spaceBefore),]) |
|
265 |
tableData.append([para,]) |
|
754 | 266 |
|
3135
3a2a8a52c1c1
reportlab.platypus: Fixes for SimpleIndex and TableOfContents.
jonas
parents:
3111
diff
changeset
|
267 |
self._table = Table(tableData, colWidths=(availWidth,), style=self.tableStyle) |
754 | 268 |
|
1493 | 269 |
self.width, self.height = self._table.wrapOn(self.canv,availWidth, availHeight) |
754 | 270 |
return (self.width, self.height) |
271 |
||
272 |
||
273 |
def split(self, availWidth, availHeight): |
|
274 |
"""At this stage we do not care about splitting the entries, |
|
275 |
we will just return a list of platypus tables. Presumably the |
|
276 |
calling app has a pointer to the original TableOfContents object; |
|
277 |
Platypus just sees tables. |
|
278 |
""" |
|
1493 | 279 |
return self._table.splitOn(self.canv,availWidth, availHeight) |
754 | 280 |
|
281 |
||
282 |
def drawOn(self, canvas, x, y, _sW=0): |
|
283 |
"""Don't do this at home! The standard calls for implementing |
|
284 |
draw(); we are hooking this in order to delegate ALL the drawing |
|
285 |
work to the embedded table object. |
|
286 |
""" |
|
287 |
self._table.drawOn(canvas, x, y, _sW) |
|
3165 | 288 |
|
3143
c704253bc72a
Added support for multi-level and alphabetical indexes.
jonas
parents:
3141
diff
changeset
|
289 |
def makeTuple(x): |
4339 | 290 |
if isinstance(x,(list,tuple)): |
3143
c704253bc72a
Added support for multi-level and alphabetical indexes.
jonas
parents:
3141
diff
changeset
|
291 |
return tuple(x) |
c704253bc72a
Added support for multi-level and alphabetical indexes.
jonas
parents:
3141
diff
changeset
|
292 |
return (x,) |
1444 | 293 |
|
294 |
class SimpleIndex(IndexingFlowable): |
|
3173 | 295 |
"""Creates multi level indexes. |
296 |
The styling can be cutomized and alphabetic headers turned on and off. |
|
297 |
""" |
|
1444 | 298 |
|
3164
0c60143b507e
Added setup method and headers parameter. AlphabeticalIndex is now deprecated.
jonas
parents:
3162
diff
changeset
|
299 |
def __init__(self, **kwargs): |
3173 | 300 |
""" |
301 |
Constructor of SimpleIndex. |
|
302 |
Accepts the same arguments as the setup method. |
|
303 |
""" |
|
1444 | 304 |
#keep stuff in a dictionary while building |
305 |
self._entries = {} |
|
306 |
self._lastEntries = {} |
|
3140
c79e6a56495d
tableofcontents: add support for index tableStyle
rgbecker
parents:
3136
diff
changeset
|
307 |
self._flowable = None |
3164
0c60143b507e
Added setup method and headers parameter. AlphabeticalIndex is now deprecated.
jonas
parents:
3162
diff
changeset
|
308 |
self.setup(**kwargs) |
3165 | 309 |
|
4551 | 310 |
def getFormatFunc(self,formatName): |
3187
2d5a6655556e
tableofcontents/paraparser: allow for format and offset parameters
rgbecker
parents:
3173
diff
changeset
|
311 |
try: |
4551 | 312 |
return getattr(rl_sequencer,'_format_%s' % formatName) |
3187
2d5a6655556e
tableofcontents/paraparser: allow for format and offset parameters
rgbecker
parents:
3173
diff
changeset
|
313 |
except ImportError: |
4551 | 314 |
raise ValueError('Unknown sequencer format %r' % formatName) |
3187
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 | 317 |
""" |
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 | 320 |
style is the paragraph style to use for index entries. |
321 |
dot can either be None or a string. If it's None, entries are immediatly followed by their |
|
322 |
corresponding page numbers. If it's a string, page numbers are aligned on the right side |
|
323 |
of the document and the gap filled with a repeating sequence of the string. |
|
324 |
tableStyle is the style used by the table which the index uses to draw itself. Use this to |
|
325 |
change properties like spacing between elements. |
|
3348 | 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 | 328 |
name makes it possible to use several indexes in one document. If you want this use this |
329 |
parameter to give each index a unique name. You can then index a term by refering to the |
|
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 | 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 | 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 | 345 |
if name is None: |
346 |
from reportlab.platypus.paraparser import DEFAULT_INDEX_NAME as name |
|
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 | 350 |
|
351 |
def __call__(self,canv,kind,label): |
|
4338
6223e7fa13f6
reproducibility fixes; version --> 3.4.3
robin <robin@reportlab.com>
parents:
4330
diff
changeset
|
352 |
label = asNative(label,'latin1') |
3187
2d5a6655556e
tableofcontents/paraparser: allow for format and offset parameters
rgbecker
parents:
3173
diff
changeset
|
353 |
try: |
3850 | 354 |
terms, format, offset = decode_label(label) |
3187
2d5a6655556e
tableofcontents/paraparser: allow for format and offset parameters
rgbecker
parents:
3173
diff
changeset
|
355 |
except: |
2d5a6655556e
tableofcontents/paraparser: allow for format and offset parameters
rgbecker
parents:
3173
diff
changeset
|
356 |
terms = label |
2d5a6655556e
tableofcontents/paraparser: allow for format and offset parameters
rgbecker
parents:
3173
diff
changeset
|
357 |
format = offset = None |
2d5a6655556e
tableofcontents/paraparser: allow for format and offset parameters
rgbecker
parents:
3173
diff
changeset
|
358 |
if format is None: |
2d5a6655556e
tableofcontents/paraparser: allow for format and offset parameters
rgbecker
parents:
3173
diff
changeset
|
359 |
formatFunc = self.formatFunc |
2d5a6655556e
tableofcontents/paraparser: allow for format and offset parameters
rgbecker
parents:
3173
diff
changeset
|
360 |
else: |
2d5a6655556e
tableofcontents/paraparser: allow for format and offset parameters
rgbecker
parents:
3173
diff
changeset
|
361 |
formatFunc = self.getFormatFunc(format) |
2d5a6655556e
tableofcontents/paraparser: allow for format and offset parameters
rgbecker
parents:
3173
diff
changeset
|
362 |
if offset is None: |
2d5a6655556e
tableofcontents/paraparser: allow for format and offset parameters
rgbecker
parents:
3173
diff
changeset
|
363 |
offset = self.offset |
2d5a6655556e
tableofcontents/paraparser: allow for format and offset parameters
rgbecker
parents:
3173
diff
changeset
|
364 |
|
2d5a6655556e
tableofcontents/paraparser: allow for format and offset parameters
rgbecker
parents:
3173
diff
changeset
|
365 |
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
|
366 |
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
|
367 |
pns = formatFunc(cPN-offset) |
3187
2d5a6655556e
tableofcontents/paraparser: allow for format and offset parameters
rgbecker
parents:
3173
diff
changeset
|
368 |
key = 'ix_%s_%s_p_%s' % (self.name, label, pns) |
3165 | 369 |
|
370 |
info = canv._curr_tx_info |
|
371 |
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
|
372 |
self.addEntry(terms, (cPN,pns), key) |
3165 | 373 |
|
3162 | 374 |
def getCanvasMaker(self, canvasmaker=canvas.Canvas): |
3165 | 375 |
|
3162 | 376 |
def newcanvasmaker(*args, **kwargs): |
377 |
from reportlab.pdfgen import canvas |
|
378 |
c = canvasmaker(*args, **kwargs) |
|
3165 | 379 |
setattr(c,self.name,self) |
3162 | 380 |
return c |
3165 | 381 |
|
3162 | 382 |
return newcanvasmaker |
3135
3a2a8a52c1c1
reportlab.platypus: Fixes for SimpleIndex and TableOfContents.
jonas
parents:
3111
diff
changeset
|
383 |
|
1444 | 384 |
def isIndexing(self): |
385 |
return 1 |
|
386 |
||
387 |
def isSatisfied(self): |
|
388 |
return (self._entries == self._lastEntries) |
|
1683 | 389 |
|
1444 | 390 |
def beforeBuild(self): |
391 |
# keep track of the last run |
|
392 |
self._lastEntries = self._entries.copy() |
|
393 |
self.clearEntries() |
|
394 |
||
395 |
def clearEntries(self): |
|
396 |
self._entries = {} |
|
397 |
||
398 |
def notify(self, kind, stuff): |
|
399 |
"""The notification hook called to register all kinds of events. |
|
400 |
||
401 |
Here we are interested in 'IndexEntry' events only. |
|
402 |
""" |
|
403 |
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
|
404 |
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
|
405 |
self.addEntry(text, (self._canv.getPageNumber(),pageNum)) |
1444 | 406 |
|
3162 | 407 |
def addEntry(self, text, pageNum, key=None): |
1444 | 408 |
"""Allows incremental buildup""" |
3162 | 409 |
self._entries.setdefault(makeTuple(text),set([])).add((pageNum, key)) |
1444 | 410 |
|
411 |
def split(self, availWidth, availHeight): |
|
412 |
"""At this stage we do not care about splitting the entries, |
|
413 |
we will just return a list of platypus tables. Presumably the |
|
414 |
calling app has a pointer to the original TableOfContents object; |
|
415 |
Platypus just sees tables. |
|
416 |
""" |
|
3140
c79e6a56495d
tableofcontents: add support for index tableStyle
rgbecker
parents:
3136
diff
changeset
|
417 |
return self._flowable.splitOn(self.canv,availWidth, availHeight) |
1444 | 418 |
|
3162 | 419 |
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
|
420 |
'''Return the last run's entries! If there are none, returns dummy.''' |
4338
6223e7fa13f6
reproducibility fixes; version --> 3.4.3
robin <robin@reportlab.com>
parents:
4330
diff
changeset
|
421 |
lE = self._lastEntries or self._entries |
6223e7fa13f6
reproducibility fixes; version --> 3.4.3
robin <robin@reportlab.com>
parents:
4330
diff
changeset
|
422 |
if not lE: |
3143
c704253bc72a
Added support for multi-level and alphabetical indexes.
jonas
parents:
3141
diff
changeset
|
423 |
return dummy |
4338
6223e7fa13f6
reproducibility fixes; version --> 3.4.3
robin <robin@reportlab.com>
parents:
4330
diff
changeset
|
424 |
return list(sorted(lE.items())) |
3165 | 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 | 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 | 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 | 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 | 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 | 442 |
tableData = [] |
3143
c704253bc72a
Added support for multi-level and alphabetical indexes.
jonas
parents:
3141
diff
changeset
|
443 |
lastTexts = [] |
3348 | 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 | 447 |
#track when the first character changes; either output some extra |
448 |
#space, or the first letter on a row of its own. We cannot do |
|
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 | 451 |
if alpha != nalpha: |
452 |
alpha = nalpha |
|
453 |
if self.headers: |
|
454 |
header = alpha |
|
455 |
else: |
|
456 |
header = ' ' |
|
457 |
tableData.append([Spacer(1, alphaStyle.spaceBefore),]) |
|
458 |
tableData.append([Paragraph(header, alphaStyle),]) |
|
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 | 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 | 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 | 488 |
|
489 |
def drawOn(self, canvas, x, y, _sW=0): |
|
490 |
"""Don't do this at home! The standard calls for implementing |
|
491 |
draw(); we are hooking this in order to delegate ALL the drawing |
|
492 |
work to the embedded table object. |
|
493 |
""" |
|
3140
c79e6a56495d
tableofcontents: add support for index tableStyle
rgbecker
parents:
3136
diff
changeset
|
494 |
self._flowable.drawOn(canvas, x, y, _sW) |
1444 | 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 | 532 |
class ReferenceText(IndexingFlowable): |
533 |
"""Fakery to illustrate how a reference would work if we could |
|
534 |
put it in a paragraph.""" |
|
535 |
def __init__(self, textPattern, targetKey): |
|
536 |
self.textPattern = textPattern |
|
537 |
self.target = targetKey |
|
538 |
self.paraStyle = ParagraphStyle('tmp') |
|
539 |
self._lastPageNum = None |
|
540 |
self._pageNum = -999 |
|
541 |
self._para = None |
|
542 |
||
543 |
def beforeBuild(self): |
|
544 |
self._lastPageNum = self._pageNum |
|
545 |
||
546 |
def notify(self, kind, stuff): |
|
547 |
if kind == 'Target': |
|
548 |
(key, pageNum) = stuff |
|
549 |
if key == self.target: |
|
550 |
self._pageNum = pageNum |
|
551 |
||
552 |
def wrap(self, availWidth, availHeight): |
|
553 |
text = self.textPattern % self._lastPageNum |
|
554 |
self._para = Paragraph(text, self.paraStyle) |
|
555 |
return self._para.wrap(availWidth, availHeight) |
|
1683 | 556 |
|
1444 | 557 |
def drawOn(self, canvas, x, y, _sW=0): |
558 |
self._para.drawOn(canvas, x, y, _sW) |