summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Artemenko <svetlyak.40wt@gmail.com>2016-05-08 02:24:48 +0300
committerkxxoling <kxxoling@gmail.com>2016-07-13 16:06:22 +0800
commit29ed171ffdf8c5e69e4dacff7027372ac48d073c (patch)
treec206ec68e3a430076f891cf4e8ddebd63eeb8050
parent052f0c85f466e6cff1f383fcdb1e985d68929166 (diff)
downloadpython-prettytable-ptable-feature/support-wrapping-options.tar.gz
New option `wrap_opts` was added.feature/support-wrapping-options
It's value is passed as keyword arguments to `textwrap.fill` function.
-rw-r--r--CHANGELOG.md9
-rw-r--r--prettytable/prettytable.py34
-rw-r--r--tests/test_prettytable.py58
3 files changed, 95 insertions, 6 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ad7af30..8f483c4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,8 +1,13 @@
## 0.10 - Unreleased
-* Now column scaling algorithm more strictly respects "max_table_width"
+* New option `wrap_opts` was added. It's value is passed
+ as keyword arguments to `textwrap.fill` function.
+ Read `textwrap's` [documentation](https://docs.python.org/2/library/textwrap.html#textwrap.TextWrapper)
+ to figure out which options are available.
+
+* Now column scaling algorithm more strictly respects ``max_table_width``
setting.
-* Also, header's width was fixed in case when "max_table_width" was
+* Also, header's width was fixed in case when ``max_table_width`` was
given and calculated column's width lesser than this field name's
length. Now pretty table just sets minimum column width to the
width of it's name.
diff --git a/prettytable/prettytable.py b/prettytable/prettytable.py
index 290038a..8a5747b 100644
--- a/prettytable/prettytable.py
+++ b/prettytable/prettytable.py
@@ -75,6 +75,10 @@ class PrettyTable(object):
self.valign = {}
self.max_width = {}
self.min_width = {}
+ # this dict contains options for textwrap's fill function
+ # for each field, ie:
+ # name -> {opts}
+ self.wrap_opts = {}
self.int_format = {}
self.float_format = {}
if field_names:
@@ -259,6 +263,8 @@ class PrettyTable(object):
self._validate_single_char(option, val)
elif option == "attributes":
self._validate_attributes(option, val)
+ elif option == "wrap_opts":
+ self._validate_dict_format(option, val)
def _validate_field_names(self, val):
# Check for appropriate length
@@ -310,6 +316,10 @@ class PrettyTable(object):
except AssertionError:
raise Exception("Invalid value for %s! Must be True or False." % name)
+ def _validate_dict_format(self, name, val):
+ if not isinstance(val, dict):
+ raise Exception("Invalid value for %s! Must be a dict." % name)
+
def _validate_int_format(self, name, val):
if val == "":
return
@@ -515,6 +525,24 @@ class PrettyTable(object):
self._max_table_width = val
@property
+ def wrap_opts(self):
+ """Additional options for wrapping text in cells.
+
+ These options are passed as keyword arguments to the
+ textwrap.fill function.
+ """
+ return self._wrap_opts
+
+ @wrap_opts.setter
+ def wrap_opts(self, val):
+ if not val:
+ self._wrap_opts = {}
+ else:
+ self._validate_option('wrap_opts', val)
+ for field in self._field_names:
+ self._wrap_opts[field] = val
+
+ @property
def fields(self):
"""List or tuple of field names to include in displays"""
return self._fields
@@ -1312,7 +1340,11 @@ class PrettyTable(object):
new_lines = []
for line in lines:
if _str_block_width(line) > width:
- line = textwrap.fill(line, width)
+ line = textwrap.fill(
+ line,
+ width,
+ **self.wrap_opts.get(field, {})
+ )
new_lines.append(line)
lines = new_lines
value = "\n".join(lines)
diff --git a/tests/test_prettytable.py b/tests/test_prettytable.py
index 8d353a7..2a34429 100644
--- a/tests/test_prettytable.py
+++ b/tests/test_prettytable.py
@@ -435,12 +435,64 @@ class BreakLineTests(unittest.TestCase):
+------------+-------------+
""".strip()
- def testHtmlBreakLine(self):
+ def testLongLineBreak(self):
+ t = PrettyTable(['F1', 'Field 2'])
+ t.add_row(['value 1', 'this is a really long-value2 in first row'])
+ t.add_row(['value 3', 'value4'])
+ t.max_table_width = 22
+ result = t.get_string(hrules=ALL)
+ expected = """
++----+--------------+
+| F1 | Field 2 |
++----+--------------+
+| va | this is a |
+| lu | really long- |
+| e | value2 in |
+| 1 | first row |
++----+--------------+
+| va | value4 |
+| lu | |
+| e | |
+| 3 | |
++----+--------------+
+"""
+
+ import logging
+ logging.error(result.strip())
+ logging.error('expected.strip(): ')
+ logging.error(expected.strip())
+ self.assertEqual(result.strip(), expected.strip())
+
+ def testLongLineBreakReactsOnOptions(self):
+ t = PrettyTable(['F1', 'Field 2'])
+ t.add_row(['value 1', 'this is a really long-value2 in first row'])
+ t.add_row(['value 3', 'value4'])
+ t.max_table_width = 22
+ t.wrap_opts = {'break_on_hyphens': False}
+ result = t.get_string(hrules=ALL)
+ expected = """
++----+--------------+
+| F1 | Field 2 |
++----+--------------+
+| va | this is a |
+| lu | really |
+| e | long-value2 |
+| 1 | in first row |
++----+--------------+
+| va | value4 |
+| lu | |
+| e | |
+| 3 | |
++----+--------------+
+"""
+ self.assertEqual(result.strip(), expected.strip())
+
+ def testHTMLBreakLine(self):
t = PrettyTable(['Field 1', 'Field 2'])
t.add_row(['value 1', 'value2\nsecond line'])
t.add_row(['value 3', 'value4'])
result = t.get_html_string(hrules=ALL)
- assert result.strip() == """
+ self.assertEqual(result.strip(), """
<table>
<tr>
<th>Field 1</th>
@@ -455,7 +507,7 @@ class BreakLineTests(unittest.TestCase):
<td>value4</td>
</tr>
</table>
-""".strip()
+""".strip())
class MaxMaxWidthsTests(unittest.TestCase):