Spaces:
Paused
Paused
| import sys | |
| import textwrap | |
| import unicodedata | |
| from itertools import groupby | |
| east_asian_widths = { | |
| 'W': 2, # Wide | |
| 'F': 2, # Full-width (wide) | |
| 'Na': 1, # Narrow | |
| 'H': 1, # Half-width (narrow) | |
| 'N': 1, # Neutral (not East Asian, treated as narrow) | |
| 'A': 1 # Ambiguous (s/b wide in East Asian context, narrow otherwise, but that doesn't work) | |
| } | |
| def column_width(text): | |
| if isinstance(text, str) and sys.version_info < (3,0): | |
| return len(text) | |
| combining_correction = sum([-1 for c in text if unicodedata.combining(c)]) | |
| try: | |
| width = sum([east_asian_widths[unicodedata.east_asian_width(c)] for c in text]) | |
| except AttributeError: | |
| width = len(text) | |
| return width + combining_correction | |
| class TextWrapper(textwrap.TextWrapper): | |
| def _wrap_chunks(self, chunks): | |
| lines = [] | |
| chunks.reverse() | |
| while chunks: | |
| cur_line = [] | |
| cur_len = 0 | |
| if lines: | |
| indent = self.subsequent_indent | |
| else: | |
| indent = self.initial_indent | |
| width = self.width - column_width(indent) | |
| if self.drop_whitespace and chunks[-1].strip() == '' and lines: | |
| del chunks[-1] | |
| while chunks: | |
| l = column_width(chunks[-1]) | |
| if cur_len + l <= width: | |
| cur_line.append(chunks.pop()) | |
| cur_len += l | |
| else: | |
| break | |
| if chunks and column_width(chunks[-1]) > width: | |
| self._handle_long_word(chunks, cur_line, cur_len, width) | |
| if self.drop_whitespace and cur_line and cur_line[-1].strip() == '': | |
| del cur_line[-1] | |
| if cur_line: | |
| lines.append(indent + ''.join(cur_line)) | |
| return lines | |
| def _break_word(self, word, space_left): | |
| total = 0 | |
| for i,c in enumerate(word): | |
| total += column_width(c) | |
| if total > space_left: | |
| return word[:i-1], word[i-1:] | |
| return word, '' | |
| def _split(self, text): | |
| split = lambda t: textwrap.TextWrapper._split(self, t) | |
| chunks = [] | |
| for chunk in split(text): | |
| for w, g in groupby(chunk, column_width): | |
| if w == 1: | |
| chunks.extend(split(''.join(g))) | |
| else: | |
| chunks.extend(list(g)) | |
| return chunks | |
| def _handle_long_word(self, reversed_chunks, cur_line, cur_len, width): | |
| space_left = max(width - cur_len, 1) | |
| if self.break_long_words: | |
| l, r = self._break_word(reversed_chunks[-1], space_left) | |
| cur_line.append(l) | |
| reversed_chunks[-1] = r | |
| elif not cur_line: | |
| cur_line.append(reversed_chunks.pop()) | |
| def fw_wrap(text,width=50): | |
| w = TextWrapper(width=width) | |
| return w.wrap(text) |