Properly handles ANSI escape sequences in table rows

This commit is contained in:
Niru Maheswaranathan
2016-09-29 14:50:40 -07:00
parent 476fbec098
commit 92571fb94e
3 changed files with 11 additions and 4 deletions

View File

@@ -5,6 +5,7 @@ python:
- "2.7" - "2.7"
- "3.4" - "3.4"
- "3.5" - "3.5"
- "3.6"
addons: addons:
apt: apt:
packages: packages:

View File

@@ -8,7 +8,7 @@ upload:
python setup.py sdist bdist_wininst upload python setup.py sdist bdist_wininst upload
test2: test2:
python2 /usr/local/bin/nosetests --logging-level=INFO python2 /Users/nirum/anaconda/bin/nosetests --logging-level=INFO
test: test:
nosetests -v --with-coverage --cover-package=tableprint --logging-level=INFO nosetests -v --with-coverage --cover-package=tableprint --logging-level=INFO

View File

@@ -15,10 +15,11 @@ from six import string_types
from collections import namedtuple from collections import namedtuple
from numbers import Number from numbers import Number
import sys import sys
import re
import numpy as np import numpy as np
__all__ = ['table', 'header', 'row', 'hr', 'top', 'bottom', 'banner', 'dataframe', 'humantime'] __all__ = ['table', 'header', 'row', 'hr', 'top', 'bottom', 'banner', 'dataframe', 'humantime']
__version__ = '0.4.3' __version__ = '0.5.0'
# set up table styles # set up table styles
LineStyle = namedtuple('LineStyle', ('begin', 'hline', 'sep', 'end')) LineStyle = namedtuple('LineStyle', ('begin', 'hline', 'sep', 'end'))
@@ -149,7 +150,7 @@ def row(values, width=WIDTH, format_spec=FMT, style=STYLE):
Parameters Parameters
---------- ----------
values : array_like values : array_like
An iterable array of data (numbers of strings), each value is printed in a separate column An iterable array of data (numbers or strings), each value is printed in a separate column
width : int width : int
The width of each column (Default: 11) The width of each column (Default: 11)
@@ -180,7 +181,7 @@ def row(values, width=WIDTH, format_spec=FMT, style=STYLE):
datum, prec = val datum, prec = val
if isinstance(datum, string_types): if isinstance(datum, string_types):
return ('{:>%i}' % width).format(datum) return ('{:>%i}' % (width + _ansi_len(datum))).format(datum)
elif isinstance(datum, Number): elif isinstance(datum, Number):
return ('{:>%i.%s}' % (width, prec)).format(datum) return ('{:>%i.%s}' % (width, prec)).format(datum)
@@ -318,6 +319,11 @@ def humantime(t):
return timestr return timestr
def _ansi_len(string):
"""Extra length due to any ANSI sequences in the string."""
return len(string) - len(re.compile(r'\x1b[^m]*m').sub('', string))
def _format_line(data, linestyle): def _format_line(data, linestyle):
"""Formats a list of elements using the given line style""" """Formats a list of elements using the given line style"""
return linestyle.begin + linestyle.sep.join(data) + linestyle.end return linestyle.begin + linestyle.sep.join(data) + linestyle.end