How to Add ANSI Colors to Table Cells Using Outfancy
Outfancy preserves ANSI escape sequences in cell values and only strips them internally when calculating column widths via widgets.printed_length, allowing you to embed color codes directly from outfancy.colors or custom ANSI strings.
Outfancy is a lightweight Python library for rendering formatted tables in the terminal. Because the library renders cells as literal strings without additional processing, you can add ANSI colors to table cells by embedding escape sequences directly in your data strings.
How Color Handling Works in the Rendering Pipeline
Outfancy does not provide a dedicated styling API. Instead, it treats any ANSI escape sequences in your data as literal text. The library strips these codes only when necessary for layout calculations, ensuring your colors appear in the final output while maintaining proper column alignment.
In outfancy/widgets.py, the remove_colors function (lines 15-27) uses a regular expression to strip \x1b[... escape sequences. This function is called exclusively by printed_length (lines 99-103), which calculates the visual width of cell content for alignment purposes. Because remove_colors operates only during width measurement—not during the actual string concatenation—the ANSI codes remain intact in the final table output produced by outfancy/table.py.
The render method in outfancy/table.py builds the table by joining these pre-colored strings, meaning whatever color codes you embed are preserved verbatim in the terminal output.
Using the Built-in Color Palette
The outfancy/colors.py file (lines 3-31) defines a ready-made palette of ANSI constants. These follow a naming convention of {style}_{color} where style can be normal, bold, or strong, and color includes standard terminal colors like red, green, blue, and violet.
Available constants include:
normal_red,normal_green,normal_blue— Standard foreground colorsbold_normal_blue,bold_strong_green— Bold and high-intensity variantsnormal_reset,bold_normal_reset,bold_strong_reset— Style reset codes
Import the palette and wrap your cell values with the appropriate opening and reset codes:
from outfancy.table import Table
from outfancy import colors
# Wrap cell values with color codes
data = [
(f"{colors.normal_red}Critical{colors.normal_reset}", "Error", "99"),
(f"{colors.normal_green}Stable{colors.normal_reset}", "OK", "42"),
(f"{colors.bold_strong_yellow}Warning{colors.bold_strong_reset}", "Check", "10")
]
tbl = Table()
print(tbl.render(data))
Coloring Table Headers
Headers defined via the label_list parameter accept colored strings through the same mechanism. Because labels pass through the same rendering pipeline as data cells, you can apply ANSI codes to column titles to create visually distinct header rows:
labels = [
f"{colors.bold_normal_violet}Status{colors.bold_normal_reset}",
f"{colors.bold_normal_violet}Message{colors.bold_normal_reset}",
f"{colors.bold_normal_violet}Code{colors.bold_normal_reset}"
]
print(tbl.render(data, label_list=labels))
Working with Custom ANSI Codes
If the built-in palette lacks the specific color you need, you can embed raw ANSI escape sequences directly. This is useful for 256-color or RGB terminal colors:
# 256-color orange
custom_orange = "\x1b[38;5;208m"
reset = "\x1b[0m"
data = [
(f"{custom_orange}Custom{reset}", "Standard", "Data")
]
When using custom codes, always include a reset sequence (such as \x1b[0m or colors.normal_reset) at the end of each colored segment to prevent the styling from bleeding into subsequent cells or text.
Summary
- Outfancy renders cell content literally, preserving any ANSI escape sequences you embed in your data strings.
- The
remove_colorsfunction inoutfancy/widgets.py(lines 15-27) strips codes only during width calculation viaprinted_length, ensuring columns align correctly despite invisible color codes. - Import pre-defined color constants from
outfancy/colors.pyor use custom\x1b[sequences for full color control. - Apply reset codes after each colored segment to isolate styling to specific cells.
- Headers support the same coloring technique via the
label_listparameter.
Frequently Asked Questions
Does Outfancy provide a dedicated API for styling individual cells?
No. According to the source code in outfancy/table.py, the library does not implement cell-level styling methods. You add colors by embedding ANSI escape sequences directly into the string values you pass to Table.render.
Will ANSI color codes break table alignment?
No. The printed_length function in outfancy/widgets.py (lines 99-103) automatically removes color codes when calculating the visual width of each cell. This ensures the column widths are computed based on the actual character count, not the length of the escape sequences, keeping your table properly aligned.
Can I color the table headers separately from the data rows?
Yes. The label_list parameter in Table.render accepts strings, so you can wrap your header labels with the same ANSI color constants used for cell data. These labels undergo the same rendering process as body cells.
How do I reset colors after styling a specific cell?
Append a reset code immediately after the colored text. Use colors.normal_reset for standard colors, colors.bold_normal_reset for bold styles, or colors.bold_strong_reset for high-intensity bold colors. Alternatively, use the universal \x1b[0m reset code to return to default terminal styling.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →