summaryrefslogtreecommitdiffstats
path: root/docs/pages/printing_text.rst
blob: 8359d5fdb0b808036f1868aa9df9cd7468020803 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
.. _printing_text:

Printing (and using) formatted text
===================================

Prompt_toolkit ships with a
:func:`~prompt_toolkit.shortcuts.print_formatted_text` function that's meant to
be (as much as possible) compatible with the built-in print function, but on
top of that, also supports colors and formatting.

On Linux systems, this will output VT100 escape sequences, while on Windows it
will use Win32 API calls or VT100 sequences, depending on what is available.

.. note::

        This page is also useful if you'd like to learn how to use formatting
        in other places, like in a prompt or a toolbar. Just like
        :func:`~prompt_toolkit.shortcuts.print_formatted_text` takes any kind
        of "formatted text" as input, prompts and toolbars also accept
        "formatted text".

Printing plain text
-------------------

The print function can be imported as follows:

.. code:: python

    from prompt_toolkit import print_formatted_text

    print_formatted_text('Hello world')

You can replace the built in ``print`` function as follows, if you want to.

.. code:: python

    from prompt_toolkit import print_formatted_text as print

    print('Hello world')

.. note::

    If you're using Python 2, make sure to add ``from __future__ import
    print_function``. Otherwise, it will not be possible to import a function
    named ``print``.

.. _formatted_text:

Formatted text
--------------

There are several ways to display colors:

- By creating an :class:`~prompt_toolkit.formatted_text.HTML` object.
- By creating an :class:`~prompt_toolkit.formatted_text.ANSI` object that
  contains ANSI escape sequences.
- By creating a list of ``(style, text)`` tuples.
- By creating a list of ``(pygments.Token, text)`` tuples, and wrapping it in
  :class:`~prompt_toolkit.formatted_text.PygmentsTokens`.

An instance of any of these four kinds of objects is called "formatted text".
There are various places in prompt toolkit, where we accept not just plain text
(as a string), but also formatted text.

HTML
^^^^

:class:`~prompt_toolkit.formatted_text.HTML` can be used to indicate that a
string contains HTML-like formatting. It recognizes the basic tags for bold,
italic and underline: ``<b>``, ``<i>`` and ``<u>``.

.. code:: python

    from prompt_toolkit import print_formatted_text, HTML

    print_formatted_text(HTML('<b>This is bold</b>'))
    print_formatted_text(HTML('<i>This is italic</i>'))
    print_formatted_text(HTML('<u>This is underlined</u>'))

Further, it's possible to use tags for foreground colors:

.. code:: python

    # Colors from the ANSI palette.
    print_formatted_text(HTML('<ansired>This is red</ansired>'))
    print_formatted_text(HTML('<ansigreen>This is green</ansigreen>'))

    # Named colors (256 color palette, or true color, depending on the output).
    print_formatted_text(HTML('<skyblue>This is sky blue</skyblue>'))
    print_formatted_text(HTML('<seagreen>This is sea green</seagreen>'))
    print_formatted_text(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:

.. code:: python

    # Colors from the ANSI palette.
    print_formatted_text(HTML('<aaa fg="ansiwhite" bg="ansigreen">White on green</aaa>'))

Underneath, all HTML tags are mapped to classes from a stylesheet, so you can
assign a style for a custom tag.

.. code:: python

    from prompt_toolkit import print_formatted_text, HTML
    from prompt_toolkit.styles import Style

    style = Style.from_dict({
        'aaa': '#ff0066',
        'bbb': '#44ff00 italic',
    })

    print_formatted_text(HTML('<aaa>Hello</aaa> <bbb>world</bbb>!'), style=style)


ANSI
^^^^

Some people like to use the VT100 ANSI escape sequences to generate output.
Natively, this is however only supported on VT100 terminals, but prompt_toolkit
can parse these, and map them to formatted text instances. This means that they
will work on Windows as well. The :class:`~prompt_toolkit.formatted_text.ANSI`
class takes care of that.

.. code:: python

    from prompt_toolkit import print_formatted_text, ANSI

    print_formatted_text(ANSI('\x1b[31mhello \x1b[32mworld'))

Keep in mind that even on a Linux VT100 terminal, the final output produced by
prompt_toolkit, is not necessarily exactly the same. Depending on the color
depth, it is possible that colors are mapped to different colors, and unknown
tags will be removed.


(style, text) tuples
^^^^^^^^^^^^^^^^^^^^

Internally, both :class:`~prompt_toolkit.formatted_text.HTML` and
:class:`~prompt_toolkit.formatted_text.ANSI` objects are mapped to a list of
``(style, text)`` tuples. It is however also possible to create such a list
manually with :class:`~prompt_toolkit.formatted_text.FormattedText` class.
This is a little more verbose, but it's probably the most powerful
way of expressing formatted text.

.. code:: python

    from prompt_toolkit import print_formatted_text
    from prompt_toolkit.formatted_text import FormattedText

    text = FormattedText([
        ('#ff0066', 'Hello'),
        ('', ' '),
        ('#44ff00 italic', 'World'),
    ])

    print_formatted_text(text)

Similar to the :class:`~prompt_toolkit.formatted_text.HTML` example, it is also
possible to use class names, and separate the styling in a style sheet.

.. code:: python

    from prompt_toolkit import print_formatted_text
    from prompt_toolkit.formatted_text import FormattedText
    from prompt_toolkit.styles import Style

    # The text.
    text = FormattedText([
        ('class:aaa', 'Hello'),
        ('', ' '),
        ('class:bbb', 'World'),
    ])

    # The style sheet.
    style = Style.from_dict({
        'aaa': '#ff0066',
        'bbb': '#44ff00 italic',
    })

    print_formatted_text(text, style=style)


Pygments ``(Token, text)`` tuples
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

When you have a list of `Pygments <http://pygments.org/>`_ ``(Token, text)``
tuples, then these can be printed by wrapping them in a
:class:`~prompt_toolkit.formatted_text.PygmentsTokens` object.

.. code:: python

    from pygments.token import Token
    from prompt_toolkit import print_formatted_text
    from prompt_toolkit.formatted_text import PygmentsTokens

    text = [
        (Token.Keyword, 'print'),
        (Token.Punctuation, '('),
        (Token.Literal.String.Double, '"'),
        (Token.Literal.String.Double, 'hello'),
        (Token.Literal.String.Double, '"'),
        (Token.Punctuation, ')'),
        (Token.Text, '\n'),
    ]

    print_formatted_text(PygmentsTokens(text))


Similarly, it is also possible to print the output of a Pygments lexer:

.. code:: python

    import pygments
    from pygments.token import Token
    from pygments.lexers.python import PythonLexer

    from prompt_toolkit.formatted_text import PygmentsTokens
    from prompt_toolkit import print_formatted_text

    # Printing the output of a pygments lexer.
    tokens = list(pygments.lex('print("Hello")', lexer=PythonLexer()))
    print_formatted_text(PygmentsTokens(tokens))

Prompt_toolkit ships with a default colorscheme which styles it just like
Pygments would do, but if you'd like to change the colors, keep in mind that
Pygments tokens map to classnames like this:

+-----------------------------------+---------------------------------------------+
| pygments.Token                    | prompt_toolkit classname                    |
+===================================+=============================================+
| - ``Token.Keyword``               | - ``"class:pygments.keyword"``              |
| - ``Token.Punctuation``           | - ``"class:pygments.punctuation"``          |
| - ``Token.Literal.String.Double`` | - ``"class:pygments.literal.string.double"``|
| - ``Token.Text``                  | - ``"class:pygments.text"``                 |
| - ``Token``                       | - ``"class:pygments"``                      |
+-----------------------------------+---------------------------------------------+

A classname like ``pygments.literal.string.double`` is actually decomposed in
the following four classnames: ``pygments``, ``pygments.literal``,
``pygments.literal.string`` and ``pygments.literal.string.double``. The final
style is computed by combining the style for these four classnames. So,
changing the style from these Pygments tokens can be done as follows:

.. code:: python

    from prompt_toolkit.styles import Style

    style = Style.from_dict({
        'pygments.keyword': 'underline',
        'pygments.literal.string': 'bg:#00ff00 #ffffff',
    })
    print_formatted_text(PygmentsTokens(tokens), style=style)


to_formatted_text
^^^^^^^^^^^^^^^^^

A useful function to know about is
:func:`~prompt_toolkit.formatted_text.to_formatted_text`. This ensures that the
given input is valid formatted text. While doing so, an additional style can be
applied as well.

.. code:: python

    from prompt_toolkit.formatted_text import to_formatted_text, HTML
    from prompt_toolkit import print_formatted_text

    html = HTML('<aaa>Hello</aaa> <bbb>world</bbb>!')
    text = to_formatted_text(html, style='class:my_html bg:#00ff00 italic')

    print_formatted_text(text)