Count the number of lines in a given string. Lines are counted as if the string was wrapped so that lines are never over linewidth characters long. Tabs are considered tabwidth characters long.
(s, linewidth=80)
| 26 | |
| 27 | |
| 28 | def count_lines_with_wrapping(s, linewidth=80): |
| 29 | """Count the number of lines in a given string. |
| 30 | |
| 31 | Lines are counted as if the string was wrapped so that lines are never over |
| 32 | linewidth characters long. |
| 33 | |
| 34 | Tabs are considered tabwidth characters long. |
| 35 | """ |
| 36 | tabwidth = 8 # Currently always true in Shell. |
| 37 | pos = 0 |
| 38 | linecount = 1 |
| 39 | current_column = 0 |
| 40 | |
| 41 | for m in re.finditer(r"[\t\n]", s): |
| 42 | # Process the normal chars up to tab or newline. |
| 43 | numchars = m.start() - pos |
| 44 | pos += numchars |
| 45 | current_column += numchars |
| 46 | |
| 47 | # Deal with tab or newline. |
| 48 | if s[pos] == '\n': |
| 49 | # Avoid the `current_column == 0` edge-case, and while we're |
| 50 | # at it, don't bother adding 0. |
| 51 | if current_column > linewidth: |
| 52 | # If the current column was exactly linewidth, divmod |
| 53 | # would give (1,0), even though a new line hadn't yet |
| 54 | # been started. The same is true if length is any exact |
| 55 | # multiple of linewidth. Therefore, subtract 1 before |
| 56 | # dividing a non-empty line. |
| 57 | linecount += (current_column - 1) // linewidth |
| 58 | linecount += 1 |
| 59 | current_column = 0 |
| 60 | else: |
| 61 | assert s[pos] == '\t' |
| 62 | current_column += tabwidth - (current_column % tabwidth) |
| 63 | |
| 64 | # If a tab passes the end of the line, consider the entire |
| 65 | # tab as being on the next line. |
| 66 | if current_column > linewidth: |
| 67 | linecount += 1 |
| 68 | current_column = tabwidth |
| 69 | |
| 70 | pos += 1 # After the tab or newline. |
| 71 | |
| 72 | # Process remaining chars (no more tabs or newlines). |
| 73 | current_column += len(s) - pos |
| 74 | # Avoid divmod(-1, linewidth). |
| 75 | if current_column > 0: |
| 76 | linecount += (current_column - 1) // linewidth |
| 77 | else: |
| 78 | # Text ended with newline; don't count an extra line after it. |
| 79 | linecount -= 1 |
| 80 | |
| 81 | return linecount |
| 82 | |
| 83 | |
| 84 | class ExpandingButton(tk.Button): |
searching dependent graphs…