diff --git a/README.md b/README.md index dedbf72..6c09f0e 100644 --- a/README.md +++ b/README.md @@ -1063,6 +1063,31 @@ the lines being wrapped would probably be significantly longer than this. ``` +Text is preferably wrapped on whitespaces and right after the hyphens in hyphenated words. + +break_long_words (default: True) If true, then words longer than width will be broken in order to ensure that no lines are longer than width. +If it is false, long words will not be broken, and some lines may be longer than width. +(Long words will be put on a line by themselves, in order to minimize the amount by which width is exceeded.) + +break_on_hyphens (default: True) If true, wrapping will occur preferably on whitespaces and right after hyphens in compound words, as it is customary in English. +If false, only whitespaces will be considered as potentially good places for line breaks. + +```pycon +>>> print(tabulate([["John Smith", "Middle-Manager"]], headers=["Name", "Title"], tablefmt="grid", maxcolwidths=[None, 5], break_long_words=False)) ++------------+---------+ +| Name | Title | ++============+=========+ +| John Smith | Middle- | +| | Manager | ++------------+---------+ +>>> print(tabulate([["John Smith", "Middle-Manager"]], headers=["Name", "Title"], tablefmt="grid", maxcolwidths=[None, 5], break_long_words=False, break_on_hyphens=False)) ++------------+----------------+ +| Name | Title | ++============+================+ +| John Smith | Middle-Manager | ++------------+----------------+ +``` + ### Adding Separating lines One might want to add one or more separating lines to highlight different sections in a table. diff --git a/tabulate/__init__.py b/tabulate/__init__.py index c752259..e100c09 100644 --- a/tabulate/__init__.py +++ b/tabulate/__init__.py @@ -33,6 +33,15 @@ def _is_file(f): # minimum extra space in headers MIN_PADDING = 2 +# Whether or not to preserve leading/trailing whitespace in data. +PRESERVE_WHITESPACE = False + +# TextWrapper breaks words longer than 'width'. +_BREAK_LONG_WORDS = True +# TextWrapper is breaking hyphenated words. +_BREAK_ON_HYPHENS = True + + _DEFAULT_FLOATFMT = "g" _DEFAULT_INTFMT = "" _DEFAULT_MISSINGVAL = "" @@ -1629,7 +1638,7 @@ def _normalize_tabular_data(tabular_data, headers, showindex="default"): return rows, headers, headers_pad -def _wrap_text_to_colwidths(list_of_lists, colwidths, numparses=True): +def _wrap_text_to_colwidths(list_of_lists, colwidths, numparses=True, break_long_words=_BREAK_LONG_WORDS, break_on_hyphens=_BREAK_ON_HYPHENS): if len(list_of_lists): num_cols = len(list_of_lists[0]) else: @@ -1646,7 +1655,7 @@ def _wrap_text_to_colwidths(list_of_lists, colwidths, numparses=True): continue if width is not None: - wrapper = _CustomTextWrap(width=width) + wrapper = _CustomTextWrap(width=width, break_long_words=break_long_words, break_on_hyphens=break_on_hyphens) casted_cell = str(cell) wrapped = [ "\n".join(wrapper.wrap(line)) @@ -1705,6 +1714,8 @@ def tabulate( headersalign=None, rowalign=None, maxheadercolwidths=None, + break_long_words=_BREAK_LONG_WORDS, + break_on_hyphens=_BREAK_ON_HYPHENS, ): """Format a fixed width table for pretty printing. @@ -2247,7 +2258,7 @@ def tabulate( numparses = _expand_numparse(disable_numparse, num_cols) list_of_lists = _wrap_text_to_colwidths( - list_of_lists, maxcolwidths, numparses=numparses + list_of_lists, maxcolwidths, numparses=numparses, break_long_words=break_long_words, break_on_hyphens=break_on_hyphens ) if maxheadercolwidths is not None: @@ -2261,7 +2272,7 @@ def tabulate( numparses = _expand_numparse(disable_numparse, num_cols) headers = _wrap_text_to_colwidths( - [headers], maxheadercolwidths, numparses=numparses + [headers], maxheadercolwidths, numparses=numparses, break_long_words=break_long_words, break_on_hyphens=break_on_hyphens )[0] # empty values in the first column of RST tables should be escaped (issue #82) diff --git a/test/test_api.py b/test/test_api.py index 062573c..f35d09a 100644 --- a/test/test_api.py +++ b/test/test_api.py @@ -56,6 +56,8 @@ def test_tabulate_signature(): ("headersalign", None), ("rowalign", None), ("maxheadercolwidths", None), + ("break_long_words", True), + ("break_on_hyphens", True), ] _check_signature(tabulate, expected_sig) diff --git a/test/test_output.py b/test/test_output.py index 2a1415b..12dfc3a 100644 --- a/test/test_output.py +++ b/test/test_output.py @@ -3319,3 +3319,32 @@ def test_preserve_whitespace(): expected = "\n".join(["h1 h2 h3", "---- ---- ----", "foo bar foo"]) result = tabulate(test_table, table_headers, preserve_whitespace=False) assert_equal(expected, result) + +def test_break_long_words(): + "Output: Default table output, with breakwords true." + table_headers = ["h1", "h2", "h3"] + test_table = [[" foo1", " bar2 ", "foo3"]] + + # Table is not wrapped on 3 letters due to long word + expected = "h1 h2 h3\n---- ---- ----\nfoo1 bar2 foo3" + result = tabulate(test_table, table_headers, maxcolwidths=3, break_long_words=False) + assert_equal(expected, result) + + # Table max width is 3 letters + expected = "h1 h2 h3\n---- ---- ----\nf ba foo\noo1 r2 3" + result = tabulate(test_table, table_headers, maxcolwidths=3, break_long_words=True) + assert_equal(expected, result) + +def test_break_on_hyphens(): + "Output: Default table output, with break on hyphens true." + table_headers = ["h1", "h2", "h3"] + test_table = [[" foo-bar", " bar-bar ", "foo-foo"]] + # Table max width is 5, long lines breaks on hyphens + expected = "h1 h2 h3\n---- ---- -----\nfoo bar- foo-f\n-bar bar oo" + result = tabulate(test_table, table_headers, maxcolwidths=5, break_on_hyphens=False) + assert_equal(expected, result) + + # Table data is no longer breaks on hyphens + expected = "h1 h2 h3\n---- ---- ----\nfoo- bar- foo-\nbar bar foo" + result = tabulate(test_table, table_headers, maxcolwidths=5, break_on_hyphens=True) + assert_equal(expected, result)