Terminal string styling done right
Project description
Terminal string styling done right
This is a feature-complete clone of the awesome Chalk (JavaScript) library.
All credits go to Sindre Sorhus.
Highlights
- Fluent, auto-complete-friendly API for maximum coding efficiency
- Ability to nest styles
- Proper handling of edge cases (same test cases as Chalk)
- Auto-detection of terminal color capabilities
- 256/Truecolor color support, with fallback to basic colors depending on capabilities
- Same conventions as Chalk to manually control color modes via
FORCE_COLOR
- No dependencies
- Fully typed (mypy strict), no stubs required
Install
$ pip install yachalk
The only requirement is a modern Python (3.6+).
Usage
from yachalk import chalk
print(chalk.blue("Hello world!"))
Chalk comes with an easy to use composable API where you just chain and nest the styles you want.
from yachalk import chalk
# Combine styled and normal strings
print(chalk.blue("Hello") + " World" + chalk.red("!"))
# Compose multiple styles using the chainable API
print(chalk.blue.bg_red.bold("Hello world!"))
# Use within f-strings
print(f"Found {chalk.bold(num_results)} results.")
# Pass in multiple arguments
print(chalk.blue("Hello", "World!"))
# Nest styles...
print(chalk.red(f"Hello {chalk.underline.bg_blue('world')}!"))
# Nest styles of the same type even (color, underline, background)
print(chalk.green(
"I am a green line " +
chalk.blue.underline.bold("with a blue substring") +
" that becomes green again!"
))
# Use RGB or HEX colors
print(chalk.rgb(123, 45, 67).underline("Underlined reddish color"))
print(chalk.hex("#DEADED").bold("Bold gray!"))
Easily define and re-use your own themes:
from yachalk import chalk
error = chalk.bold.red
warning = chalk.hex("#FFA500")
print(error("Error!"))
print(warning("Warning!"))
API
In general there is no need to remember the API, because it is written in a way that it fully auto-completes in common IDEs:
chalk.<style>[.<style>...](string, [string...], sep=" ")
Example: chalk.red.bold.underline("Hello", "world")
Chain styles and call the last one as a method with a string argument. Order doesn't matter, and later styles take precedent in case of a conflict. This simply means that chalk.red.yellow.green
is equivalent to chalk.green
.
Multiple arguments will be separated by a space, but the separator can also be passed in as keyword argument sep="..."
.
chalk.set_color_mode(mode: ColorMode)
Set the color mode manually. ColorMode
is an enum with the value:
ColorMode.AllOff
ColorMode.Basic16
(basic 16-color ANSI colors)ColorMode.Extended256
(256-color ANSI color mode)ColorMode.FullTrueColor
(full true color support)
See color mode control for more details.
chalk.disable_all_ansi()
Shorthand for chalk.set_color_mode(ColorMode.AllOff)
.
chalk.enable_basic_colors()
Shorthand for chalk.set_color_mode(ColorMode.Basic16)
.
chalk.enable_extended_colors()
Shorthand for chalk.set_color_mode(ColorMode.Extended256)
.
chalk.enable_full_colors()
Shorthand for chalk.set_color_mode(ColorMode.FullTrueColor)
.
chalk.get_color_mode() -> ColorMode
Return current color mode.
Styles
Modifiers
reset
- Resets the current color chain.bold
- Make text bold.dim
- Emitting only a small amount of light.italic
- Make text italic. (Not widely supported)underline
- Make text underline. (Not widely supported)inverse
- Inverse background and foreground colors.hidden
- Prints the text, but makes it invisible.strikethrough
- Puts a horizontal line through the center of the text. (Not widely supported)visible
- Prints the text only when Chalk has a color level > 0. Can be useful for things that are purely cosmetic.
Colors
black
red
green
yellow
blue
magenta
cyan
white
black_bright
(alias:gray
,grey
)red_bright
green_bright
yellow_bright
blue_bright
magenta_bright
cyan_bright
white_bright
Background colors
bg_black
bg_red
bg_green
bg_yellow
bg_blue
bg_nagenta
bg_cyan
bg_white
bg_black_bright
(alias:bg_gray
,bg_grey
)bg_red_bright
bg_green_bright
bg_yellow_bright
bg_blue_bright
bg_magenta_bright
bg_cyan_bright
bg_white_bright
256 and Truecolor color support
Chalk supports 256 colors and Truecolor (16 million colors) on supported terminal apps.
Colors are downsampled from 16 million RGB values to an ANSI color format that is supported by the terminal emulator (or by setting a specific ColorMode
manually). For example, Chalk configured to run at level ColorMode.Basic16
will downsample an RGB value of #FF0000 (red) to 31 (ANSI escape for red).
Examples:
chalk.rgb(15, 100, 204)("Hello!")
chalk.hex("#DEADED").underline("Hello, world!")
Background versions of these models are prefixed with bg_
:
chalk.bg_rgb(15, 100, 204)("Hello!")
chalk.bg_hex("#DEADED").underline("Hello, world!")
Color mode control
The imported symbol chalk
is a singleton that is initialized with the color mode resulting from the auto-detection. This means that if you run on a terminal that has e.g. only basic 16 colors support, you can still use the full RGB/HEX API, but the resulting colors would be approximated by the available colors. If the terminal doesn't support any ANSI escape codes, the resulting strings would be completely free of any ANSI codes.
If you would like to take manual control of the color mode, you have three options.
1. Use environment variables
Chalk has introduced the convention to use the FORCE_COLOR
environment variable as an override in the auto-detection. The semantics are:
FORCE_COLOR=0
enforcesColorMode.AllOff
.FORCE_COLOR=1
enforcesColorMode.Basic16
.FORCE_COLOR=2
enforcesColorMode.Extended256
.FORCE_COLOR=3
enforcesColorMode.FullTrueColor
.
This can be a convenient solution in CI/cloud-based contexts.
2. Set the color mode manually on the chalk
instance
If you don't care about auto-detection, you might as well set your desired color mode unconditionally.
The chalk
singleton supports setting the color mode via chalk.disable_all_ansi
, chalk.enable_..._colors
, or chalk.set_color_mode
.
A reasonable place to configure the singleton is e.g. at the beginning of a main
function, similar to where logging is configured.
3. Use your own chalk
instance
For advanced use cases that e.g. require to dynamically switch the color mode in a multi-threaded context, you can opt-out of the convenience of using a singleton, and use a custom chalk
instances where desired. In general chalk
is just an instance of ChalkFactory
, which takes the color mode as input in its constructor.
from yachalk import ChalkFactory
def some_function():
# create your own chalk instance with explicit mode control
chalk = ChalkFactory(ColorMode.FullTrueColor)
# ...
colored_messages.append(chalk.red("An error occurred"))
Or if you'd like to use your own mode-detection logic, you could create the chalk
singleton yourself in one of your modules
# e.g. in my_chalk.py
from yachalk import ChalkFactory
def custom_color_mode_detection() -> ColorMode:
# ...
return ColorMode.Basic16
chalk = ChalkFactory(custom_color_mode_detection())
and replace usages of from yachalk import chalk
with from my_chalk import chalk
.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.