Skip to content

Commit 91de4cc

Browse files
authored
feat: Support for auto-sizing specific columns using None (#38)
1 parent edc2c67 commit 91de4cc

File tree

4 files changed

+49
-15
lines changed

4 files changed

+49
-15
lines changed

Diff for: table2ascii/options.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@ class Options:
1111

1212
first_col_heading: bool
1313
last_col_heading: bool
14-
column_widths: Optional[List[int]]
14+
column_widths: Optional[List[Optional[int]]]
1515
alignments: Optional[List[Alignment]]
1616
style: TableStyle

Diff for: table2ascii/table_style.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,10 @@ def from_string(cls, string: str) -> "TableStyle":
6565
Create a TableStyle from a string
6666
6767
Args:
68-
string: The string to create the TableStyle from
68+
string (:class:`str`): The string to create the TableStyle from
6969
7070
Returns:
71-
TableStyle: A TableStyle object
71+
:class:`TableStyle`: A TableStyle object
7272
7373
Example::
7474

Diff for: table2ascii/table_to_ascii.py

+24-12
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,13 @@ def __init__(
5656
for i in range(len(options.column_widths)):
5757
option = options.column_widths[i]
5858
minimum = self.__column_widths[i]
59-
if option < minimum:
59+
if option is None:
60+
option = minimum
61+
elif option < minimum:
6062
raise ValueError(
6163
f"The value at index {i} of `column_widths` is {option} which is less than the minimum {minimum}."
6264
)
63-
self.__column_widths = options.column_widths
65+
self.__column_widths[i] = option
6466

6567
self.__alignments = options.alignments or [Alignment.CENTER] * self.__columns
6668

@@ -314,25 +316,35 @@ def table2ascii(
314316
*,
315317
first_col_heading: bool = False,
316318
last_col_heading: bool = False,
317-
column_widths: Optional[List[int]] = None,
319+
column_widths: Optional[List[Optional[int]]] = None,
318320
alignments: Optional[List[Alignment]] = None,
319321
style: TableStyle = PresetStyle.double_thin_compact,
320322
) -> str:
321323
"""
322324
Convert a 2D Python table to ASCII text
323325
324326
Args:
325-
header (:class:`Optional[List[Any]]`): List of column values in the table's header row
326-
body (:class:`Optional[List[List[Any]]]`): 2-dimensional list of values in the table's body
327-
footer (:class:`Optional[List[Any]]`): List of column values in the table's footer row
328-
first_col_heading (:class:`bool`): Whether to add a header column separator after the first column
329-
last_col_heading (:class:`bool`): Whether to add a header column separator before the last column
330-
column_widths (:class:`Optional[List[int]]`): List of widths in characters for each column (``None`` for auto-sizing)
331-
alignments (:class:`List[Alignment]`): List of alignments (ex. `[Alignment.LEFT, Alignment.CENTER, Alignment.RIGHT]`)
332-
style (:class:`TableStyle`): Table style to use for styling (preset styles can be imported)
327+
header (Optional[List[Any]]): List of column values in the table's header row.
328+
If not specified, the table will not have a header row.
329+
body (Optional[List[List[Any]]]): 2-dimensional list of values in the table's body.
330+
If not specified, the table will not have a body.
331+
footer (Optional[List[Any]]): List of column values in the table's footer row.
332+
If not specified, the table will not have a footer row.
333+
first_col_heading (:class:`bool`): Whether to add a header column separator after the first
334+
column. Defaults to ``False``.
335+
last_col_heading (:class:`bool`): Whether to add a header column separator before the last
336+
column. Defaults to ``False``.
337+
column_widths (Optional[List[Optional[:class:`int`]]]): List of widths in characters for each
338+
column. Any value of ``None`` indicates that the column width should be determined automatically.
339+
If ``column_widths`` is set to ``None``, all columns will be automatically sized. Defaults to ``None``.
340+
alignments (Optional[List[:class:`Alignment`]]): List of alignments for each column
341+
(ex. ``[Alignment.LEFT, Alignment.CENTER, Alignment.RIGHT]``). If not specified or set to ``None``,
342+
all columns will be center-aligned. Defaults to ``None``.
343+
style (:class:`TableStyle`): Table style to use for styling (preset styles can be imported).
344+
Defaults to :data:`PresetStyle.double_thin_compact`.
333345
334346
Returns:
335-
str: The generated ASCII table
347+
:class:`str`: The generated ASCII table
336348
"""
337349
return TableToAscii(
338350
header,

Diff for: tests/test_column_widths.py

+22
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,28 @@ def test_column_widths_none():
4747
assert text == expected
4848

4949

50+
def test_column_widths_contains_none():
51+
text = t2a(
52+
header=["#", "G", "H", "R", "S"],
53+
body=[["1", "30", "40", "35", "30"], ["2", "30", "40", "35", "30"]],
54+
footer=["TOTL", "130", "140", "135", "130"],
55+
first_col_heading=True,
56+
last_col_heading=True,
57+
column_widths=[7, None, 5, 5, None],
58+
)
59+
expected = (
60+
"╔═══════╦═════════════════╦═════╗\n"
61+
"║ # ║ G H R ║ S ║\n"
62+
"╟───────╫─────────────────╫─────╢\n"
63+
"║ 1 ║ 30 40 35 ║ 30 ║\n"
64+
"║ 2 ║ 30 40 35 ║ 30 ║\n"
65+
"╟───────╫─────────────────╫─────╢\n"
66+
"║ TOTL ║ 130 140 135 ║ 130 ║\n"
67+
"╚═══════╩═════════════════╩═════╝"
68+
)
69+
assert text == expected
70+
71+
5072
def test_wrong_number_column_widths():
5173
with pytest.raises(ValueError):
5274
t2a(

0 commit comments

Comments
 (0)