Skip to content

Commit e3e4104

Browse files
committed
Additional customizations of the python textwrap.Textwrapper to address wrapping unicode characters of variable width.
Now uses wcwidth to measure words too large to fit and decreases the word shard until the wcwidth comes in below the remaining available display space. Fixes #32
1 parent f90a897 commit e3e4104

File tree

1 file changed

+39
-0
lines changed

1 file changed

+39
-0
lines changed

tableformatter.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,45 @@ def _split(self, text):
125125
chunks = [c for c in chunks if c]
126126
return chunks
127127

128+
def _handle_long_word(self, reversed_chunks, cur_line, cur_len, width):
129+
"""_handle_long_word(chunks : [string],
130+
cur_line : [string],
131+
cur_len : int, width : int)
132+
133+
Handle a chunk of text (most likely a word, not whitespace) that
134+
is too long to fit in any line.
135+
"""
136+
# Figure out when indent is larger than the specified width, and make
137+
# sure at least one character is stripped off on every pass
138+
if width < 1:
139+
space_left = 1
140+
else:
141+
space_left = width - cur_len
142+
143+
# If we're allowed to break long words, then do so: put as much
144+
# of the next chunk onto the current line as will fit.
145+
if self.break_long_words:
146+
shard_length = space_left
147+
shard = reversed_chunks[-1][:shard_length]
148+
while _wcswidth(shard) > space_left and shard_length > 0:
149+
shard_length -= 1
150+
shard = reversed_chunks[-1][:shard_length]
151+
if shard_length > 0:
152+
cur_line.append(shard)
153+
reversed_chunks[-1] = reversed_chunks[-1][shard_length:]
154+
155+
# Otherwise, we have to preserve the long word intact. Only add
156+
# it to the current line if there's nothing already there --
157+
# that minimizes how much we violate the width constraint.
158+
elif not cur_line:
159+
cur_line.append(reversed_chunks.pop())
160+
161+
# If we're not allowed to break long words, and there's already
162+
# text on the current line, do nothing. Next time through the
163+
# main loop of _wrap_chunks(), we'll wind up here again, but
164+
# cur_len will be zero, so the next line will be entirely
165+
# devoted to the long word that we can't handle right now.
166+
128167
def _wrap_chunks(self, chunks):
129168
"""_wrap_chunks(chunks : [string]) -> [string]
130169

0 commit comments

Comments
 (0)