diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..65c5ca8 --- /dev/null +++ b/LICENSE @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/PKG-INFO b/PKG-INFO index 53bff59..a3079ad 100644 --- a/PKG-INFO +++ b/PKG-INFO @@ -1,12 +1,12 @@ -Metadata-Version: 1.1 +Metadata-Version: 1.0 Name: texttable -Version: 0.8.1 +Version: 0.8.4 Summary: module for creating simple ASCII tables -Home-page: http://foutaise.org/code/ +Home-page: https://github.com/foutaise/texttable/ Author: Gerome Fournier Author-email: jef(at)foutaise.org License: LGPL -Download-URL: http://foutaise.org/code/texttable/texttable-0.8.1.tar.gz +Download-URL: https://github.com/foutaise/texttable/archive/v0.8.4.tar.gz Description: texttable is a module to generate a formatted text table, using ASCII characters. Platform: any diff --git a/README.md b/README.md new file mode 100644 index 0000000..0d9895e --- /dev/null +++ b/README.md @@ -0,0 +1,223 @@ +# texttable + +Python module for creating simple ASCII tables + +## Availability + +This module is available on [PypI](https://pypi.python.org/pypi/texttable/0.8.4), and has been packaged for several Linux/Unix platforms +([Debian](https://packages.debian.org/search?&searchon=names&keywords=python-texttable+), +[FreeBSD](https://www.freebsd.org/cgi/ports.cgi?query=texttable&stype=all), Fedora, Suse...). + +## Documentation + +``` +NAME + texttable - module for creating simple ASCII tables + +FILE + /usr/lib/python2.3/site-packages/texttable.py + +DESCRIPTION + + Example: + + table = Texttable() + table.set_cols_align(["l", "r", "c"]) + table.set_cols_valign(["t", "m", "b"]) + table.add_rows([["Name", "Age", "Nickname"], + ["Mr\nXavier\nHuon", 32, "Xav'"], + ["Mr\nBaptiste\nClement", 1, "Baby"]]) + print table.draw() + "\n" + + table = Texttable() + table.set_deco(Texttable.HEADER) + table.set_cols_dtype(['t', # text + 'f', # float (decimal) + 'e', # float (exponent) + 'i', # integer + 'a']) # automatic + table.set_cols_align(["l", "r", "r", "r", "l"]) + table.add_rows([["text", "float", "exp", "int", "auto"], + ["abcd", "67", 654, 89, 128.001], + ["efghijk", 67.5434, .654, 89.6, 12800000000000000000000.00023], + ["lmn", 5e-78, 5e-78, 89.4, .000000000000128], + ["opqrstu", .023, 5e+78, 92., 12800000000000000000000]]) + print table.draw() + + Result: + + +----------+-----+----------+ + | Name | Age | Nickname | + +==========+=====+==========+ + | Mr | | | + | Xavier | 32 | | + | Huon | | Xav' | + +----------+-----+----------+ + | Mr | | | + | Baptiste | 1 | | + | Clement | | Baby | + +----------+-----+----------+ + + text float exp int auto + =========================================== + abcd 67.000 6.540e+02 89 128.001 + efgh 67.543 6.540e-01 90 1.280e+22 + ijkl 0.000 5.000e-78 89 0.000 + mnop 0.023 5.000e+78 92 1.280e+22 + +CLASSES + class Texttable + | Methods defined here: + | + | __init__(self, max_width=80) + | Constructor + | + | - max_width is an integer, specifying the maximum width of the table + | - if set to 0, size is unlimited, therefore cells won't be wrapped + | + | add_row(self, array) + | Add a row in the rows stack + | + | - cells can contain newlines and tabs + | + | add_rows(self, rows, header=True) + | Add several rows in the rows stack + | + | - The 'rows' argument can be either an iterator returning arrays, + | or a by-dimensional array + | - 'header' specifies if the first row should be used as the header + | of the table + | + | draw(self) + | Draw the table + | + | - the table is returned as a whole string + | + | header(self, array) + | Specify the header of the table + | + | reset(self) + | Reset the instance + | + | - reset rows and header + | + | set_chars(self, array) + | Set the characters used to draw lines between rows and columns + | + | - the array should contain 4 fields: + | + | [horizontal, vertical, corner, header] + | + | - default is set to: + | + | ['-', '|', '+', '='] + | + | set_cols_align(self, array) + | Set the desired columns alignment + | + | - the elements of the array should be either "l", "c" or "r": + | + | * "l": column flushed left + | * "c": column centered + | * "r": column flushed right + | + | set_cols_dtype(self, array) + | Set the desired columns datatype for the cols. + | + | - the elements of the array should be either "a", "t", "f", "e" or "i": + | + | * "a": automatic (try to use the most appropriate datatype) + | * "t": treat as text + | * "f": treat as float in decimal format + | * "e": treat as float in exponential format + | * "i": treat as int + | + | - by default, automatic datatyping is used for each column + | + | set_cols_valign(self, array) + | Set the desired columns vertical alignment + | + | - the elements of the array should be either "t", "m" or "b": + | + | * "t": column aligned on the top of the cell + | * "m": column aligned on the middle of the cell + | * "b": column aligned on the bottom of the cell + | + | set_cols_width(self, array) + | Set the desired columns width + | + | - the elements of the array should be integers, specifying the + | width of each column. For example: + | + | [10, 20, 5] + | + | set_deco(self, deco) + | Set the table decoration + | + | - 'deco' can be a combinaison of: + | + | Texttable.BORDER: Border around the table + | Texttable.HEADER: Horizontal line below the header + | Texttable.HLINES: Horizontal lines between rows + | Texttable.VLINES: Vertical lines between columns + | + | All of them are enabled by default + | + | - example: + | + | Texttable.BORDER | Texttable.HEADER + | + | set_precision(self, width) + | Set the desired precision for float/exponential formats + | + | - width must be an integer >= 0 + | + | - default value is set to 3 + | + | ---------------------------------------------------------------------- + | Data and other attributes defined here: + | + | BORDER = 1 + | + | HEADER = 2 + | + | HLINES = 4 + | + | VLINES = 8 + +DATA + __all__ = ['Texttable', 'ArraySizeError'] + __author__ = 'Gerome Fournier ' + __credits__ = 'Jeff Kowalczyk:\n - textwrap improved import\n ...:\... + __license__ = 'LGPL' + __version__ = '0.8.4' + +VERSION + 0.8.4 + +AUTHOR + Gerome Fournier + +CREDITS + Jeff Kowalczyk: + - textwrap improved import + - comment concerning header output + + Anonymous: + - add_rows method, for adding rows in one go + + Sergey Simonenko: + - redefined len() function to deal with non-ASCII characters + + Roger Lew: + - columns datatype specifications + + Brian Peterson: + - better handling of unicode errors + + Frank Sachsenheim: + - add Python 2/3-compatibility + + Maximilian Hils: + - fix minor bug for Python 3 compatibility +``` diff --git a/setup.py b/setup.py index c6fa645..eb8c9e3 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # # texttable - module for creating simple ASCII tables -# Copyright (C) 2003-2011 Gerome Fournier +# Copyright (C) 2003-2015 Gerome Fournier # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -33,11 +33,11 @@ if sys.version < '2.2.3': setup( name = "texttable", - version = "0.8.1", + version = "0.8.4", author = "Gerome Fournier", author_email = "jef(at)foutaise.org", - url = "http://foutaise.org/code/", - download_url = "http://foutaise.org/code/texttable/texttable-0.8.1.tar.gz", + url = "https://github.com/foutaise/texttable/", + download_url = "https://github.com/foutaise/texttable/archive/v0.8.4.tar.gz", license = "LGPL", py_modules = ["texttable"], description = DESCRIPTION, diff --git a/texttable.py b/texttable.py index ece839a..775a43e 100644 --- a/texttable.py +++ b/texttable.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # # texttable - module for creating simple ASCII tables -# Copyright (C) 2003-2011 Gerome Fournier +# Copyright (C) 2003-2015 Gerome Fournier # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -15,7 +15,7 @@ # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA """module for creating simple ASCII tables @@ -25,9 +25,9 @@ Example: table = Texttable() table.set_cols_align(["l", "r", "c"]) table.set_cols_valign(["t", "m", "b"]) - table.add_rows([ ["Name", "Age", "Nickname"], - ["Mr\\nXavier\\nHuon", 32, "Xav'"], - ["Mr\\nBaptiste\\nClement", 1, "Baby"] ]) + table.add_rows([["Name", "Age", "Nickname"], + ["Mr\\nXavier\\nHuon", 32, "Xav'"], + ["Mr\\nBaptiste\\nClement", 1, "Baby"]]) print table.draw() + "\\n" table = Texttable() @@ -71,7 +71,7 @@ __all__ = ["Texttable", "ArraySizeError"] __author__ = 'Gerome Fournier ' __license__ = 'LGPL' -__version__ = '0.8.1' +__version__ = '0.8.4' __credits__ = """\ Jeff Kowalczyk: - textwrap improved import @@ -88,6 +88,12 @@ Roger Lew: Brian Peterson: - better handling of unicode errors + +Frank Sachsenheim: + - add Python 2/3-compatibility + +Maximilian Hils: + - fix minor bug for Python 3 compatibility """ import sys @@ -104,10 +110,8 @@ except ImportError: sys.stderr.write("Can't import textwrap module!\n") raise -try: - True, False -except NameError: - (True, False) = (1, 0) +if sys.version >= '2.7': + from functools import reduce def len(iterable): """Redefining len here so it will be able to work with non-ASCII characters @@ -116,10 +120,14 @@ def len(iterable): return iterable.__len__() try: - return len(unicode(iterable, 'utf')) + if sys.version >= '3.0': + return len(str) + else: + return len(unicode(iterable, 'utf')) except: return iterable.__len__() + class ArraySizeError(Exception): """Exception raised when specified rows don't fit the required size """ @@ -131,6 +139,7 @@ class ArraySizeError(Exception): def __str__(self): return self.msg + class Texttable: BORDER = 1 @@ -179,7 +188,7 @@ class Texttable: """ if len(array) != 4: - raise ArraySizeError, "array should contain 4 characters" + raise ArraySizeError("array should contain 4 characters") array = [ x[:1] for x in [ str(s) for s in array ] ] (self._char_horiz, self._char_vert, self._char_corner, self._char_header) = array @@ -257,7 +266,7 @@ class Texttable: self._check_row_size(array) try: - array = map(int, array) + array = list(map(int, array)) if reduce(min, array) <= 0: raise ValueError except ValueError: @@ -282,7 +291,7 @@ class Texttable: """ self._check_row_size(array) - self._header = map(str, array) + self._header = list(map(str, array)) def add_row(self, array): """Add a row in the rows stack @@ -296,8 +305,8 @@ class Texttable: self._dtype = ["a"] * self._row_size cells = [] - for i,x in enumerate(array): - cells.append(self._str(i,x)) + for i, x in enumerate(array): + cells.append(self._str(i, x)) self._rows.append(cells) def add_rows(self, rows, header=True): @@ -388,8 +397,8 @@ class Texttable: if not self._row_size: self._row_size = len(array) elif self._row_size != len(array): - raise ArraySizeError, "array should contain %d elements" \ - % self._row_size + raise ArraySizeError("array should contain %d elements" \ + % self._row_size) def _has_vlines(self): """Return a boolean, if vlines are required or not @@ -440,7 +449,7 @@ class Texttable: s = "%s%s%s" % (horiz, [horiz, self._char_corner][self._has_vlines()], horiz) # build the line - l = string.join([horiz * n for n in self._width], s) + l = s.join([horiz * n for n in self._width]) # add border if needed if self._has_border(): l = "%s%s%s%s%s\n" % (self._char_corner, horiz, l, horiz, @@ -461,10 +470,10 @@ class Texttable: for line in cell_lines: length = 0 parts = line.split('\t') - for part, i in zip(parts, range(1, len(parts) + 1)): + for part, i in zip(parts, list(range(1, len(parts) + 1))): length = length + len(part) if i < len(parts): - length = (length/8 + 1) * 8 + length = (length//8 + 1) * 8 maxi = max(maxi, length) return maxi @@ -482,16 +491,16 @@ class Texttable: if self._header: maxi = [ self._len_cell(x) for x in self._header ] for row in self._rows: - for cell,i in zip(row, range(len(row))): + for cell,i in zip(row, list(range(len(row)))): try: maxi[i] = max(maxi[i], self._len_cell(cell)) except (TypeError, IndexError): maxi.append(self._len_cell(cell)) items = len(maxi) - length = reduce(lambda x,y: x+y, maxi) + length = reduce(lambda x, y: x+y, maxi) if self._max_width and length + items * 3 + 1 > self._max_width: - maxi = [(self._max_width - items * 3 -1) / items \ - for n in range(items)] + maxi = [(self._max_width - items * 3 -1) // items \ + for n in range(items)] self._width = maxi def _check_align(self): @@ -511,7 +520,7 @@ class Texttable: line = self._splitit(line, isheader) space = " " - out = "" + out = "" for i in range(len(line[0])): if self._has_border(): out += "%s " % self._char_vert @@ -525,8 +534,8 @@ class Texttable: if align == "r": out += "%s " % (fill * space + cell_line) elif align == "c": - out += "%s " % (fill/2 * space + cell_line \ - + (fill/2 + fill%2) * space) + out += "%s " % (int(fill/2) * space + cell_line \ + + int(fill/2 + fill%2) * space) else: out += "%s " % (cell_line + fill * space) if length < len(line): @@ -546,34 +555,41 @@ class Texttable: array = [] for c in cell.split('\n'): try: - c = unicode(c, 'utf') - except UnicodeDecodeError, strerror: + if sys.version >= '3.0': + c = str(c) + else: + c = unicode(c, 'utf') + except UnicodeDecodeError as strerror: sys.stderr.write("UnicodeDecodeError exception for string '%s': %s\n" % (c, strerror)) - c = unicode(c, 'utf', 'replace') + if sys.version >= '3.0': + c = str(c, 'utf', 'replace') + else: + c = unicode(c, 'utf', 'replace') array.extend(textwrap.wrap(c, width)) line_wrapped.append(array) - max_cell_lines = reduce(max, map(len, line_wrapped)) + max_cell_lines = reduce(max, list(map(len, line_wrapped))) for cell, valign in zip(line_wrapped, self._valign): if isheader: valign = "t" if valign == "m": missing = max_cell_lines - len(cell) - cell[:0] = [""] * (missing / 2) - cell.extend([""] * (missing / 2 + missing % 2)) + cell[:0] = [""] * int(missing / 2) + cell.extend([""] * int(missing / 2 + missing % 2)) elif valign == "b": cell[:0] = [""] * (max_cell_lines - len(cell)) else: cell.extend([""] * (max_cell_lines - len(cell))) return line_wrapped + if __name__ == '__main__': table = Texttable() table.set_cols_align(["l", "r", "c"]) table.set_cols_valign(["t", "m", "b"]) - table.add_rows([ ["Name", "Age", "Nickname"], - ["Mr\nXavier\nHuon", 32, "Xav'"], - ["Mr\nBaptiste\nClement", 1, "Baby"] ]) - print table.draw() + "\n" + table.add_rows([["Name", "Age", "Nickname"], + ["Mr\nXavier\nHuon", 32, "Xav'"], + ["Mr\nBaptiste\nClement", 1, "Baby"]]) + print(table.draw() + "\n") table = Texttable() table.set_deco(Texttable.HEADER) @@ -588,4 +604,4 @@ if __name__ == '__main__': ["efghijk", 67.5434, .654, 89.6, 12800000000000000000000.00023], ["lmn", 5e-78, 5e-78, 89.4, .000000000000128], ["opqrstu", .023, 5e+78, 92., 12800000000000000000000]]) - print table.draw() + print(table.draw())