Given a string of text, and a width (measured in cells), return a list of cell offsets which the string should be split at in order for it to fit within the given width. Args: text: The text to examine. width: The available cell width. fold: If True, words longer
(text: str, width: int, fold: bool = True)
| 24 | |
| 25 | |
| 26 | def divide_line(text: str, width: int, fold: bool = True) -> list[int]: |
| 27 | """Given a string of text, and a width (measured in cells), return a list |
| 28 | of cell offsets which the string should be split at in order for it to fit |
| 29 | within the given width. |
| 30 | |
| 31 | Args: |
| 32 | text: The text to examine. |
| 33 | width: The available cell width. |
| 34 | fold: If True, words longer than `width` will be folded onto a new line. |
| 35 | |
| 36 | Returns: |
| 37 | A list of indices to break the line at. |
| 38 | """ |
| 39 | break_positions: list[int] = [] # offsets to insert the breaks at |
| 40 | append = break_positions.append |
| 41 | cell_offset = 0 |
| 42 | _cell_len = cell_len |
| 43 | |
| 44 | for start, _end, word in words(text): |
| 45 | word_length = _cell_len(word.rstrip()) |
| 46 | remaining_space = width - cell_offset |
| 47 | word_fits_remaining_space = remaining_space >= word_length |
| 48 | |
| 49 | if word_fits_remaining_space: |
| 50 | # Simplest case - the word fits within the remaining width for this line. |
| 51 | cell_offset += _cell_len(word) |
| 52 | else: |
| 53 | # Not enough space remaining for this word on the current line. |
| 54 | if word_length > width: |
| 55 | # The word doesn't fit on any line, so we can't simply |
| 56 | # place it on the next line... |
| 57 | if fold: |
| 58 | # Fold the word across multiple lines. |
| 59 | folded_word = chop_cells(word, width=width) |
| 60 | for last, line in loop_last(folded_word): |
| 61 | if start: |
| 62 | append(start) |
| 63 | if last: |
| 64 | cell_offset = _cell_len(line) |
| 65 | else: |
| 66 | start += len(line) |
| 67 | else: |
| 68 | # Folding isn't allowed, so crop the word. |
| 69 | if start: |
| 70 | append(start) |
| 71 | cell_offset = _cell_len(word) |
| 72 | elif cell_offset and start: |
| 73 | # The word doesn't fit within the remaining space on the current |
| 74 | # line, but it *can* fit on to the next (empty) line. |
| 75 | append(start) |
| 76 | cell_offset = _cell_len(word) |
| 77 | |
| 78 | return break_positions |
| 79 | |
| 80 | |
| 81 | if __name__ == "__main__": # pragma: no cover |