Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/denvercoder1/table2ascii

An intuitive and type-safe Python library for converting lists to fancy ASCII tables for displaying in the terminal or code-blocks
https://github.com/denvercoder1/table2ascii

ascii discord discord-py formatter graphics hacktoberfest markdown pretty-print python terminal terminal-graphics unicode utilities utils

Last synced: about 3 hours ago
JSON representation

An intuitive and type-safe Python library for converting lists to fancy ASCII tables for displaying in the terminal or code-blocks

Awesome Lists containing this project

README

        

# table2ascii

[![build](https://img.shields.io/github/actions/workflow/status/DenverCoder1/table2ascii/python-test.yml?branch=main)](https://github.com/DenverCoder1/table2ascii/actions/workflows/python-app.yml)
[![version](https://img.shields.io/pypi/v/table2ascii)](https://pypi.org/project/table2ascii/)
[![downloads](https://static.pepy.tech/personalized-badge/table2ascii?period=total&left_color=grey&right_color=blue&left_text=downloads)](https://pepy.tech/project/table2ascii)
[![license](https://img.shields.io/pypi/l/table2ascii)](https://github.com/DenverCoder1/table2ascii/blob/main/LICENSE)
[![discord](https://img.shields.io/discord/819650821314052106?color=5865F2&logo=discord&logoColor=white "Dev Pro Tips Discussion & Support Server")](https://discord.gg/fPrdqh3Zfu)

An intuitive and type-safe library for converting 2D Python lists to fancy ASCII/Unicode tables

Documentation and examples are available at [table2ascii.rtfd.io](https://table2ascii.readthedocs.io/)

## ๐Ÿ“ฅ Installation

`pip install -U table2ascii`

**Requirements:** `Python 3.7+`

## ๐Ÿง‘โ€๐Ÿ’ป Usage

### ๐Ÿš€ Convert lists to ASCII tables

```py
from table2ascii import table2ascii

output = table2ascii(
header=["#", "G", "H", "R", "S"],
body=[["1", "30", "40", "35", "30"], ["2", "30", "40", "35", "30"]],
footer=["SUM", "130", "140", "135", "130"],
)

print(output)

"""
โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—
โ•‘ # G H R S โ•‘
โ•Ÿโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ข
โ•‘ 1 30 40 35 30 โ•‘
โ•‘ 2 30 40 35 30 โ•‘
โ•Ÿโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ข
โ•‘ SUM 130 140 135 130 โ•‘
โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
"""
```

### ๐Ÿ† Set first or last column headings

```py
from table2ascii import table2ascii

output = table2ascii(
body=[["Assignment", "30", "40", "35", "30"], ["Bonus", "10", "20", "5", "10"]],
first_col_heading=True,
)

print(output)

"""
โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ฆโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—
โ•‘ Assignment โ•‘ 30 40 35 30 โ•‘
โ•‘ Bonus โ•‘ 10 20 5 10 โ•‘
โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ฉโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
"""
```

### ๐Ÿ“ฐ Set column widths and alignments

```py
from table2ascii import table2ascii, Alignment

output = table2ascii(
header=["Product", "Category", "Price", "Rating"],
body=[
["Milk", "Dairy", "$2.99", "6.283"],
["Cheese", "Dairy", "$10.99", "8.2"],
["Apples", "Produce", "$0.99", "10.00"],
],
column_widths=[12, 12, 12, 12],
alignments=[Alignment.LEFT, Alignment.CENTER, Alignment.RIGHT, Alignment.DECIMAL],
)

print(output)

"""
โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—
โ•‘ Product Category Price Rating โ•‘
โ•Ÿโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ข
โ•‘ Milk Dairy $2.99 6.283 โ•‘
โ•‘ Cheese Dairy $10.99 8.2 โ•‘
โ•‘ Apples Produce $0.99 10.00 โ•‘
โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
"""
```

### ๐ŸŽจ Use a preset style

See a list of 30+ preset styles [here](https://table2ascii.readthedocs.io/en/latest/styles.html).

```py
from table2ascii import table2ascii, Alignment, PresetStyle

output = table2ascii(
header=["First", "Second", "Third", "Fourth"],
body=[["10", "30", "40", "35"], ["20", "10", "20", "5"]],
column_widths=[10, 10, 10, 10],
style=PresetStyle.ascii_box
)

print(output)

"""
+----------+----------+----------+----------+
| First | Second | Third | Fourth |
+----------+----------+----------+----------+
| 10 | 30 | 40 | 35 |
+----------+----------+----------+----------+
| 20 | 10 | 20 | 5 |
+----------+----------+----------+----------+
"""

output = table2ascii(
header=["First", "Second", "Third", "Fourth"],
body=[["10", "30", "40", "35"], ["20", "10", "20", "5"]],
style=PresetStyle.plain,
cell_padding=0,
alignments=Alignment.LEFT,
)

print(output)

"""
First Second Third Fourth
10 30 40 35
20 10 20 5
"""
```

### ๐ŸŽฒ Define a custom style

Check [`TableStyle`](https://github.com/DenverCoder1/table2ascii/blob/main/table2ascii/table_style.py) for more info and [`PresetStyle`](https://github.com/DenverCoder1/table2ascii/blob/main/table2ascii/preset_style.py) for examples.

```py
from table2ascii import table2ascii, TableStyle

my_style = TableStyle.from_string("*-..*||:+-+:+ *''*")

output = table2ascii(
header=["First", "Second", "Third"],
body=[["10", "30", "40"], ["20", "10", "20"], ["30", "20", "30"]],
style=my_style
)

print(output)

"""
*-------.--------.-------*
| First : Second : Third |
+-------:--------:-------+
| 10 : 30 : 40 |
| 20 : 10 : 20 |
| 30 : 20 : 30 |
*-------'--------'-------*
"""
```

### ๐Ÿช„ Merge adjacent cells

```py
from table2ascii import table2ascii, Merge, PresetStyle

output = table2ascii(
header=["#", "G", "Merge", Merge.LEFT, "S"],
body=[
[1, 5, 6, 200, Merge.LEFT],
[2, "E", "Long cell", Merge.LEFT, Merge.LEFT],
["Bonus", Merge.LEFT, Merge.LEFT, "F", "G"],
],
footer=["SUM", "100", "200", Merge.LEFT, "300"],
style=PresetStyle.double_thin_box,
first_col_heading=True,
)

print(output)

"""
โ•”โ•โ•โ•โ•โ•โ•ฆโ•โ•โ•โ•โ•โ•คโ•โ•โ•โ•โ•โ•โ•โ•คโ•โ•โ•โ•โ•โ•—
โ•‘ # โ•‘ G โ”‚ Merge โ”‚ S โ•‘
โ• โ•โ•โ•โ•โ•โ•ฌโ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•คโ•โ•โ•โ•งโ•โ•โ•โ•โ•โ•ฃ
โ•‘ 1 โ•‘ 5 โ”‚ 6 โ”‚ 200 โ•‘
โ•Ÿโ”€โ”€โ”€โ”€โ”€โ•ซโ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ข
โ•‘ 2 โ•‘ E โ”‚ Long cell โ•‘
โ•Ÿโ”€โ”€โ”€โ”€โ”€โ•จโ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ•ข
โ•‘ Bonus โ”‚ F โ”‚ G โ•‘
โ• โ•โ•โ•โ•โ•โ•ฆโ•โ•โ•โ•โ•โ•คโ•โ•โ•โ•งโ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•ฃ
โ•‘ SUM โ•‘ 100 โ”‚ 200 โ”‚ 300 โ•‘
โ•šโ•โ•โ•โ•โ•โ•ฉโ•โ•โ•โ•โ•โ•งโ•โ•โ•โ•โ•โ•โ•โ•งโ•โ•โ•โ•โ•โ•
"""
```

## โš™๏ธ Options

All parameters are optional. At least one of `header`, `body`, and `footer` must be provided.

Refer to the [documentation](https://table2ascii.readthedocs.io/en/stable/api.html#table2ascii) for more information.

| Option | Supported Types | Description |
| :-----------------: | :-----------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------: |
| `header` | `Sequence[SupportsStr]`, `None`
(Default: `None`) | First table row seperated by header row separator. Values should support `str()` |
| `body` | `Sequence[Sequence[SupportsStr]]`, `None`
(Default: `None`) | 2D List of rows for the main section of the table. Values should support `str()` |
| `footer` | `Sequence[SupportsStr]`, `None`
(Default: `None`) | Last table row seperated by header row separator. Values should support `str()` |
| `column_widths` | `Sequence[Optional[int]]`, `None`
(Default: `None` / automatic) | List of column widths in characters for each column |
| `alignments` | `Sequence[Alignment]`, `Alignment`, `None`
(Default: `None` / all centered) | Column alignments
(ex. `[Alignment.LEFT, Alignment.CENTER, Alignment.RIGHT, Alignment.DECIMAL]`) |
| `number_alignments` | `Sequence[Alignment]`, `Alignment`, `None`
(Default: `None`) | Column alignments for numeric values. `alignments` will be used if not specified. |
| `style` | `TableStyle`
(Default: `double_thin_compact`) | Table style to use for the table\* |
| `first_col_heading` | `bool`
(Default: `False`) | Whether to add a heading column separator after the first column |
| `last_col_heading` | `bool`
(Default: `False`) | Whether to add a heading column separator before the last column |
| `cell_padding` | `int`
(Default: `1`) | The minimum number of spaces to add between the cell content and the cell border |
| `use_wcwidth` | `bool`
(Default: `True`) | Whether to use [wcwidth][wcwidth] instead of `len()` to calculate cell width |

[wcwidth]: https://pypi.org/project/wcwidth/

\*See a list of all preset styles [here](https://table2ascii.readthedocs.io/en/latest/styles.html).

See the [API Reference](https://table2ascii.readthedocs.io/en/latest/api.html) for more info.

## ๐Ÿ‘จโ€๐ŸŽจ Use cases

### ๐Ÿ—จ๏ธ Discord messages and embeds

- Display tables nicely inside markdown code blocks on Discord
- Useful for making Discord bots with [Discord.py](https://github.com/Rapptz/discord.py)

![image](https://user-images.githubusercontent.com/20955511/116203248-2973c600-a744-11eb-97d8-4b75ed2845c9.png)

### ๐Ÿ’ป Terminal outputs

- Tables display nicely whenever monospace fonts are fully supported
- Tables make terminal outputs look more professional

![image](https://user-images.githubusercontent.com/20955511/207134452-a1eb1b9f-e63b-459b-8feb-fc6c234e902e.png)

## ๐Ÿค— Contributing

Contributions are welcome!

See [CONTRIBUTING.md](https://github.com/DenverCoder1/table2ascii/blob/main/CONTRIBUTING.md) for more details on how to get involved.