Skip to content

Print formatted text

The BLISS shell provides different way to print formatted text.

Note

Usage of styles is a manner to keep readable colors on dark and light terminals.

The easiest way to print colors is to use print_html() with a HTML-like formatting. It supports some common tags, and few others for colors.

Most colors are intented to be abstract in order to be picked according to the environement. Right now it is selected according to the dark/light mode of the background. But it could be selected according to the used style, the beamline or the session.

That is one of the recommended way to add colors, in order to provide a more consistent UI. This also can be tuned globally if needed.

Common tags

print_html("""
<h1>My title</h1>
   <h2>My title</h2>
      <h3>My title</h3>
You can use the mark tag to <mark>highlight</mark> text.
<del>This line of text is meant to be treated as deleted text.</del>
<s>This line of text is meant to be treated as no longer accurate.</s>
<ins>This line of text is meant to be treated as an addition to the document.</ins>
<u>This line of text will render as underlined.</u>
<small>This line of text is meant to be treated as fine print.</small>
<strong>This line rendered as bold text.</strong>
<em>This line rendered as italicized text.</em>
""")

Screenshot

Color palette tags

Few abstract colors are defined if you want to identify different elements. It’s a set of color from a consistent palette.

print_html("""
 <color1>It's the color1</color1>
 <color2>It's the color2</color2>
 <color3>It's the color3</color3>
 <color4>It's the color4</color4>
 <color5>It's the color5</color5>
 <color6>It's the color6</color6>
""")

Screenshot

For now this palette reuses the one defined for the standard terminal. But this could change in the future.

Warning tags

Some tags for warnings are also available. The name was reused from the Bootstrap library.

print_html("""
<info>Info color</info>
<success>Success color</success>
<warning>Warning color</warning>
<danger>Danger color</danger>
<fatal>Fatal color</fatal>

<bg-info> Info colors      </bg-info>
<bg-success> Success colors   </bg-success>
<bg-warning> Warning colors   </bg-warning>
<bg-danger> Danger colors    </bg-danger>
<bg-fatal> Fatal colors     </bg-fatal>
""")

Screenshot

Fixed color tags

Note

Fixed color tags are not recommended.

If needed, fixed colors can be used the following way.

# Colors from the ANSI palette.
print_html("<ansired>This is red</ansired>")
print_html("<ansigreen>This is green</ansigreen>")
# Named colors (256 color palette, or true color, depending on the output).
print_html("<skyblue>This is sky blue</skyblue>")
print_html("<seagreen>This is sea green</seagreen>")
print_html("<violet>This is violet</violet>")

Both foreground and background colors can also be specified setting the fg and bg attributes of any HTML tag:

print_html("<aaa fg='ansiwhite' bg='ansigreen'>White on green</aaa>")

The color attributes can also be specified using hexadecial HTML color.

print_html("<aaa fg='#FF0000' bg='#404040'>Red on grey</aaa>")

Note

ANSI colors tags are not recommended.

A dedicated print is provided to display colors with ANSI sequence.

It can be used together with color helper.

It is mostly here for compatibility, and still have maybe use cases.

from bliss.shell.formatters.ansi import PURPLE, CYAN, DARKCYAN, BLUE, GREEN, YELLOW, RED, UNDERLINE, BOLD

print_ansi(RED("Abort !!!"))
  • PURPLE(msg)
  • CYAN(msg)
  • DARKCYAN(msg)
  • BLUE(msg)
  • GREEN(msg)
  • YELLOW(msg)
  • RED(msg)
  • UNDERLINE(msg)
  • BOLD(msg)

Tables

A common library to display table is tabulate. Unfortunatly it does not support style.

A simplified version was designed to support styles.

It can be used the following way:

from bliss.shell.formatters import tabulate
print(tabulate.tabulate([
    [("class:header", "axis"), ("class:header", "position"), ("class:header", "unit")],
    [robx.name, ("class:warning", robx.position), robx.unit],
    [roby.name, ("class:color1", roby.position), roby.unit]
]))

You could want to display in the shell the content of something that can be updated or displayed until a manual abort.

We provide a text_block() helper for that.

It ansure to properly handle a user abort (CTRL-C) and that the display will not be broken by other print or logging. For that every use of print() or logging module will be displayed above this context.

Follow a processing

Here we change the displayed content between some processing.

with text_block() as tb:
    tb.set_text("Prepare processing")
    sleep(2)  # do stuff
    tb.set_text("Processing...")
    sleep(5)  # do stuff
    tb.set_text("Processing done")

Programatic rendering

Instead of explicitly tell what to display, a callback can be defined. This callback will be called everytime the block have to be redisplayed (commonly 3 times every seconds).

import time

start_time = time.time()

def render():
    # User function which returns height and content
    import time
    return 1, f" {time.time() - start_time:.2f} s"

with text_block(render):
    # wait forever
    while True:
        sleep(1)

Screenshot

Notice that it displays for you a toolbar to remember to use CTRL-C to abort.

In this case it raises a KeyboardInterrupt which can be captured by you if you need.

Feedback on error

The next step to setup this TextBlockApplication is to use a processing which have to be monitored.

For example you want to move a device and to monitor something until the motion is done.

robx.acceleration = 0.5  # let's slow down for the example

with text_block() as tb:
    step = "INIT"

    def render():
        nonlocal step
        return 1, f" {step} {robx.name}: {robx.position:0.2f} {robx.unit}"

    tb.set_render(render)
    try:
        # Init
        move(robx, 0, display_mode="no")
        # Do some stuffs
        step = "MOVE"
        move(robx, 5, display_mode="no")
        # Stabilisation
        step = "STAB"
        sleep(5.0)
    except BaseException:
        step = "ABORTED"
        raise
    step = "DONE"

Screenshot

If the user abort the task with CTRL-C, first the background task will be cancelled, then the application will refresh the display, and finally the KeyboardInterrupt will be raised. The displayed information will be consistent.

Custom the style

By default the title <h1> is white in a dark theme.

One could prefer to have a colorful title.

Here is a recipe that can be used in the session setup to change that.

from bliss.shell.pt import default_style

default_style.DARK_STYLE["h1"] = "red underline bold"

Now every scripts which use <h1>, or getval.title() will use this custom style. This includes for example the KB focusing.

Screenshot