ioL can do much more than display text, but plain text is where every program starts. This chapter shows how the ioL console treats the text your program prints, and how to get exactly the text you want on the screen.
Save the following Python program as hello.py:
print('Hello world!')
input()
Then run it in an ioL console:
$ iol -- python3 hello.py
A console window opens with your text in it:
Hello world!Why the input() at the end? When a program finishes successfully, the ioL console
closes along with it. Without something to keep the program running, the window would vanish
before you could read it. Waiting for input keeps the program alive. (For now, close the window
to end the program. In a later chapter we'll give the user a proper way to quit.)
You don't need to flush your output. The ioL console arranges for programs written in Python, C, C++ and other languages built on the C runtime to send their output straight away, rather than holding it back in a buffer. If you use a language whose output still appears late, flush it after printing.
Let's print something spread over several lines:
print('''
Hello world!
'I am still learning'
-- Michelangelo
''')
input()
In an ordinary terminal you'd see three lines. In the ioL console you see this:
Hello world! 'I am still learning' -- MichelangeloThe ioL console collapses every run of whitespace (spaces, tabs and newlines) into a single space. This is deliberate. Once your output contains formatting instructions, you'll want to lay it out over several lines of code, and indent it so it's easy to read, without that layout showing up on screen.
So how do you print a line break when you actually want one? With an escape sequence.
An escape sequence is a short code that stands for a character you can't (or shouldn't) print directly. In ioL, every escape sequence starts with </ and ends with >.
The most useful ones control spacing:
| Sequence | Meaning |
|---|---|
| </n> | New line |
| </p> | New paragraph (a line break with extra space) |
| </t> | Wide space, like a tab |
| </ > | A space that won't be collapsed (use several in a row for extra spacing) |
Now we can lay out our quote properly:
print('''
Hello world!</p>
'I am still learning'</n>
</t>-- Michelangelo
''')
input()
Hello world!Notice that the line breaks in the Python code make no difference to the result. Only the escape sequences do. You could print the whole thing on one line and get the same output.
A few characters mean something special to ioL, so they can't be printed directly as text. The most important are the angle brackets and braces:
< > { }
You'll see why in the next chapter: angle brackets surround tags, and braces surround blocks of text. A few other characters are safe in ordinary text but have special meanings inside tags, so you may sometimes need to escape them too:
= @ # [ ] /
Each one has its own escape sequence:
| Sequence | Prints | Sequence | Prints |
|---|---|---|---|
| </<> | < | </=> | = |
| </>> | > | </@> | @ |
| </{> | { | </#> | # |
| </}> | } | </[> | [ |
| <//> | / | </]> | ] |
For example, to show the user a keyboard shortcut:
print('Press </<>Ctrl</>> and </<>S</>> to save.')
Press <Ctrl> and <S> to save.
Every character has a number in the Unicode standard. You can print any character, including ones you can't type on your keyboard, by putting its number after </#. The number can be written in decimal, or in hexadecimal, octal or binary by starting it with x, o or b. These all print a lowercase z:
| Sequence | Number system |
|---|---|
| </#122> | decimal |
| </#x7A> | hexadecimal |
| </#o172> | octal |
| </#b1111010> | binary |
Hexadecimal digits A–F must be written in UPPERCASE: x7A, not x7a. You'll find out why in the chapter on values.
Character tables online usually list codes in hexadecimal, so that's the form you'll use most. For example, a proper dash (—) is character x2014:
print("'I am still learning' </#x2014> Michelangelo")
'I am still learning' — Michelangelo
Whether a character actually appears also depends on the console's font. A character the font doesn't have may show up as a blank space.
Anything between <! and !> is a comment. The ioL console ignores it completely, and nothing is displayed:
print('<!This is a comment.!>')
Why put comments in your output, when you can already write comments in your program's code? Two reasons:
Comments can't be nested inside each other. A comment ends at the first !>, even if you opened another <! inside it.
If your output breaks ioL's rules, the console doesn't stop. It skips what it couldn't understand and carries on. It also prints an error message to the terminal you ran iol from, so keep an eye on that terminal while you're testing.
For example, a lone closing brace isn't allowed in text:
print('I will not be trapped here! }')
ioL | invalid syntax | unexpected '}' while reading text at root level
| in stream: I will not be trapped here! } ⇜1:29
The message says what went wrong, shows the output just before the problem, and gives the line and column where it happened (here, line 1, column 29).
Some mistakes produce no message at all. An unclosed { or <, for instance, just makes the console wait for the rest. As far as it knows, your program hasn't finished printing yet. If part of your output never appears, look for something you forgot to close.
You don't always need to write a program to try something out. Run the ioL console like this:
$ iol -
Now you are the program. Each line you type into the terminal is treated as program output and appears in the console window as you press Enter. Anything the console sends back as input appears in the terminal. To finish, press Ctrl+D on an empty line.
print statement.input() from hello.py and run it again. What happens, and why?