Given a ASCII string containing control characters, compute what it should look like when printed to a terminal. Imagining the behaviour of a cursor, this is how to treat each character in the input:
- 0x08 backspace (
\b
): go left one (if already at the start of a line, do not go up) - 0x09 horizontal tab (
\t
): go right one, and then right until the column number (0-indexed) is a multiple of 8 - 0x0A line feed (
\n
): go down one line and back to the start of the line - 0x0B vertical tab (
\v
): go down one line without changing horizontal position - 0x0D carriage return (
\r
): go back to the start of the line - 0x20 space (
- Any other printable ASCII character should be appended literally
- Any characters that aren't listed above (other control characters, NULL bytes, Unicode, etc.) will not be given in the input, so you don't have to handle them
Note: The behaviours above are those of modern terminal emulators; in the olden days, on a printer or teletype, \n
would have done what \v
does here, and \v
would have moved the print head down so that the line number was a multiple of 8 (or however else the tab stops were configured). More information
Since this is like a terminal or printer, you can assume the output will never be longer than 80 columns.
Gaps that were never printed on (because the cursor moved over it) should be filled in with spaces, but gaps that are further to the right than the cursor ever went should be stripped off.
If you try these in a shell (particularly those with \b
and \r
), the shell prompt may overwrite some of the text - try printing a newline afterwards or add a ; sleep 1
to see the effect properly.
Here is a reference implementation: Try it online!
Test cases
Input and output are given in C-style escaped string syntax. To clarify, your program does not need to interpret backslash escape sequences - the input will contain the literal control codes themselves.
Input Output
-----------------------------------
"" ""
"A" "A"
" " " "
"\n" "\n"
"A\nB\nC" "A\nB\nC"
"\t" " "
"A\t" "A "
"A\t\t" "A "
"\tA" " A"
"A\tB\tC" "A B C"
"ABCDEF\t" "ABCDEF "
"ABCDEFG\t" "ABCDEFG "
"ABCDEFGH\t" "ABCDEFGH "
"ABCDEFGHI\t" "ABCDEFGHI "
"\b" ""
"A\b" "A"
"A\bB" "B"
"A\n\bB" "A\nB"
"AB\b\bC" "CB"
"A\b " " "
"\r" ""
"A\r" "A"
"A\rB" "B"
"A\rB\rC" "C"
"ABC\rD" "DBC"
"A\rB\nC" "B\nC"
"A\n\rB" "A\nB"
"A \r" "A "
"A\t\r" "A "
"AB\vC\rD" "AB\nD C"
"\v" "\n"
"A\v" "A\n "
"A\vB" "A\n B"
"AB\vCD" "AB\n CD"
"AB\v\bCD" "AB\n CD"
"AB\v\rCD" "AB\nCD"
"AB\tC\rD" "DB C"
"AB\t\bC" "AB C"
"AB\b\t" "AB "
"ABCDEF\b\t" "ABCDEF "
"ABCDEFG\b\t" "ABCDEFG "
"ABCDEFGH\b\t" "ABCDEFGH"
"ABCDEFGHI\b\t" "ABCDEFGHI "
"a very long string that is approaching the 80-column limit\t!\n" "a very long string that is approaching the 80-column limit !\n"
Rules
- You may input and output a list of ASCII integer code-points instead of a string
- You may use any sensible I/O format
- Standard loopholes are forbidden
- This is code-golf, so the shortest code in bytes wins
echo
doesn't format the whitespace, your terminal emulator does. So you're welcome to submitxterm
for however large that is (very), butecho
just prints the control code bytes so it doesn't answer the question. Not to mention neitherxterm
norecho
are programming languages. \$\endgroup\$printf
? \$\endgroup\$printf '\b' | xxd
you will see that allprintf
is doing is outputting the byte0x08
, not spaces or anything \$\endgroup\$