Skip to content
This repository has been archived by the owner on Mar 31, 2024. It is now read-only.

Commit

Permalink
Merge pull request #147 from wkentaro/fix-max-width-for-colored-text
Browse files Browse the repository at this point in the history
Fix wrong line width calculation in max_width for colored text
  • Loading branch information
jpiper committed Aug 25, 2015
2 parents fa79d0d + d0a5237 commit a47ed4f
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 8 deletions.
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,4 @@ Patches and Suggestions
- Eric Anderson
- Joshua Richardson
- Brandon Liu <thenovices>
- Kentaro Wada <www.kentaro.wada@gmail.com>
32 changes: 24 additions & 8 deletions clint/textui/formatters.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,27 @@ def min_width(string, cols, padding=' '):


def max_width(string, cols, separator='\n'):
"""Returns a freshly formatted """
"""Returns a freshly formatted
:param string: string to be formatted
:type string: basestring or clint.textui.colorred.ColoredString
:param cols: max width the text to be formatted
:type cols: int
:param separator: separator to break rows
:type separator: basestring
>>> formatters.max_width('123 5678', 8)
'123 5678'
>>> formatters.max_width('123 5678', 7)
'123 \n5678'
"""

is_color = isinstance(string, ColoredString)

if is_color:
offset = 10
string_copy = string._new('')
else:
offset = 0

string = string.s

stack = tsplit(string, NEWLINES)

for i, substring in enumerate(stack):
Expand All @@ -56,31 +67,36 @@ def max_width(string, cols, separator='\n'):
_row_i = 0

for word in row:
if (len(_row[_row_i]) + len(word)) < (cols + offset):
if (len(_row[_row_i]) + len(word)) <= cols:
_row[_row_i] += word
_row[_row_i] += ' '

elif len(word) > (cols - offset):
elif len(word) > cols:

# ensure empty row
if len(_row[_row_i]):
_row[_row_i] = _row[_row_i].rstrip()
_row.append('')
_row_i += 1

chunks = schunk(word, (cols + offset))
chunks = schunk(word, cols)
for i, chunk in enumerate(chunks):
if not (i + 1) == len(chunks):
_row[_row_i] += chunk
_row[_row_i] = _row[_row_i].rstrip()
_row.append('')
_row_i += 1
else:
_row[_row_i] += chunk
_row[_row_i] += ' '
else:
_row[_row_i] = _row[_row_i].rstrip()
_row.append('')
_row_i += 1
_row[_row_i] += word
_row[_row_i] += ' '
else:
_row[_row_i] = _row[_row_i].rstrip()

_row = map(str, _row)
_stack.append(separator.join(_row))
Expand Down
25 changes: 25 additions & 0 deletions test_clint.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,30 @@ def test_clint_force_color_env_var(self):
assert new_str.always_color == True


class TextuiFormatterTestCase(unittest.TestCase):

def test_max_width(self):

def _test_n_rows_width(ins, rows, n_rows, max_width):
ins.assertEqual(len(rows), n_rows)
for row in rows:
ins.assertLessEqual(len(row), max_width)

from clint.textui.formatters import max_width
from clint.textui import colored
# normal text
text = ' '.join(['XXX'] * 3)
rows = max_width(text, 6).split('\n')
_test_n_rows_width(self, rows, 3, 6)
rows = max_width(text, 7).split('\n')
_test_n_rows_width(self, rows, 2, 7)
# colored text
c_text = colored.yellow(text)
rows = max_width(c_text, 6).split('\n')
_test_n_rows_width(self, rows, 3, 6)
rows = max_width(c_text, 7).split('\n')
_test_n_rows_width(self, rows, 2, 7)


if __name__ == '__main__':
unittest.main()

0 comments on commit a47ed4f

Please sign in to comment.