ul - do underlining

Yesterday I got to know the ul command while I was listening the "GNU World Order" podcast episode 48 of season 13 [1]. I was curious about this command and the mentioned command line option `-i`, `--indicated`. The option was not considered in detail in the episode.

From the man page of ul:

ul reads the named files (or standard input if none are given) and
translates occurrences of underscores to the sequence which indicates
underlining for the terminal in use, as specified by the environment
variable TERM.

I have tested the command with Ubuntu 22.04.3, Bash and GNOME-Terminal (and xterm too). ul uses the backspace control character combined with underscore to underline a character. For example for the sequence "a\b_" ul outputs an underlined "a" where "\b" is the backspace.

echo -e "a\b_" | ul

(The output is omitted because I do not know a good way to render an underlined "a" just with Unicode. :-) I guess I could combine the "a" with the COMBINING LOW LINE Unicode character, but it seems that there are programs which are not able to render it nicely.)

The `-e` for echo enables the interpretation of backslash escapes, so "\b" is interpreted as backspace. Alternatively you can type `C-v C-h` (control+v followed by control+h) instead of "\b" to enter a verbatim backspace. This way the `-e` option can be omitted. The verbatim backspace is shown as "^H".

echo "a^H_" | ul

The meaning of backspace can be imagined as follows: It is used to move the cursor a step back while keeping the existing character under the new cursor position. (A character is not deleted by backspace here.) This allows to handle two characters at the same position and combine a character with underscore to underline the character. It does not matter which character comes first. You can also type:

echo -e "_\ba" | ul

If there are multiple characters to be underlined you have to use backspace and underscore for each character.

echo -e "a\b_b\b_" | ul

You can type all backspaces and underscores in sequence:

echo -e "ab\b\b__" | ul

And now to the command line option `--indicated`: This changes the output of ul and adds a separate line of underscores to indicate the underlined characters. For example

echo -e "ab\b_c" | ul -i

prints

abc
 _

Finally the question: What happens if the backspace is not used together with underscore but a different character? The answer is: The second character is ignored.

echo -e "ab\bc" | ul

prints

ab

This is different to the output without using ul.

echo -e "ab\bc"

prints

ac

This is different because ul eliminates the backspace and just ignores the "c" because it cannot be combined with "b" (none of the characters is an underscore). Without ul the backspace is still part of the echoed string and the backspace is handled as usual for printing.

You can see that the backspace still exists using hd.

echo -e "ab\bc" | hd

prints

00000000  61 62 08 63 0a                                    |ab.c.|
00000005

where "08" is the hexadecimal value of backspace.

Links:

[1] GNU World Order 13x48