0
# Text Formatting
1
2
Text formatting utilities for creating well-structured help output, text wrapping, and table formatting. These functions are primarily used internally by Click but can be useful for custom help formatting and output generation.
3
4
## Capabilities
5
6
### Help Formatting
7
8
Core class for formatting help text with proper indentation, sections, and layout.
9
10
```python { .api }
11
class HelpFormatter:
12
indent_increment: int
13
width: int | None
14
current_indent: int
15
buffer: list[str]
16
17
def __init__(
18
self,
19
indent_increment: int = 2,
20
width: int | None = None,
21
max_width: int | None = None
22
) -> None:
23
"""
24
Create a help formatter.
25
26
Parameters:
27
- indent_increment: Spaces per indent level
28
- width: Target width for output
29
- max_width: Maximum width for output
30
"""
31
32
def write(self, string: str) -> None:
33
"""
34
Write text to the formatter buffer.
35
36
Parameters:
37
- string: Text to write
38
"""
39
40
def indent(self) -> None:
41
"""Increase indentation level."""
42
43
def dedent(self) -> None:
44
"""Decrease indentation level."""
45
46
def write_usage(self, prog: str, args: str = '', prefix: str = 'Usage: ') -> None:
47
"""
48
Write a usage line.
49
50
Parameters:
51
- prog: Program name
52
- args: Arguments string
53
- prefix: Usage prefix text
54
"""
55
56
def write_heading(self, heading: str) -> None:
57
"""
58
Write a section heading.
59
60
Parameters:
61
- heading: Heading text
62
"""
63
64
def write_paragraph(self) -> None:
65
"""Write a paragraph break."""
66
67
def write_text(self, text: str) -> None:
68
"""
69
Write wrapped text.
70
71
Parameters:
72
- text: Text to write and wrap
73
"""
74
75
def write_dl(
76
self,
77
rows: Iterable[Iterable[str]],
78
col_max: int = 30,
79
col_spacing: int = 2
80
) -> None:
81
"""
82
Write a definition list (two-column layout).
83
84
Parameters:
85
- rows: Iterable of rows, each containing (term, definition)
86
- col_max: Maximum width for first column
87
- col_spacing: Spacing between columns
88
"""
89
90
def section(self, name: str) -> ContextManager[None]:
91
"""
92
Context manager for a formatted section.
93
94
Parameters:
95
- name: Section name
96
97
Usage:
98
formatter = HelpFormatter()
99
with formatter.section('Options'):
100
formatter.write_text('Available options:')
101
formatter.write_dl([('--help', 'Show help message')])
102
"""
103
104
def indentation(self) -> ContextManager[None]:
105
"""
106
Context manager for temporary indentation.
107
108
Usage:
109
formatter = HelpFormatter()
110
formatter.write('Normal text')
111
with formatter.indentation():
112
formatter.write('Indented text')
113
formatter.write('Normal text again')
114
"""
115
116
def getvalue(self) -> str:
117
"""
118
Get the formatted output.
119
120
Returns:
121
Complete formatted text
122
"""
123
```
124
125
### Text Wrapping
126
127
Functions for wrapping and formatting text content.
128
129
```python { .api }
130
def wrap_text(
131
text: str,
132
width: int = 78,
133
initial_indent: str = '',
134
subsequent_indent: str = '',
135
preserve_paragraphs: bool = False,
136
) -> str:
137
"""
138
Wrap text to specified width with indentation control.
139
140
Parameters:
141
- text: Text to wrap
142
- width: Target line width
143
- initial_indent: Indent for first line
144
- subsequent_indent: Indent for continuation lines
145
- preserve_paragraphs: Keep paragraph breaks
146
147
Returns:
148
Wrapped text string
149
150
Usage:
151
# Basic wrapping
152
wrapped = click.formatting.wrap_text('Long text...', width=60)
153
154
# With indentation
155
wrapped = click.formatting.wrap_text(
156
'Long help text...',
157
width=70,
158
initial_indent=' ',
159
subsequent_indent=' '
160
)
161
162
# Preserve paragraphs
163
wrapped = click.formatting.wrap_text(
164
'Para 1\\n\\nPara 2',
165
preserve_paragraphs=True
166
)
167
"""
168
```
169
170
### Table Utilities
171
172
Functions for measuring and formatting tabular data.
173
174
```python { .api }
175
def measure_table(rows: Iterable[Iterable[str]]) -> tuple[int, ...]:
176
"""
177
Measure column widths for a table.
178
179
Parameters:
180
- rows: Table rows as iterables of strings
181
182
Returns:
183
Tuple of maximum widths for each column
184
185
Usage:
186
table_data = [
187
['Name', 'Age', 'City'],
188
['Alice', '25', 'New York'],
189
['Bob', '30', 'San Francisco']
190
]
191
widths = click.formatting.measure_table(table_data)
192
# widths = (5, 3, 13)
193
"""
194
195
def iter_rows(
196
rows: Iterable[Iterable[str]],
197
col_count: int
198
) -> Generator[tuple[str, ...], None, None]:
199
"""
200
Iterate table rows, ensuring consistent column count.
201
202
Parameters:
203
- rows: Table rows as iterables of strings
204
- col_count: Expected number of columns
205
206
Yields:
207
Tuples of strings with consistent column count
208
209
Usage:
210
table_data = [['A', 'B'], ['C']] # Inconsistent columns
211
for row in click.formatting.iter_rows(table_data, 2):
212
print(row) # ('A', 'B'), ('C', '')
213
"""
214
```
215
216
### Option Formatting
217
218
Utilities for formatting command-line options.
219
220
```python { .api }
221
def join_options(options: list[str]) -> tuple[str, bool]:
222
"""
223
Join option names for display.
224
225
Parameters:
226
- options: List of option strings
227
228
Returns:
229
Tuple of (joined_options, any_prefix_is_long)
230
231
Usage:
232
joined, has_long = click.formatting.join_options(['-v', '--verbose'])
233
# joined = '-v, --verbose', has_long = True
234
235
joined, has_long = click.formatting.join_options(['-h'])
236
# joined = '-h', has_long = False
237
"""
238
```
239
240
### Module Constants
241
242
Configuration constants for formatting behavior.
243
244
```python { .api }
245
FORCED_WIDTH: int | None
246
"""
247
Global width override for all formatting operations.
248
When set, overrides automatic width detection.
249
250
Usage:
251
import click.formatting
252
click.formatting.FORCED_WIDTH = 80 # Force 80-column output
253
"""
254
```
255
256
## Usage Examples
257
258
### Custom Help Formatting
259
260
```python
261
from click.formatting import HelpFormatter
262
263
def format_custom_help(commands):
264
formatter = HelpFormatter(width=80)
265
266
formatter.write_usage('myapp', '[OPTIONS] COMMAND [ARGS]')
267
formatter.write_paragraph()
268
269
with formatter.section('Available Commands'):
270
rows = [(name, cmd.get_short_help_str()) for name, cmd in commands.items()]
271
formatter.write_dl(rows)
272
273
return formatter.getvalue()
274
```
275
276
### Table Formatting
277
278
```python
279
from click.formatting import measure_table, iter_rows
280
281
def format_table(data, headers):
282
all_rows = [headers] + data
283
widths = measure_table(all_rows)
284
285
result = []
286
for row in iter_rows(all_rows, len(headers)):
287
formatted_row = ' '.join(
288
cell.ljust(width) for cell, width in zip(row, widths)
289
)
290
result.append(formatted_row)
291
292
return '\\n'.join(result)
293
294
# Usage
295
data = [['Alice', '25'], ['Bob', '30']]
296
headers = ['Name', 'Age']
297
table = format_table(data, headers)
298
click.echo(table)
299
```
300
301
### Text Wrapping with Custom Indentation
302
303
```python
304
from click.formatting import wrap_text
305
306
def format_command_help(help_text):
307
return wrap_text(
308
help_text,
309
width=72,
310
initial_indent=' ',
311
subsequent_indent=' ',
312
preserve_paragraphs=True
313
)
314
315
# Usage
316
help_text = "This is a long help message that needs to be wrapped properly..."
317
formatted = format_command_help(help_text)
318
click.echo(formatted)
319
```