0
# Theming and Colors
1
2
Comprehensive theming system with support for dark/light backgrounds, custom color schemes, and terminal color output. Provides both pre-built themes and extensible customization options for styling ASCII tree output with colors, attributes, and visual effects.
3
4
## Capabilities
5
6
### Theme Creation
7
8
Create appropriate themes based on terminal background and color preferences.
9
10
```python { .api }
11
def get_theme(dark_background, colored=None):
12
"""
13
Create an appropriate theme for the terminal environment.
14
15
Parameters:
16
- dark_background: bool - True for dark background terminals, False for light
17
- colored: Callable - Color function to use, defaults to _no_color function
18
19
Returns:
20
Theme - DarkBackgroundTheme or LightBackgroundTheme instance
21
"""
22
```
23
24
**Usage Examples:**
25
26
```python
27
from eliottree import get_theme, colored
28
29
# Basic theme for dark terminal
30
dark_theme = get_theme(dark_background=True)
31
32
# Theme with colors enabled
33
color_theme = get_theme(dark_background=True, colored=colored)
34
35
# Light background theme
36
light_theme = get_theme(dark_background=False, colored=colored)
37
```
38
39
### Theme Customization
40
41
Apply custom color overrides to existing themes for personalized styling.
42
43
```python { .api }
44
def apply_theme_overrides(theme, overrides):
45
"""
46
Apply color overrides to an existing theme.
47
48
Parameters:
49
- theme: Theme - Existing theme object to modify
50
- overrides: dict - Dictionary mapping theme color names to color specifications
51
52
Returns:
53
Theme - Modified theme with overrides applied
54
"""
55
```
56
57
**Usage Example:**
58
59
```python
60
from eliottree import get_theme, apply_theme_overrides, colored
61
62
# Create base theme
63
theme = get_theme(dark_background=True, colored=colored)
64
65
# Define custom overrides
66
overrides = {
67
'root': ['magenta', None, ['bold']], # Bold magenta for task roots
68
'prop_key': ['cyan'], # Cyan for property keys
69
'status_success': ['bright_green'], # Bright green for success
70
'status_failure': ['red', None, ['bold']] # Bold red for failures
71
}
72
73
# Apply overrides
74
custom_theme = apply_theme_overrides(theme, overrides)
75
```
76
77
### Theme Base Class
78
79
Base class for creating custom theme implementations with full color specification control.
80
81
```python { .api }
82
class Theme:
83
"""
84
Theme base class for styling tree output.
85
86
Attributes (all callable color functions):
87
- root: Color function for task root (UUID)
88
- parent: Color function for action/message nodes
89
- task_level: Color function for task level indicators
90
- status_success: Color function for successful action status
91
- status_failure: Color function for failed action status
92
- timestamp: Color function for timestamps
93
- duration: Color function for durations
94
- prop_key: Color function for property keys
95
- prop_value: Color function for property values
96
- error: Color function for error messages
97
- tree_failed: Color function for failed task tree elements
98
- tree_color0, tree_color1, tree_color2: Cycling colors for tree structure
99
"""
100
101
def __init__(self, color, **theme):
102
"""
103
Initialize theme with color factory and theme specifications.
104
105
Parameters:
106
- color: Callable - Color factory function
107
- **theme: Color specifications for theme elements
108
"""
109
```
110
111
**Usage Example:**
112
113
```python
114
from eliottree import Theme, color_factory, colored
115
116
# Create custom theme class
117
class CustomTheme(Theme):
118
def __init__(self, colored_func):
119
super(CustomTheme, self).__init__(
120
color=color_factory(colored_func),
121
root=('yellow', None, ['bold']),
122
parent=('blue',),
123
status_success=('green', None, ['bright']),
124
status_failure=('red', 'white', ['bold']),
125
prop_key=('cyan',),
126
prop_value=('white',),
127
error=('red', None, ['bold', 'underlined'])
128
)
129
130
# Use custom theme
131
theme = CustomTheme(colored)
132
```
133
134
### Specific Theme Classes
135
136
The actual theme classes returned by `get_theme()`:
137
138
```python { .api }
139
class DarkBackgroundTheme(Theme):
140
"""
141
Color theme for dark terminal backgrounds.
142
143
Provides colors that are visible and readable on dark backgrounds.
144
"""
145
146
def __init__(self, colored):
147
"""Initialize with appropriate colors for dark backgrounds."""
148
149
class LightBackgroundTheme(Theme):
150
"""
151
Color theme for light terminal backgrounds.
152
153
Provides colors that are visible and readable on light backgrounds.
154
"""
155
156
def __init__(self, colored):
157
"""Initialize with appropriate colors for light backgrounds."""
158
```
159
160
### Color Functions
161
162
Low-level color functions for terminal text styling and color factory creation.
163
164
```python { .api }
165
def colored(text, fg=None, bg=None, attrs=None):
166
"""
167
Wrap text in terminal color codes.
168
169
Parameters:
170
- text: str - Text to colorize
171
- fg: str - Foreground color name or code
172
- bg: str - Background color name or code
173
- attrs: list - List of text attributes (bold, dim, underlined, etc.)
174
175
Returns:
176
str - Text wrapped with terminal color escape codes
177
"""
178
179
def color_factory(colored):
180
"""
181
Factory for making text color-wrapper functions.
182
183
Parameters:
184
- colored: Callable - Base color function (like the colored function above)
185
186
Returns:
187
Callable - Color factory function that creates color-wrapper functions
188
"""
189
```
190
191
**Usage Examples:**
192
193
```python
194
from eliottree import colored, color_factory
195
196
# Direct color usage
197
red_text = colored("Error message", fg='red', attrs=['bold'])
198
highlighted = colored("Important", fg='yellow', bg='blue')
199
200
# Create color factory
201
color_func = color_factory(colored)
202
203
# Create specific color functions
204
red_bold = color_func('red', None, ['bold'])
205
blue_bg = color_func('white', 'blue')
206
207
# Use color functions
208
styled_text = red_bold("This is red and bold")
209
highlighted_text = blue_bg("This has blue background")
210
```
211
212
## Complete Theming Example
213
214
```python
215
import sys
216
from eliottree import (
217
tasks_from_iterable, render_tasks, get_theme,
218
apply_theme_overrides, colored
219
)
220
221
def render_with_custom_theme(messages):
222
"""Render tasks with a fully customized theme."""
223
224
# Create base theme
225
theme = get_theme(dark_background=True, colored=colored)
226
227
# Define comprehensive overrides
228
theme_overrides = {
229
# Task identification
230
'root': ['bright_white', None, ['bold']],
231
'parent': ['magenta', None, ['bold']],
232
233
# Status indicators
234
'status_success': ['bright_green'],
235
'status_failure': ['bright_red', None, ['bold']],
236
237
# Data presentation
238
'prop_key': ['cyan'],
239
'prop_value': ['white'],
240
'timestamp': ['yellow', None, ['dim']],
241
'duration': ['blue', None, ['dim']],
242
243
# Tree structure
244
'tree_color0': ['white', None, ['dim']],
245
'tree_color1': ['blue', None, ['dim']],
246
'tree_color2': ['green', None, ['dim']],
247
'tree_failed': ['red'],
248
249
# Errors
250
'error': ['red', 'white', ['bold']]
251
}
252
253
# Apply customizations
254
custom_theme = apply_theme_overrides(theme, theme_overrides)
255
256
# Parse and render with full styling
257
tasks = tasks_from_iterable(messages)
258
render_tasks(
259
sys.stdout.write,
260
tasks,
261
theme=custom_theme,
262
colorize_tree=True, # Enable tree structure coloring
263
human_readable=True, # Format timestamps/durations
264
field_limit=150, # Limit field lengths
265
)
266
```
267
268
## Available Colors and Attributes
269
270
### Foreground/Background Colors
271
272
- **Basic**: `black`, `red`, `green`, `yellow`, `blue`, `magenta`, `cyan`, `white`
273
- **Bright**: `bright_black`, `bright_red`, `bright_green`, `bright_yellow`, `bright_blue`, `bright_magenta`, `bright_cyan`, `bright_white`
274
- **Extended**: `dark_gray`, `light_gray` and 256-color codes
275
276
### Text Attributes
277
278
- `bold` - Bold text
279
- `dim` - Dimmed/faint text
280
- `underlined` - Underlined text
281
- `blink` - Blinking text (rarely supported)
282
- `reverse` - Reverse video (swap fg/bg)
283
- `hidden` - Hidden text
284
285
## Theme Color Specifications
286
287
Theme colors are specified as tuples: `[foreground, background, attributes]`
288
289
- `[color]` - Foreground color only
290
- `[fg_color, bg_color]` - Foreground and background
291
- `[fg_color, None, [attrs]]` - Foreground with attributes
292
- `[fg_color, bg_color, [attrs]]` - Full specification
293
294
**Examples:**
295
296
```python
297
overrides = {
298
'root': ['white'], # White text
299
'parent': ['magenta', 'black'], # Magenta on black
300
'status_success': ['green', None, ['bold']], # Bold green
301
'error': ['red', 'yellow', ['bold', 'underlined']] # Bold underlined red on yellow
302
}
303
```
304
305
## Configuration File Integration
306
307
Themes can be configured via JSON configuration files:
308
309
```json
310
{
311
"theme_overrides": {
312
"root": ["magenta", null, ["bold"]],
313
"prop_key": ["red"],
314
"status_success": ["bright_green"],
315
"status_failure": ["bright_red", null, ["bold"]]
316
}
317
}
318
```
319
320
Load and apply configuration:
321
322
```python
323
import json
324
from eliottree import get_theme, apply_theme_overrides, colored
325
326
# Load configuration
327
with open('config.json') as f:
328
config = json.load(f)
329
330
# Apply to theme
331
theme = get_theme(dark_background=True, colored=colored)
332
if 'theme_overrides' in config:
333
theme = apply_theme_overrides(theme, config['theme_overrides'])
334
```