A helper function that intelligently wraps text. By default, it assumes that it operates on a single paragraph of text but if the `preserve_paragraphs` parameter is provided it will intelligently handle paragraphs (defined by two empty lines). If paragraphs are handled, a paragraph
(
text: str,
width: int = 78,
initial_indent: str = "",
subsequent_indent: str = "",
preserve_paragraphs: bool = False,
)
| 29 | |
| 30 | |
| 31 | def wrap_text( |
| 32 | text: str, |
| 33 | width: int = 78, |
| 34 | initial_indent: str = "", |
| 35 | subsequent_indent: str = "", |
| 36 | preserve_paragraphs: bool = False, |
| 37 | ) -> str: |
| 38 | """A helper function that intelligently wraps text. By default, it |
| 39 | assumes that it operates on a single paragraph of text but if the |
| 40 | `preserve_paragraphs` parameter is provided it will intelligently |
| 41 | handle paragraphs (defined by two empty lines). |
| 42 | |
| 43 | If paragraphs are handled, a paragraph can be prefixed with an empty |
| 44 | line containing the ``\\b`` character (``\\x08``) to indicate that |
| 45 | no rewrapping should happen in that block. |
| 46 | |
| 47 | :param text: the text that should be rewrapped. |
| 48 | :param width: the maximum width for the text. |
| 49 | :param initial_indent: the initial indent that should be placed on the |
| 50 | first line as a string. |
| 51 | :param subsequent_indent: the indent string that should be placed on |
| 52 | each consecutive line. |
| 53 | :param preserve_paragraphs: if this flag is set then the wrapping will |
| 54 | intelligently handle paragraphs. |
| 55 | |
| 56 | .. versionchanged:: 8.4.0 |
| 57 | Width is measured in visible characters. ANSI escape sequences in |
| 58 | ``text``, ``initial_indent``, or ``subsequent_indent`` no longer |
| 59 | count toward the width budget, so styled input wraps based on what |
| 60 | the user sees instead of raw byte length. |
| 61 | """ |
| 62 | from ._textwrap import TextWrapper |
| 63 | |
| 64 | text = text.expandtabs() |
| 65 | wrapper = TextWrapper( |
| 66 | width, |
| 67 | initial_indent=initial_indent, |
| 68 | subsequent_indent=subsequent_indent, |
| 69 | replace_whitespace=False, |
| 70 | ) |
| 71 | if not preserve_paragraphs: |
| 72 | return wrapper.fill(text) |
| 73 | |
| 74 | p: list[tuple[int, bool, str]] = [] |
| 75 | buf: list[str] = [] |
| 76 | indent = None |
| 77 | |
| 78 | def _flush_par() -> None: |
| 79 | if not buf: |
| 80 | return |
| 81 | if buf[0].strip() == "\b": |
| 82 | p.append((indent or 0, True, "\n".join(buf[1:]))) |
| 83 | else: |
| 84 | p.append((indent or 0, False, " ".join(buf))) |
| 85 | del buf[:] |
| 86 | |
| 87 | for line in text.splitlines(): |
| 88 | if not line: |
no test coverage detected