diff --git a/table2ascii/options.py b/table2ascii/options.py index 12f04dd..10ae1b2 100644 --- a/table2ascii/options.py +++ b/table2ascii/options.py @@ -11,6 +11,6 @@ class Options: first_col_heading: bool last_col_heading: bool - column_widths: Optional[List[int]] + column_widths: Optional[List[Optional[int]]] alignments: Optional[List[Alignment]] style: TableStyle diff --git a/table2ascii/table_style.py b/table2ascii/table_style.py index 0be50e2..d3c9b93 100644 --- a/table2ascii/table_style.py +++ b/table2ascii/table_style.py @@ -65,10 +65,10 @@ def from_string(cls, string: str) -> "TableStyle": Create a TableStyle from a string Args: - string: The string to create the TableStyle from + string (:class:`str`): The string to create the TableStyle from Returns: - TableStyle: A TableStyle object + :class:`TableStyle`: A TableStyle object Example:: diff --git a/table2ascii/table_to_ascii.py b/table2ascii/table_to_ascii.py index 3f77d89..51a4768 100644 --- a/table2ascii/table_to_ascii.py +++ b/table2ascii/table_to_ascii.py @@ -56,11 +56,13 @@ def __init__( for i in range(len(options.column_widths)): option = options.column_widths[i] minimum = self.__column_widths[i] - if option < minimum: + if option is None: + option = minimum + elif option < minimum: raise ValueError( f"The value at index {i} of `column_widths` is {option} which is less than the minimum {minimum}." ) - self.__column_widths = options.column_widths + self.__column_widths[i] = option self.__alignments = options.alignments or [Alignment.CENTER] * self.__columns @@ -314,7 +316,7 @@ def table2ascii( *, first_col_heading: bool = False, last_col_heading: bool = False, - column_widths: Optional[List[int]] = None, + column_widths: Optional[List[Optional[int]]] = None, alignments: Optional[List[Alignment]] = None, style: TableStyle = PresetStyle.double_thin_compact, ) -> str: @@ -322,17 +324,27 @@ def table2ascii( Convert a 2D Python table to ASCII text Args: - header (:class:`Optional[List[Any]]`): List of column values in the table's header row - body (:class:`Optional[List[List[Any]]]`): 2-dimensional list of values in the table's body - footer (:class:`Optional[List[Any]]`): List of column values in the table's footer row - first_col_heading (:class:`bool`): Whether to add a header column separator after the first column - last_col_heading (:class:`bool`): Whether to add a header column separator before the last column - column_widths (:class:`Optional[List[int]]`): List of widths in characters for each column (``None`` for auto-sizing) - alignments (:class:`List[Alignment]`): List of alignments (ex. `[Alignment.LEFT, Alignment.CENTER, Alignment.RIGHT]`) - style (:class:`TableStyle`): Table style to use for styling (preset styles can be imported) + header (Optional[List[Any]]): List of column values in the table's header row. + If not specified, the table will not have a header row. + body (Optional[List[List[Any]]]): 2-dimensional list of values in the table's body. + If not specified, the table will not have a body. + footer (Optional[List[Any]]): List of column values in the table's footer row. + If not specified, the table will not have a footer row. + first_col_heading (:class:`bool`): Whether to add a header column separator after the first + column. Defaults to ``False``. + last_col_heading (:class:`bool`): Whether to add a header column separator before the last + column. Defaults to ``False``. + column_widths (Optional[List[Optional[:class:`int`]]]): List of widths in characters for each + column. Any value of ``None`` indicates that the column width should be determined automatically. + If ``column_widths`` is set to ``None``, all columns will be automatically sized. Defaults to ``None``. + alignments (Optional[List[:class:`Alignment`]]): List of alignments for each column + (ex. ``[Alignment.LEFT, Alignment.CENTER, Alignment.RIGHT]``). If not specified or set to ``None``, + all columns will be center-aligned. Defaults to ``None``. + style (:class:`TableStyle`): Table style to use for styling (preset styles can be imported). + Defaults to :data:`PresetStyle.double_thin_compact`. Returns: - str: The generated ASCII table + :class:`str`: The generated ASCII table """ return TableToAscii( header, diff --git a/tests/test_column_widths.py b/tests/test_column_widths.py index f7b367d..60f23f9 100644 --- a/tests/test_column_widths.py +++ b/tests/test_column_widths.py @@ -47,6 +47,28 @@ def test_column_widths_none(): assert text == expected +def test_column_widths_contains_none(): + text = t2a( + header=["#", "G", "H", "R", "S"], + body=[["1", "30", "40", "35", "30"], ["2", "30", "40", "35", "30"]], + footer=["TOTL", "130", "140", "135", "130"], + first_col_heading=True, + last_col_heading=True, + column_widths=[7, None, 5, 5, None], + ) + expected = ( + "╔═══════╦═════════════════╦═════╗\n" + "║ # ║ G H R ║ S ║\n" + "╟───────╫─────────────────╫─────╢\n" + "║ 1 ║ 30 40 35 ║ 30 ║\n" + "║ 2 ║ 30 40 35 ║ 30 ║\n" + "╟───────╫─────────────────╫─────╢\n" + "║ TOTL ║ 130 140 135 ║ 130 ║\n" + "╚═══════╩═════════════════╩═════╝" + ) + assert text == expected + + def test_wrong_number_column_widths(): with pytest.raises(ValueError): t2a(