Skip to main content

Escape SeQuence Generator: Another ANSI escape-code tool

Project description

ESQ, an Escape SeQuence Generator for Python

https://github.com/SuperFLEB/esq | https://superfleb.github.io/esq | pip install fleb-esq

"You know what the world needs? Another ANSI escape-code generator for Python!" -- Absolutely Nobody

In the interest of reinventing wheels, I've written another ANSI color escape code generator to throw onto the pile. This was originally made to serve as a quick addition to my Blender Addon Template (and other addons), but it makes a better submodule so I'm passing the savings along to you.

Okay, it does a couple things different. Maybe it's a bit clever. You be the judge.

Using the thing

Install it with:

pip install fleb-esq

Import it like:

from fleb.esq import ESQ

It uses a pretty natural chained format to build styles:

print(ESQ.red.on.blue.underline.blink("This color scheme will be eye-searing, I'm sure."))

Chain off of the ESQ object, and end with a function call, with the body being a string or another ESQ. You can also nest ESQs and concatenate them to strings or other ESQs with +. You don't need to reset your styles-- they revert themselves and restore the parent style when a block ends.

print(ESQ.red.on.white("Red on white, " + ESQ.green.on.blue("now green on blue, ") + "and back to red on white."))

The function returns an ESQBlock object that will render the escape codes when printed or cast to a string with str(). The ESQ function itself can be assigned to a variable, creating a reusable shortcut to a style.

from esq import ESQ

# Use str(...) to make it a string.
some_string = str(ESQ.red.on.white.blink("This will result in a string with escape codes in it."))

# It will print in color if you have an ANSI terminal.
print(ESQ.bright.white.on.blue("This will print in color (if you've got an ANSI terminal)"))

# Nesting and concatenation with `+` are supported.
print(ESQ.red("This is red... " + ESQ.on.blue("This is red on blue... " + ESQ.italic("and this is red on blue and italic, which is probably impossible to read."))))

# Save a style for later...
emphasis = ESQ.bright.yellow.italic
print("For when you plan on getting mad " + emphasis("a whole lot") + " and you " + emphasis("really, really") + " mean it!")

Supported colors and styles

"But", I hear you asking, "what can you do with it?"

Well, bucko, you can do... some stuff. I did make this over a week of lunch hours, so it's not exactly packed with features. Right now, it only supports the basic color set, not any of that fancy 256-color stuff. File an issue to show you really care, and I might get around to adding things like 256-color support.

But, hey, you didn't pay much and there are a lot of options. Lookit 'em all!

Colors

  • default - Use the default color.
  • black
  • red
  • green
  • yellow - A muddy brown-yellow on some screens, but folks call it yellow
  • brown - An alias for "yellow" if you're like me and think it's not actually yellow
  • blue
  • magenta
  • cyan
  • white - The mediocre "enthusiastic gray" white color.
  • light_gray - An alias for "white", again, if you're like me and think it's not actually white.
  • gray - An alias for "bright black", because... what even is "bright black"?
  • bright_black
  • bright_red
  • bright_green
  • bright_yellow
  • bright_blue
  • bright_magenta
  • bright_cyan
  • bright_white

These can be used as foreground colors-- just say the name-- or as background colors by adding on. or on_. The "bright" variation can also be chained with bright. or prefixed with bright_ (see "modifiers" below).

Modifiers

Subject modifiers (don't type the angle brackets). Subject modifiers can chain with a . or be _ prefixes on a color or style as appropriate.

  • on.<color> / on_<color> - Set the background color to <color>.
  • bright.<color> / bright_<color> - Use the bright variant of the color.
  • no.<style> / no_<style> - Turn off a style (listed below) if it is on.

Style modifiers. Some may or may not work depending on how much extra you paid for your terminal.

  • normal - Reset styles. (Note normal for style, default for color.)
  • bold
  • dim
  • italic
  • underline
  • blink
  • blink2
  • reverse
  • hidden
  • strike
ESQ.red.on.white("This is red on white.")

ESQ.on.red("This changes the background to red but leaves the foreground color.")

ESQ.on.white.red("This makes you sound like a pretentious dork or Yoda.")

ESQ.bright.white.underline.italic.strike("Because you just have to hit all the buttons on the elevator to see what happens.")

ESQ.underline("And sometimes you just" + ESQ.no.underline(" need a break from all the underlining ") + "for a bit.")

Utility Functions

(That plural's a lie, there's only one. It's join.)

join(list[str | ESQBlock], str?)

Join a list with strings and/or ESQ blocks into a single ESQ block with an optional glue string.

from esq import ESQ, join

rainbow = [
    ESQ.red('red'),
    "no orange because 16-color ANSI doesn't have it",
    ESQ.yellow('yellow'),
    ESQ.green('green'),
    ESQ.blue('blue'),
    "what's indigo again?"
    "no violet either -- maybe a rainbow was a bad demo idea"
]

print(join(rainbow, " and "))

Mode

By default, ESQ will generate escape codes if STDOUT is a terminal, and will suppress them (print without any codes) if it is not. It will also jostle the Windows terminal into shape by turning on Virtual Terminal Mode when running in Windows. (If you don't know what that all means-- it's just a way to make ANSI codes work on some Windows terminals, such as Git Bash.)

This behavior can be overridden, though, with the mode submodule.

from esq import mode

What will that get you? A bunch of switches that you usually don't need to twiddle with, but they're there to play with if you're finicky.

Mode Values

These Enum values denote the different modes.

  • mode.DISABLED - ESQ will not generate escape codes, regardless of output type.
  • mode.AUTO - ESQ will detect the output type and generate escape codes if appropriate.
  • mode.ENABLED - ESQ will always generate escape codes, regardless of output type.

mode.set(<mode.DISABLED | mode.ENABLED | mode.AUTO>)

Set the mode. ESQ starts in mode.AUTO and will detect non-TTY STDOUT automatically. You only need to call this if you want to override that behavior.

from esq import ESQ, mode

mode.set(mode.DISABLED)
print(ESQ.red.on.red("No matter how red I make this, it won't be red."))

mode.get()

This returns either mode.DISABLED or mode.ENABLED, resolving mode.AUTO to the actual mode.

from esq import ESQ, mode

# Keep in mind that this only returns mode.ENABLED or mode.DISABLED, so a simple if/else suffices.
if mode.get() == mode.ENABLED:
    print(ESQ.green("Full color!"))
else:
    print("Boring text.")

mode.init()

This initializes the terminal to turn on features necessary to properly support ANSI codes. This happens automatically whenever ESQ generates an escape code. If it is called after a previous init() (but before a revert()), it will do nothing.

from esq import ESQ, mode

mode.init()
print(ESQ.red("That was wholly unnecessary, because the first time it hits the \"red\" color code it'll do that anyway."))

mode.revert()

This undoes the initialization done by mode.init(). This will run automatically when the program exits.

This does not change the mode setting, and a subsequent call to ESQ may re-init() the terminal if the terminal type and mode setting should necessitate it.

from esq import ESQ, mode

# If we were on some two-bit Windows terminal that needs a kick in the rear to get its ANSI on, then...
print("\033[31mThis would show escape-code garbage, because I'm adding the codes manually and we haven't run init().\033[0m")
mode.init()
print("\033[31mThis would be red, since I called init().\033[0m")
mode.revert()
print("\033[31mThis would go back to showing escape-code garbage, because I called revert().\033[0m")

print(ESQ.red("This would always show red, because ESQ calls init() automatically"))

# (...and revert() will be called automatically when the program exits so the parent process doesn't get a screwy terminal.)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fleb_esq-0.1.2.tar.gz (8.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fleb_esq-0.1.2-py3-none-any.whl (9.6 kB view details)

Uploaded Python 3

File details

Details for the file fleb_esq-0.1.2.tar.gz.

File metadata

  • Download URL: fleb_esq-0.1.2.tar.gz
  • Upload date:
  • Size: 8.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.14

File hashes

Hashes for fleb_esq-0.1.2.tar.gz
Algorithm Hash digest
SHA256 00a1e27527ea8b85f615bb49737801bb144f8da18a1f02b18ddcc0a7f051d6b9
MD5 7f0a36f6dbd9b21c08a88cce4615223d
BLAKE2b-256 4544ad0c1612474254ac386627ae507510bfe78eb1c9caf1e81cd2a2b551a52f

See more details on using hashes here.

File details

Details for the file fleb_esq-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: fleb_esq-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 9.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.14

File hashes

Hashes for fleb_esq-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 e66e56d77ac18b28747c0899c50a5089c569fc91b4f656e1a141d446a17fba31
MD5 ef0e14ca0b2eef9cdca7a339ae92658f
BLAKE2b-256 1013502c412e21752a2a3bc9eab28ac4392d38a5c44e6fd7f84ef2759501abe6

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page