table2ascii 1.1.2__tar.gz → 1.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {table2ascii-1.1.2/table2ascii.egg-info → table2ascii-1.2.0}/PKG-INFO +31 -6
- {table2ascii-1.1.2 → table2ascii-1.2.0}/README.md +2 -1
- {table2ascii-1.1.2 → table2ascii-1.2.0}/pyproject.toml +19 -13
- {table2ascii-1.1.2 → table2ascii-1.2.0}/table2ascii/__init__.py +1 -0
- {table2ascii-1.1.2 → table2ascii-1.2.0}/table2ascii/exceptions.py +5 -5
- {table2ascii-1.1.2 → table2ascii-1.2.0}/table2ascii/table_to_ascii.py +28 -19
- {table2ascii-1.1.2 → table2ascii-1.2.0/table2ascii.egg-info}/PKG-INFO +31 -6
- table2ascii-1.2.0/table2ascii.egg-info/requires.txt +27 -0
- {table2ascii-1.1.2 → table2ascii-1.2.0}/tests/test_convert.py +38 -0
- table2ascii-1.1.2/table2ascii.egg-info/requires.txt +0 -23
- {table2ascii-1.1.2 → table2ascii-1.2.0}/LICENSE +0 -0
- {table2ascii-1.1.2 → table2ascii-1.2.0}/setup.cfg +0 -0
- {table2ascii-1.1.2 → table2ascii-1.2.0}/setup.py +0 -0
- {table2ascii-1.1.2 → table2ascii-1.2.0}/table2ascii/alignment.py +0 -0
- {table2ascii-1.1.2 → table2ascii-1.2.0}/table2ascii/annotations.py +0 -0
- {table2ascii-1.1.2 → table2ascii-1.2.0}/table2ascii/merge.py +0 -0
- {table2ascii-1.1.2 → table2ascii-1.2.0}/table2ascii/options.py +0 -0
- {table2ascii-1.1.2 → table2ascii-1.2.0}/table2ascii/preset_style.py +0 -0
- {table2ascii-1.1.2 → table2ascii-1.2.0}/table2ascii/py.typed +0 -0
- {table2ascii-1.1.2 → table2ascii-1.2.0}/table2ascii/table_style.py +0 -0
- {table2ascii-1.1.2 → table2ascii-1.2.0}/table2ascii.egg-info/SOURCES.txt +0 -0
- {table2ascii-1.1.2 → table2ascii-1.2.0}/table2ascii.egg-info/dependency_links.txt +0 -0
- {table2ascii-1.1.2 → table2ascii-1.2.0}/table2ascii.egg-info/top_level.txt +0 -0
- {table2ascii-1.1.2 → table2ascii-1.2.0}/tests/test_alignments.py +0 -0
- {table2ascii-1.1.2 → table2ascii-1.2.0}/tests/test_cell_padding.py +0 -0
- {table2ascii-1.1.2 → table2ascii-1.2.0}/tests/test_column_widths.py +0 -0
- {table2ascii-1.1.2 → table2ascii-1.2.0}/tests/test_heading_cols.py +0 -0
- {table2ascii-1.1.2 → table2ascii-1.2.0}/tests/test_merge.py +0 -0
- {table2ascii-1.1.2 → table2ascii-1.2.0}/tests/test_styles.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: table2ascii
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.2.0
|
|
4
4
|
Summary: Convert 2D Python lists into Unicode/ASCII tables
|
|
5
5
|
Author-email: Jonah Lawrence <jonah@freshidea.com>
|
|
6
6
|
License: MIT License
|
|
@@ -41,22 +41,46 @@ Classifier: Operating System :: OS Independent
|
|
|
41
41
|
Classifier: Programming Language :: Python
|
|
42
42
|
Classifier: Programming Language :: Python :: 3
|
|
43
43
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
44
|
-
Classifier: Programming Language :: Python :: 3.7
|
|
45
44
|
Classifier: Programming Language :: Python :: 3.8
|
|
46
45
|
Classifier: Programming Language :: Python :: 3.9
|
|
47
46
|
Classifier: Programming Language :: Python :: 3.10
|
|
48
47
|
Classifier: Programming Language :: Python :: 3.11
|
|
48
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
49
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
50
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
49
51
|
Classifier: Topic :: Multimedia :: Graphics :: Presentation
|
|
50
52
|
Classifier: Topic :: Utilities
|
|
51
53
|
Classifier: Topic :: Text Processing :: General
|
|
52
54
|
Classifier: Topic :: Printing
|
|
53
55
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
54
56
|
Classifier: Typing :: Typed
|
|
55
|
-
Requires-Python: >=3.
|
|
57
|
+
Requires-Python: >=3.8
|
|
56
58
|
Description-Content-Type: text/markdown
|
|
59
|
+
License-File: LICENSE
|
|
60
|
+
Requires-Dist: wcwidth<1,>=0.5.3
|
|
57
61
|
Provides-Extra: docs
|
|
62
|
+
Requires-Dist: enum-tools; extra == "docs"
|
|
63
|
+
Requires-Dist: sphinx<5,>=4.0.0; extra == "docs"
|
|
64
|
+
Requires-Dist: sphinx-autobuild; extra == "docs"
|
|
65
|
+
Requires-Dist: sphinx-toolbox; extra == "docs"
|
|
66
|
+
Requires-Dist: sphinxcontrib_trio; extra == "docs"
|
|
67
|
+
Requires-Dist: sphinxext-opengraph; extra == "docs"
|
|
68
|
+
Requires-Dist: sphinx-book-theme==0.3.3; extra == "docs"
|
|
69
|
+
Requires-Dist: sphinxcontrib-applehelp==1.0.4; extra == "docs"
|
|
70
|
+
Requires-Dist: sphinxcontrib-devhelp==1.0.2; extra == "docs"
|
|
71
|
+
Requires-Dist: sphinxcontrib-htmlhelp==2.0.1; extra == "docs"
|
|
72
|
+
Requires-Dist: sphinxcontrib-qthelp==1.0.3; extra == "docs"
|
|
73
|
+
Requires-Dist: sphinxcontrib-serializinghtml==1.1.5; extra == "docs"
|
|
58
74
|
Provides-Extra: dev
|
|
59
|
-
|
|
75
|
+
Requires-Dist: mypy<2,>=0.982; extra == "dev"
|
|
76
|
+
Requires-Dist: pre-commit<5,>=2.0.0; extra == "dev"
|
|
77
|
+
Requires-Dist: pyright<2,>=1.0.0; extra == "dev"
|
|
78
|
+
Requires-Dist: pytest<9,>=6.0.0; extra == "dev"
|
|
79
|
+
Requires-Dist: slotscheck<1,>=0.1.0; extra == "dev"
|
|
80
|
+
Requires-Dist: taskipy<2,>=1.0.0; extra == "dev"
|
|
81
|
+
Requires-Dist: tox<5,>=3.0.0; extra == "dev"
|
|
82
|
+
Requires-Dist: setuptools>=66.1.0; python_version >= "3.12" and extra == "dev"
|
|
83
|
+
Dynamic: license-file
|
|
60
84
|
|
|
61
85
|
# table2ascii
|
|
62
86
|
|
|
@@ -74,7 +98,7 @@ Documentation and examples are available at [table2ascii.rtfd.io](https://table2
|
|
|
74
98
|
|
|
75
99
|
`pip install -U table2ascii`
|
|
76
100
|
|
|
77
|
-
**Requirements:** `Python 3.
|
|
101
|
+
**Requirements:** `Python 3.8+`
|
|
78
102
|
|
|
79
103
|
## 🧑💻 Usage
|
|
80
104
|
|
|
@@ -296,6 +320,7 @@ See the [API Reference](https://table2ascii.readthedocs.io/en/latest/api.html) f
|
|
|
296
320
|
|
|
297
321
|
- Tables display nicely whenever monospace fonts are fully supported
|
|
298
322
|
- Tables make terminal outputs look more professional
|
|
323
|
+
- Tables may contain contain terminal sequences, like colors
|
|
299
324
|
|
|
300
325
|

|
|
301
326
|
|
|
@@ -14,7 +14,7 @@ Documentation and examples are available at [table2ascii.rtfd.io](https://table2
|
|
|
14
14
|
|
|
15
15
|
`pip install -U table2ascii`
|
|
16
16
|
|
|
17
|
-
**Requirements:** `Python 3.
|
|
17
|
+
**Requirements:** `Python 3.8+`
|
|
18
18
|
|
|
19
19
|
## 🧑💻 Usage
|
|
20
20
|
|
|
@@ -236,6 +236,7 @@ See the [API Reference](https://table2ascii.readthedocs.io/en/latest/api.html) f
|
|
|
236
236
|
|
|
237
237
|
- Tables display nicely whenever monospace fonts are fully supported
|
|
238
238
|
- Tables make terminal outputs look more professional
|
|
239
|
+
- Tables may contain contain terminal sequences, like colors
|
|
239
240
|
|
|
240
241
|

|
|
241
242
|
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
[build-system]
|
|
2
|
-
requires = ["setuptools>=
|
|
2
|
+
requires = ["setuptools>=66.1.0"]
|
|
3
3
|
build-backend = "setuptools.build_meta"
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
[project]
|
|
7
7
|
name = "table2ascii"
|
|
8
|
-
version = "1.
|
|
8
|
+
version = "1.2.0"
|
|
9
9
|
authors = [{name = "Jonah Lawrence", email = "jonah@freshidea.com"}]
|
|
10
10
|
description = "Convert 2D Python lists into Unicode/ASCII tables"
|
|
11
11
|
readme = "README.md"
|
|
12
|
-
requires-python = ">=3.
|
|
12
|
+
requires-python = ">=3.8"
|
|
13
13
|
license = {file = "LICENSE"}
|
|
14
14
|
keywords = ["table", "ascii", "unicode", "formatter"]
|
|
15
15
|
classifiers = [
|
|
@@ -25,11 +25,13 @@ classifiers = [
|
|
|
25
25
|
"Programming Language :: Python",
|
|
26
26
|
"Programming Language :: Python :: 3",
|
|
27
27
|
"Programming Language :: Python :: 3 :: Only",
|
|
28
|
-
"Programming Language :: Python :: 3.7",
|
|
29
28
|
"Programming Language :: Python :: 3.8",
|
|
30
29
|
"Programming Language :: Python :: 3.9",
|
|
31
30
|
"Programming Language :: Python :: 3.10",
|
|
32
31
|
"Programming Language :: Python :: 3.11",
|
|
32
|
+
"Programming Language :: Python :: 3.12",
|
|
33
|
+
"Programming Language :: Python :: 3.13",
|
|
34
|
+
"Programming Language :: Python :: 3.14",
|
|
33
35
|
"Topic :: Multimedia :: Graphics :: Presentation",
|
|
34
36
|
"Topic :: Utilities",
|
|
35
37
|
"Topic :: Text Processing :: General",
|
|
@@ -38,29 +40,33 @@ classifiers = [
|
|
|
38
40
|
"Typing :: Typed",
|
|
39
41
|
]
|
|
40
42
|
dependencies = [
|
|
41
|
-
"
|
|
42
|
-
"importlib-metadata<5,>=1; python_version<'3.8'",
|
|
43
|
-
"wcwidth<1",
|
|
43
|
+
"wcwidth>=0.5.3,<1",
|
|
44
44
|
]
|
|
45
45
|
|
|
46
46
|
[project.optional-dependencies]
|
|
47
47
|
docs = [
|
|
48
48
|
"enum-tools",
|
|
49
|
-
"sphinx",
|
|
49
|
+
"sphinx>=4.0.0,<5",
|
|
50
50
|
"sphinx-autobuild",
|
|
51
51
|
"sphinx-toolbox",
|
|
52
52
|
"sphinxcontrib_trio",
|
|
53
53
|
"sphinxext-opengraph",
|
|
54
54
|
"sphinx-book-theme==0.3.3",
|
|
55
|
+
"sphinxcontrib-applehelp==1.0.4",
|
|
56
|
+
"sphinxcontrib-devhelp==1.0.2",
|
|
57
|
+
"sphinxcontrib-htmlhelp==2.0.1",
|
|
58
|
+
"sphinxcontrib-qthelp==1.0.3",
|
|
59
|
+
"sphinxcontrib-serializinghtml==1.1.5",
|
|
55
60
|
]
|
|
56
61
|
dev = [
|
|
57
62
|
"mypy>=0.982,<2",
|
|
58
|
-
"pre-commit>=2.0.0,<
|
|
63
|
+
"pre-commit>=2.0.0,<5",
|
|
59
64
|
"pyright>=1.0.0,<2",
|
|
60
|
-
"pytest>=6.0.0,<
|
|
65
|
+
"pytest>=6.0.0,<9",
|
|
61
66
|
"slotscheck>=0.1.0,<1",
|
|
62
67
|
"taskipy>=1.0.0,<2",
|
|
63
68
|
"tox>=3.0.0,<5",
|
|
69
|
+
"setuptools>=66.1.0; python_version>='3.12'",
|
|
64
70
|
]
|
|
65
71
|
|
|
66
72
|
[project.urls]
|
|
@@ -71,7 +77,7 @@ repository = "https://github.com/DenverCoder1/table2ascii"
|
|
|
71
77
|
|
|
72
78
|
[tool.black]
|
|
73
79
|
line-length = 100
|
|
74
|
-
target-version = ["
|
|
80
|
+
target-version = ["py38", "py39", "py310", "py311", "py312", "py313"]
|
|
75
81
|
|
|
76
82
|
|
|
77
83
|
[tool.isort]
|
|
@@ -106,7 +112,7 @@ include = [
|
|
|
106
112
|
"tests",
|
|
107
113
|
"*.py",
|
|
108
114
|
]
|
|
109
|
-
pythonVersion = "3.
|
|
115
|
+
pythonVersion = "3.8"
|
|
110
116
|
|
|
111
117
|
# https://github.com/microsoft/pyright/blob/main/docs/configuration.md
|
|
112
118
|
reportInvalidStringEscapeSequence = false
|
|
@@ -127,7 +133,7 @@ reportUnnecessaryTypeIgnoreComment = true
|
|
|
127
133
|
|
|
128
134
|
|
|
129
135
|
[tool.mypy]
|
|
130
|
-
python_version = "3.
|
|
136
|
+
python_version = "3.14"
|
|
131
137
|
namespace_packages = true
|
|
132
138
|
|
|
133
139
|
|
|
@@ -40,7 +40,7 @@ class FooterColumnCountMismatchError(ColumnCountMismatchError):
|
|
|
40
40
|
This class is a subclass of :class:`ColumnCountMismatchError`.
|
|
41
41
|
|
|
42
42
|
Attributes:
|
|
43
|
-
footer (:class:`Sequence <collections.abc.Sequence
|
|
43
|
+
footer (:class:`Sequence <collections.abc.Sequence>` [:class:`SupportsStr`]):
|
|
44
44
|
The footer that caused the error
|
|
45
45
|
expected_columns (:class:`int`): The number of columns that were expected
|
|
46
46
|
"""
|
|
@@ -64,10 +64,10 @@ class BodyColumnCountMismatchError(ColumnCountMismatchError):
|
|
|
64
64
|
This class is a subclass of :class:`ColumnCountMismatchError`.
|
|
65
65
|
|
|
66
66
|
Attributes:
|
|
67
|
-
body (:class:`Sequence <collections.abc.Sequence
|
|
67
|
+
body (:class:`Sequence <collections.abc.Sequence>` [ :class:`Sequence <collections.abc.Sequence>` [:class:`SupportsStr`]]):
|
|
68
68
|
The body that caused the error
|
|
69
69
|
expected_columns (:class:`int`): The number of columns that were expected
|
|
70
|
-
first_invalid_row (:class:`Sequence <collections.abc.Sequence
|
|
70
|
+
first_invalid_row (:class:`Sequence <collections.abc.Sequence>` [:class:`SupportsStr`]):
|
|
71
71
|
The first row with an invalid column count
|
|
72
72
|
"""
|
|
73
73
|
|
|
@@ -93,7 +93,7 @@ class AlignmentCountMismatchError(ColumnCountMismatchError):
|
|
|
93
93
|
This class is a subclass of :class:`ColumnCountMismatchError`.
|
|
94
94
|
|
|
95
95
|
Attributes:
|
|
96
|
-
alignments (:class:`Sequence <collections.abc.Sequence
|
|
96
|
+
alignments (:class:`Sequence <collections.abc.Sequence>` [:class:`Alignment`]):
|
|
97
97
|
The alignments that caused the error
|
|
98
98
|
expected_columns (:class:`int`): The number of columns that were expected
|
|
99
99
|
"""
|
|
@@ -117,7 +117,7 @@ class ColumnWidthsCountMismatchError(ColumnCountMismatchError):
|
|
|
117
117
|
This class is a subclass of :class:`ColumnCountMismatchError`.
|
|
118
118
|
|
|
119
119
|
Attributes:
|
|
120
|
-
column_widths (:class:`Sequence <collections.abc.Sequence
|
|
120
|
+
column_widths (:class:`Sequence <collections.abc.Sequence>` [:data:`Optional <typing.Optional>` [:class:`int`]]):
|
|
121
121
|
The column widths that caused the error
|
|
122
122
|
expected_columns (:class:`int`): The number of columns that were expected
|
|
123
123
|
"""
|
|
@@ -4,7 +4,7 @@ import textwrap
|
|
|
4
4
|
from math import ceil, floor
|
|
5
5
|
from collections.abc import Sequence
|
|
6
6
|
|
|
7
|
-
from wcwidth import
|
|
7
|
+
from wcwidth import width
|
|
8
8
|
|
|
9
9
|
from .alignment import Alignment
|
|
10
10
|
from .annotations import SupportsStr
|
|
@@ -130,6 +130,11 @@ class TableToAscii:
|
|
|
130
130
|
|
|
131
131
|
return list(alignments)
|
|
132
132
|
|
|
133
|
+
def __widest_line(self, value: SupportsStr) -> int:
|
|
134
|
+
"""Returns the width of the longest line in a multi-line string"""
|
|
135
|
+
text = str(value)
|
|
136
|
+
return max(self.__str_width(line) for line in text.splitlines()) if len(text) else 0
|
|
137
|
+
|
|
133
138
|
def __auto_column_widths(self) -> list[int]:
|
|
134
139
|
"""Get the minimum number of characters needed for the values in each column in the table
|
|
135
140
|
with 1 space of padding on each side.
|
|
@@ -138,18 +143,13 @@ class TableToAscii:
|
|
|
138
143
|
The minimum number of characters needed for each column
|
|
139
144
|
"""
|
|
140
145
|
|
|
141
|
-
def widest_line(value: SupportsStr) -> int:
|
|
142
|
-
"""Returns the width of the longest line in a multi-line string"""
|
|
143
|
-
text = str(value)
|
|
144
|
-
return max(self.__str_width(line) for line in text.splitlines()) if len(text) else 0
|
|
145
|
-
|
|
146
146
|
def get_column_width(row: Sequence[SupportsStr], column: int) -> int:
|
|
147
147
|
"""Get the width of a cell in a column"""
|
|
148
148
|
value = row[column]
|
|
149
149
|
next_value = row[column + 1] if column < self.__columns - 1 else None
|
|
150
150
|
if value is Merge.LEFT or next_value is Merge.LEFT:
|
|
151
151
|
return 0
|
|
152
|
-
return
|
|
152
|
+
return self.__widest_line(value)
|
|
153
153
|
|
|
154
154
|
column_widths = []
|
|
155
155
|
# get the width necessary for each column
|
|
@@ -306,7 +306,12 @@ class TableToAscii:
|
|
|
306
306
|
if row[other_col_index] is not Merge.LEFT:
|
|
307
307
|
break
|
|
308
308
|
merged_width += self.__column_widths[other_col_index] + len(column_separator)
|
|
309
|
-
cell =
|
|
309
|
+
cell = str(cell)
|
|
310
|
+
# if the text is too wide, wrap it
|
|
311
|
+
inner_cell_width = merged_width - self.__cell_padding * 2
|
|
312
|
+
if self.__widest_line(cell) > inner_cell_width:
|
|
313
|
+
cell = textwrap.fill(cell, inner_cell_width)
|
|
314
|
+
# add the wrapped cell to the row
|
|
310
315
|
wrapped_row.append(cell)
|
|
311
316
|
return wrapped_row
|
|
312
317
|
|
|
@@ -604,7 +609,8 @@ class TableToAscii:
|
|
|
604
609
|
Returns the width of the string in characters for the purposes of monospace
|
|
605
610
|
formatting. This is usually the same as the length of the string, but can be
|
|
606
611
|
different for double-width characters (East Asian Wide and East Asian Fullwidth)
|
|
607
|
-
or zero-width characters (combining characters, zero-width space, etc.)
|
|
612
|
+
or zero-width characters (combining characters, zero-width space, etc.),
|
|
613
|
+
some kinds of emoji sequences, and terminal attributes (color, etc).
|
|
608
614
|
|
|
609
615
|
Args:
|
|
610
616
|
text: The text to measure
|
|
@@ -612,9 +618,7 @@ class TableToAscii:
|
|
|
612
618
|
Returns:
|
|
613
619
|
The width of the string in characters
|
|
614
620
|
"""
|
|
615
|
-
width
|
|
616
|
-
# if use_wcwidth is False or wcswidth fails, fall back to len
|
|
617
|
-
return width if width >= 0 else len(text)
|
|
621
|
+
return width(text) if self.__use_wcwidth else len(text)
|
|
618
622
|
|
|
619
623
|
@staticmethod
|
|
620
624
|
def __is_number(text: str) -> bool:
|
|
@@ -677,20 +681,20 @@ def table2ascii(
|
|
|
677
681
|
"""Convert a 2D Python table to ASCII text
|
|
678
682
|
|
|
679
683
|
Args:
|
|
680
|
-
header (:data:`Optional <typing.Optional
|
|
684
|
+
header (:data:`Optional <typing.Optional>` [:class:`Sequence <collections.abc.Sequence>` [:class:`SupportsStr`]]):
|
|
681
685
|
List of column values in the table's header row. All values should be :class:`str`
|
|
682
686
|
or support :class:`str` conversion. If not specified, the table will not have a header row.
|
|
683
|
-
body (:data:`Optional <typing.Optional
|
|
687
|
+
body (:data:`Optional <typing.Optional>` [:class:`Sequence <collections.abc.Sequence>` [:class:`Sequence <collections.abc.Sequence>` [:class:`SupportsStr`]]]):
|
|
684
688
|
2-dimensional list of values in the table's body. All values should be :class:`str`
|
|
685
689
|
or support :class:`str` conversion. If not specified, the table will not have a body.
|
|
686
|
-
footer (:data:`Optional <typing.Optional
|
|
690
|
+
footer (:data:`Optional <typing.Optional>` [:class:`Sequence <collections.abc.Sequence>` [:class:`SupportsStr`]]):
|
|
687
691
|
List of column values in the table's footer row. All values should be :class:`str`
|
|
688
692
|
or support :class:`str` conversion. If not specified, the table will not have a footer row.
|
|
689
693
|
first_col_heading: Whether to add a header column separator after the first column.
|
|
690
694
|
Defaults to :py:obj:`False`.
|
|
691
695
|
last_col_heading: Whether to add a header column separator before the last column.
|
|
692
696
|
Defaults to :py:obj:`False`.
|
|
693
|
-
column_widths (:data:`Optional <typing.Optional
|
|
697
|
+
column_widths (:data:`Optional <typing.Optional>` [:class:`Sequence <collections.abc.Sequence>` [:data:`Optional <typing.Optional>` [:class:`int`]]]):
|
|
694
698
|
List of widths in characters for each column. Any value of :py:obj:`None`
|
|
695
699
|
indicates that the column width should be determined automatically. If :py:obj:`None`
|
|
696
700
|
is passed instead of a :class:`~collections.abc.Sequence`, all columns will be automatically
|
|
@@ -716,12 +720,17 @@ def table2ascii(
|
|
|
716
720
|
Defaults to ``1``.
|
|
717
721
|
style: Table style to use for styling (preset styles can be imported).
|
|
718
722
|
Defaults to :ref:`PresetStyle.double_thin_compact`.
|
|
719
|
-
use_wcwidth: Whether to use :func:`wcwidth.
|
|
720
|
-
:func:`len`. The :func:`~wcwidth.
|
|
723
|
+
use_wcwidth: Whether to use :func:`wcwidth.width` to determine the width of each cell instead of
|
|
724
|
+
:func:`len`. The :func:`~wcwidth.width` function takes into account double-width characters
|
|
721
725
|
(East Asian Wide and East Asian Fullwidth) and zero-width characters (combining characters,
|
|
722
|
-
zero-width space, etc.),
|
|
726
|
+
zero-width space, etc.), emoji sequences, and terminal control codes and escape
|
|
727
|
+
sequences, whereas :func:`len` determines the width solely based on the number of
|
|
723
728
|
characters in the string. Defaults to :py:obj:`True`.
|
|
724
729
|
|
|
730
|
+
.. versionchanged:: 1.2.0
|
|
731
|
+
``use_wcwidth`` now uses the :func:`wcwidth.width` function from the ``wcwidth`` package
|
|
732
|
+
instead of :func:`wcwidth.wcswidth` to better handle terminal control codes, escape sequences,
|
|
733
|
+
certain emoji sequences, and other strings with mixed-width characters.
|
|
725
734
|
.. versionadded:: 1.0.0
|
|
726
735
|
|
|
727
736
|
Returns:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: table2ascii
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.2.0
|
|
4
4
|
Summary: Convert 2D Python lists into Unicode/ASCII tables
|
|
5
5
|
Author-email: Jonah Lawrence <jonah@freshidea.com>
|
|
6
6
|
License: MIT License
|
|
@@ -41,22 +41,46 @@ Classifier: Operating System :: OS Independent
|
|
|
41
41
|
Classifier: Programming Language :: Python
|
|
42
42
|
Classifier: Programming Language :: Python :: 3
|
|
43
43
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
44
|
-
Classifier: Programming Language :: Python :: 3.7
|
|
45
44
|
Classifier: Programming Language :: Python :: 3.8
|
|
46
45
|
Classifier: Programming Language :: Python :: 3.9
|
|
47
46
|
Classifier: Programming Language :: Python :: 3.10
|
|
48
47
|
Classifier: Programming Language :: Python :: 3.11
|
|
48
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
49
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
50
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
49
51
|
Classifier: Topic :: Multimedia :: Graphics :: Presentation
|
|
50
52
|
Classifier: Topic :: Utilities
|
|
51
53
|
Classifier: Topic :: Text Processing :: General
|
|
52
54
|
Classifier: Topic :: Printing
|
|
53
55
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
54
56
|
Classifier: Typing :: Typed
|
|
55
|
-
Requires-Python: >=3.
|
|
57
|
+
Requires-Python: >=3.8
|
|
56
58
|
Description-Content-Type: text/markdown
|
|
59
|
+
License-File: LICENSE
|
|
60
|
+
Requires-Dist: wcwidth<1,>=0.5.3
|
|
57
61
|
Provides-Extra: docs
|
|
62
|
+
Requires-Dist: enum-tools; extra == "docs"
|
|
63
|
+
Requires-Dist: sphinx<5,>=4.0.0; extra == "docs"
|
|
64
|
+
Requires-Dist: sphinx-autobuild; extra == "docs"
|
|
65
|
+
Requires-Dist: sphinx-toolbox; extra == "docs"
|
|
66
|
+
Requires-Dist: sphinxcontrib_trio; extra == "docs"
|
|
67
|
+
Requires-Dist: sphinxext-opengraph; extra == "docs"
|
|
68
|
+
Requires-Dist: sphinx-book-theme==0.3.3; extra == "docs"
|
|
69
|
+
Requires-Dist: sphinxcontrib-applehelp==1.0.4; extra == "docs"
|
|
70
|
+
Requires-Dist: sphinxcontrib-devhelp==1.0.2; extra == "docs"
|
|
71
|
+
Requires-Dist: sphinxcontrib-htmlhelp==2.0.1; extra == "docs"
|
|
72
|
+
Requires-Dist: sphinxcontrib-qthelp==1.0.3; extra == "docs"
|
|
73
|
+
Requires-Dist: sphinxcontrib-serializinghtml==1.1.5; extra == "docs"
|
|
58
74
|
Provides-Extra: dev
|
|
59
|
-
|
|
75
|
+
Requires-Dist: mypy<2,>=0.982; extra == "dev"
|
|
76
|
+
Requires-Dist: pre-commit<5,>=2.0.0; extra == "dev"
|
|
77
|
+
Requires-Dist: pyright<2,>=1.0.0; extra == "dev"
|
|
78
|
+
Requires-Dist: pytest<9,>=6.0.0; extra == "dev"
|
|
79
|
+
Requires-Dist: slotscheck<1,>=0.1.0; extra == "dev"
|
|
80
|
+
Requires-Dist: taskipy<2,>=1.0.0; extra == "dev"
|
|
81
|
+
Requires-Dist: tox<5,>=3.0.0; extra == "dev"
|
|
82
|
+
Requires-Dist: setuptools>=66.1.0; python_version >= "3.12" and extra == "dev"
|
|
83
|
+
Dynamic: license-file
|
|
60
84
|
|
|
61
85
|
# table2ascii
|
|
62
86
|
|
|
@@ -74,7 +98,7 @@ Documentation and examples are available at [table2ascii.rtfd.io](https://table2
|
|
|
74
98
|
|
|
75
99
|
`pip install -U table2ascii`
|
|
76
100
|
|
|
77
|
-
**Requirements:** `Python 3.
|
|
101
|
+
**Requirements:** `Python 3.8+`
|
|
78
102
|
|
|
79
103
|
## 🧑💻 Usage
|
|
80
104
|
|
|
@@ -296,6 +320,7 @@ See the [API Reference](https://table2ascii.readthedocs.io/en/latest/api.html) f
|
|
|
296
320
|
|
|
297
321
|
- Tables display nicely whenever monospace fonts are fully supported
|
|
298
322
|
- Tables make terminal outputs look more professional
|
|
323
|
+
- Tables may contain contain terminal sequences, like colors
|
|
299
324
|
|
|
300
325
|

|
|
301
326
|
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
wcwidth<1,>=0.5.3
|
|
2
|
+
|
|
3
|
+
[dev]
|
|
4
|
+
mypy<2,>=0.982
|
|
5
|
+
pre-commit<5,>=2.0.0
|
|
6
|
+
pyright<2,>=1.0.0
|
|
7
|
+
pytest<9,>=6.0.0
|
|
8
|
+
slotscheck<1,>=0.1.0
|
|
9
|
+
taskipy<2,>=1.0.0
|
|
10
|
+
tox<5,>=3.0.0
|
|
11
|
+
|
|
12
|
+
[dev:python_version >= "3.12"]
|
|
13
|
+
setuptools>=66.1.0
|
|
14
|
+
|
|
15
|
+
[docs]
|
|
16
|
+
enum-tools
|
|
17
|
+
sphinx<5,>=4.0.0
|
|
18
|
+
sphinx-autobuild
|
|
19
|
+
sphinx-toolbox
|
|
20
|
+
sphinxcontrib_trio
|
|
21
|
+
sphinxext-opengraph
|
|
22
|
+
sphinx-book-theme==0.3.3
|
|
23
|
+
sphinxcontrib-applehelp==1.0.4
|
|
24
|
+
sphinxcontrib-devhelp==1.0.2
|
|
25
|
+
sphinxcontrib-htmlhelp==2.0.1
|
|
26
|
+
sphinxcontrib-qthelp==1.0.3
|
|
27
|
+
sphinxcontrib-serializinghtml==1.1.5
|
|
@@ -286,6 +286,25 @@ def test_east_asian_wide_characters_and_zero_width_wcwidth():
|
|
|
286
286
|
assert text2 == expected
|
|
287
287
|
|
|
288
288
|
|
|
289
|
+
def test_terminal_sequences_width_wcwidth():
|
|
290
|
+
text = t2a(
|
|
291
|
+
header=["\x1b[38;2;255;0;0mX", "Foo", None],
|
|
292
|
+
body=[[1, "Foo", None]],
|
|
293
|
+
footer=["\x1b]8;;https://example.com\x07X\x1b]8;;\x07", "Foo", None],
|
|
294
|
+
first_col_heading=True,
|
|
295
|
+
)
|
|
296
|
+
expected = (
|
|
297
|
+
"╔═══╦════════════╗\n"
|
|
298
|
+
"║ \x1b[38;2;255;0;0mX ║ Foo None ║\n"
|
|
299
|
+
"╟───╫────────────╢\n"
|
|
300
|
+
"║ 1 ║ Foo None ║\n"
|
|
301
|
+
"╟───╫────────────╢\n"
|
|
302
|
+
"║ \x1b]8;;https://example.com\x07X\x1b]8;;\x07 ║ Foo None ║\n"
|
|
303
|
+
"╚═══╩════════════╝"
|
|
304
|
+
)
|
|
305
|
+
assert text == expected
|
|
306
|
+
|
|
307
|
+
|
|
289
308
|
def test_east_asian_wide_characters_and_zero_width_no_wcwidth():
|
|
290
309
|
# using len() to count the number of characters
|
|
291
310
|
text = t2a(
|
|
@@ -305,3 +324,22 @@ def test_east_asian_wide_characters_and_zero_width_no_wcwidth():
|
|
|
305
324
|
"╚════╩═══════════════╝"
|
|
306
325
|
)
|
|
307
326
|
assert text == expected
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
def test_multiline_cells_with_wrappable_lines():
|
|
330
|
+
text = t2a(
|
|
331
|
+
header=["Test"],
|
|
332
|
+
body=[["Line One...\nSecond Line...\nLineNumThree\nLineFour\nFive FinalLine"]],
|
|
333
|
+
)
|
|
334
|
+
expected = (
|
|
335
|
+
"╔════════════════╗\n"
|
|
336
|
+
"║ Test ║\n"
|
|
337
|
+
"╟────────────────╢\n"
|
|
338
|
+
"║ Line One... ║\n"
|
|
339
|
+
"║ Second Line... ║\n"
|
|
340
|
+
"║ LineNumThree ║\n"
|
|
341
|
+
"║ LineFour ║\n"
|
|
342
|
+
"║ Five FinalLine ║\n"
|
|
343
|
+
"╚════════════════╝"
|
|
344
|
+
)
|
|
345
|
+
assert text == expected
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
wcwidth<1
|
|
2
|
-
|
|
3
|
-
[:python_version < "3.8"]
|
|
4
|
-
typing-extensions>=3.7.4
|
|
5
|
-
importlib-metadata<5,>=1
|
|
6
|
-
|
|
7
|
-
[dev]
|
|
8
|
-
mypy<2,>=0.982
|
|
9
|
-
pre-commit<4,>=2.0.0
|
|
10
|
-
pyright<2,>=1.0.0
|
|
11
|
-
pytest<8,>=6.0.0
|
|
12
|
-
slotscheck<1,>=0.1.0
|
|
13
|
-
taskipy<2,>=1.0.0
|
|
14
|
-
tox<5,>=3.0.0
|
|
15
|
-
|
|
16
|
-
[docs]
|
|
17
|
-
enum-tools
|
|
18
|
-
sphinx
|
|
19
|
-
sphinx-autobuild
|
|
20
|
-
sphinx-toolbox
|
|
21
|
-
sphinxcontrib_trio
|
|
22
|
-
sphinxext-opengraph
|
|
23
|
-
sphinx-book-theme==0.3.3
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|