|
4 | 4 | placed in this module and only imported as needed. |
5 | 5 | """ |
6 | 6 | import contextlib |
| 7 | +import io |
7 | 8 | import math |
8 | 9 | import os |
9 | 10 | import sys |
@@ -328,6 +329,24 @@ def generator(self): |
328 | 329 | self.render_progress() |
329 | 330 |
|
330 | 331 |
|
| 332 | +class StripAnsi(io.TextIOWrapper): |
| 333 | + @classmethod |
| 334 | + def maybe(cls, stream, *, color, encoding): |
| 335 | + if not getattr(stream, "encoding", None): |
| 336 | + if color: |
| 337 | + # just wrap the byte stream in a text stream |
| 338 | + stream = io.TextIOWrapper(stream, encoding=encoding) |
| 339 | + else: |
| 340 | + # wrap in a text stream *and* strip ansi chars |
| 341 | + stream = cls(stream, encoding=encoding) |
| 342 | + # stream is already a text stream, can't do anything. |
| 343 | + return stream |
| 344 | + |
| 345 | + def write(self, text): |
| 346 | + text = strip_ansi(text) |
| 347 | + return super().write(text) |
| 348 | + |
| 349 | + |
331 | 350 | def _pager_contextmanager(color=None): |
332 | 351 | """Decide what method to use for paging through text.""" |
333 | 352 | stdout = _default_text_stdout() |
@@ -357,13 +376,24 @@ def _pager_contextmanager(color=None): |
357 | 376 | os.unlink(filename) |
358 | 377 |
|
359 | 378 |
|
360 | | -def pager(generator, color=None): |
| 379 | +@contextlib.contextmanager |
| 380 | +def get_pager_file(color=None): |
| 381 | + """Context manager. |
| 382 | + Yields a writable file-like object which can be used as an output pager. |
| 383 | + .. versionadded:: 8.0 |
| 384 | + :param color: controls if the pager supports ANSI colors or not. The |
| 385 | + default is autodetection. |
| 386 | + """ |
| 387 | + with _pager_contextmanager(color=color) as (stream, encoding, color): |
| 388 | + with StripAnsi.maybe(stream, color=color, encoding=encoding) as text_stream: |
| 389 | + yield text_stream |
| 390 | + |
| 391 | + |
| 392 | +def echo_via_pager(generator, color=None): |
361 | 393 | """Given an iterable of text, write it all to an output pager.""" |
362 | | - with _pager_contextmanager(color=color) as (pager_file, encoding, color): |
| 394 | + with get_pager_file(color=color) as pager_file: |
363 | 395 | for text in generator: |
364 | | - if not color: |
365 | | - text = strip_ansi(text) |
366 | | - pager_file.write(text.encode(encoding, "replace")) |
| 396 | + pager_file.write(text) |
367 | 397 |
|
368 | 398 |
|
369 | 399 | @contextlib.contextmanager |
|
0 commit comments