This content originally appeared on DEV Community and was authored by Sivaprasad Murali
🎨 Stop Fighting with ANSI Codes
Let's be honest — styling terminal output in Python has always been a bit of a pain:
# The old way 😓
print('\033[1m\033[91mError:\033[0m \033[4mFile not found\033[0m')
Compare that to this:
# The Vargula way ✨
import vargula as vg
vg.write("<bold><red>Error:</red></bold> <underline>File not found</underline>")
Much better, right? But Vargula goes way beyond just making syntax prettier. It brings color theory, accessibility checking, and professional UI components to your terminal.
🚀 Quick Start
pip install vargula
import vargula as vg
# HTML-like tags for styling
vg.write("This is <red>red</red> and <bold>bold</bold>")
# Hex colors work too
vg.write("Custom <#FF5733>orange</#FF5733> text")
# Background colors with @
vg.write("<@yellow><black>Black on yellow</@yellow></black>")
# Nest as much as you want
vg.write("<bold>Bold with <italic><cyan>italic cyan</cyan></italic></bold>")
🎯 The Problem It Solves
I built Vargula because I kept running into the same issues:
- Verbose ANSI codes that make code unreadable
- No guidance on creating harmonious color palettes
- Zero accessibility checking — is my output readable for colorblind users?
- Repetitive boilerplate for tables and progress bars
Vargula tackles all of these.
🌈 Built-in Color Theory
Here's where it gets interesting. Need a color palette? Generate one based on actual color theory:
# Generate complementary colors
colors = vg.generate_palette("#3498db", "complementary", 5)
print(vg.preview_palette(colors))
Available schemes:
-
monochromatic— Single hue variations -
analogous— Adjacent colors (±30°) -
complementary— Opposite colors (180°) -
triadic— Three evenly spaced (120°) -
tetradic— Four colors in pairs -
split_complementary— Softer complementary -
square— Four evenly spaced (90°)
Create a Complete Theme
# Generate a themed palette
theme = vg.generate_theme_palette("analogous", "#e74c3c")
vg.apply_palette_theme(theme)
# Now use semantic tags
vg.write("<primary>Primary action</primary>")
vg.write("<error>Error message</error>")
vg.write("<success>All good!</success>")
vg.write("<warning>Be careful</warning>")
This automatically creates primary, secondary, accent, success, warning, error, info, and neutral colors based on your chosen scheme.
♿ Accessibility First
About 8% of men and 0.5% of women have some form of color vision deficiency. Vargula helps you create inclusive terminal apps:
# Check WCAG contrast compliance
ratio = vg.calculate_contrast_ratio("#FFFFFF", "#3498db")
print(f"Contrast ratio: {ratio:.2f}")
# Verify WCAG AA/AAA compliance
if vg.meets_wcag("#FFFFFF", "#000000", "AA"):
print("✓ Passes WCAG AA")
# Generate accessible themes automatically
theme = vg.generate_accessible_theme(
base_color="#3498db",
background="#ffffff",
wcag_level="AA" # or "AAA"
)
Colorblind Simulation
See how your colors appear to users with different types of color blindness:
colors = ["#FF0000", "#00FF00", "#0000FF"]
# Simulate different types
types = ["protanopia", "deuteranopia", "tritanopia"]
for cb_type in types:
simulated = [vg.simulate_colorblindness(c, cb_type) for c in colors]
print(f"{cb_type}: {simulated}")
# Check if palette is distinguishable
is_safe, problems = vg.validate_colorblind_safety(colors, "deuteranopia")
if not is_safe:
print(f"⚠ Found {len(problems)} problematic color pairs")
📊 Tables Made Easy
Creating professional tables is trivial:
table = vg.Table(
title="Q4 2024 Sales",
border_style="blue",
box="double",
show_lines=True
)
table.add_column("Region", style="bold", justify="left")
table.add_column("Revenue", style="green", justify="right")
table.add_column("Growth", style="cyan", justify="center")
table.add_row("North", "$1.2M", "+15%")
table.add_row("Europe", "$890K", "+8%")
table.add_row("Asia", "$1.5M", "+22%")
print(table)
Box styles: rounded, square, double, heavy, minimal, none
⏱️ Progress Bars
Single or multiple progress bars with ETA and rate display:
import time
# Simple progress bar
for item in vg.progress_bar(range(100), desc="Processing"):
time.sleep(0.01)
# Multiple concurrent bars
with vg.MultiProgress() as mp:
download = mp.add_task("Downloading", total=100)
process = mp.add_task("Processing", total=50)
upload = mp.add_task("Uploading", total=80)
# Update independently
for i in range(100):
mp.update(download, 1)
if i % 2 == 0:
mp.update(process, 1)
if i % 3 == 0:
mp.update(upload, 1)
time.sleep(0.02)
🎨 Color Manipulation
Need to adjust colors programmatically?
base = "#3498db"
# Adjust brightness
lighter = vg.lighten(base, 0.2)
darker = vg.darken(base, 0.2)
# Adjust saturation
vivid = vg.saturate(base, 0.3)
muted = vg.desaturate(base, 0.3)
# Rotate hue (color wheel)
shifted = vg.shift_hue("#FF0000", 120) # Red → Green
# Mix colors
purple = vg.mix("#FF0000", "#0000FF", 0.5)
# Invert
inverted = vg.invert("#FF0000") # → #00FFFF
🔧 Custom Styles
Define reusable styles once, use them everywhere:
# Create custom styles
vg.create("error", color="red", look="bold")
vg.create("success", color="green", look="bold")
vg.create("debug", color="cyan", look="dim")
# Use them with tags
vg.write("<error>Connection failed</error>")
vg.write("<success>Upload complete</success>")
vg.write("<debug>Debug info here</debug>")
# Temporary styles with context manager
with vg.temporary("temp", color="magenta"):
vg.write("<temp>This style is temporary</temp>")
# Automatically cleaned up
💾 Save & Load Palettes
Share your color schemes across projects:
# Generate and save
colors = vg.generate_palette("#3498db", "analogous", 5)
vg.save_palette(colors, "ocean_theme.json",
metadata={"name": "Ocean Blue", "author": "Me"})
# Load later
colors, metadata = vg.load_palette("ocean_theme.json")
# Works with themes too
theme = vg.generate_theme_palette("triadic", "#9b59b6")
vg.save_theme(theme, "purple_theme.json")
🔥 Real-World Example: Styled Logger
Let's build a production-ready logger with proper theming:
import vargula as vg
from datetime import datetime
# Setup theme
theme = vg.generate_theme_palette("analogous", "#2196F3")
vg.apply_palette_theme(theme)
# Custom log level styles
vg.create("timestamp", color="#666666")
vg.create("debug", color="cyan", look="dim")
vg.create("info", color="blue")
vg.create("warning", color="yellow", look="bold")
vg.create("error", color="red", look="bold")
vg.create("critical", color="white", bg="red", look="bold")
class Logger:
def log(self, level, message):
ts = datetime.now().strftime("%H:%M:%S")
vg.write(f"<timestamp>[{ts}]</timestamp> <{level}>{level.upper():<8}</{level}> {message}")
def debug(self, msg): self.log("debug", msg)
def info(self, msg): self.log("info", msg)
def warning(self, msg): self.log("warning", msg)
def error(self, msg): self.log("error", msg)
def critical(self, msg): self.log("critical", msg)
# Usage
log = Logger()
log.info("Application started")
log.debug("Loading config from config.json")
log.warning("Cache is 90% full")
log.error("Failed to connect to API")
log.critical("System out of memory!")
🎯 Advanced Features
Escape Sequences
Need to show literal tags in documentation?
# Use raw strings with backslash
vg.write(r"Use \<red>text\</red> to make text red")
# Or double backslash
vg.write("Tag syntax: \\<bold>...</bold>")
Direct Styling (Without Tags)
# Style text directly
print(vg.style("Error", color="red", look="bold"))
print(vg.style("Custom", color="#FF5733", bg="#1a1a1a"))
print(vg.style("Fancy", color=(255, 87, 51), look=["bold", "underline"]))
Utility Functions
# Strip markup tags
plain = vg.strip("Hello <red>world</red>!") # "Hello world!"
# Remove ANSI codes
styled = vg.style("Text", color="red")
clean = vg.clean(styled) # "Text"
# Get visible length (ignoring ANSI)
styled = vg.style("Hello", color="red")
print(len(styled)) # 18 (includes ANSI)
print(vg.length(styled)) # 5 (visible only)
# Globally enable/disable styling
vg.disable() # No colors
vg.enable() # Colors back
🎓 Tag Syntax Reference
-
<colorname>— Named foreground (e.g.,<red>,<bright_blue>) -
<@colorname>— Named background (e.g.,<@yellow>) -
<#hexcode>— Hex foreground (e.g.,<#FF5733>) -
<@#hexcode>— Hex background (e.g.,<@#FF0000>) -
<lookname>— Text style (e.g.,<bold>,<italic>) -
<customname>— Your custom styles -
\<tag>or\\<tag>— Escape sequences for literal tags
Available colors: black, red, green, yellow, blue, magenta, cyan, white, plus bright_* variants
Available styles: bold, dim, italic, underline, blink, reverse, hidden, strikethrough
🌟 Why Vargula?
For developers who:
- Build CLI tools that need professional output
- Want accessible, inclusive terminal applications
- Need harmonious color schemes without a design degree
- Prefer readable code over ANSI escape sequences
- Value WCAG compliance in terminal UIs
Key advantages:
- ✅ Intuitive HTML-like syntax
- ✅ Color theory algorithms built in
- ✅ WCAG compliance checking
- ✅ Colorblind simulation & validation
- ✅ Professional tables & progress bars
- ✅ Cross-platform (Windows, macOS, Linux)
- ✅ Zero dependencies for core features
📚 Resources
- GitHub: crystallinecore/vargula
- Docs: vargula.readthedocs.io
-
PyPI:
pip install vargula
🤝 Contributing
Contributions are welcome! Check out the GitHub repo to:
- Report bugs
- Request features
- Submit pull requests
- Share your color themes
🎬 Try It Now
import vargula as vg
# Generate a random palette
colors = vg.generate_palette(scheme="triadic", count=5)
# Preview it
print(vg.preview_palette(colors))
# Check accessibility
is_safe, _ = vg.validate_colorblind_safety(colors)
print("✓ Colorblind-safe!" if is_safe else "⚠ Needs adjustment")
# Create and apply theme
theme = vg.generate_theme_palette("complementary", colors[0])
vg.apply_palette_theme(theme)
# Use semantic colors
vg.write("<primary>Primary</primary>")
vg.write("<error>Error</error>")
vg.write("<success>Success</success>")
What kind of CLI tools are you building? Have you tried Vargula? Drop a comment below! 👇
Made with 🎨 by Sivaprasad Murali
This content originally appeared on DEV Community and was authored by Sivaprasad Murali
Sivaprasad Murali | Sciencx (2025-11-24T13:04:10+00:00) Vargula: Terminal Styling with Color Theory & Accessibility Built In. Retrieved from https://www.scien.cx/2025/11/24/vargula-terminal-styling-with-color-theory-accessibility-built-in/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.