Spaces:
Building
Building
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) |