_wrap.py 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. import re
  2. from typing import Iterable, List, Tuple
  3. from ._loop import loop_last
  4. from .cells import cell_len, chop_cells
  5. re_word = re.compile(r"\s*\S+\s*")
  6. def words(text: str) -> Iterable[Tuple[int, int, str]]:
  7. position = 0
  8. word_match = re_word.match(text, position)
  9. while word_match is not None:
  10. start, end = word_match.span()
  11. word = word_match.group(0)
  12. yield start, end, word
  13. word_match = re_word.match(text, end)
  14. def divide_line(text: str, width: int, fold: bool = True) -> List[int]:
  15. divides: List[int] = []
  16. append = divides.append
  17. line_position = 0
  18. _cell_len = cell_len
  19. for start, _end, word in words(text):
  20. word_length = _cell_len(word.rstrip())
  21. if line_position + word_length > width:
  22. if word_length > width:
  23. if fold:
  24. chopped_words = chop_cells(word, max_size=width, position=0)
  25. for last, line in loop_last(chopped_words):
  26. if start:
  27. append(start)
  28. if last:
  29. line_position = _cell_len(line)
  30. else:
  31. start += len(line)
  32. else:
  33. if start:
  34. append(start)
  35. line_position = _cell_len(word)
  36. elif line_position and start:
  37. append(start)
  38. line_position = _cell_len(word)
  39. else:
  40. line_position += _cell_len(word)
  41. return divides
  42. if __name__ == "__main__": # pragma: no cover
  43. from .console import Console
  44. console = Console(width=10)
  45. console.print("12345 abcdefghijklmnopqrstuvwyxzABCDEFGHIJKLMNOPQRSTUVWXYZ 12345")
  46. print(chop_cells("abcdefghijklmnopqrstuvwxyz", 10, position=2))