Skip to content

Tags

Basics

TIM syntax tends to be simple. At the base, we have the following structure:

[tag1 tag2 ...]My content
     ^              ^
 tag group     plain text

...where tag1 & tag2 are some valid markup tags, and My content is the string you want them to modify.

Tag groups are always denoted by square brackets ([ and ]). All text outside of a tag group is considered to be plain text.

Nesting

When encountering nested tag groups, only the innermost one will be parsed:

"[[bold]bold [/ lightblue]lightblue[/]][italic lightgreen]Hello"

[ bold  lightblue ] Hello

Escaping

You can escape a tag group using backslashes (\):

"\[bold lightblue][italic lightgreen]Hello"

[bold lightblue] Hello

Re-parsing escaped markup

Escaping tag groups will only be effective for the first parsing of said string. During parsing, the escaped tag group will lose the backslash to hide it from the output.

Styles

We support all generally supported terminal "modes":

Resource

For a great overview on these styles & ANSI sequences in general, see this gist by Christian Petersen, or this website.

  • bold (mode 1):

    Traditionally (and on some older emulators) makes text brighter, nowadays it increases the font's weight.

  • dim (mode 2):

    The opposite of the traditional function behind bold, makes text a bit darker.

  • italic (mode 3):

    Uses the italicized font variant, which tilts each character.

  • underline (mode 4):

    Draws a thin line under each character.

  • blink & blink2 (mode 5 & 6):

    Repeatedly shows and hides the characters at an internal frequency. Like HTML's <blink>, it seems to have fallen out of favor and is no longer supported on many terminals. Some terminal's support one, but not the other.

  • inverse (mode 7):

    Inverts the function of the foreground and background colors, i.e. the foreground color will now act on the background and vice-versa.

  • invisible (mode 8):

    Hides text. Not widely supported, for some reason.

  • strikethrough (mode 9):

    Draws a line through each character, somewhere near the vertical middle.

  • overline (mode 53):

    Draws a line above each character.

docs/src/tim/tags_modes.py ┌ Available modes  ───────────────────────────────────────────────────────────── │                                                                                 │ │                                                                                 │ │                                                                                 │ │                                                                                 │ │                                                                                 │ │                                                                                 │ │                                       bold                                       │ │                                        dim                                       │ │                                      italic                                      │ │                                     underline                                    │ │                                       blink                                      │ │                                      blink2                                      │ │                                      inverse                                     │ │                                     invisible                                    │ │                                   strikethrough                                  │ │                                     overline                                     │ │                                                                                 │ │                                                                                 │ │                                                                                 │ │                                                                                 │ │                                                                                 │ │                                                                                 │ ──────────────────────────────────────────────────────────────────────────────

Implementation

Under the hood, these styles are set by printing a special escape sequence to the terminal. These sequences are structured the following way:

\x1b[{mode_id}m

In effect, this means bold stands for \x1b[1m, and inverse for \x1b[7m.

Colors

The terminal generally supports 3 color palettes

  • 3 bit, or 16-color

    8 base colors (red, green, yellow, blue, magenta, cyan, white and black), and high-brightness version of each, making a total of 16.

  • 8-bit, or 256-color:

    256 colors, each using 8 bits of information. The standard colors make up the first 16 indices.

  • 24-bit, or truecolor

    Something in the ballpark of 16.7 million colors, this set represents all colors definable by 3 8-bit (0-255) values, each standing for one of the RED, GREEN and BLUE channels.

Lucky for you, the reader, TIM exposes convenient syntax for all of these!

  • Indexed colors (3-bit and 8-bit):

    [{index}], where index is a number in the range 0-255, including both ends.

  • RGB colors (24-bit):

    [{rrr};{ggg};{bbb}], where rrr, ggg and bbb each represent a number alike the ones indexed colors use, standing for the red, green and blue channels respectively.

  • HEX colors (alternate representation of 24-bit):

    [#{rr};{gg};{bb}], where each value represents a 3-bit number like above, as a hexadecimal value.

  • Named colors (3-bit or 24-bit):

    [{name}], where name is a CSS color name known to TIM:

CSS Colors aliceblue                 gainsboro                  mistyrose antiquewhite              ghostwhite                  moccasin aqua                         gold                  navajowhite aquamarine                goldenrod                       navy azure                        gray                      oldlace beige                        grey                        olive bisque                      green                    olivedrab black                    greenyellow                    orange blanchedalmond             honeydew                  orangered blue                       hotpink                      orchid blueviolet                indianred              palegoldenrod brown                       indigo                   palegreen burlywood                   ivory                paleturquoise cadetblue                   khaki                palevioletred chartreuse                 lavender                 papayawhip chocolate               lavenderblush                peachpuff coral                     lawngreen                       peru cornflowerblue           lemonchiffon                     pink cornsilk                  lightblue                       plum crimson                   lightcoral                powderblue cyan                      lightcyan                     purple darkblue             lightgoldenrodyellow                  red darkcyan                  lightgray                  rosybrown darkgoldenrod             lightgrey                  royalblue darkgray                  lightgreen               saddlebrown darkgrey                  lightpink                     salmon darkgreen                lightsalmon                sandybrown darkkhaki               lightseagreen                 seagreen darkmagenta              lightskyblue                 seashell darkolivegreen          lightslategray                  sienna darkorange              lightslategrey                  silver darkorchid              lightsteelblue                 skyblue darkred                  lightyellow                 slateblue darksalmon                   lime                    slategray darkseagreen              limegreen                  slategrey darkslateblue               linen                         snow darkslategray              magenta                 springgreen darkslategrey               maroon                   steelblue darkturquoise          mediumaquamarine                    tan darkviolet                mediumblue                      teal deeppink                 mediumorchid                  thistle deepskyblue              mediumpurple                   tomato dimgray                 mediumseagreen               turquoise dimgrey                mediumslateblue                  violet dodgerblue            mediumspringgreen                  wheat firebrick              mediumturquoise                   white floralwhite            mediumvioletred              whitesmoke forestgreen              midnightblue                   yellow fuchsia                   mintcream                yellowgreen

Colors, by default, will act on the foreground. This can be changed by prefixing the color markup by an at-symbol (@), like so:

"[78 @34;52;111] My text [inverse] and now inversed! "

 My text   and now inversed! 

Clearers

After you set a style, you might want to stop it affecting text. To do so, you want to use a clearer token.

Clearer tokens are denoted with the slash (/) prefix, and contain the identifier they are targeting.

For example:

  • To clear all attributes, including modes, colors, macros, use / with no identifier.
  • To clear a simple terminal mode, use /{mode}, like /italic.
  • To clear a color, use /fg for foreground colors, and /bg for background ones.
  • To clear a macro, use either /!{name}, or /! to clear all active macros.
  • To clear a hyperlink, use /~.

Clearing specific links

Since the terminal only supports having one active hyperlink at a time, there is no reason to have syntax for specifically clearing a single link.

Newer terminals allow HTML anchor-inspired hyperlinks that can be clicked and take the user to places.

Resource

For information on the implementation of terminal-hyperlinks, check out this gist.

In PyTermGUI TIM, we use the syntax:

[~{protocol}://{uri}]

...where protocol is a data-transfer protocol supported by the client (usually http, https or file), and uri is a standard URI readable by the specified protocol.

For example:

This documentation is hosted as a [~https://ptg.bczsalba.com]subdomain[/~] on my [~https://bczsalba.com]website!

...would create markup equivalent to the HTML:

This documentation is hosted as a <a href="https://ptg.bczsalba.com">subdomain</a> on my <a href="https://bczsalba.com">website!</a>

Macros

Info

This section details the syntax, but none of the semantics and usage tips, For a more in-depth explanation on macros, see the macro docs.

Macros use the syntax:

[!{name}({arg1}:{arg2})]

...or the shorthand

[!{name}]

when there are no arguments passed.

In both examples, name is the name the macro is defined as, and arg1 and arg2 are some arguments passed to it. Macro arguments are separated by colons (:), in order to clearly visually differentiate them from Python function calls.

Positioners

You can position text in the terminal using the syntax:

[({x};{y})]

Where x and y are terminal coordinates, starting from terminal.origin.

"[61]This is some normal text[(3;5)]But this part is located somewhere else!"

This is some normal text But this part is located somewhere else!

Pseudo-s

All tags above have behaviour that is "pre-defined"; their meaning will be the same in all uses, regardless of context. Pseudo tags are a sort of context-aware group, where they have don't have a consistent meaning: They modify the existing meaning based on the context around them.

Auto

It's easier to explain by-example, so here is our first pseudo tag, #auto:

from pytermgui import tim

tim.print("[@black #auto]White on black [@white #auto] Black on white")

docs/src/tim/tags_pseudo1.py White on black   Black on white

What this tag does is prompt the engine to look around in the current tag group, and inspect the colors set. From then it does the following (simplified):

foreground = ...
background = ...

if foreground is None and background is not None:
    foreground = get_contrasting_color(background)

In essence, it looks for any foreground color. If there is None, but there is a background color, it finds a color that contrasts the background (either an off-white or off-black) and applies that to the foreground. You get color-contrast matches that follow the W3C guidelines with just one tag!