0
# Context Management
1
2
Advanced processing context management for controlling the HTML-to-PDF conversion pipeline. The context system manages fonts, CSS processing, resource handling, fragment management, and overall conversion state throughout the document processing lifecycle.
3
4
## Capabilities
5
6
### Main Processing Context
7
8
The central context class that manages all aspects of the HTML-to-PDF conversion process, including CSS accumulation, font management, resource resolution, and content fragment handling.
9
10
```python { .api }
11
class pisaContext:
12
def __init__(self, path="", debug=0, capacity=-1):
13
"""
14
Initialize processing context for HTML-to-PDF conversion.
15
16
Args:
17
path (str): Base path for resolving relative resources
18
debug (int): Debug level (0=none, 1=basic, 2=detailed)
19
capacity (int): Memory capacity for temp files (-1=unlimited)
20
"""
21
22
# CSS Management
23
def addCSS(self, value):
24
"""
25
Add CSS content to the context for processing.
26
27
Args:
28
value (str): CSS content to add
29
"""
30
31
def addDefaultCSS(self, value):
32
"""
33
Add default CSS that will be processed before document CSS.
34
35
Args:
36
value (str): Default CSS content
37
"""
38
39
def parseCSS(self):
40
"""
41
Parse all accumulated CSS content and build style cascade.
42
43
Returns:
44
bool: True if parsing successful, False otherwise
45
"""
46
47
# Content Management
48
def addStory(self, data):
49
"""
50
Add content data to the ReportLab story.
51
52
Args:
53
data: Story data to add (ReportLab flowables)
54
"""
55
56
def swapStory(self, story=None):
57
"""
58
Replace the current story with new content.
59
60
Args:
61
story (list): New story content (None creates empty story)
62
63
Returns:
64
list: Previous story content
65
"""
66
67
# Paragraph and Style Management
68
def toParagraphStyle(self, first):
69
"""
70
Convert current fragment style to ReportLab paragraph style.
71
72
Args:
73
first (bool): Whether this is the first paragraph
74
75
Returns:
76
ParagraphStyle: ReportLab paragraph style object
77
"""
78
79
def addTOC(self):
80
"""
81
Add table of contents placeholder to story.
82
83
Creates a TOC structure that will be populated with headings
84
and page numbers during the multi-pass PDF generation process.
85
"""
86
87
def addPageCount(self):
88
"""
89
Enable page counting and add page count tracking to context.
90
91
Sets up the context for multi-pass processing to calculate
92
total page numbers for page X of Y displays.
93
"""
94
95
def addPara(self, *, force=False):
96
"""
97
Add current paragraph to story.
98
99
Args:
100
force (bool): Force paragraph creation even if empty
101
"""
102
103
def setDir(self, direction):
104
"""
105
Set text direction for RTL/LTR language support.
106
107
Args:
108
direction (str): Text direction - 'rtl' or 'ltr'
109
"""
110
111
def UID(self):
112
"""
113
Generate unique identifier for elements.
114
115
Returns:
116
int: Unique ID number
117
"""
118
119
# Fragment Management
120
def clearFrag(self):
121
"""Clear current text fragment."""
122
123
def copyFrag(self, **kw):
124
"""
125
Copy current fragment with optional modifications.
126
127
Args:
128
**kw: Fragment attributes to modify
129
130
Returns:
131
Fragment: Copied fragment with modifications
132
"""
133
134
def newFrag(self, **kw):
135
"""
136
Create new text fragment with specified attributes.
137
138
Args:
139
**kw: Fragment attributes
140
141
Returns:
142
Fragment: New fragment object
143
"""
144
145
def addFrag(self, text="", frag=None):
146
"""
147
Add text fragment to current paragraph.
148
149
Args:
150
text (str): Text content to add
151
frag (Fragment): Fragment object (creates new if None)
152
"""
153
154
def pushFrag(self):
155
"""Push current fragment onto fragment stack."""
156
157
def pullFrag(self):
158
"""
159
Pull fragment from fragment stack.
160
161
Returns:
162
Fragment: Fragment from stack (None if empty)
163
"""
164
165
# Logging and Error Handling
166
def warning(self, msg, *args):
167
"""
168
Log warning message.
169
170
Args:
171
msg (str): Warning message format string
172
*args: Message formatting arguments
173
"""
174
175
def error(self, msg, *args):
176
"""
177
Log error message and increment error count.
178
179
Args:
180
msg (str): Error message format string
181
*args: Message formatting arguments
182
"""
183
184
# Resource Management
185
def getFile(self, name, relative=None):
186
"""
187
Get file resource with path resolution.
188
189
Args:
190
name (str): File name or path
191
relative (str): Relative path base
192
193
Returns:
194
pisaFileObject: File object for resource
195
"""
196
197
# Font Management
198
def getFontName(self, names, default="helvetica"):
199
"""
200
Get available font name from font list.
201
202
Args:
203
names (str or list): Font name(s) to look for
204
default (str): Default font if none found
205
206
Returns:
207
str: Available font name
208
"""
209
210
def registerFont(self, fontname, alias=None):
211
"""
212
Register font with ReportLab.
213
214
Args:
215
fontname (str): Font file name or registered font name
216
alias (str): Alias name for font (optional)
217
"""
218
219
def loadFont(self, names, src, encoding="WinAnsiEncoding", bold=0, italic=0):
220
"""
221
Load font from file and register with context.
222
223
Args:
224
names (str or list): Font name(s) to register
225
src (str): Font file path
226
encoding (str): Font encoding
227
bold (int): Bold weight (0=normal, 1=bold)
228
italic (int): Italic style (0=normal, 1=italic)
229
"""
230
231
# Direction and Text Management
232
def setDir(self, direction):
233
"""
234
Set text direction for document.
235
236
Args:
237
direction (str): Text direction ('ltr' or 'rtl')
238
"""
239
240
def UID(self):
241
"""
242
Generate unique identifier.
243
244
Returns:
245
int: Unique identifier number
246
"""
247
```
248
249
#### Usage Examples
250
251
**Basic context setup:**
252
253
```python
254
from xhtml2pdf.context import pisaContext
255
256
# Create context with base path and debug enabled
257
context = pisaContext(path="/path/to/resources", debug=1)
258
259
# Add custom CSS
260
context.addCSS("""
261
@page { size: A4; margin: 2cm; }
262
body { font-family: Arial; color: #333; }
263
""")
264
265
# Parse CSS before processing
266
context.parseCSS()
267
```
268
269
**Font management:**
270
271
```python
272
context = pisaContext()
273
274
# Register custom font
275
context.loadFont(
276
names=["CustomFont", "custom"],
277
src="/path/to/custom-font.ttf",
278
encoding="UTF-8"
279
)
280
281
# Use font in CSS
282
context.addCSS("h1 { font-family: CustomFont; }")
283
```
284
285
**Fragment manipulation:**
286
287
```python
288
context = pisaContext()
289
290
# Create and modify text fragments
291
frag = context.newFrag(fontName="Arial", fontSize=12, textColor="blue")
292
context.addFrag("Hello ", frag)
293
294
# Copy fragment with modifications
295
bold_frag = context.copyFrag(fontName="Arial-Bold")
296
context.addFrag("World!", bold_frag)
297
298
# Add paragraph to story
299
context.addPara()
300
```
301
302
### CSS Builder
303
304
Specialized CSS builder for xhtml2pdf that handles PDF-specific CSS extensions and at-rules.
305
306
```python { .api }
307
class pisaCSSBuilder:
308
def atFontFace(self, declarations):
309
"""
310
Process @font-face CSS at-rule.
311
312
Args:
313
declarations (list): CSS declarations from @font-face rule
314
"""
315
316
def atPage(self):
317
"""
318
Process @page CSS at-rule for page formatting.
319
320
Returns:
321
Page configuration object
322
"""
323
324
def atFrame(self):
325
"""
326
Process @frame CSS at-rule for PDF frame layout.
327
328
Returns:
329
Frame configuration object
330
"""
331
```
332
333
### CSS Parser
334
335
CSS parser specialized for xhtml2pdf's needs, handling external CSS files and PDF-specific CSS extensions.
336
337
```python { .api }
338
class pisaCSSParser:
339
def parseExternal(self, cssResourceName):
340
"""
341
Parse external CSS file and add to context.
342
343
Args:
344
cssResourceName (str): Path or URL to CSS file
345
346
Returns:
347
bool: True if parsing successful
348
"""
349
```
350
351
### Specialized Text Handlers
352
353
Text handling classes for dynamic content like page numbers and page counts.
354
355
```python { .api }
356
class PageNumberText:
357
"""Handler for dynamic page number insertion in PDF content."""
358
359
class PageCountText:
360
"""Handler for dynamic page count insertion in PDF content."""
361
```
362
363
### Fragment Management Utilities
364
365
Utility functions for working with text fragments and paragraph styles.
366
367
```python { .api }
368
def clone(self, **kwargs):
369
"""
370
Clone paragraph fragment with optional modifications.
371
372
Args:
373
**kwargs: Attributes to modify in cloned fragment
374
375
Returns:
376
Fragment: Cloned fragment object
377
"""
378
379
def getParaFrag(style):
380
"""
381
Create paragraph fragment from style information.
382
383
Args:
384
style: Style object containing fragment properties
385
386
Returns:
387
Fragment: New paragraph fragment
388
"""
389
```
390
391
### Path and Directory Utilities
392
393
Utility functions for path and directory name handling in the context system.
394
395
```python { .api }
396
def getDirName(path):
397
"""
398
Get directory name from file path.
399
400
Args:
401
path (str): File path
402
403
Returns:
404
str: Directory name
405
"""
406
407
def reverse_sentence(sentence):
408
"""
409
Reverse sentence for right-to-left language support.
410
411
Args:
412
sentence (str): Input sentence
413
414
Returns:
415
str: Reversed sentence for RTL display
416
"""
417
```
418
419
## Advanced Context Usage
420
421
### Memory Management
422
423
Context capacity controls memory usage during processing:
424
425
```python
426
# Unlimited memory (default)
427
context = pisaContext(capacity=-1)
428
429
# Limited memory for large documents
430
context = pisaContext(capacity=2*1024*1024) # 2MB limit
431
```
432
433
### Error and Warning Handling
434
435
```python
436
context = pisaContext(debug=1)
437
438
# Check for errors and warnings during processing
439
if context.err > 0:
440
print(f"Errors: {context.err}")
441
442
if context.warn > 0:
443
print(f"Warnings: {context.warn}")
444
445
# Access detailed log
446
for entry in context.log:
447
print(entry)
448
```
449
450
### CSS Processing Pipeline
451
452
```python
453
context = pisaContext()
454
455
# Add CSS in order of precedence
456
context.addDefaultCSS("""
457
/* Default styles */
458
body { margin: 0; padding: 0; }
459
""")
460
461
context.addCSS("""
462
/* Document styles */
463
body { font-family: Arial; }
464
h1 { color: blue; }
465
""")
466
467
# Parse all CSS at once
468
context.parseCSS()
469
```
470
471
### Resource Path Resolution
472
473
```python
474
context = pisaContext(path="/base/path")
475
476
# Files will be resolved relative to /base/path
477
file_obj = context.getFile("images/logo.png") # -> /base/path/images/logo.png
478
file_obj = context.getFile("/absolute/path.png") # -> /absolute/path.png
479
```
480
481
## Types
482
483
```python { .api }
484
class pisaContext:
485
"""
486
Main processing context for HTML-to-PDF conversion.
487
488
Attributes:
489
err (int): Number of errors encountered
490
warn (int): Number of warnings generated
491
log (list): Processing log messages
492
cssText (str): Accumulated CSS content
493
cssParser: CSS parser instance
494
fontList (list): Available font names
495
path (str): Base path for resource resolution
496
story (list): ReportLab story elements
497
fragList (list): Current paragraph fragments
498
fragStack (list): Fragment stack for nested elements
499
debug (int): Debug level (0-2)
500
capacity (int): Memory capacity for temp files
501
"""
502
503
class Fragment:
504
"""
505
Text fragment with styling information.
506
507
Attributes:
508
fontName (str): Font family name
509
fontSize (int): Font size in points
510
textColor: Text color specification
511
fontWeight (str): Font weight ('normal', 'bold')
512
fontStyle (str): Font style ('normal', 'italic')
513
textDecoration (str): Text decoration ('none', 'underline')
514
"""
515
```