From 2580160759629c7b270fb2193670a76b8a9f916d Mon Sep 17 00:00:00 2001 From: Jakob Scheid Date: Mon, 9 Feb 2026 14:38:30 +0100 Subject: [PATCH] neue Datei: README.md neue Datei: pyproject.toml neue Datei: src/text-table/__init__.py neue Datei: src/text-table/_core.py --- README.md | 15 ++++ pyproject.toml | 9 +++ src/text-table/__init__.py | 8 ++ src/text-table/_core.py | 155 +++++++++++++++++++++++++++++++++++++ 4 files changed, 187 insertions(+) create mode 100644 README.md create mode 100644 pyproject.toml create mode 100644 src/text-table/__init__.py create mode 100644 src/text-table/_core.py diff --git a/README.md b/README.md new file mode 100644 index 0000000..36920be --- /dev/null +++ b/README.md @@ -0,0 +1,15 @@ +# Text table + +A simple library for creating text tables. + +## Installation +You can install the library using pip: + +```bash +pip install text-table --index-url https://jcloud-services.ddns.net/simple/ +``` + +## Usage +- `table`: The function which creates a text table from the params. +- `TableBorderCharset`: A class for the charset of a table border. +- `BORDER_THIN`, `BORDER_THICK`, `BORDER_DOUBLE`, `BORDER_ROUND`: Prepared border charsets. \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..54bb250 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,9 @@ +[build-system] +requires = ["setuptools"] +build-backend = "setuptools.build_meta" + +[project] +name = "text_table" +version = "0.1.1" +description = "A simple library for creating text tables." +readme = "README.md" \ No newline at end of file diff --git a/src/text-table/__init__.py b/src/text-table/__init__.py new file mode 100644 index 0000000..10e3801 --- /dev/null +++ b/src/text-table/__init__.py @@ -0,0 +1,8 @@ +''' +A simple library for creating text tables. +''' + +from ._core import * +from ._core import __all__ as _core_all + +__all__ = _core_all[:] \ No newline at end of file diff --git a/src/text-table/_core.py b/src/text-table/_core.py new file mode 100644 index 0000000..e935f9e --- /dev/null +++ b/src/text-table/_core.py @@ -0,0 +1,155 @@ +__all__ = [ + 'TableBorderCharset', + 'BORDER_THIN', + 'BORDER_THICK', + 'BORDER_DOUBLE', + 'BORDER_ROUND', + 'table', +] + + +class TableBorderCharset: + def __init__(self, + corner_top_left: str, corner_top_right: str, corner_bottom_left: str, corner_bottom_right: str, + line_horizontal: str, line_vertical: str, + t_junction_horizontal_top: str, t_junction_horizontal_bottom: str, t_junction_vertical_left: str, t_junction_vertical_right: str, + intersection: str + ): + ''' + Charset for a table border. + + :param corner_top_left: Character for top left corners + :type corner_top_left: str + :param corner_top_right: Character for top right corners + :type corner_top_right: str + :param corner_bottom_left: Character for bottom left corners + :type corner_bottom_left: str + :param corner_bottom_right: Character for bottom right corners + :type corner_bottom_right: str + :param line_horizontal: Character for horizontal lines + :type line_horizontal: str + :param line_vertical: Character for vertical lines + :type line_vertical: str + :param t_junction_horizontal_top: Character for horizontal T junctions facing upwards + :type t_junction_horizontal_top: str + :param t_junction_horizontal_bottom: Character for horizontal T junctions facing downwards + :type t_junction_horizontal_bottom: str + :param t_junction_vertical_left: Character for vertical T junctions facing left + :type t_junction_vertical_left: str + :param t_junction_vertical_right: Character for vertical T junctions facing right + :type t_junction_vertical_right: str + :param intersection: Character for intersections + :type intersection: str + ''' + self.corner_top_left = corner_top_left + self.corner_top_right = corner_top_right + self.corner_bottom_left = corner_bottom_left + self.corner_bottom_right = corner_bottom_right + self.line_horizontal = line_horizontal + self.line_vertical = line_vertical + self.t_junction_horizontal_top = t_junction_horizontal_top + self.t_junction_horizontal_bottom = t_junction_horizontal_bottom + self.t_junction_vertical_left = t_junction_vertical_left + self.t_junction_vertical_right = t_junction_vertical_right + self.intersection = intersection + +BORDER_THIN = TableBorderCharset( + '┌', '┐', '└', '┘', + '─', '│', + '┴', '┬', '┤', '├', + '┼' +) + +BORDER_THICK = TableBorderCharset( + '┏', '┓', '┗', '┛', + '━', '┃', + '┻', '┳', '┫', '┣', + '╋' +) + +BORDER_DOUBLE = TableBorderCharset( + '╔', '╗', '╚', '╝', + '═', '║', + '╩', '╦', '╣', '╠', + '╬' +) + +BORDER_ROUND = TableBorderCharset( + '╭', '╮', '╰', '╯', + '─', '│', + '┴', '┬', '┤', '├', + '┼' +) + +def _get_max_widths(data: dict) -> dict: + max_widths = {} + for row in data: + for col in row: + max_widths[col] = max(len(str(row[col])), max_widths.get(col, 0)) + return max_widths + +def table(data: dict, *, borders: bool = False, border_charset: TableBorderCharset = BORDER_THIN, column_space: int = 1, uppercase_column_headers: bool = True) -> str: + ''' + Creates a text table. + + :param data: The data. + :type data: dict + :param borders: If True, the table will have borders, otherwise it will not have any borders. + :type borders: bool + :param border_charset: The charset for the borders. + :type border_charset: TableBorderCharset + :param column_space: The number of spaces between the columns. + :type column_space: int + :param uppercase_column_headers: If True, the column headers will consist of capital letters. + :type uppercase_column_headers: bool + + :return: The table. + :rtype: str + ''' + + column_widths = _get_max_widths(data) + columns = list(column_widths.keys()) + table = f'''{(column_space * ' ').join([(c.upper() if uppercase_column_headers else c) + ' ' * (column_widths[c] - len(c)) for c in columns])}''' + table = '' + for col in columns: + column_widths[col] = max(column_widths[col], len(col)) + for col in columns: + table += col.upper() if uppercase_column_headers else col + table += ' ' * (column_widths[col] - len(col)) + table += ' ' * column_space + if borders: + table += border_charset.line_vertical + ' ' + for row in data: + table += '\n' + for column in columns: + value = str(row.get(column, '')) + table += value + table += ' ' * (column_widths[column] - len(str(value))) + table += column_space * ' ' + if borders: + table += border_charset.line_vertical + ' ' + if borders: + table_without_borders = table + table_width = max([len(r) for r in table_without_borders.split('\n')]) + table = border_charset.corner_top_left + for col in columns: + table += border_charset.line_horizontal * (column_widths[col] + 2) + table += border_charset.t_junction_horizontal_bottom + table = table[:-1] + border_charset.corner_top_right + table += '\n' + for row in table_without_borders.split('\n'): + table += border_charset.line_vertical + ' ' + table += row + table += '\n' + table += border_charset.t_junction_vertical_right + for i in range(len(columns)): + table += border_charset.line_horizontal * (column_widths[columns[i]] + 2) + table += border_charset.intersection if i != (len(columns) - 1) else border_charset.t_junction_vertical_left + table += '\n' + table = '\n'.join(table.split('\n')[:-2]) + '\n' + table += border_charset.corner_bottom_left + for col in columns: + table += border_charset.line_horizontal * (column_widths[col] + 2) + table += border_charset.t_junction_horizontal_top + table = table[:-1] + border_charset.corner_bottom_right + return table \ No newline at end of file