0
# Layout and Positioning
1
2
Advanced layout control with positioning, spacing, alignment, and minipage environments for precise document formatting. PyLaTeX provides comprehensive tools for managing document layout, from simple spacing commands to complex multi-column layouts and precise element positioning.
3
4
## Capabilities
5
6
### Spacing Commands
7
8
Control horizontal and vertical spacing between document elements with precise measurements.
9
10
```python { .api }
11
class HorizontalSpace(CommandBase):
12
def __init__(self, size, *, star=True):
13
"""
14
Add horizontal space between elements.
15
16
Parameters:
17
- size: str, amount of space to add (e.g., '1cm', '10pt', '0.5in')
18
- star: bool, use starred version (hspace*) that doesn't disappear at line breaks
19
"""
20
21
class VerticalSpace(CommandBase):
22
def __init__(self, size, *, star=True):
23
"""
24
Add vertical space between elements.
25
26
Parameters:
27
- size: str, amount of space to add (e.g., '1cm', '10pt', '0.5em')
28
- star: bool, use starred version (vspace*) that doesn't disappear at page breaks
29
"""
30
```
31
32
Usage example:
33
34
```python
35
from pylatex import Document, Section, NoEscape
36
from pylatex.position import HorizontalSpace, VerticalSpace
37
38
doc = Document()
39
40
with doc.create(Section('Spacing Examples')):
41
doc.append('Text before horizontal space')
42
doc.append(HorizontalSpace('2cm'))
43
doc.append('Text after 2cm space')
44
45
doc.append(VerticalSpace('1cm'))
46
doc.append('Text after 1cm vertical space')
47
48
# Negative spacing (overlap)
49
doc.append('Overlapping')
50
doc.append(HorizontalSpace('-0.5cm'))
51
doc.append('Text')
52
53
# Various units
54
doc.append(VerticalSpace('2em')) # Relative to font size
55
doc.append('Text after 2em space')
56
57
doc.append(VerticalSpace('12pt')) # Points
58
doc.append('Text after 12pt space')
59
60
doc.append(VerticalSpace('0.2in')) # Inches
61
doc.append('Text after 0.2 inch space')
62
```
63
64
### Alignment Environments
65
66
Control text and content alignment within specific regions of the document.
67
68
```python { .api }
69
class Center(Environment):
70
"""
71
Center-aligned environment.
72
73
Requires:
74
- ragged2e package (automatically added)
75
"""
76
77
class FlushLeft(Environment):
78
"""
79
Left-aligned environment.
80
81
Requires:
82
- ragged2e package (automatically added)
83
"""
84
85
class FlushRight(Environment):
86
"""
87
Right-aligned environment.
88
89
Requires:
90
- ragged2e package (automatically added)
91
"""
92
```
93
94
Usage example:
95
96
```python
97
from pylatex import Document, Section
98
from pylatex.position import Center, FlushLeft, FlushRight
99
100
doc = Document()
101
102
with doc.create(Section('Text Alignment')):
103
with doc.create(Center()):
104
doc.append('This text is centered on the page.')
105
doc.append('Multiple lines are all centered.')
106
107
with doc.create(FlushLeft()):
108
doc.append('This text is left-aligned.')
109
doc.append('Even in a document with different default alignment.')
110
111
with doc.create(FlushRight()):
112
doc.append('This text is right-aligned.')
113
doc.append('Useful for signatures or dates.')
114
115
# Centering specific elements
116
with doc.create(Section('Centered Elements')):
117
doc.append('Normal paragraph text flows naturally.')
118
119
with doc.create(Center()):
120
doc.append('--- Important Notice ---')
121
122
doc.append('Back to normal text flow after the centered element.')
123
```
124
125
### MiniPage Environment
126
127
Create flexible sub-documents within the main document with independent formatting and layout control.
128
129
```python { .api }
130
class MiniPage(Environment):
131
def __init__(self, *, width=NoEscape(r"\textwidth"), pos=None,
132
height=None, content_pos=None, align=None,
133
fontsize=None, data=None):
134
"""
135
Create a minipage environment for complex layouts.
136
137
Parameters:
138
- width: str or NoEscape, width of minipage (default: full text width)
139
- pos: str, vertical alignment relative to baseline ('c', 't', 'b')
140
- 'c': center (default)
141
- 't': top
142
- 'b': bottom
143
- height: str, fixed height of minipage
144
- content_pos: str, content position within minipage ('c', 't', 'b', 's')
145
- 'c': center
146
- 't': top
147
- 'b': bottom
148
- 's': stretch (spread content)
149
- align: str, text alignment within minipage
150
- fontsize: str, font size for minipage content
151
- data: initial content
152
153
Requires:
154
- ragged2e package (automatically added)
155
"""
156
```
157
158
Usage example:
159
160
```python
161
from pylatex import Document, Section, NoEscape
162
from pylatex.position import MiniPage
163
from pylatex.figure import StandAloneGraphic
164
165
doc = Document()
166
167
with doc.create(Section('Complex Layouts')):
168
# Side-by-side content
169
with doc.create(MiniPage(width=NoEscape(r'0.45\textwidth'))) as left:
170
left.append('This is the left column content. ')
171
left.append('It can contain multiple paragraphs and will wrap ')
172
left.append('within the specified width.')
173
174
doc.append(NoEscape(r'\hfill')) # Push to opposite sides
175
176
with doc.create(MiniPage(width=NoEscape(r'0.45\textwidth'))) as right:
177
right.append('This is the right column content. ')
178
right.append('Both minipages will appear side by side ')
179
right.append('on the same horizontal line.')
180
181
# Text and image layout
182
with doc.create(Section('Mixed Content Layout')):
183
with doc.create(MiniPage(width=NoEscape(r'0.6\textwidth'),
184
pos='t')) as text_box:
185
text_box.append('Detailed explanation of the concept. ')
186
text_box.append('This text appears alongside the diagram. ')
187
text_box.append('The minipage allows precise control over ')
188
text_box.append('the text width and positioning.')
189
190
doc.append(NoEscape(r'\hfill'))
191
192
with doc.create(MiniPage(width=NoEscape(r'0.35\textwidth'),
193
pos='t')) as image_box:
194
image_box.append(StandAloneGraphic('diagram.png',
195
image_options=NoEscape(r'width=\textwidth')))
196
197
# Vertical alignment examples
198
with doc.create(Section('Vertical Alignment')):
199
with doc.create(MiniPage(width=NoEscape(r'0.3\textwidth'),
200
height='4cm', pos='t', content_pos='t')) as top:
201
top.append('Content aligned to top of minipage.')
202
203
doc.append(NoEscape(r'\hfill'))
204
205
with doc.create(MiniPage(width=NoEscape(r'0.3\textwidth'),
206
height='4cm', pos='t', content_pos='c')) as center:
207
center.append('Content centered in minipage.')
208
209
doc.append(NoEscape(r'\hfill'))
210
211
with doc.create(MiniPage(width=NoEscape(r'0.3\textwidth'),
212
height='4cm', pos='t', content_pos='b')) as bottom:
213
bottom.append('Content aligned to bottom.')
214
```
215
216
### Advanced Layout Patterns
217
218
#### Multi-Column Layouts
219
220
```python
221
from pylatex import Document, Section, NoEscape
222
from pylatex.position import MiniPage
223
224
doc = Document()
225
226
with doc.create(Section('Three-Column Layout')):
227
# Three equal columns
228
column_width = NoEscape(r'0.32\textwidth')
229
230
with doc.create(MiniPage(width=column_width, pos='t')) as col1:
231
col1.append('First Column')
232
col1.append('Content for the first column goes here. ')
233
col1.append('This could be text, lists, or other elements.')
234
235
doc.append(NoEscape(r'\hfill'))
236
237
with doc.create(MiniPage(width=column_width, pos='t')) as col2:
238
col2.append('Second Column')
239
col2.append('Content for the second column. ')
240
col2.append('Each column is independent.')
241
242
doc.append(NoEscape(r'\hfill'))
243
244
with doc.create(MiniPage(width=column_width, pos='t')) as col3:
245
col3.append('Third Column')
246
col3.append('Final column content. ')
247
col3.append('Columns align at the top.')
248
249
# Asymmetric layout
250
with doc.create(Section('Asymmetric Layout')):
251
# Wide left, narrow right
252
with doc.create(MiniPage(width=NoEscape(r'0.7\textwidth'))) as main:
253
main.append('Main Content Area')
254
main.append('This wider area contains the primary content. ')
255
main.append('It takes up most of the page width.')
256
257
doc.append(NoEscape(r'\hfill'))
258
259
with doc.create(MiniPage(width=NoEscape(r'0.25\textwidth'))) as sidebar:
260
sidebar.append('Sidebar')
261
sidebar.append('Notes, references, or supplementary information.')
262
```
263
264
#### Boxed Content
265
266
```python
267
from pylatex import Document, Section, Command, NoEscape
268
from pylatex.position import MiniPage, Center
269
270
doc = Document()
271
272
with doc.create(Section('Boxed Content')):
273
# Framed minipage
274
with doc.create(Center()):
275
doc.append(Command('fbox',
276
MiniPage(width=NoEscape(r'0.8\textwidth'), data=[
277
'Important Information',
278
NoEscape(r'\\[0.5em]'),
279
'This content is highlighted in a box for emphasis. ',
280
'The minipage provides the content structure, while ',
281
'fbox adds the border.'
282
])
283
))
284
285
# Custom spacing and padding
286
with doc.create(Section('Padded Boxes')):
287
with doc.create(Center()):
288
# Custom padding using fboxsep
289
doc.append(Command('setlength', arguments=[NoEscape(r'\fboxsep'), '10pt']))
290
doc.append(Command('fbox',
291
MiniPage(width=NoEscape(r'0.6\textwidth'), data=[
292
'Padded Content',
293
NoEscape(r'\\[0.5em]'),
294
'Extra padding makes this more readable.'
295
])
296
))
297
```
298
299
#### Header and Footer Layouts
300
301
```python
302
from pylatex import Document, Section, NoEscape
303
from pylatex.position import MiniPage, FlushLeft, FlushRight, Center
304
305
doc = Document()
306
307
# Custom header layout
308
def create_header(title, author, date):
309
with doc.create(MiniPage(width=NoEscape(r'\textwidth'))) as header:
310
with header.create(FlushLeft()):
311
header.append(f'Title: {title}')
312
313
with header.create(Center()):
314
header.append(f'Author: {author}')
315
316
with header.create(FlushRight()):
317
header.append(f'Date: {date}')
318
319
doc.append(NoEscape(r'\hrule'))
320
doc.append(NoEscape(r'\vspace{1em}'))
321
322
create_header('Research Report', 'Dr. Jane Smith', '2024-01-15')
323
324
with doc.create(Section('Document Content')):
325
doc.append('Main document content follows the custom header.')
326
```
327
328
## Text Block Positioning
329
330
```python { .api }
331
class TextBlock(Environment):
332
def __init__(self, width, horizontal_pos, vertical_pos, *,
333
indent=False, data=None):
334
"""
335
Create positioned text block using textpos package.
336
337
Parameters:
338
- width: float, width of text block in TPHorizModule units
339
- horizontal_pos: float, horizontal position in TPHorizModule units
340
- vertical_pos: float, vertical position in TPVertModule units
341
- indent: bool, enable paragraph indentation (default False)
342
- data: initial content for the text block
343
344
Requires:
345
- textpos package (automatically added)
346
"""
347
```
348
349
Usage example:
350
351
```python
352
from pylatex import Document, Package
353
from pylatex.position import TextBlock
354
355
doc = Document()
356
doc.packages.append(Package('textpos'))
357
358
# Absolute positioning
359
with doc.create(TextBlock(width='5cm', horizontal_pos=2, vertical_pos=3)):
360
doc.append('This text block is positioned at specific coordinates.')
361
doc.append('Useful for overlays, annotations, or precise layouts.')
362
```
363
364
## Layout Utilities and Helpers
365
366
### Flexible Spacing
367
368
```python
369
from pylatex import Document, NoEscape
370
from pylatex.position import HorizontalSpace, VerticalSpace
371
372
doc = Document()
373
374
# Responsive spacing
375
doc.append('Text')
376
doc.append(HorizontalSpace(NoEscape(r'0.1\textwidth'))) # 10% of text width
377
doc.append('More text')
378
379
# Fill remaining space
380
doc.append('Left')
381
doc.append(NoEscape(r'\hfill')) # Fills all available space
382
doc.append('Right')
383
384
# Stretchable space
385
doc.append('Item 1')
386
doc.append(NoEscape(r'\hspace{\stretch{1}}'))
387
doc.append('Item 2')
388
doc.append(NoEscape(r'\hspace{\stretch{2}}')) # Twice as much space
389
doc.append('Item 3')
390
```
391
392
### Page Layout Control
393
394
```python
395
from pylatex import Document, Command, Package, NoEscape
396
from pylatex.position import VerticalSpace
397
398
doc = Document()
399
doc.packages.append(Package('geometry', options=['margin=1in']))
400
401
# Page-level spacing adjustments
402
doc.preamble.append(Command('setlength', arguments=[NoEscape(r'\parskip'), '1em']))
403
doc.preamble.append(Command('setlength', arguments=[NoEscape(r'\parindent'), '0pt']))
404
405
# Dynamic page breaks
406
doc.append('Content before page break')
407
doc.append(VerticalSpace(NoEscape(r'\fill'))) # Push to bottom
408
doc.append('Content at bottom of page')
409
doc.append(Command('newpage'))
410
doc.append('Content on next page')
411
```
412
413
## Advanced Layout Techniques
414
415
### Overlay Positioning
416
417
```python
418
from pylatex import Document, Package, NoEscape, Command
419
from pylatex.position import MiniPage
420
421
doc = Document()
422
doc.packages.append(Package('tikz'))
423
424
# TikZ overlay on minipage
425
with doc.create(MiniPage(width=NoEscape(r'0.8\textwidth'))) as container:
426
container.append('Base content that will have overlays.')
427
container.append(NoEscape(r'\\[2em]'))
428
container.append('More base content here.')
429
430
# Add TikZ overlay
431
container.append(NoEscape(r'''
432
\begin{tikzpicture}[remember picture, overlay]
433
\node[red, font=\Large] at (2, 0) {Overlay Text};
434
\draw[blue, thick] (0, -1) rectangle (4, 1);
435
\end{tikzpicture}
436
'''))
437
```
438
439
### Responsive Layouts
440
441
```python
442
from pylatex import Document, Command, NoEscape
443
from pylatex.position import MiniPage
444
445
doc = Document()
446
447
# Conditional layout based on text width
448
doc.preamble.append(Command('newlength', arguments=NoEscape(r'\columnwidth')))
449
doc.preamble.append(Command('setlength', arguments=[
450
NoEscape(r'\columnwidth'), NoEscape(r'0.45\textwidth')
451
]))
452
453
# Use calculated width
454
with doc.create(MiniPage(width=NoEscape(r'\columnwidth'))) as responsive:
455
responsive.append('This minipage uses a calculated width.')
456
responsive.append('It adapts to different document settings.')
457
```
458
459
## Package Dependencies
460
461
Layout functionality requires specific LaTeX packages:
462
463
- **Basic spacing**: No additional packages
464
- **Alignment environments**: `ragged2e` package (automatically added)
465
- **MiniPage**: `ragged2e` package (automatically added)
466
- **TextBlock**: `textpos` package (must be added manually)
467
- **Advanced positioning**: `tikz` package for overlays
468
469
```python
470
from pylatex import Document, Package
471
472
doc = Document()
473
474
# Layout packages
475
doc.packages.append(Package('ragged2e'))
476
doc.packages.append(Package('textpos'))
477
doc.packages.append(Package('tikz'))
478
doc.packages.append(Package('geometry', options=['margin=1in']))
479
```
480
481
## Layout Best Practices
482
483
### Consistent Spacing
484
485
```python
486
from pylatex import Document, Command, NoEscape
487
from pylatex.position import VerticalSpace
488
489
doc = Document()
490
491
# Define standard spacing units
492
doc.preamble.append(Command('newlength', arguments=NoEscape(r'\standardspace')))
493
doc.preamble.append(Command('setlength', arguments=[
494
NoEscape(r'\standardspace'), '1em'
495
]))
496
497
# Use consistent spacing throughout
498
doc.append('Section 1')
499
doc.append(VerticalSpace(NoEscape(r'\standardspace')))
500
doc.append('Section 2')
501
doc.append(VerticalSpace(NoEscape(r'\standardspace')))
502
doc.append('Section 3')
503
```
504
505
### Modular Layout Components
506
507
```python
508
from pylatex import Document, NoEscape
509
from pylatex.position import MiniPage, Center
510
511
def create_info_box(title, content, width=NoEscape(r'0.8\textwidth')):
512
"""Create a standardized information box."""
513
with doc.create(Center()):
514
with doc.create(MiniPage(width=width)) as box:
515
with box.create(Center()):
516
box.append(Command('textbf', title))
517
box.append(NoEscape(r'\\[0.5em]'))
518
box.append(content)
519
return box
520
521
doc = Document()
522
523
# Reusable layout components
524
create_info_box('Important Note', 'This is highlighted information.')
525
create_info_box('Warning', 'Please review this carefully.')
526
```
527
528
The layout system in PyLaTeX provides powerful tools for creating professional, precisely controlled document layouts while maintaining the flexibility to adapt to different content requirements.