Terminal Emulation
byexample
can use different emulation modes to process the output of the
runners.
By default byexample
uses a dumb terminal (+term=dumb
) which
is fast and works well in most cases.
But you can change this to disable emulation with +term=as-is
or
to enable full ANSI terminal emulation with +term=ansi
.
Dumb terminal
In this mode, byexample
emulates a very simple terminal, processing
only the white spaces.
It does not have the concept of a cursor, does not interpret escape codes and does not break lines automatically.
Even if a geometry is defined
with +geometry
, the dumb terminal
does not force any boundaries: the following example
will print a string longer than the width of the terminal.
>>> print("aaaabbbb" * 8) # byexample: +geometry 24x32
aaaabbbbaaaabbbbaaaabbbbaaaabbbbaaaabbbbaaaabbbbaaaabbbbaaaabbbb
White space processing
The dumb terminal removes any trailing whitespace, converts tabs to spaces and standardizes the new lines.
This suits most examples, reducing the need to add tabs into the
examples or requiring the
normalization of whitespace
with +norm-ws
.
>>> print("\tfoo\tbar\nbaz\tsaz \rtaz")
foo bar
baz saz
taz
If you need to check whitespace characters, you can use +term=as-is
to
disable terminal emulation.
Escape/Control sequences filter
Since 11.0.0
, byexample
strips any escape and control sequence.
The following example prints a message partially in red using the
special \033[31m
and \033[0m
sequences.
The dumb
terminal will filter them by default:
$ echo -e "This is a \033[31mmessage in red\033[0m but not panic"
<...>This is a message in red but not panic
If you want the pre-11.0.0
behaviour, you can turn off the filtering:
$ echo -e "This is a \033[31mmessage in red\033[0m but not panic" # byexample: -filter-esc-seqs
<...>This is a <...>[31mmessage in red<...>[0m but not panic
If filtering is not enough (the example’s output does not display well)
you probably will need to use a full terminal emulation with
+term=ansi
.
In those cases byexample
will print a hint about that:
$ byexample -l shell test/ds/cli.md # byexample: +norm-ws +timeout 8
<...>
Failed example:
echo -e "This is a broken \033[23;2Hmessage\033[23;77H"
<...>
- Escape/control sequences were detected. If the output looks
scrambled or dirty, you may try a full terminal emulation with
'+term=ansi'
<...>
As-is terminal
When +term=as-is
is activated the output is passed as is without
any modification except for standardization of new lines.
It can be useful in some special cases to check white spaces that are removed by the dumb or ANSI terminals.
>>> print("\tfoo\tbar\nbaz\tsaz \rtaz") # byexample: +term=as-is
foo bar
baz saz
taz
Following the message printed partially in red, the as-is
terminal
will not filter any escape/control sequence:
$ echo -e "This is a \033[31mmessage in red\033[0m but not panic" # byexample: +term=as-is
<...>This is a <...>[31mmessage in red<...>[0m but not panic
ANSI terminal
Some programs may need a real terminal or at least an emulated ANSI terminal.
byexample
can emulate one capable of interpreting and emulating
all the control sequences and escape codes using +term=ansi
.
A full emulation allows you to render correctly any output, not just filtering the escape/control sequences but interpreting it correctly.
$ echo -e "This is a \033[31mmessage in red\033[0m but not panic" # byexample: +term=ansi
<...>This is a message in red but not panic
The ANSI terminal emulation comes with some reasonable but unexpected behaviours, some gotchas and a slightly slower performance.
Note: terminal emulation is not fully supported in
Python 2.7
. It should work but using a modernPython
version is recommended.
Terminal boundaries
Keep in mind that an emulated terminal will honor its own boundaries or geometry: if an example prints a string longer than the width of the terminal, the string will spawn multiple lines (a newline is added automatically).
>>> print("aaaabbbb" * 8) # byexample: +term=ansi +geometry 24x32
aaaabbbbaaaabbbbaaaabbbbaaaabbbb
aaaabbbbaaaabbbbaaaabbbbaaaabbbb
This is especially useful to work with ncurses
or other advanced programs.
ncurses support
Some applications use advanced terminal features (like the ones
that use ncurses
) and require a terminal emulator.
Examples of this are programs like less
, more
, top
and man
.
$ less test/ds/python-tutorial.v2.md # byexample: +term=ansi +rm= +stop-on-timeout
This is a 101 Python tutorial
The following is an example written in Python about arithmetics
```
>>> from __future__ import print_function
>>> 1 + 2
3
```
The next examples show you about complex numbers in Python
```
>>> 2j * 2
4j
>>> 2j + 4j
6j
```
<...>(END)
Try the above example with
+term=as-is
and see what happens.
Pagination
byexample
will not emulate pagination. When the output is larger than
the height of the terminal, lines that scroll off the top are discarded.
The following example prints more lines than are available in the terminal so only the last lines are shown.
>>> for i in range(1,33): # byexample: +term=ansi +geometry=5x80
... print("line %i" % i)
line 29
line 30
line 31
line 32
If this is a problem change the geometry:
increase the count of rows that the terminal has with +geometry
.
Performance
Emulation is slightly slower than the normal mode
(+term=dumb
).
Keep that in mind and try to not enable it by default.