Render Eliot logs as an ASCII tree
—
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.
Create appropriate themes based on terminal background and color preferences.
def get_theme(dark_background, colored=None):
"""
Create an appropriate theme for the terminal environment.
Parameters:
- dark_background: bool - True for dark background terminals, False for light
- colored: Callable - Color function to use, defaults to _no_color function
Returns:
Theme - DarkBackgroundTheme or LightBackgroundTheme instance
"""Usage Examples:
from eliottree import get_theme, colored
# Basic theme for dark terminal
dark_theme = get_theme(dark_background=True)
# Theme with colors enabled
color_theme = get_theme(dark_background=True, colored=colored)
# Light background theme
light_theme = get_theme(dark_background=False, colored=colored)Apply custom color overrides to existing themes for personalized styling.
def apply_theme_overrides(theme, overrides):
"""
Apply color overrides to an existing theme.
Parameters:
- theme: Theme - Existing theme object to modify
- overrides: dict - Dictionary mapping theme color names to color specifications
Returns:
Theme - Modified theme with overrides applied
"""Usage Example:
from eliottree import get_theme, apply_theme_overrides, colored
# Create base theme
theme = get_theme(dark_background=True, colored=colored)
# Define custom overrides
overrides = {
'root': ['magenta', None, ['bold']], # Bold magenta for task roots
'prop_key': ['cyan'], # Cyan for property keys
'status_success': ['bright_green'], # Bright green for success
'status_failure': ['red', None, ['bold']] # Bold red for failures
}
# Apply overrides
custom_theme = apply_theme_overrides(theme, overrides)Base class for creating custom theme implementations with full color specification control.
class Theme:
"""
Theme base class for styling tree output.
Attributes (all callable color functions):
- root: Color function for task root (UUID)
- parent: Color function for action/message nodes
- task_level: Color function for task level indicators
- status_success: Color function for successful action status
- status_failure: Color function for failed action status
- timestamp: Color function for timestamps
- duration: Color function for durations
- prop_key: Color function for property keys
- prop_value: Color function for property values
- error: Color function for error messages
- tree_failed: Color function for failed task tree elements
- tree_color0, tree_color1, tree_color2: Cycling colors for tree structure
"""
def __init__(self, color, **theme):
"""
Initialize theme with color factory and theme specifications.
Parameters:
- color: Callable - Color factory function
- **theme: Color specifications for theme elements
"""Usage Example:
from eliottree import Theme, color_factory, colored
# Create custom theme class
class CustomTheme(Theme):
def __init__(self, colored_func):
super(CustomTheme, self).__init__(
color=color_factory(colored_func),
root=('yellow', None, ['bold']),
parent=('blue',),
status_success=('green', None, ['bright']),
status_failure=('red', 'white', ['bold']),
prop_key=('cyan',),
prop_value=('white',),
error=('red', None, ['bold', 'underlined'])
)
# Use custom theme
theme = CustomTheme(colored)The actual theme classes returned by get_theme():
class DarkBackgroundTheme(Theme):
"""
Color theme for dark terminal backgrounds.
Provides colors that are visible and readable on dark backgrounds.
"""
def __init__(self, colored):
"""Initialize with appropriate colors for dark backgrounds."""
class LightBackgroundTheme(Theme):
"""
Color theme for light terminal backgrounds.
Provides colors that are visible and readable on light backgrounds.
"""
def __init__(self, colored):
"""Initialize with appropriate colors for light backgrounds."""Low-level color functions for terminal text styling and color factory creation.
def colored(text, fg=None, bg=None, attrs=None):
"""
Wrap text in terminal color codes.
Parameters:
- text: str - Text to colorize
- fg: str - Foreground color name or code
- bg: str - Background color name or code
- attrs: list - List of text attributes (bold, dim, underlined, etc.)
Returns:
str - Text wrapped with terminal color escape codes
"""
def color_factory(colored):
"""
Factory for making text color-wrapper functions.
Parameters:
- colored: Callable - Base color function (like the colored function above)
Returns:
Callable - Color factory function that creates color-wrapper functions
"""Usage Examples:
from eliottree import colored, color_factory
# Direct color usage
red_text = colored("Error message", fg='red', attrs=['bold'])
highlighted = colored("Important", fg='yellow', bg='blue')
# Create color factory
color_func = color_factory(colored)
# Create specific color functions
red_bold = color_func('red', None, ['bold'])
blue_bg = color_func('white', 'blue')
# Use color functions
styled_text = red_bold("This is red and bold")
highlighted_text = blue_bg("This has blue background")import sys
from eliottree import (
tasks_from_iterable, render_tasks, get_theme,
apply_theme_overrides, colored
)
def render_with_custom_theme(messages):
"""Render tasks with a fully customized theme."""
# Create base theme
theme = get_theme(dark_background=True, colored=colored)
# Define comprehensive overrides
theme_overrides = {
# Task identification
'root': ['bright_white', None, ['bold']],
'parent': ['magenta', None, ['bold']],
# Status indicators
'status_success': ['bright_green'],
'status_failure': ['bright_red', None, ['bold']],
# Data presentation
'prop_key': ['cyan'],
'prop_value': ['white'],
'timestamp': ['yellow', None, ['dim']],
'duration': ['blue', None, ['dim']],
# Tree structure
'tree_color0': ['white', None, ['dim']],
'tree_color1': ['blue', None, ['dim']],
'tree_color2': ['green', None, ['dim']],
'tree_failed': ['red'],
# Errors
'error': ['red', 'white', ['bold']]
}
# Apply customizations
custom_theme = apply_theme_overrides(theme, theme_overrides)
# Parse and render with full styling
tasks = tasks_from_iterable(messages)
render_tasks(
sys.stdout.write,
tasks,
theme=custom_theme,
colorize_tree=True, # Enable tree structure coloring
human_readable=True, # Format timestamps/durations
field_limit=150, # Limit field lengths
)black, red, green, yellow, blue, magenta, cyan, whitebright_black, bright_red, bright_green, bright_yellow, bright_blue, bright_magenta, bright_cyan, bright_whitedark_gray, light_gray and 256-color codesbold - Bold textdim - Dimmed/faint textunderlined - Underlined textblink - Blinking text (rarely supported)reverse - Reverse video (swap fg/bg)hidden - Hidden textTheme colors are specified as tuples: [foreground, background, attributes]
[color] - Foreground color only[fg_color, bg_color] - Foreground and background[fg_color, None, [attrs]] - Foreground with attributes[fg_color, bg_color, [attrs]] - Full specificationExamples:
overrides = {
'root': ['white'], # White text
'parent': ['magenta', 'black'], # Magenta on black
'status_success': ['green', None, ['bold']], # Bold green
'error': ['red', 'yellow', ['bold', 'underlined']] # Bold underlined red on yellow
}Themes can be configured via JSON configuration files:
{
"theme_overrides": {
"root": ["magenta", null, ["bold"]],
"prop_key": ["red"],
"status_success": ["bright_green"],
"status_failure": ["bright_red", null, ["bold"]]
}
}Load and apply configuration:
import json
from eliottree import get_theme, apply_theme_overrides, colored
# Load configuration
with open('config.json') as f:
config = json.load(f)
# Apply to theme
theme = get_theme(dark_background=True, colored=colored)
if 'theme_overrides' in config:
theme = apply_theme_overrides(theme, config['theme_overrides'])Install with Tessl CLI
npx tessl i tessl/pypi-eliot-tree