From 0ae67432ff0814939fb13de4f14b3a352267d777 Mon Sep 17 00:00:00 2001 From: Marius Gedminas Date: Thu, 29 Mar 2018 11:39:05 +0300 Subject: [PATCH 1/2] Pad centered colored text consistently Fixes #55. --- terminaltables/width_and_alignment.py | 11 +++++++---- .../test_align_and_pad_cell.py | 3 +++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/terminaltables/width_and_alignment.py b/terminaltables/width_and_alignment.py index 057e800f..0ec1a6cf 100644 --- a/terminaltables/width_and_alignment.py +++ b/terminaltables/width_and_alignment.py @@ -70,13 +70,16 @@ def align_and_pad_cell(string, align, inner_dimensions, padding, space=' '): # Horizontally align and pad. for i, line in enumerate(lines): - new_width = inner_dimensions[0] + len(line) - visible_width(line) + lpad, rpad = padding[:2] + extra_padding = inner_dimensions[0] - visible_width(line) if 'right' in align: - lines[i] = line.rjust(padding[0] + new_width, space) + (space * padding[1]) + lpad += extra_padding elif 'center' in align: - lines[i] = (space * padding[0]) + line.center(new_width, space) + (space * padding[1]) + lpad += extra_padding // 2 + rpad += (extra_padding + 1) // 2 else: - lines[i] = (space * padding[0]) + line.ljust(new_width + padding[1], space) + rpad += extra_padding + lines[i] = (space * lpad) + line + (space * rpad) return lines diff --git a/tests/test_width_and_alignment/test_align_and_pad_cell.py b/tests/test_width_and_alignment/test_align_and_pad_cell.py index e0a928e7..aa8bd275 100644 --- a/tests/test_width_and_alignment/test_align_and_pad_cell.py +++ b/tests/test_width_and_alignment/test_align_and_pad_cell.py @@ -74,6 +74,9 @@ ('蓝色', 'center', 6, [' 蓝色 ']), (u'שלום', 'center', 6, [u' \u05e9\u05dc\u05d5\u05dd ']), (u'معرب', 'center', 6, [u' \u0645\u0639\u0631\u0628 ']), + + ('00:00', 'center', 8, [' 00:00 ']), + (colored('00:00', 'blue'), 'center', 8, [' \x1b[34m00:00\x1b[0m ']), ]) def test_width(string, align, width, expected): """Test width and horizontal alignment. From c00687feecf8e1956fa2415a5d7d6714f4308c99 Mon Sep 17 00:00:00 2001 From: Marius Gedminas Date: Thu, 29 Mar 2018 17:28:41 +0300 Subject: [PATCH 2/2] Replicate Python's str.center() logic precisely CPython's str.center() does unicode_center_impl(PyObject *self, Py_ssize_t width, Py_UCS4 fillchar) { Py_ssize_t marg, left; ... marg = width - PyUnicode_GET_LENGTH(self); left = marg / 2 + (marg & width & 1); return pad(self, left, marg - left, fillchar); } Here we have inner_dimensions[0] instead of width and extra_padding instead of marg. --- terminaltables/width_and_alignment.py | 6 ++++-- tests/test_width_and_alignment/test_align_and_pad_cell.py | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/terminaltables/width_and_alignment.py b/terminaltables/width_and_alignment.py index 0ec1a6cf..cba2b346 100644 --- a/terminaltables/width_and_alignment.py +++ b/terminaltables/width_and_alignment.py @@ -75,8 +75,10 @@ def align_and_pad_cell(string, align, inner_dimensions, padding, space=' '): if 'right' in align: lpad += extra_padding elif 'center' in align: - lpad += extra_padding // 2 - rpad += (extra_padding + 1) // 2 + # Replicate Python's str.center() logic, but using visible_width() instead of len(). + left = extra_padding // 2 + (extra_padding & inner_dimensions[0] & 1) + lpad += left + rpad += extra_padding - left else: rpad += extra_padding lines[i] = (space * lpad) + line + (space * rpad) diff --git a/tests/test_width_and_alignment/test_align_and_pad_cell.py b/tests/test_width_and_alignment/test_align_and_pad_cell.py index aa8bd275..4a058953 100644 --- a/tests/test_width_and_alignment/test_align_and_pad_cell.py +++ b/tests/test_width_and_alignment/test_align_and_pad_cell.py @@ -75,6 +75,8 @@ (u'שלום', 'center', 6, [u' \u05e9\u05dc\u05d5\u05dd ']), (u'معرب', 'center', 6, [u' \u0645\u0639\u0631\u0628 ']), + ('0000', 'center', 7, [' 0000 ']), + (colored('0000', 'blue'), 'center', 7, [' \x1b[34m0000\x1b[0m ']), ('00:00', 'center', 8, [' 00:00 ']), (colored('00:00', 'blue'), 'center', 8, [' \x1b[34m00:00\x1b[0m ']), ])