Custom Styles Tutorial¶
Learn how to create and use custom styles in PyRePrint.
Understanding Styles¶
Styles are functions that transform text into formatted output. They receive the text content and optional parameters, returning the styled string.
Creating a Style¶
Using the Decorator¶
The simplest way to create a style is with @register_style:
from pyreprint import register_style, reprint
@register_style("emphasis")
def emphasis_style(text, **kwargs):
return f"*** {text} ***"
# Use it
reprint("Important", style="emphasis")
# Output: *** Important ***
Style Function Signature¶
Style functions should follow this pattern:
text: The content to style (required)width: Common parameter for width-based formatting**kwargs: Catch additional parameters for flexibility
Practical Style Examples¶
Bordered Section¶
@register_style("bordered")
def bordered_style(text, width=60, char="#", **kwargs):
border = char * width
padding = char + " " * (width - 2) + char
centered = text.center(width - 4)
content = f"{char} {centered} {char}"
return f"{border}\n{padding}\n{content}\n{padding}\n{border}"
Code Block¶
@register_style("code")
def code_style(text, language="", **kwargs):
if language:
return f"```{language}\n{text}\n```"
return f"```\n{text}\n```"
Timestamp¶
from datetime import datetime
@register_style("timestamped")
def timestamped_style(text, **kwargs):
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
return f"[{now}] {text}"
Multi-line Box¶
@register_style("multibox")
def multibox_style(text, width=0, char="|", corner="+", horizontal="-", **kwargs):
lines = text.split("\n")
max_len = max(len(line) for line in lines)
effective_width = width if width > 0 else max_len + 4
border = corner + horizontal * (effective_width - 2) + corner
result = [border]
for line in lines:
padded = line.center(effective_width - 4)
result.append(f"{char} {padded} {char}")
result.append(border)
return "\n".join(result)
Loading Styles from Files¶
YAML Configuration¶
Create a styles.yaml file:
styles:
alert:
before:
char: "!"
width: 40
after:
char: "!"
width: 40
prefix: "[ALERT] "
quiet:
prefix: " "
suffix: ""
centered:
center: true
before:
char: "-"
width: 60
after:
char: "-"
width: 60
Load and use:
from pyreprint import load_styles_from_file, reprint
load_styles_from_file("styles.yaml")
reprint("System Alert", style="alert")
reprint("Quiet message", style="quiet")
reprint("Centered Text", style="centered")
TOML Configuration¶
Create a styles.toml file:
[styles.notice]
prefix = "[*] "
[styles.divider]
before = { char = "~", width = 50 }
after = { char = "~", width = 50 }
Load it:
Dictionary Configuration¶
For programmatic configuration:
from pyreprint import load_styles_from_dict
config = {
"highlight": {
"prefix": ">>> ",
"suffix": " <<<",
},
"muted": {
"prefix": " ",
}
}
load_styles_from_dict(config)
Managing the Style Registry¶
Listing Available Styles¶
from pyreprint import list_styles
print("Available styles:")
for style in list_styles():
print(f" - {style}")
Checking Style Existence¶
from pyreprint import registry
if "custom" in registry:
reprint("Text", style="custom")
else:
reprint("Text") # Fallback
Removing Styles¶
Clearing All Styles¶
from pyreprint import registry
registry.clear()
# Note: Built-in styles will be gone until you re-import
Style Composition¶
Create styles that build on others:
@register_style("urgent")
def urgent_style(text, **kwargs):
from pyreprint.styles.builtins import banner_style
return banner_style(f"URGENT: {text}", width=60, char="!")
@register_style("section_header")
def section_header_style(text, width=60, **kwargs):
line = "=" * width
return f"\n{line}\n{text.upper()}\n{line}\n"
Best Practices¶
-
Accept
**kwargs: Always include**kwargsfor forward compatibility -
Document your styles: Add docstrings explaining usage
-
Handle edge cases: Check for empty text, very long text, etc.
-
Use sensible defaults: Provide good default values for all parameters
-
Organize styles: Group related styles in separate files
@register_style("robust")
def robust_style(text, width=60, fallback="(empty)", **kwargs):
"""A robust style that handles edge cases.
Args:
text: Content to style
width: Output width
fallback: Text to use if input is empty
"""
if not text or not text.strip():
text = fallback
if len(text) > width - 4:
text = text[:width - 7] + "..."
return f"[ {text.center(width - 4)} ]"
Next Steps¶
- Learn about Jupyter Integration
- See the Styles API Reference