python/blessings/PKG-INFO

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 Metadata-Version: 1.0
michael@0 2 Name: blessings
michael@0 3 Version: 1.3
michael@0 4 Summary: A thin, practical wrapper around terminal formatting, positioning, and more
michael@0 5 Home-page: https://github.com/erikrose/blessings
michael@0 6 Author: Erik Rose
michael@0 7 Author-email: erikrose@grinchcentral.com
michael@0 8 License: MIT
michael@0 9 Description: =========
michael@0 10 Blessings
michael@0 11 =========
michael@0 12
michael@0 13 Coding with Blessings looks like this... ::
michael@0 14
michael@0 15 from blessings import Terminal
michael@0 16
michael@0 17 t = Terminal()
michael@0 18
michael@0 19 print t.bold('Hi there!')
michael@0 20 print t.bold_red_on_bright_green('It hurts my eyes!')
michael@0 21
michael@0 22 with t.location(0, t.height - 1):
michael@0 23 print 'This is at the bottom.'
michael@0 24
michael@0 25 Or, for byte-level control, you can drop down and play with raw terminal
michael@0 26 capabilities::
michael@0 27
michael@0 28 print '{t.bold}All your {t.red}bold and red base{t.normal}'.format(t=t)
michael@0 29 print t.wingo(2)
michael@0 30
michael@0 31 The Pitch
michael@0 32 =========
michael@0 33
michael@0 34 Blessings lifts several of curses_' limiting assumptions, and it makes your
michael@0 35 code pretty, too:
michael@0 36
michael@0 37 * Use styles, color, and maybe a little positioning without clearing the whole
michael@0 38 screen first.
michael@0 39 * Leave more than one screenful of scrollback in the buffer after your program
michael@0 40 exits, like a well-behaved command-line app should.
michael@0 41 * Get rid of all those noisy, C-like calls to ``tigetstr`` and ``tparm``, so
michael@0 42 your code doesn't get crowded out by terminal bookkeeping.
michael@0 43 * Act intelligently when somebody redirects your output to a file, omitting the
michael@0 44 terminal control codes the user doesn't want to see (optional).
michael@0 45
michael@0 46 .. _curses: http://docs.python.org/library/curses.html
michael@0 47
michael@0 48 Before And After
michael@0 49 ----------------
michael@0 50
michael@0 51 Without Blessings, this is how you'd print some underlined text at the bottom
michael@0 52 of the screen::
michael@0 53
michael@0 54 from curses import tigetstr, setupterm, tparm
michael@0 55 from fcntl import ioctl
michael@0 56 from os import isatty
michael@0 57 import struct
michael@0 58 import sys
michael@0 59 from termios import TIOCGWINSZ
michael@0 60
michael@0 61 # If we want to tolerate having our output piped to other commands or
michael@0 62 # files without crashing, we need to do all this branching:
michael@0 63 if hasattr(sys.stdout, 'fileno') and isatty(sys.stdout.fileno()):
michael@0 64 setupterm()
michael@0 65 sc = tigetstr('sc')
michael@0 66 cup = tigetstr('cup')
michael@0 67 rc = tigetstr('rc')
michael@0 68 underline = tigetstr('smul')
michael@0 69 normal = tigetstr('sgr0')
michael@0 70 else:
michael@0 71 sc = cup = rc = underline = normal = ''
michael@0 72 print sc # Save cursor position.
michael@0 73 if cup:
michael@0 74 # tigetnum('lines') doesn't always update promptly, hence this:
michael@0 75 height = struct.unpack('hhhh', ioctl(0, TIOCGWINSZ, '\000' * 8))[0]
michael@0 76 print tparm(cup, height - 1, 0) # Move cursor to bottom.
michael@0 77 print 'This is {under}underlined{normal}!'.format(under=underline,
michael@0 78 normal=normal)
michael@0 79 print rc # Restore cursor position.
michael@0 80
michael@0 81 Phew! That was long and full of incomprehensible trash! Let's try it again,
michael@0 82 this time with Blessings::
michael@0 83
michael@0 84 from blessings import Terminal
michael@0 85
michael@0 86 term = Terminal()
michael@0 87 with term.location(0, term.height - 1):
michael@0 88 print 'This is', term.underline('pretty!')
michael@0 89
michael@0 90 Much better.
michael@0 91
michael@0 92 What It Provides
michael@0 93 ================
michael@0 94
michael@0 95 Blessings provides just one top-level object: ``Terminal``. Instantiating a
michael@0 96 ``Terminal`` figures out whether you're on a terminal at all and, if so, does
michael@0 97 any necessary terminal setup. After that, you can proceed to ask it all sorts
michael@0 98 of things about the terminal. Terminal terminal terminal.
michael@0 99
michael@0 100 Simple Formatting
michael@0 101 -----------------
michael@0 102
michael@0 103 Lots of handy formatting codes ("capabilities" in low-level parlance) are
michael@0 104 available as attributes on a ``Terminal``. For example::
michael@0 105
michael@0 106 from blessings import Terminal
michael@0 107
michael@0 108 term = Terminal()
michael@0 109 print 'I am ' + term.bold + 'bold' + term.normal + '!'
michael@0 110
michael@0 111 You can also use them as wrappers so you don't have to say ``normal``
michael@0 112 afterward::
michael@0 113
michael@0 114 print 'I am', term.bold('bold') + '!'
michael@0 115
michael@0 116 Or, if you want fine-grained control while maintaining some semblance of
michael@0 117 brevity, you can combine it with Python's string formatting, which makes
michael@0 118 attributes easy to access::
michael@0 119
michael@0 120 print 'All your {t.red}base {t.underline}are belong to us{t.normal}'.format(t=term)
michael@0 121
michael@0 122 Simple capabilities of interest include...
michael@0 123
michael@0 124 * ``bold``
michael@0 125 * ``reverse``
michael@0 126 * ``underline``
michael@0 127 * ``no_underline`` (which turns off underlining)
michael@0 128 * ``blink``
michael@0 129 * ``normal`` (which turns off everything, even colors)
michael@0 130 * ``clear_eol`` (clear to the end of the line)
michael@0 131 * ``clear_bol`` (clear to beginning of line)
michael@0 132 * ``clear_eos`` (clear to end of screen)
michael@0 133
michael@0 134 Here are a few more which are less likely to work on all terminals:
michael@0 135
michael@0 136 * ``dim``
michael@0 137 * ``italic`` and ``no_italic``
michael@0 138 * ``shadow`` and ``no_shadow``
michael@0 139 * ``standout`` and ``no_standout``
michael@0 140 * ``subscript`` and ``no_subscript``
michael@0 141 * ``superscript`` and ``no_superscript``
michael@0 142 * ``flash`` (which flashes the screen once)
michael@0 143
michael@0 144 Note that, while the inverse of ``underline`` is ``no_underline``, the only way
michael@0 145 to turn off ``bold`` or ``reverse`` is ``normal``, which also cancels any
michael@0 146 custom colors. This is because there's no way to tell the terminal to undo
michael@0 147 certain pieces of formatting, even at the lowest level.
michael@0 148
michael@0 149 You might notice that the above aren't the typical incomprehensible terminfo
michael@0 150 capability names; we alias a few of the harder-to-remember ones for
michael@0 151 readability. However, you aren't limited to these: you can reference any
michael@0 152 string-returning capability listed on the `terminfo man page`_ by the name
michael@0 153 under the "Cap-name" column: for example, ``term.rum``.
michael@0 154
michael@0 155 .. _`terminfo man page`: http://www.manpagez.com/man/5/terminfo/
michael@0 156
michael@0 157 Color
michael@0 158 -----
michael@0 159
michael@0 160 16 colors, both foreground and background, are available as easy-to-remember
michael@0 161 attributes::
michael@0 162
michael@0 163 from blessings import Terminal
michael@0 164
michael@0 165 term = Terminal()
michael@0 166 print term.red + term.on_green + 'Red on green? Ick!' + term.normal
michael@0 167 print term.bright_red + term.on_bright_blue + 'This is even worse!' + term.normal
michael@0 168
michael@0 169 You can also call them as wrappers, which sets everything back to normal at the
michael@0 170 end::
michael@0 171
michael@0 172 print term.red_on_green('Red on green? Ick!')
michael@0 173 print term.yellow('I can barely see it.')
michael@0 174
michael@0 175 The available colors are...
michael@0 176
michael@0 177 * ``black``
michael@0 178 * ``red``
michael@0 179 * ``green``
michael@0 180 * ``yellow``
michael@0 181 * ``blue``
michael@0 182 * ``magenta``
michael@0 183 * ``cyan``
michael@0 184 * ``white``
michael@0 185
michael@0 186 You can set the background color instead of the foreground by prepending
michael@0 187 ``on_``, as in ``on_blue``. There is also a ``bright`` version of each color:
michael@0 188 for example, ``on_bright_blue``.
michael@0 189
michael@0 190 There is also a numerical interface to colors, which takes an integer from
michael@0 191 0-15::
michael@0 192
michael@0 193 term.color(5) + 'Hello' + term.normal
michael@0 194 term.on_color(3) + 'Hello' + term.normal
michael@0 195
michael@0 196 term.color(5)('Hello')
michael@0 197 term.on_color(3)('Hello')
michael@0 198
michael@0 199 If some color is unsupported (for instance, if only the normal colors are
michael@0 200 available, not the bright ones), trying to use it will, on most terminals, have
michael@0 201 no effect: the foreground and background colors will stay as they were. You can
michael@0 202 get fancy and do different things depending on the supported colors by checking
michael@0 203 `number_of_colors`_.
michael@0 204
michael@0 205 .. _`number_of_colors`: http://packages.python.org/blessings/#blessings.Terminal.number_of_colors
michael@0 206
michael@0 207 Compound Formatting
michael@0 208 -------------------
michael@0 209
michael@0 210 If you want to do lots of crazy formatting all at once, you can just mash it
michael@0 211 all together::
michael@0 212
michael@0 213 from blessings import Terminal
michael@0 214
michael@0 215 term = Terminal()
michael@0 216 print term.bold_underline_green_on_yellow + 'Woo' + term.normal
michael@0 217
michael@0 218 Or you can use your newly coined attribute as a wrapper, which implicitly sets
michael@0 219 everything back to normal afterward::
michael@0 220
michael@0 221 print term.bold_underline_green_on_yellow('Woo')
michael@0 222
michael@0 223 This compound notation comes in handy if you want to allow users to customize
michael@0 224 the formatting of your app: just have them pass in a format specifier like
michael@0 225 "bold_green" on the command line, and do a quick ``getattr(term,
michael@0 226 that_option)('Your text')`` when you do your formatting.
michael@0 227
michael@0 228 I'd be remiss if I didn't credit couleur_, where I probably got the idea for
michael@0 229 all this mashing.
michael@0 230
michael@0 231 .. _couleur: http://pypi.python.org/pypi/couleur
michael@0 232
michael@0 233 Parametrized Capabilities
michael@0 234 -------------------------
michael@0 235
michael@0 236 Some capabilities take parameters. Rather than making you dig up ``tparm()``
michael@0 237 all the time, we simply make such capabilities into callable strings. You can
michael@0 238 pass the parameters right in::
michael@0 239
michael@0 240 from blessings import Terminal
michael@0 241
michael@0 242 term = Terminal()
michael@0 243 print term.move(10, 1)
michael@0 244
michael@0 245 Here are some of interest:
michael@0 246
michael@0 247 ``move``
michael@0 248 Position the cursor elsewhere. Parameters are y coordinate, then x
michael@0 249 coordinate.
michael@0 250 ``move_x``
michael@0 251 Move the cursor to the given column.
michael@0 252 ``move_y``
michael@0 253 Move the cursor to the given row.
michael@0 254
michael@0 255 You can also reference any other string-returning capability listed on the
michael@0 256 `terminfo man page`_ by its name under the "Cap-name" column.
michael@0 257
michael@0 258 .. _`terminfo man page`: http://www.manpagez.com/man/5/terminfo/
michael@0 259
michael@0 260 Height and Width
michael@0 261 ----------------
michael@0 262
michael@0 263 It's simple to get the height and width of the terminal, in characters::
michael@0 264
michael@0 265 from blessings import Terminal
michael@0 266
michael@0 267 term = Terminal()
michael@0 268 height = term.height
michael@0 269 width = term.width
michael@0 270
michael@0 271 These are newly updated each time you ask for them, so they're safe to use from
michael@0 272 SIGWINCH handlers.
michael@0 273
michael@0 274 Temporary Repositioning
michael@0 275 -----------------------
michael@0 276
michael@0 277 Sometimes you need to flit to a certain location, print something, and then
michael@0 278 return: for example, when updating a progress bar at the bottom of the screen.
michael@0 279 ``Terminal`` provides a context manager for doing this concisely::
michael@0 280
michael@0 281 from blessings import Terminal
michael@0 282
michael@0 283 term = Terminal()
michael@0 284 with term.location(0, term.height - 1):
michael@0 285 print 'Here is the bottom.'
michael@0 286 print 'This is back where I came from.'
michael@0 287
michael@0 288 Parameters to ``location()`` are ``x`` and then ``y``, but you can also pass
michael@0 289 just one of them, leaving the other alone. For example... ::
michael@0 290
michael@0 291 with term.location(y=10):
michael@0 292 print 'We changed just the row.'
michael@0 293
michael@0 294 If you want to reposition permanently, see ``move``, in an example above.
michael@0 295
michael@0 296 Pipe Savvy
michael@0 297 ----------
michael@0 298
michael@0 299 If your program isn't attached to a terminal, like if it's being piped to
michael@0 300 another command or redirected to a file, all the capability attributes on
michael@0 301 ``Terminal`` will return empty strings. You'll get a nice-looking file without
michael@0 302 any formatting codes gumming up the works.
michael@0 303
michael@0 304 If you want to override this--like if you anticipate your program being piped
michael@0 305 through ``less -r``, which handles terminal escapes just fine--pass
michael@0 306 ``force_styling=True`` to the ``Terminal`` constructor.
michael@0 307
michael@0 308 In any case, there is an ``is_a_tty`` attribute on ``Terminal`` that lets you
michael@0 309 see whether the attached stream seems to be a terminal. If it's false, you
michael@0 310 might refrain from drawing progress bars and other frippery, since you're
michael@0 311 apparently headed into a pipe::
michael@0 312
michael@0 313 from blessings import Terminal
michael@0 314
michael@0 315 term = Terminal()
michael@0 316 if term.is_a_tty:
michael@0 317 with term.location(0, term.height - 1):
michael@0 318 print 'Progress: [=======> ]'
michael@0 319 print term.bold('Important stuff')
michael@0 320
michael@0 321 Shopping List
michael@0 322 =============
michael@0 323
michael@0 324 There are decades of legacy tied up in terminal interaction, so attention to
michael@0 325 detail and behavior in edge cases make a difference. Here are some ways
michael@0 326 Blessings has your back:
michael@0 327
michael@0 328 * Uses the terminfo database so it works with any terminal type
michael@0 329 * Provides up-to-the-moment terminal height and width, so you can respond to
michael@0 330 terminal size changes (SIGWINCH signals). (Most other libraries query the
michael@0 331 ``COLUMNS`` and ``LINES`` environment variables or the ``cols`` or ``lines``
michael@0 332 terminal capabilities, which don't update promptly, if at all.)
michael@0 333 * Avoids making a mess if the output gets piped to a non-terminal
michael@0 334 * Works great with standard Python string templating
michael@0 335 * Provides convenient access to all terminal capabilities, not just a sugared
michael@0 336 few
michael@0 337 * Outputs to any file-like object, not just stdout
michael@0 338 * Keeps a minimum of internal state, so you can feel free to mix and match with
michael@0 339 calls to curses or whatever other terminal libraries you like
michael@0 340
michael@0 341 Blessings does not provide...
michael@0 342
michael@0 343 * Native color support on the Windows command prompt. However, it should work
michael@0 344 when used in concert with colorama_.
michael@0 345
michael@0 346 .. _colorama: http://pypi.python.org/pypi/colorama/0.2.4
michael@0 347
michael@0 348 Bugs
michael@0 349 ====
michael@0 350
michael@0 351 Bugs or suggestions? Visit the `issue tracker`_.
michael@0 352
michael@0 353 .. _`issue tracker`: https://github.com/erikrose/blessings/issues/new
michael@0 354
michael@0 355 License
michael@0 356 =======
michael@0 357
michael@0 358 Blessings is under the MIT License. See the LICENSE file.
michael@0 359
michael@0 360 Version History
michael@0 361 ===============
michael@0 362
michael@0 363 1.3
michael@0 364 * Add ``number_of_colors``, which tells you how many colors the terminal
michael@0 365 supports.
michael@0 366 * Made ``color(n)`` and ``on_color(n)`` callable to wrap a string, like the
michael@0 367 named colors can. Also, make them both fall back to the ``setf`` and
michael@0 368 ``setb`` capabilities (like the named colors do) if the ANSI ``setaf`` and
michael@0 369 ``setab`` aren't available.
michael@0 370 * Allow ``color`` attr to act as an unparametrized string, not just a
michael@0 371 callable.
michael@0 372 * Make ``height`` and ``width`` examine any passed-in stream before falling
michael@0 373 back to stdout. (This rarely if ever affects actual behavior; it's mostly
michael@0 374 philosophical.)
michael@0 375 * Make caching simpler and slightly more efficient.
michael@0 376 * Get rid of a reference cycle between Terminals and FormattingStrings.
michael@0 377 * Update docs to reflect that terminal addressing (as in ``location()``) is
michael@0 378 0-based.
michael@0 379
michael@0 380 1.2
michael@0 381 * Added support for Python 3! We need 3.2.3 or greater, because the curses
michael@0 382 library couldn't decide whether to accept strs or bytes before that
michael@0 383 (http://bugs.python.org/issue10570).
michael@0 384 * Everything that comes out of the library is now unicode. This lets us
michael@0 385 support Python 3 without making a mess of the code, and Python 2 should
michael@0 386 continue to work unless you were testing types (and badly). Please file a
michael@0 387 bug if this causes trouble for you.
michael@0 388 * Changed to the MIT License for better world domination.
michael@0 389 * Added Sphinx docs.
michael@0 390
michael@0 391 1.1
michael@0 392 * Added nicely named attributes for colors.
michael@0 393 * Introduced compound formatting.
michael@0 394 * Added wrapper behavior for styling and colors.
michael@0 395 * Let you force capabilities to be non-empty, even if the output stream is
michael@0 396 not a terminal.
michael@0 397 * Added the ``is_a_tty`` attribute for telling whether the output stream is a
michael@0 398 terminal.
michael@0 399 * Sugared the remaining interesting string capabilities.
michael@0 400 * Let ``location()`` operate on just an x *or* y coordinate.
michael@0 401
michael@0 402 1.0
michael@0 403 * Extracted Blessings from nose-progressive, my `progress-bar-having,
michael@0 404 traceback-shortcutting, rootin', tootin' testrunner`_. It provided the
michael@0 405 tootin' functionality.
michael@0 406
michael@0 407 .. _`progress-bar-having, traceback-shortcutting, rootin', tootin' testrunner`: http://pypi.python.org/pypi/nose-progressive/
michael@0 408
michael@0 409 Keywords: terminal,tty,curses,ncurses,formatting,style,color,console
michael@0 410 Platform: UNKNOWN
michael@0 411 Classifier: Intended Audience :: Developers
michael@0 412 Classifier: Natural Language :: English
michael@0 413 Classifier: Development Status :: 5 - Production/Stable
michael@0 414 Classifier: Environment :: Console
michael@0 415 Classifier: Environment :: Console :: Curses
michael@0 416 Classifier: License :: OSI Approved :: MIT License
michael@0 417 Classifier: Operating System :: POSIX
michael@0 418 Classifier: Programming Language :: Python :: 2
michael@0 419 Classifier: Programming Language :: Python :: 2.5
michael@0 420 Classifier: Programming Language :: Python :: 2.6
michael@0 421 Classifier: Programming Language :: Python :: 2.7
michael@0 422 Classifier: Programming Language :: Python :: 3
michael@0 423 Classifier: Programming Language :: Python :: 3.2
michael@0 424 Classifier: Topic :: Software Development :: Libraries
michael@0 425 Classifier: Topic :: Software Development :: User Interfaces
michael@0 426 Classifier: Topic :: Terminals

mercurial