Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/traitlets/utils/text.py: 30%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1"""
2Utilities imported from ipython_genutils
3"""
4from __future__ import annotations
6import re
7import textwrap
8from textwrap import indent as _indent
11def indent(val: str) -> str:
12 return _indent(val, " ")
15def _dedent(text: str) -> str:
16 """Equivalent of textwrap.dedent that ignores unindented first line."""
18 if text.startswith("\n"):
19 # text starts with blank line, don't ignore the first line
20 return textwrap.dedent(text)
22 # split first line
23 splits = text.split("\n", 1)
24 if len(splits) == 1:
25 # only one line
26 return textwrap.dedent(text)
28 first, rest = splits
29 # dedent everything but the first line
30 rest = textwrap.dedent(rest)
31 return "\n".join([first, rest])
34def wrap_paragraphs(text: str, ncols: int = 80) -> list[str]:
35 """Wrap multiple paragraphs to fit a specified width.
37 This is equivalent to textwrap.wrap, but with support for multiple
38 paragraphs, as separated by empty lines.
40 Returns
41 -------
43 list of complete paragraphs, wrapped to fill `ncols` columns.
44 """
45 paragraph_re = re.compile(r"\n(\s*\n)+", re.MULTILINE)
46 text = _dedent(text).strip()
47 paragraphs = paragraph_re.split(text)[::2] # every other entry is space
48 out_ps = []
49 indent_re = re.compile(r"\n\s+", re.MULTILINE)
50 for p in paragraphs:
51 # presume indentation that survives dedent is meaningful formatting,
52 # so don't fill unless text is flush.
53 if indent_re.search(p) is None:
54 # wrap paragraph
55 p = textwrap.fill(p, ncols)
56 out_ps.append(p)
57 return out_ps