author | robin <robin@reportlab.com> |
Tue, 07 Mar 2017 10:00:34 +0000 | |
changeset 4330 | 617ffa6bbdc8 |
parent 4252 | fe660f227cac |
child 4370 | 823a8c33ce43 |
permissions | -rw-r--r-- |
4330 | 1 |
#Copyright ReportLab Europe Ltd. 2000-2017 |
2963 | 2 |
#see license.txt for license details |
3 |
#history http://www.reportlab.co.uk/cgi-bin/viewcvs.cgi/public/reportlab/trunk/reportlab/docs/userguide/ch4_platypus_concepts.py |
|
2966 | 4 |
from tools.docco.rl_doc_utils import * |
2963 | 5 |
|
6 |
#####################################################################################################3 |
|
7 |
||
8 |
||
9 |
heading1("PLATYPUS - Page Layout and Typography Using Scripts") |
|
10 |
||
11 |
heading2("Design Goals") |
|
12 |
||
13 |
disc(""" |
|
14 |
Platypus stands for "Page Layout and Typography Using Scripts". It is a high |
|
15 |
level page layout library which lets you programmatically create complex |
|
16 |
documents with a minimum of effort. |
|
17 |
""") |
|
18 |
||
19 |
||
20 |
||
21 |
disc(""" |
|
22 |
The design of Platypus seeks to separate "high level" layout decisions |
|
23 |
from the document content as much as possible. Thus, for example, paragraphs |
|
24 |
are constructed using paragraph styles and pages are constructed |
|
25 |
using page templates with the intention that hundreds of |
|
26 |
documents with thousands of pages can be reformatted to different |
|
27 |
style specifications with the modifications of a few lines in a single |
|
28 |
shared file which contains the paragraph styles and page layout specifications. |
|
29 |
""") |
|
30 |
||
31 |
||
32 |
disc(""" |
|
33 |
The overall design of Platypus can be thought of has having |
|
34 |
several layers, top down, these are""") |
|
35 |
||
36 |
disc("<b>$DocTemplates$</b> the outermost container for the document;") |
|
37 |
||
38 |
disc("<b>$PageTemplates$</b> specifications for layouts of pages of various kinds;") |
|
39 |
||
40 |
disc("<b>$Frames$</b> specifications of regions in pages that can contain flowing text or graphics.") |
|
41 |
||
42 |
disc("""<b>$Flowables$</b> text or graphic elements that should be "flowed |
|
43 |
into the document (i.e. things like images, paragraphs and tables, but not things |
|
44 |
like page footers or fixed page graphics).""") |
|
45 |
||
46 |
disc("""<b>$pdfgen.Canvas$</b> the lowest level which ultimately receives the painting of the |
|
47 |
document from the other layers.""") |
|
48 |
||
49 |
illust(examples.doctemplateillustration, "Illustration of DocTemplate structure") |
|
50 |
||
51 |
disc(""" |
|
52 |
The illustration above graphically illustrates the concepts of $DocTemplates$, |
|
53 |
$PageTemplates$ and $Flowables$. It is deceptive, however, because each |
|
54 |
of the $PageTemplates$ actually may specify the format for any number of pages |
|
55 |
(not just one as might be inferred from the diagram). |
|
56 |
""") |
|
57 |
||
58 |
disc(""" |
|
59 |
$DocTemplates$ contain one or more $PageTemplates$ each of which contain one or more |
|
60 |
$Frames$. $Flowables$ are things which can be <i>flowed</i> into a $Frame$ e.g. |
|
61 |
a $Paragraph$ or a $Table$. |
|
62 |
""") |
|
63 |
||
64 |
disc(""" |
|
65 |
To use platypus you create a document from a $DocTemplate$ class and pass |
|
66 |
a list of $Flowable$s to its $build$ method. The document |
|
67 |
$build$ method knows how to process the list of flowables |
|
68 |
into something reasonable. |
|
69 |
""") |
|
70 |
||
71 |
disc(""" |
|
72 |
Internally the $DocTemplate$ class implements page layout and formatting |
|
73 |
using various events. Each of the events has a corresponding handler method |
|
74 |
called $handle_XXX$ where $XXX$ is the event name. A typical event is |
|
75 |
$frameBegin$ which occurs when the machinery begins to use a frame for the |
|
76 |
first time. |
|
77 |
""") |
|
78 |
||
79 |
disc(""" |
|
80 |
A Platypus story consists of a sequence of basic elements called $Flowables$ |
|
81 |
and these elements drive the data driven Platypus formatting engine. |
|
82 |
To modify the behavior of the engine |
|
83 |
a special kind of flowable, $ActionFlowables$, tell the layout engine to, |
|
84 |
for example, skip to the next |
|
85 |
column or change to another $PageTemplate$. |
|
86 |
""") |
|
87 |
||
88 |
||
89 |
heading2("""Getting started""") |
|
90 |
||
91 |
disc("""Consider the following code sequence which provides |
|
92 |
a very simple "hello world" example for Platypus.""") |
|
93 |
||
94 |
eg(examples.platypussetup) |
|
95 |
||
96 |
disc("""First we import some constructors, some paragraph styles |
|
97 |
and other conveniences from other modules.""") |
|
98 |
||
99 |
eg(examples.platypusfirstpage) |
|
100 |
||
101 |
disc("""We define the fixed features of the first page of the document |
|
102 |
with the function above.""") |
|
103 |
||
104 |
eg(examples.platypusnextpage) |
|
105 |
||
106 |
disc("""Since we want pages after the first to look different from the |
|
107 |
first we define an alternate layout for the fixed features |
|
108 |
of the other pages. Note that the two functions above use |
|
109 |
the $pdfgen$ level canvas operations to paint the annotations for |
|
110 |
the pages. |
|
111 |
""") |
|
112 |
||
113 |
eg(examples.platypusgo) |
|
114 |
||
115 |
disc(""" |
|
116 |
Finally, we create a story and build the document. |
|
117 |
Note that we are using a "canned" document template here which |
|
118 |
comes pre-built with page templates. We are also using a pre-built |
|
119 |
paragraph style. We are only using two types of flowables here |
|
120 |
-- $Spacers$ and $Paragraphs$. The first $Spacer$ ensures that the |
|
121 |
Paragraphs skip past the title string. |
|
122 |
""") |
|
123 |
||
124 |
disc(""" |
|
125 |
To see the output of this example program run the module |
|
126 |
$docs/userguide/examples.py$ (from the ReportLab $docs$ distribution) |
|
127 |
as a "top level script". The script interpretation $python examples.py$ will |
|
128 |
generate the Platypus output $phello.pdf$. |
|
129 |
""") |
|
130 |
||
131 |
||
132 |
heading2("$Flowables$") |
|
133 |
disc(""" |
|
134 |
$Flowables$ are things which can be drawn and which have $wrap$, $draw$ and perhaps $split$ methods. |
|
135 |
$Flowable$ is an abstract base class for things to be drawn and an instance knows its size |
|
136 |
and draws in its own coordinate system (this requires the base API to provide an absolute coordinate |
|
137 |
system when the $Flowable.draw$ method is called). To get an instance use $f=Flowable()$. |
|
138 |
""") |
|
139 |
disc(""" |
|
140 |
It should be noted that the $Flowable$ class is an <i>abstract</i> class and is normally |
|
141 |
only used as a base class. |
|
142 |
""") |
|
143 |
k=startKeep() |
|
144 |
disc(""" |
|
145 |
To illustrate the general way in which $Flowables$ are used we show how a derived class $Paragraph$ |
|
146 |
is used and drawn on a canvas. $Paragraphs$ are so important they will get a whole chapter |
|
147 |
to themselves. |
|
148 |
""") |
|
149 |
eg(""" |
|
150 |
from reportlab.lib.styles import getSampleStyleSheet |
|
151 |
from reportlab.platypus import Paragraph |
|
152 |
from reportlab.pdfgen.canvas import Canvas |
|
153 |
styleSheet = getSampleStyleSheet() |
|
154 |
style = styleSheet['BodyText'] |
|
155 |
P=Paragraph('This is a very silly example',style) |
|
156 |
canv = Canvas('doc.pdf') |
|
157 |
aW = 460 # available width and height |
|
158 |
aH = 800 |
|
159 |
w,h = P.wrap(aW, aH) # find required space |
|
160 |
if w<=aW and h<=aH: |
|
161 |
P.drawOn(canv,0,aH) |
|
162 |
aH = aH - h # reduce the available height |
|
163 |
canv.save() |
|
164 |
else: |
|
165 |
raise ValueError, "Not enough room" |
|
166 |
""") |
|
167 |
endKeep(k) |
|
168 |
heading3("$Flowable$ User Methods") |
|
169 |
eg(""" |
|
170 |
Flowable.draw() |
|
171 |
""") |
|
172 |
disc("""This will be called to ask the flowable to actually render itself. |
|
173 |
The $Flowable$ class does not implement $draw$. |
|
174 |
The calling code should ensure that the flowable has an attribute $canv$ |
|
175 |
which is the $pdfgen.Canvas$ which should be drawn to an that the $Canvas$ |
|
176 |
is in an appropriate state (as regards translations rotations, etc). Normally |
|
177 |
this method will only be called internally by the $drawOn$ method. Derived classes |
|
178 |
must implement this method. |
|
179 |
""") |
|
180 |
eg(""" |
|
181 |
Flowable.drawOn(canvas,x,y) |
|
182 |
""") |
|
183 |
disc(""" |
|
184 |
This is the method which controlling programs use to render the flowable to a particular |
|
185 |
canvas. It handles the translation to the canvas coordinate (<i>x</i>,<i>y</i>) and ensuring that |
|
186 |
the flowable has a $canv$ attribute so that the |
|
187 |
$draw$ method (which is not implemented in the base class) can render in an |
|
188 |
absolute coordinate frame. |
|
189 |
""") |
|
190 |
eg(""" |
|
191 |
Flowable.wrap(availWidth, availHeight) |
|
192 |
""") |
|
193 |
disc("""This will be called by the enclosing frame before objects |
|
194 |
are asked their size, drawn or whatever. It returns the |
|
195 |
size actually used.""") |
|
196 |
eg(""" |
|
197 |
Flowable.split(self, availWidth, availheight): |
|
198 |
""") |
|
199 |
disc("""This will be called by more sophisticated frames when |
|
200 |
wrap fails. Stupid flowables should return [] meaning that they are unable to split. |
|
201 |
Clever flowables should split themselves and return a list of flowables. It is up to |
|
202 |
the client code to ensure that repeated attempts to split are avoided. |
|
203 |
If the space is sufficient the split method should return [self]. |
|
204 |
Otherwise |
|
205 |
the flowable should rearrange itself and return a list $[f0,...]$ of flowables |
|
206 |
which will be considered in order. The implemented split method should avoid |
|
207 |
changing $self$ as this will allow sophisticated layout mechanisms to do multiple |
|
208 |
passes over a list of flowables. |
|
209 |
""") |
|
210 |
||
211 |
heading2("Guidelines for flowable positioning") |
|
212 |
||
213 |
disc("""Two methods, which by default return zero, provide guidance on vertical |
|
214 |
spacing of flowables: |
|
215 |
""") |
|
216 |
||
217 |
eg(""" |
|
218 |
Flowable.getSpaceAfter(self): |
|
219 |
Flowable.getSpaceBefore(self): |
|
220 |
""") |
|
221 |
disc("""These methods return how much space should follow or precede |
|
222 |
the flowable. The space doesn't belong to the flowable itself i.e. the flowable's |
|
223 |
$draw$ method shouldn't consider it when rendering. Controlling programs |
|
224 |
will use the values returned in determining how much space is required by |
|
225 |
a particular flowable in context. |
|
226 |
""") |
|
227 |
||
228 |
disc("""All flowables have an $hAlign$ property: $('LEFT', 'RIGHT', 'CENTER' or 'CENTRE')$. |
|
229 |
For paragraphs, which fill the full width of the frame, this has no effect. For tables, |
|
230 |
images or other objects which are less than the width of the frame, this determines their |
|
231 |
horizontal placement. |
|
232 |
||
233 |
""") |
|
234 |
||
235 |
||
236 |
disc("""The chapters which follow will cover the most important |
|
237 |
specific types of flowables: Paragraphs and Tables.""") |
|
238 |
||
239 |
||
240 |
heading2("Frames") |
|
241 |
disc(""" |
|
242 |
$Frames$ are active containers which are themselves contained in $PageTemplates$. |
|
243 |
$Frames$ have a location and size and maintain a concept of remaining drawable |
|
244 |
space. The command |
|
245 |
""") |
|
246 |
||
247 |
eg(""" |
|
248 |
Frame(x1, y1, width,height, leftPadding=6, bottomPadding=6, |
|
249 |
rightPadding=6, topPadding=6, id=None, showBoundary=0) |
|
250 |
""") |
|
251 |
disc("""creates a $Frame$ instance with lower left hand corner at coordinate $(x1,y1)$ |
|
252 |
(relative to the canvas at use time) and with dimensions $width$ x $height$. The $Padding$ |
|
253 |
arguments are positive quantities used to reduce the space available for drawing. |
|
254 |
The $id$ argument is an identifier for use at runtime e.g. 'LeftColumn' or 'RightColumn' etc. |
|
255 |
If the $showBoundary$ argument is non-zero then the boundary of the frame will get drawn |
|
256 |
at run time (this is useful sometimes). |
|
257 |
""") |
|
258 |
heading3("$Frame$ User Methods") |
|
259 |
eg(""" |
|
260 |
Frame.addFromList(drawlist, canvas) |
|
261 |
""") |
|
262 |
disc("""consumes $Flowables$ from the front of $drawlist$ until the |
|
263 |
frame is full. If it cannot fit one object, raises |
|
264 |
an exception.""") |
|
265 |
||
266 |
eg(""" |
|
267 |
Frame.split(flowable,canv) |
|
268 |
""") |
|
269 |
disc('''Asks the flowable to split using up the available space and return |
|
270 |
the list of flowables. |
|
271 |
''') |
|
272 |
||
273 |
eg(""" |
|
274 |
Frame.drawBoundary(canvas) |
|
275 |
""") |
|
276 |
disc("draws the frame boundary as a rectangle (primarily for debugging).") |
|
277 |
heading3("Using $Frames$") |
|
278 |
disc(""" |
|
279 |
$Frames$ can be used directly with canvases and flowables to create documents. |
|
280 |
The $Frame.addFromList$ method handles the $wrap$ & $drawOn$ calls for you. |
|
281 |
You don't need all of the Platypus machinery to get something useful into |
|
282 |
PDF. |
|
283 |
""") |
|
284 |
eg(""" |
|
285 |
from reportlab.pdfgen.canvas import Canvas |
|
286 |
from reportlab.lib.styles import getSampleStyleSheet |
|
287 |
from reportlab.lib.units import inch |
|
288 |
from reportlab.platypus import Paragraph, Frame |
|
289 |
styles = getSampleStyleSheet() |
|
290 |
styleN = styles['Normal'] |
|
291 |
styleH = styles['Heading1'] |
|
292 |
story = [] |
|
293 |
||
294 |
#add some flowables |
|
295 |
story.append(Paragraph("This is a Heading",styleH)) |
|
296 |
story.append(Paragraph("This is a paragraph in <i>Normal</i> style.", |
|
297 |
styleN)) |
|
298 |
c = Canvas('mydoc.pdf') |
|
299 |
f = Frame(inch, inch, 6*inch, 9*inch, showBoundary=1) |
|
300 |
f.addFromList(story,c) |
|
301 |
c.save() |
|
302 |
""") |
|
303 |
||
304 |
heading2("Documents and Templates") |
|
305 |
||
306 |
disc(""" |
|
307 |
The $BaseDocTemplate$ class implements the basic machinery for document |
|
308 |
formatting. An instance of the class contains a list of one or more |
|
309 |
$PageTemplates$ that can be used to describe the layout of information |
|
310 |
on a single page. The $build$ method can be used to process |
|
311 |
a list of $Flowables$ to produce a <b>PDF</b> document. |
|
312 |
""") |
|
313 |
||
314 |
CPage(3.0) |
|
315 |
heading3("The $BaseDocTemplate$ class") |
|
316 |
||
317 |
eg(""" |
|
318 |
BaseDocTemplate(self, filename, |
|
319 |
pagesize=defaultPageSize, |
|
320 |
pageTemplates=[], |
|
321 |
showBoundary=0, |
|
322 |
leftMargin=inch, |
|
323 |
rightMargin=inch, |
|
324 |
topMargin=inch, |
|
325 |
bottomMargin=inch, |
|
326 |
allowSplitting=1, |
|
327 |
title=None, |
|
328 |
author=None, |
|
3051
28a7d8fb1fc1
Added documentation in userguide for encryption options on Canvas and BaseDocTemplate.
jonas
parents:
2966
diff
changeset
|
329 |
_pageBreakQuick=1, |
28a7d8fb1fc1
Added documentation in userguide for encryption options on Canvas and BaseDocTemplate.
jonas
parents:
2966
diff
changeset
|
330 |
encrypt=None) |
2963 | 331 |
""") |
332 |
||
333 |
disc(""" |
|
334 |
creates a document template suitable for creating a basic document. It comes with quite a lot |
|
335 |
of internal machinery, but no default page templates. The required $filename$ can be a string, |
|
336 |
the name of a file to receive the created <b>PDF</b> document; alternatively it |
|
3848 | 337 |
can be an object which has a $write$ method such as a $BytesIO$ or $file$ or $socket$. |
2963 | 338 |
""") |
339 |
||
340 |
disc(""" |
|
341 |
The allowed arguments should be self explanatory, but $showBoundary$ controls whether or |
|
342 |
not $Frame$ boundaries are drawn which can be useful for debugging purposes. The |
|
343 |
$allowSplitting$ argument determines whether the builtin methods should try to <i>split</i> |
|
344 |
individual $Flowables$ across $Frames$. The $_pageBreakQuick$ argument determines whether |
|
345 |
an attempt to do a page break should try to end all the frames on the page or not, before ending |
|
3051
28a7d8fb1fc1
Added documentation in userguide for encryption options on Canvas and BaseDocTemplate.
jonas
parents:
2966
diff
changeset
|
346 |
the page. The encrypt argument determines wether or not and how the document is encrypted. |
28a7d8fb1fc1
Added documentation in userguide for encryption options on Canvas and BaseDocTemplate.
jonas
parents:
2966
diff
changeset
|
347 |
By default, the document is not encrypted. |
28a7d8fb1fc1
Added documentation in userguide for encryption options on Canvas and BaseDocTemplate.
jonas
parents:
2966
diff
changeset
|
348 |
If $encrypt$ is a string object, it is used as the user password for the pdf. |
28a7d8fb1fc1
Added documentation in userguide for encryption options on Canvas and BaseDocTemplate.
jonas
parents:
2966
diff
changeset
|
349 |
If $encrypt$ is an instance of $reportlab.lib.pdfencrypt.StandardEncryption$, this object is |
28a7d8fb1fc1
Added documentation in userguide for encryption options on Canvas and BaseDocTemplate.
jonas
parents:
2966
diff
changeset
|
350 |
used to encrypt the pdf. This allows more finegrained control over the encryption settings. |
2963 | 351 |
""") |
352 |
||
353 |
heading4("User $BaseDocTemplate$ Methods") |
|
354 |
||
355 |
disc("""These are of direct interest to client programmers |
|
356 |
in that they are normally expected to be used. |
|
357 |
""") |
|
358 |
eg(""" |
|
359 |
BaseDocTemplate.addPageTemplates(self,pageTemplates) |
|
360 |
""") |
|
361 |
disc(""" |
|
362 |
This method is used to add one or a list of $PageTemplates$ to an existing documents. |
|
363 |
""") |
|
364 |
eg(""" |
|
365 |
BaseDocTemplate.build(self, flowables, filename=None, canvasmaker=canvas.Canvas) |
|
366 |
""") |
|
367 |
disc(""" |
|
368 |
This is the main method which is of interest to the application |
|
369 |
programmer. Assuming that the document instance is correctly set up the |
|
370 |
$build$ method takes the <i>story</i> in the shape of the list of flowables |
|
371 |
(the $flowables$ argument) and loops through the list forcing the flowables |
|
372 |
one at a time through the formatting machinery. Effectively this causes |
|
373 |
the $BaseDocTemplate$ instance to issue calls to the instance $handle_XXX$ methods |
|
374 |
to process the various events. |
|
375 |
""") |
|
376 |
heading4("User Virtual $BaseDocTemplate$ Methods") |
|
377 |
disc(""" |
|
378 |
These have no semantics at all in the base class. They are intended as pure virtual hooks |
|
379 |
into the layout machinery. Creators of immediately derived classes can override these |
|
380 |
without worrying about affecting the properties of the layout engine. |
|
381 |
""") |
|
382 |
eg(""" |
|
383 |
BaseDocTemplate.afterInit(self) |
|
384 |
""") |
|
385 |
disc(""" |
|
386 |
This is called after initialisation of the base class; a derived class could overide |
|
387 |
the method to add default $PageTemplates$. |
|
388 |
""") |
|
389 |
||
390 |
eg(""" |
|
391 |
BaseDocTemplate.afterPage(self) |
|
392 |
""") |
|
393 |
disc("""This is called after page processing, and |
|
394 |
immediately after the afterDrawPage method |
|
395 |
of the current page template. A derived class could |
|
396 |
use this to do things which are dependent on information in the page |
|
397 |
such as the first and last word on the page of a dictionary. |
|
398 |
""") |
|
399 |
||
400 |
eg(""" |
|
401 |
BaseDocTemplate.beforeDocument(self) |
|
402 |
""") |
|
403 |
||
404 |
disc("""This is called before any processing is |
|
405 |
done on the document, but after the processing machinery |
|
406 |
is ready. It can therefore be used to do things to the instance\'s |
|
407 |
$pdfgen.canvas$ and the like. |
|
408 |
""") |
|
409 |
||
410 |
eg(""" |
|
411 |
BaseDocTemplate.beforePage(self) |
|
412 |
""") |
|
413 |
||
414 |
disc("""This is called at the beginning of page |
|
415 |
processing, and immediately before the |
|
416 |
beforeDrawPage method of the current page |
|
417 |
template. It could be used to reset page specific |
|
418 |
information holders.""") |
|
419 |
||
420 |
eg(""" |
|
421 |
BaseDocTemplate.filterFlowables(self,flowables) |
|
422 |
""") |
|
423 |
||
424 |
disc("""This is called to filter flowables at the start of the main handle_flowable method. |
|
425 |
Upon return if flowables[0] has been set to None it is discarded and the main |
|
426 |
method returns immediately. |
|
427 |
""") |
|
428 |
||
429 |
eg(""" |
|
430 |
BaseDocTemplate.afterFlowable(self, flowable) |
|
431 |
""") |
|
432 |
||
433 |
disc("""Called after a flowable has been rendered. An interested class could use this |
|
434 |
hook to gather information about what information is present on a particular page or frame.""") |
|
435 |
||
436 |
heading4("$BaseDocTemplate$ Event handler Methods") |
|
437 |
disc(""" |
|
438 |
These methods constitute the greater part of the layout engine. Programmers shouldn't |
|
439 |
have to call or override these methods directly unless they are trying to modify the layout engine. |
|
440 |
Of course, the experienced programmer who wants to intervene at a particular event, $XXX$, |
|
441 |
which does not correspond to one of the virtual methods can always override and |
|
442 |
call the base method from the drived class version. We make this easy by providing |
|
443 |
a base class synonym for each of the handler methods with the same name prefixed by an underscore '_'. |
|
444 |
""") |
|
445 |
||
446 |
eg(""" |
|
447 |
def handle_pageBegin(self): |
|
448 |
doStuff() |
|
449 |
BaseDocTemplate.handle_pageBegin(self) |
|
450 |
doMoreStuff() |
|
451 |
||
452 |
#using the synonym |
|
453 |
def handle_pageEnd(self): |
|
454 |
doStuff() |
|
455 |
self._handle_pageEnd() |
|
456 |
doMoreStuff() |
|
457 |
""") |
|
458 |
disc(""" |
|
459 |
Here we list the methods only as an indication of the events that are being |
|
460 |
handled. |
|
461 |
Interested programmers can take a look at the source. |
|
462 |
""") |
|
463 |
eg(""" |
|
464 |
handle_currentFrame(self,fx) |
|
465 |
handle_documentBegin(self) |
|
466 |
handle_flowable(self,flowables) |
|
467 |
handle_frameBegin(self,*args) |
|
468 |
handle_frameEnd(self) |
|
469 |
handle_nextFrame(self,fx) |
|
470 |
handle_nextPageTemplate(self,pt) |
|
471 |
handle_pageBegin(self) |
|
472 |
handle_pageBreak(self) |
|
473 |
handle_pageEnd(self) |
|
474 |
""") |
|
475 |
||
476 |
disc(""" |
|
477 |
Using document templates can be very easy; $SimpleDoctemplate$ is a class derived from |
|
478 |
$BaseDocTemplate$ which provides its own $PageTemplate$ and $Frame$ setup. |
|
479 |
""") |
|
480 |
||
481 |
eg(""" |
|
482 |
from reportlab.lib.styles import getSampleStyleSheet |
|
483 |
from reportlab.lib.pagesizes import letter |
|
484 |
from reportlab.platypus import Paragraph, SimpleDocTemplate |
|
485 |
styles = getSampleStyleSheet() |
|
486 |
styleN = styles['Normal'] |
|
487 |
styleH = styles['Heading1'] |
|
488 |
story = [] |
|
489 |
||
490 |
#add some flowables |
|
491 |
story.append(Paragraph("This is a Heading",styleH)) |
|
492 |
story.append(Paragraph("This is a paragraph in <i>Normal</i> style.", |
|
493 |
styleN)) |
|
494 |
doc = SimpleDocTemplate('mydoc.pdf',pagesize = letter) |
|
495 |
doc.build(story) |
|
496 |
""") |
|
497 |
heading3("$PageTemplates$") |
|
498 |
disc(""" |
|
499 |
The $PageTemplate$ class is a container class with fairly minimal semantics. Each instance |
|
500 |
contains a list of $Frames$ and has methods which should be called at the start and end |
|
501 |
of each page. |
|
502 |
""") |
|
503 |
eg("PageTemplate(id=None,frames=[],onPage=_doNothing,onPageEnd=_doNothing)") |
|
504 |
disc(""" |
|
505 |
is used to initialize an instance, the $frames$ argument should be a list of $Frames$ |
|
506 |
whilst the optional $onPage$ and $onPageEnd$ arguments are callables which should have signature |
|
507 |
$def XXX(canvas,document)$ where $canvas$ and $document$ |
|
508 |
are the canvas and document being drawn. These routines are intended to be used to paint non-flowing (i.e. standard) |
|
509 |
parts of pages. These attribute functions are exactly parallel to the pure virtual methods |
|
510 |
$PageTemplate.beforPage$ and $PageTemplate.afterPage$ which have signature |
|
511 |
$beforPage(self,canvas,document)$. The methods allow class derivation to be used to define |
|
512 |
standard behaviour, whilst the attributes allow instance changes. The $id$ argument is used at |
|
513 |
run time to perform $PageTemplate$ switching so $id='FirstPage'$ or $id='TwoColumns'$ are typical. |
|
514 |
""") |