# py-markdown-table
[![build](https://github.com/hvalev/py-markdown-table/actions/workflows/build.yml/badge.svg)](https://github.com/hvalev/py-markdown-table/actions/workflows/build.yml)
[![codecov](https://codecov.io/gh/hvalev/py-markdown-table/branch/main/graph/badge.svg?token=ZZ8WXO4H6P)](https://codecov.io/gh/hvalev/py-markdown-table)
[![Downloads](https://static.pepy.tech/badge/py-markdown-table)](https://pepy.tech/project/py-markdown-table)
[![Downloads](https://static.pepy.tech/badge/py-markdown-table/month)](https://pepy.tech/project/py-markdown-table)
[![Downloads](https://static.pepy.tech/badge/py-markdown-table/week)](https://pepy.tech/project/py-markdown-table)
Tiny python library with zero dependencies which generates formatted multiline tables in `markdown`.
## Basic Use
Install via pip as follows:
```bash
pip install py-markdown-table
```
Pass a `list` of `dict`s where the `dict`s must have uniform keys which serve as column headers and the values are expanded to be rows. Simple example with no special formatting:
```python
from py_markdown_table.markdown_table import markdown_table
data = [
{
"Product": "Smartphone",
"Brand": "Apple",
"Price": 999.99
},
{
"Product": "Laptop",
"Brand": "Dell",
"Price": 1299.99
}
]
markdown = markdown_table(data).get_markdown()
print(markdown)
```
```
+------------------------+
| Product |Brand| Price |
+----------+-----+-------+
|Smartphone|Apple| 999.99|
+----------+-----+-------+
| Laptop | Dell|1299.99|
+------------------------+
```
A more comprehensive example showcasing some of the formatting options:
```python
from py_markdown_table.markdown_table import markdown_table
jokes_list = [
{
"joke1": "Why don't scientists trust atoms? Because they make up everything!",
"joke2": "Did you hear about the mathematician who's afraid of negative numbers? He will stop at nothing to avoid them!",
"joke3": "Why don't skeletons fight each other? They don't have the guts!"
},
{
"joke1": "What do you call a snowman with a six-pack? An abdominal snowman!",
"joke2": "Why don't eggs tell jokes? Because they might crack up!",
"joke3": "How does a penguin build its house? Igloos it together!"
}
]
markdown = markdown_table(jokes_list).set_params(padding_width = 3,
padding_weight = 'centerleft',
multiline = {'joke1': 30, 'joke2': 30, 'joke3': 30}
).get_markdown()
```
```
+--------------------------------------------------------------------------------------------------------------+
| joke1 | joke2 | joke3 |
+------------------------------------+------------------------------------+------------------------------------+
| Why don't scientists trust atoms? | Did you hear about the | Why don't skeletons fight each |
| Because they make up everything! | mathematician who's afraid of | other? They don't have the guts! |
| | negative numbers? He will stop at | |
| | nothing to avoid them! | |
+------------------------------------+------------------------------------+------------------------------------+
| What do you call a snowman with a | Why don't eggs tell jokes? | How does a penguin build its |
| six-pack? An abdominal snowman! | Because they might crack up! | house? Igloos it together! |
+--------------------------------------------------------------------------------------------------------------+
```
You can also use pandas dataframes by formatting them as follows:
```python
from py_markdown_table.markdown_table import markdown_table
data = df.to_dict(orient='records')
markdown_table(data).get_markdown()
```
## Advanced Use
To add parameters to how the markdown table is formatted, you can use the `set_params()` function on a `markdown_table` object, i.e. `markdown_table(data).set_params(...).get_markdown()`, which allows you to pass the following keyword arguments:
```
+--------------------------------------------------------------------------------------------------+
| param | type | values | description |
+-----------------------+---------------------+-------------------+--------------------------------+
| row_sep | str | | Row separation strategy using |
| | | | `----` as pattern |
+-----------------------+---------------------+-------------------+--------------------------------+
| | | always | Separate each row |
+-----------------------+---------------------+-------------------+--------------------------------+
| | | topbottom | Separate the top (header) and |
| | | | bottom (last row) of the table |
+-----------------------+---------------------+-------------------+--------------------------------+
| | | markdown | Separate only header from body |
+-----------------------+---------------------+-------------------+--------------------------------+
| | | None | No row separators will be |
| | | | inserted |
+-----------------------+---------------------+-------------------+--------------------------------+
| padding_width | int or | | Allocate padding to all table |
| | dict<str,int> | | cells when passing an int or |
| | | | per-column when passing a dict |
+-----------------------+---------------------+-------------------+--------------------------------+
| padding_weight | str or | | Strategy for allocating |
| | dict<str,str> | | padding within table cells. |
| | | | Per-column when passing a dict |
+-----------------------+---------------------+-------------------+--------------------------------+
| | | left | Aligns the cell's contents to |
| | | | the end of the cell |
+-----------------------+---------------------+-------------------+--------------------------------+
| | | right | Aligns the cell's contents to |
| | | | the beginning of the cell |
+-----------------------+---------------------+-------------------+--------------------------------+
| | | centerleft | Centers cell's contents with |
| | | | extra padding allocated to the |
| | | | beginning of the cell |
+-----------------------+---------------------+-------------------+--------------------------------+
| | | centerright | Centers cell's contents with |
| | | | extra padding allocated to the |
| | | | end of the cell |
+-----------------------+---------------------+-------------------+--------------------------------+
| padding_char | str | | Single character used to fill |
| | | | padding with. Default is a |
| | | | blank space ` `. |
+-----------------------+---------------------+-------------------+--------------------------------+
| newline_char | str | | Character appended to each row |
| | | | to force a newline. Default is |
| | | | `\n` |
+-----------------------+---------------------+-------------------+--------------------------------+
| float_rounding | int | | Integer denoting the precision |
| | | | of cells of `floats` after the |
| | | | decimal point. Default is |
| | | | `None`. |
+-----------------------+---------------------+-------------------+--------------------------------+
| emoji_spacing | str | | Strategy for rendering emojis |
| | | | in tables. Currently only |
| | | | `mono` is supported for |
| | | | monospaced fonts. Default is |
| | | | `None` which disables special |
| | | | handling of emojis. |
+-----------------------+---------------------+-------------------+--------------------------------+
| multiline | dict<Any,int> | | Renders the table with |
| | | | predefined widths by passing a |
| | | | `dict` with `keys` being the |
| | | | column names (e.g. equivalent |
| | | | to those in the passed `data` |
| | | | variable) and `values` -- the |
| | | | `width` of each column as an |
| | | | integer. Note that the width |
| | | | of a column cannot be smaller |
| | | | than the longest contiguous |
| | | | string present in the data. |
+-----------------------+---------------------+-------------------+--------------------------------+
| multiline_strategy | str | | Strategy applied to rendering |
| | | | contents in multiple lines. |
| | | | Possible values are `rows`, |
| | | | `header` or `rows_and_header`. |
| | | | The default value is `rows`. |
+-----------------------+---------------------+-------------------+--------------------------------+
| | | rows | Splits only rows overfilling |
| | | | by the predefined column width |
| | | | as provided in the `multiline` |
| | | | variable |
+-----------------------+---------------------+-------------------+--------------------------------+
| | | header | Splits only the header |
| | | | overfilling by the predefined |
| | | | column width as provided in |
| | | | the `multiline` variable |
+-----------------------+---------------------+-------------------+--------------------------------+
| | | rows_and_header | Splits rows and header |
| | | | overfilling by the predefined |
| | | | column width as provided in |
| | | | the `multiline` variable |
+-----------------------+---------------------+-------------------+--------------------------------+
| multiline_delimiter | str | | Character that will be used to |
| | | | split a cell's contents into |
| | | | multiple rows. The default |
| | | | value is a blank space ` `. |
+-----------------------+---------------------+-------------------+--------------------------------+
| quote | bool | | Wraps the generated markdown |
| | | | table in block quotes |
| | | | ```table```. Default is |
| | | | `True`. |
+--------------------------------------------------------------------------------------------------+
```
## Utils
The namespace `py_markdown_table.utils` provides the functions `count_emojis()` and `find_longest_contiguous_strings()`. `count_emojis()` detects emojis and their position in a given string, and `find_longest_contiguous_strings()` finds the longest continuous strings present in the rows and/or columns of your input data. `find_longest_contiguous_strings()` can be useful to figure out the minimal width of each column given a particular data.
## Further Examples
### Row separatation
```python
markdown_table(data).set_params(row_sep = 'always').get_markdown()
```
<details>
<summary >
see example
</summary>
```
+----------------------------------------+
| title | time | date |seats|
+------------+-----------+---------+-----+
|Vrij Zwemmen|21:30-23:00|Wed 09.12|24/24|
+------------+-----------+---------+-----+
|Vrij Zwemmen|12:00-13:00|Thu 10.12|18/18|
+------------+-----------+---------+-----+
|Vrij zwemmen| 7:30-8:30 |Fri 11.12|18/18|
+------------+-----------+---------+-----+
|Vrij Zwemmen|13:15-14:15|Sat 12.12|18/18|
+----------------------------------------+
```
</details>
<br/>
```python
markdown_table(data).set_params(row_sep = 'topbottom').get_markdown()
```
<details>
<summary >
see example
</summary>
```
+----------------------------------------+
| title | time | date |seats|
|Vrij Zwemmen|21:30-23:00|Wed 09.12|24/24|
|Vrij Zwemmen|12:00-13:00|Thu 10.12|18/18|
|Vrij zwemmen| 7:30-8:30 |Fri 11.12|18/18|
|Vrij Zwemmen|13:15-14:15|Sat 12.12|18/18|
+----------------------------------------+
```
</details>
<br/>
```python
markdown_table(data).set_params(row_sep = 'markdown').get_markdown()
```
<details>
<summary >
see example
</summary>
```
| title | time | date |seats|
|------------|-----------|---------|-----|
|Vrij Zwemmen|21:30-23:00|Wed 09.12|24/24|
|Vrij Zwemmen|12:00-13:00|Thu 10.12|18/18|
|Vrij zwemmen| 7:30-8:30 |Fri 11.12|18/18|
|Vrij Zwemmen|13:15-14:15|Sat 12.12|18/18|
```
</details>
<br/>
```python
markdown_table(data).set_params(row_sep = 'markdown', quote = False).get_markdown()
```
<details>
<summary >
see example
</summary>
| title | time | date |seats|
|------------|-----------|---------|-----|
|Vrij Zwemmen|21:30-23:00|Wed 09.12|24/24|
|Vrij Zwemmen|12:00-13:00|Thu 10.12|18/18|
|Vrij zwemmen| 7:30-8:30 |Fri 11.12|18/18|
|Vrij Zwemmen|13:15-14:15|Sat 12.12|18/18|
</details>
<br/>
### Padding, padding weight and padding char
```python
markdown_table(data).set_params(row_sep = 'topbottom', padding_width = 5, padding_weight = 'left').get_markdown()
```
<details>
<summary >
see example
</summary>
```
+------------------------------------------------------------+
| title| time| date| seats|
| Vrij Zwemmen| 21:30-23:00| Wed 09.12| 24/24|
| Vrij Zwemmen| 12:00-13:00| Thu 10.12| 18/18|
| Vrij zwemmen| 7:30-8:30| Fri 11.12| 18/18|
| Vrij Zwemmen| 13:15-14:15| Sat 12.12| 18/18|
+------------------------------------------------------------+
```
</details>
<br/>
```python
markdown_table(data).set_params(row_sep = 'topbottom', padding_width = 5, padding_weight = 'centerright').get_markdown()
```
<details>
<summary >
see example
</summary>
```
+------------------------------------------------------------+
| title | time | date | seats |
| Vrij Zwemmen | 21:30-23:00 | Wed 09.12 | 24/24 |
| Vrij Zwemmen | 12:00-13:00 | Thu 10.12 | 18/18 |
| Vrij zwemmen | 7:30-8:30 | Fri 11.12 | 18/18 |
| Vrij Zwemmen | 13:15-14:15 | Sat 12.12 | 18/18 |
+------------------------------------------------------------+
```
</details>
<br/>
```python
markdown_table(data).set_params(row_sep = 'always', padding_width = 5, padding_weight = 'centerright', padding_char = '.').get_markdown()
```
<details>
<summary >
see example
</summary>
```
+------------------------------------------------------------+
|......title......|......time......|.....date.....|..seats...|
+-----------------+----------------+--------------+----------+
|..Vrij Zwemmen...|..21:30-23:00...|..Wed 09.12...|..24/24...|
+-----------------+----------------+--------------+----------+
|..Vrij Zwemmen...|..12:00-13:00...|..Thu 10.12...|..18/18...|
+-----------------+----------------+--------------+----------+
|..Vrij zwemmen...|...7:30-8:30....|..Fri 11.12...|..18/18...|
+-----------------+----------------+--------------+----------+
|..Vrij Zwemmen...|..13:15-14:15...|..Sat 12.12...|..18/18...|
+------------------------------------------------------------+
```
</details>
<br/>
```python
markdown_table(data).set_params(row_sep = 'always', padding_width = 5, padding_weight = 'centerright', padding_char = '.').get_markdown()
```
<details>
<summary >
see example
</summary>
```
+------------------------------------------------------------+
|......title......|......time......|.....date.....|..seats...|
+-----------------+----------------+--------------+----------+
|..Vrij Zwemmen...|..21:30-23:00...|..Wed 09.12...|..24/24...|
+-----------------+----------------+--------------+----------+
|..Vrij Zwemmen...|..12:00-13:00...|..Thu 10.12...|..18/18...|
+-----------------+----------------+--------------+----------+
|..Vrij zwemmen...|...7:30-8:30....|..Fri 11.12...|..18/18...|
+-----------------+----------------+--------------+----------+
|..Vrij Zwemmen...|..13:15-14:15...|..Sat 12.12...|..18/18...|
+------------------------------------------------------------+
```
</details>
<br/>
### Per-column padding and padding weight
```python
markdown_table(data).set_params(row_sep = 'always', padding_width = {"title": 2, "time": 4, "date": 3, "seats": 1}, padding_weight = {"title": "left", "time": "right", "date": "centerleft", "seats": "centerright"}).get_markdown()
```
<details>
<summary >
see example
</summary>
```
+--------------------------------------------------+
| title|time | date |seats |
+--------------+---------------+------------+------+
| Vrij Zwemmen|21:30-23:00 | Wed 09.12 |24/24 |
+--------------+---------------+------------+------+
| Vrij Zwemmen|12:00-13:00 | Thu 10.12 |18/18 |
+--------------+---------------+------------+------+
| Vrij Zwemmen|7:30-8:30 | Fri 11.12 |18/18 |
+--------------+---------------+------------+------+
| Vrij Zwemmen|13:15-14:15 | Sat 12.12 |18/18 |
+--------------------------------------------------+
```
</details>
<br/>
```python
markdown_table(data).set_params(row_sep = 'always', padding_width = {"A": 2, "B": 4, "C": 3}, padding_weight = {"A": "left", "B": "right", "C": "centerleft"}).get_markdown()
```
<details>
<summary >
see example
</summary>
```
+-----------------------------------------------------------------------+
| A|B | C |
+-----------------------------+-------------------------------+---------+
| row1_A and additional stuff|row1_B | row1_C |
+-----------------------------+-------------------------------+---------+
| row2_A|row2_B and additional stuff | row2_C |
+-----------------------------+-------------------------------+---------+
| row3_A|row3_B | row3_C |
+-----------------------------------------------------------------------+
```
</details>
<br/>
### Multiline and emoji
```python
markdown_table(data).set_params(padding_width = 0, padding_weight = "centerleft", multiline = {"A": 25, "B": 12, "C": 9}).get_markdown()
```
<details>
<summary >
see example
</summary>
```
+------------------------------------------------+
| A | B | C |
+-------------------------+------------+---------+
| row1_A and additional | row1_B | row1_C |
| stuff | | |
+-------------------------+------------+---------+
| row2_A | row2_B and | row2_C |
| | additional | |
| | stuff | |
+-------------------------+------------+---------+
| row3_A | row3_B | row3_C |
+------------------------------------------------+
```
</details>
<br/>
```python
markdown_table(data).set_params(padding_width = 2, padding_weight = "centerleft", multiline = {"A": 25, "B": 12, "C": 9}).get_markdown())
```
<details>
<summary >
see example
</summary>
```
+------------------------------------------------------------+
| A | B | C |
+-----------------------------+----------------+-------------+
| row1_A and additional stuff | row1_B | row1_C |
+-----------------------------+----------------+-------------+
| row2_A | row2_B and | row2_C |
| | additional | |
| | stuff | |
+-----------------------------+----------------+-------------+
| row3_A | row3_B | row3_C |
+------------------------------------------------------------+
```
</details>
<br/>
```python
markdown_table(data).set_params(row_sep = "always", multiline = {"those are multi rows": 5}, multiline_strategy = "rows_and_header").get_markdown()
```
<details>
<summary >
see example
</summary>
```
+-----+
|those|
| are |
|multi|
| rows|
+-----+
| yes |
| they|
| are |
+-----+
| no |
| they|
| are |
| not |
+-----+
```
</details>
<br/>
```python
markdown_table(data).set_params(row_sep = "topbottom", emoji_spacing = "mono", multiline = {"title that is maybe too long": 7, "time": 11, "date": 5, "seats": 5,}, multiline_strategy = "rows_and_header").get_markdown()
```
<details>
<summary >
see example
</summary>
*Note:* Github's markdown preview does not render emojis as two whole characters, hence the slight offsets in cells containing emojis.
```
+-------------------------------+
| title | time | date|seats|
|that is| | | |
| maybe | | | |
| too | | | |
| long | | | |
| Vrij |21:30-23:00| 😊 |24/24|
|Zwemmen| | | |
| Vrij |12:00-13:00| Thu |18/18|
|Zwemmen| |10.12| |
| Vrij | 7:30-8:30 | Fri | 😊 |
|Zwemmen| |11.12|🌍 🎉|
| Vrij |13:15-14:15| Sat |20/20|
|Zwemmen| |12.12| |
| Vrij | 7:30-8:30 | Fri | asd |
|Zwemmen| |11.12| 😊-|
| | | | 🌍: |
| | | | 🎉 |
|Zwemmen|13:15-14:15| Sat |20/20|
| | |12.12| |
+-------------------------------+
```
Below is an example from a monospaced terminal, where the table is rendered correctly.
![Table with emoji in terminal](res/table_w_emoji.jpg)
</details>
## Benchmarks
The table below provide some benchmark results, evaluating the performance on data containing incrementally larger number of `columns`, `rows`, and characters in each table cell (i.e. `cell_size`). You can benchmark it on your own system using the script contained within `py_markdown_table/utils/benchmark.py`. Generally, reasonably-sized tables intended to be read by a human can be generated within a millisecond.
<details>
<summary >
see benchmark
</summary>
```
+-----------------------------------------------+
| parameters |Multiline| speed |
+------------------+---------+------------------+
| columns: 2 | False | 0.000000 ms |
| rows: 10 | | |
| cell_size: 5 | | |
+------------------+---------+------------------+
| columns: 4 | False | 0.000000 ms |
| rows: 40 | | |
| cell_size: 20 | | |
+------------------+---------+------------------+
| columns: 8 | False | 6.999756 ms |
| rows: 160 | | |
| cell_size: 80 | | |
+------------------+---------+------------------+
| columns: 16 | False | 1173.794678 ms |
| rows: 640 | | |
| cell_size: 320 | | |
+------------------+---------+------------------+
| columns: 2 | True | 0.000000 ms |
| rows: 10 | | |
| cell_size: 5 | | |
+------------------+---------+------------------+
| columns: 4 | True | 0.996338 ms |
| rows: 40 | | |
| cell_size: 20 | | |
+------------------+---------+------------------+
| columns: 8 | True | 16.038330 ms |
| rows: 160 | | |
| cell_size: 80 | | |
+------------------+---------+------------------+
| columns: 16 | True | 1448.473633 ms |
| rows: 640 | | |
| cell_size: 320 | | |
+-----------------------------------------------+
```
</details>
Raw data
{
"_id": null,
"home_page": "https://github.com/hvalev/py-markdown-table",
"name": "py-markdown-table",
"maintainer": null,
"docs_url": null,
"requires_python": "<4.0,>=3.8",
"maintainer_email": null,
"keywords": null,
"author": "hvalev",
"author_email": null,
"download_url": "https://files.pythonhosted.org/packages/68/f4/c93684cc0db074ee5f9eb6a00e905f64a956d9035d9cc8cb96e837d663b5/py_markdown_table-1.2.0.tar.gz",
"platform": null,
"description": "# py-markdown-table\n[![build](https://github.com/hvalev/py-markdown-table/actions/workflows/build.yml/badge.svg)](https://github.com/hvalev/py-markdown-table/actions/workflows/build.yml)\n[![codecov](https://codecov.io/gh/hvalev/py-markdown-table/branch/main/graph/badge.svg?token=ZZ8WXO4H6P)](https://codecov.io/gh/hvalev/py-markdown-table)\n[![Downloads](https://static.pepy.tech/badge/py-markdown-table)](https://pepy.tech/project/py-markdown-table)\n[![Downloads](https://static.pepy.tech/badge/py-markdown-table/month)](https://pepy.tech/project/py-markdown-table)\n[![Downloads](https://static.pepy.tech/badge/py-markdown-table/week)](https://pepy.tech/project/py-markdown-table)\n\nTiny python library with zero dependencies which generates formatted multiline tables in `markdown`. \n\n## Basic Use\nInstall via pip as follows: \n```bash\npip install py-markdown-table\n```\n\nPass a `list` of `dict`s where the `dict`s must have uniform keys which serve as column headers and the values are expanded to be rows. Simple example with no special formatting:\n```python\nfrom py_markdown_table.markdown_table import markdown_table\ndata = [\n {\n \"Product\": \"Smartphone\",\n \"Brand\": \"Apple\",\n \"Price\": 999.99\n },\n {\n \"Product\": \"Laptop\",\n \"Brand\": \"Dell\",\n \"Price\": 1299.99\n }\n]\nmarkdown = markdown_table(data).get_markdown()\nprint(markdown)\n```\n\n```\n+------------------------+\n| Product |Brand| Price |\n+----------+-----+-------+\n|Smartphone|Apple| 999.99|\n+----------+-----+-------+\n| Laptop | Dell|1299.99|\n+------------------------+\n```\n\nA more comprehensive example showcasing some of the formatting options:\n```python\nfrom py_markdown_table.markdown_table import markdown_table\njokes_list = [\n {\n \"joke1\": \"Why don't scientists trust atoms? Because they make up everything!\",\n \"joke2\": \"Did you hear about the mathematician who's afraid of negative numbers? He will stop at nothing to avoid them!\",\n \"joke3\": \"Why don't skeletons fight each other? They don't have the guts!\"\n },\n {\n \"joke1\": \"What do you call a snowman with a six-pack? An abdominal snowman!\",\n \"joke2\": \"Why don't eggs tell jokes? Because they might crack up!\",\n \"joke3\": \"How does a penguin build its house? Igloos it together!\"\n }\n]\nmarkdown = markdown_table(jokes_list).set_params(padding_width = 3, \n padding_weight = 'centerleft', \n multiline = {'joke1': 30, 'joke2': 30, 'joke3': 30}\n ).get_markdown()\n```\n```\n+--------------------------------------------------------------------------------------------------------------+\n| joke1 | joke2 | joke3 |\n+------------------------------------+------------------------------------+------------------------------------+\n| Why don't scientists trust atoms? | Did you hear about the | Why don't skeletons fight each |\n| Because they make up everything! | mathematician who's afraid of | other? They don't have the guts! |\n| | negative numbers? He will stop at | |\n| | nothing to avoid them! | |\n+------------------------------------+------------------------------------+------------------------------------+\n| What do you call a snowman with a | Why don't eggs tell jokes? | How does a penguin build its |\n| six-pack? An abdominal snowman! | Because they might crack up! | house? Igloos it together! |\n+--------------------------------------------------------------------------------------------------------------+\n```\n\nYou can also use pandas dataframes by formatting them as follows:\n```python\nfrom py_markdown_table.markdown_table import markdown_table\ndata = df.to_dict(orient='records')\nmarkdown_table(data).get_markdown()\n```\n\n## Advanced Use\nTo add parameters to how the markdown table is formatted, you can use the `set_params()` function on a `markdown_table` object, i.e. `markdown_table(data).set_params(...).get_markdown()`, which allows you to pass the following keyword arguments:\n\n```\n+--------------------------------------------------------------------------------------------------+\n| param | type | values | description |\n+-----------------------+---------------------+-------------------+--------------------------------+\n| row_sep | str | | Row separation strategy using |\n| | | | `----` as pattern |\n+-----------------------+---------------------+-------------------+--------------------------------+\n| | | always | Separate each row |\n+-----------------------+---------------------+-------------------+--------------------------------+\n| | | topbottom | Separate the top (header) and |\n| | | | bottom (last row) of the table |\n+-----------------------+---------------------+-------------------+--------------------------------+\n| | | markdown | Separate only header from body |\n+-----------------------+---------------------+-------------------+--------------------------------+\n| | | None | No row separators will be |\n| | | | inserted |\n+-----------------------+---------------------+-------------------+--------------------------------+\n| padding_width | int or | | Allocate padding to all table |\n| | dict<str,int> | | cells when passing an int or |\n| | | | per-column when passing a dict |\n+-----------------------+---------------------+-------------------+--------------------------------+\n| padding_weight | str or | | Strategy for allocating |\n| | dict<str,str> | | padding within table cells. |\n| | | | Per-column when passing a dict |\n+-----------------------+---------------------+-------------------+--------------------------------+\n| | | left | Aligns the cell's contents to |\n| | | | the end of the cell |\n+-----------------------+---------------------+-------------------+--------------------------------+\n| | | right | Aligns the cell's contents to |\n| | | | the beginning of the cell |\n+-----------------------+---------------------+-------------------+--------------------------------+\n| | | centerleft | Centers cell's contents with |\n| | | | extra padding allocated to the |\n| | | | beginning of the cell |\n+-----------------------+---------------------+-------------------+--------------------------------+\n| | | centerright | Centers cell's contents with |\n| | | | extra padding allocated to the |\n| | | | end of the cell |\n+-----------------------+---------------------+-------------------+--------------------------------+\n| padding_char | str | | Single character used to fill |\n| | | | padding with. Default is a |\n| | | | blank space ` `. |\n+-----------------------+---------------------+-------------------+--------------------------------+\n| newline_char | str | | Character appended to each row |\n| | | | to force a newline. Default is |\n| | | | `\\n` |\n+-----------------------+---------------------+-------------------+--------------------------------+\n| float_rounding | int | | Integer denoting the precision |\n| | | | of cells of `floats` after the |\n| | | | decimal point. Default is |\n| | | | `None`. |\n+-----------------------+---------------------+-------------------+--------------------------------+\n| emoji_spacing | str | | Strategy for rendering emojis |\n| | | | in tables. Currently only |\n| | | | `mono` is supported for |\n| | | | monospaced fonts. Default is |\n| | | | `None` which disables special |\n| | | | handling of emojis. |\n+-----------------------+---------------------+-------------------+--------------------------------+\n| multiline | dict<Any,int> | | Renders the table with |\n| | | | predefined widths by passing a |\n| | | | `dict` with `keys` being the |\n| | | | column names (e.g. equivalent |\n| | | | to those in the passed `data` |\n| | | | variable) and `values` -- the |\n| | | | `width` of each column as an |\n| | | | integer. Note that the width |\n| | | | of a column cannot be smaller |\n| | | | than the longest contiguous |\n| | | | string present in the data. |\n+-----------------------+---------------------+-------------------+--------------------------------+\n| multiline_strategy | str | | Strategy applied to rendering |\n| | | | contents in multiple lines. |\n| | | | Possible values are `rows`, |\n| | | | `header` or `rows_and_header`. |\n| | | | The default value is `rows`. |\n+-----------------------+---------------------+-------------------+--------------------------------+\n| | | rows | Splits only rows overfilling |\n| | | | by the predefined column width |\n| | | | as provided in the `multiline` |\n| | | | variable |\n+-----------------------+---------------------+-------------------+--------------------------------+\n| | | header | Splits only the header |\n| | | | overfilling by the predefined |\n| | | | column width as provided in |\n| | | | the `multiline` variable |\n+-----------------------+---------------------+-------------------+--------------------------------+\n| | | rows_and_header | Splits rows and header |\n| | | | overfilling by the predefined |\n| | | | column width as provided in |\n| | | | the `multiline` variable |\n+-----------------------+---------------------+-------------------+--------------------------------+\n| multiline_delimiter | str | | Character that will be used to |\n| | | | split a cell's contents into |\n| | | | multiple rows. The default |\n| | | | value is a blank space ` `. |\n+-----------------------+---------------------+-------------------+--------------------------------+\n| quote | bool | | Wraps the generated markdown |\n| | | | table in block quotes |\n| | | | ```table```. Default is |\n| | | | `True`. |\n+--------------------------------------------------------------------------------------------------+\n```\n## Utils\nThe namespace `py_markdown_table.utils` provides the functions `count_emojis()` and `find_longest_contiguous_strings()`. `count_emojis()` detects emojis and their position in a given string, and `find_longest_contiguous_strings()` finds the longest continuous strings present in the rows and/or columns of your input data. `find_longest_contiguous_strings()` can be useful to figure out the minimal width of each column given a particular data.\n\n## Further Examples\n### Row separatation\n```python\nmarkdown_table(data).set_params(row_sep = 'always').get_markdown()\n```\n<details>\n <summary >\n see example\n </summary>\n\n```\n+----------------------------------------+\n| title | time | date |seats|\n+------------+-----------+---------+-----+\n|Vrij Zwemmen|21:30-23:00|Wed 09.12|24/24|\n+------------+-----------+---------+-----+\n|Vrij Zwemmen|12:00-13:00|Thu 10.12|18/18|\n+------------+-----------+---------+-----+\n|Vrij zwemmen| 7:30-8:30 |Fri 11.12|18/18|\n+------------+-----------+---------+-----+\n|Vrij Zwemmen|13:15-14:15|Sat 12.12|18/18|\n+----------------------------------------+\n```\n</details>\n<br/>\n\n```python\nmarkdown_table(data).set_params(row_sep = 'topbottom').get_markdown()\n```\n<details>\n <summary >\n see example\n </summary>\n\n```\n+----------------------------------------+\n| title | time | date |seats|\n|Vrij Zwemmen|21:30-23:00|Wed 09.12|24/24|\n|Vrij Zwemmen|12:00-13:00|Thu 10.12|18/18|\n|Vrij zwemmen| 7:30-8:30 |Fri 11.12|18/18|\n|Vrij Zwemmen|13:15-14:15|Sat 12.12|18/18|\n+----------------------------------------+\n```\n</details>\n<br/>\n\n```python\nmarkdown_table(data).set_params(row_sep = 'markdown').get_markdown()\n```\n<details>\n <summary >\n see example\n </summary>\n\n```\n| title | time | date |seats|\n|------------|-----------|---------|-----|\n|Vrij Zwemmen|21:30-23:00|Wed 09.12|24/24|\n|Vrij Zwemmen|12:00-13:00|Thu 10.12|18/18|\n|Vrij zwemmen| 7:30-8:30 |Fri 11.12|18/18|\n|Vrij Zwemmen|13:15-14:15|Sat 12.12|18/18|\n```\n</details>\n<br/>\n\n\n```python\nmarkdown_table(data).set_params(row_sep = 'markdown', quote = False).get_markdown()\n```\n<details>\n <summary >\n see example\n </summary>\n\n| title | time | date |seats|\n|------------|-----------|---------|-----|\n|Vrij Zwemmen|21:30-23:00|Wed 09.12|24/24|\n|Vrij Zwemmen|12:00-13:00|Thu 10.12|18/18|\n|Vrij zwemmen| 7:30-8:30 |Fri 11.12|18/18|\n|Vrij Zwemmen|13:15-14:15|Sat 12.12|18/18|\n</details>\n<br/>\n\n\n### Padding, padding weight and padding char\n```python\nmarkdown_table(data).set_params(row_sep = 'topbottom', padding_width = 5, padding_weight = 'left').get_markdown()\n```\n<details>\n <summary >\n see example\n </summary>\n\n```\n+------------------------------------------------------------+\n| title| time| date| seats|\n| Vrij Zwemmen| 21:30-23:00| Wed 09.12| 24/24|\n| Vrij Zwemmen| 12:00-13:00| Thu 10.12| 18/18|\n| Vrij zwemmen| 7:30-8:30| Fri 11.12| 18/18|\n| Vrij Zwemmen| 13:15-14:15| Sat 12.12| 18/18|\n+------------------------------------------------------------+\n```\n</details>\n<br/>\n\n\n```python\nmarkdown_table(data).set_params(row_sep = 'topbottom', padding_width = 5, padding_weight = 'centerright').get_markdown()\n```\n<details>\n <summary >\n see example\n </summary>\n\n```\n+------------------------------------------------------------+\n| title | time | date | seats |\n| Vrij Zwemmen | 21:30-23:00 | Wed 09.12 | 24/24 |\n| Vrij Zwemmen | 12:00-13:00 | Thu 10.12 | 18/18 |\n| Vrij zwemmen | 7:30-8:30 | Fri 11.12 | 18/18 |\n| Vrij Zwemmen | 13:15-14:15 | Sat 12.12 | 18/18 |\n+------------------------------------------------------------+\n```\n</details>\n<br/>\n\n\n```python\nmarkdown_table(data).set_params(row_sep = 'always', padding_width = 5, padding_weight = 'centerright', padding_char = '.').get_markdown()\n```\n<details>\n <summary >\n see example\n </summary>\n\n```\n+------------------------------------------------------------+\n|......title......|......time......|.....date.....|..seats...|\n+-----------------+----------------+--------------+----------+\n|..Vrij Zwemmen...|..21:30-23:00...|..Wed 09.12...|..24/24...|\n+-----------------+----------------+--------------+----------+\n|..Vrij Zwemmen...|..12:00-13:00...|..Thu 10.12...|..18/18...|\n+-----------------+----------------+--------------+----------+\n|..Vrij zwemmen...|...7:30-8:30....|..Fri 11.12...|..18/18...|\n+-----------------+----------------+--------------+----------+\n|..Vrij Zwemmen...|..13:15-14:15...|..Sat 12.12...|..18/18...|\n+------------------------------------------------------------+\n```\n</details>\n<br/>\n\n```python\nmarkdown_table(data).set_params(row_sep = 'always', padding_width = 5, padding_weight = 'centerright', padding_char = '.').get_markdown()\n```\n<details>\n <summary >\n see example\n </summary>\n\n```\n+------------------------------------------------------------+\n|......title......|......time......|.....date.....|..seats...|\n+-----------------+----------------+--------------+----------+\n|..Vrij Zwemmen...|..21:30-23:00...|..Wed 09.12...|..24/24...|\n+-----------------+----------------+--------------+----------+\n|..Vrij Zwemmen...|..12:00-13:00...|..Thu 10.12...|..18/18...|\n+-----------------+----------------+--------------+----------+\n|..Vrij zwemmen...|...7:30-8:30....|..Fri 11.12...|..18/18...|\n+-----------------+----------------+--------------+----------+\n|..Vrij Zwemmen...|..13:15-14:15...|..Sat 12.12...|..18/18...|\n+------------------------------------------------------------+\n```\n</details>\n<br/>\n\n### Per-column padding and padding weight\n```python\nmarkdown_table(data).set_params(row_sep = 'always', padding_width = {\"title\": 2, \"time\": 4, \"date\": 3, \"seats\": 1}, padding_weight = {\"title\": \"left\", \"time\": \"right\", \"date\": \"centerleft\", \"seats\": \"centerright\"}).get_markdown()\n\n```\n<details>\n <summary >\n see example\n </summary>\n\n```\n+--------------------------------------------------+\n| title|time | date |seats |\n+--------------+---------------+------------+------+\n| Vrij Zwemmen|21:30-23:00 | Wed 09.12 |24/24 |\n+--------------+---------------+------------+------+\n| Vrij Zwemmen|12:00-13:00 | Thu 10.12 |18/18 |\n+--------------+---------------+------------+------+\n| Vrij Zwemmen|7:30-8:30 | Fri 11.12 |18/18 |\n+--------------+---------------+------------+------+\n| Vrij Zwemmen|13:15-14:15 | Sat 12.12 |18/18 |\n+--------------------------------------------------+\n```\n</details>\n<br/>\n\n\n```python\nmarkdown_table(data).set_params(row_sep = 'always', padding_width = {\"A\": 2, \"B\": 4, \"C\": 3}, padding_weight = {\"A\": \"left\", \"B\": \"right\", \"C\": \"centerleft\"}).get_markdown()\n```\n<details>\n <summary >\n see example\n </summary>\n\n```\n+-----------------------------------------------------------------------+\n| A|B | C |\n+-----------------------------+-------------------------------+---------+\n| row1_A and additional stuff|row1_B | row1_C |\n+-----------------------------+-------------------------------+---------+\n| row2_A|row2_B and additional stuff | row2_C |\n+-----------------------------+-------------------------------+---------+\n| row3_A|row3_B | row3_C |\n+-----------------------------------------------------------------------+\n```\n</details>\n<br/>\n\n### Multiline and emoji\n```python\nmarkdown_table(data).set_params(padding_width = 0, padding_weight = \"centerleft\", multiline = {\"A\": 25, \"B\": 12, \"C\": 9}).get_markdown()\n```\n<details>\n <summary >\n see example\n </summary>\n\n```\n+------------------------------------------------+\n| A | B | C |\n+-------------------------+------------+---------+\n| row1_A and additional | row1_B | row1_C |\n| stuff | | |\n+-------------------------+------------+---------+\n| row2_A | row2_B and | row2_C |\n| | additional | |\n| | stuff | |\n+-------------------------+------------+---------+\n| row3_A | row3_B | row3_C |\n+------------------------------------------------+\n```\n</details>\n<br/>\n\n\n```python\nmarkdown_table(data).set_params(padding_width = 2, padding_weight = \"centerleft\", multiline = {\"A\": 25, \"B\": 12, \"C\": 9}).get_markdown())\n```\n<details>\n <summary >\n see example\n </summary>\n\n```\n+------------------------------------------------------------+\n| A | B | C |\n+-----------------------------+----------------+-------------+\n| row1_A and additional stuff | row1_B | row1_C |\n+-----------------------------+----------------+-------------+\n| row2_A | row2_B and | row2_C |\n| | additional | |\n| | stuff | |\n+-----------------------------+----------------+-------------+\n| row3_A | row3_B | row3_C |\n+------------------------------------------------------------+\n```\n</details>\n<br/>\n\n\n```python\nmarkdown_table(data).set_params(row_sep = \"always\", multiline = {\"those are multi rows\": 5}, multiline_strategy = \"rows_and_header\").get_markdown()\n```\n<details>\n <summary >\n see example\n </summary>\n\n```\n+-----+\n|those|\n| are |\n|multi|\n| rows|\n+-----+\n| yes |\n| they|\n| are |\n+-----+\n| no |\n| they|\n| are |\n| not |\n+-----+\n```\n</details>\n<br/>\n\n\n```python\nmarkdown_table(data).set_params(row_sep = \"topbottom\", emoji_spacing = \"mono\", multiline = {\"title that is maybe too long\": 7, \"time\": 11, \"date\": 5, \"seats\": 5,}, multiline_strategy = \"rows_and_header\").get_markdown()\n```\n<details>\n <summary >\n see example\n </summary>\n*Note:* Github's markdown preview does not render emojis as two whole characters, hence the slight offsets in cells containing emojis. \n\n```\n+-------------------------------+\n| title | time | date|seats|\n|that is| | | |\n| maybe | | | |\n| too | | | |\n| long | | | |\n| Vrij |21:30-23:00| \ud83d\ude0a |24/24|\n|Zwemmen| | | |\n| Vrij |12:00-13:00| Thu |18/18|\n|Zwemmen| |10.12| |\n| Vrij | 7:30-8:30 | Fri | \ud83d\ude0a |\n|Zwemmen| |11.12|\ud83c\udf0d \ud83c\udf89|\n| Vrij |13:15-14:15| Sat |20/20|\n|Zwemmen| |12.12| |\n| Vrij | 7:30-8:30 | Fri | asd |\n|Zwemmen| |11.12| \ud83d\ude0a-|\n| | | | \ud83c\udf0d: |\n| | | | \ud83c\udf89 |\n|Zwemmen|13:15-14:15| Sat |20/20|\n| | |12.12| |\n+-------------------------------+\n```\n\nBelow is an example from a monospaced terminal, where the table is rendered correctly.\n\n![Table with emoji in terminal](res/table_w_emoji.jpg)\n</details>\n\n\n## Benchmarks\nThe table below provide some benchmark results, evaluating the performance on data containing incrementally larger number of `columns`, `rows`, and characters in each table cell (i.e. `cell_size`). You can benchmark it on your own system using the script contained within `py_markdown_table/utils/benchmark.py`. Generally, reasonably-sized tables intended to be read by a human can be generated within a millisecond. \n\n<details>\n <summary >\n see benchmark\n </summary>\n\n```\n+-----------------------------------------------+\n| parameters |Multiline| speed |\n+------------------+---------+------------------+\n| columns: 2 | False | 0.000000 ms |\n| rows: 10 | | |\n| cell_size: 5 | | |\n+------------------+---------+------------------+\n| columns: 4 | False | 0.000000 ms |\n| rows: 40 | | |\n| cell_size: 20 | | |\n+------------------+---------+------------------+\n| columns: 8 | False | 6.999756 ms |\n| rows: 160 | | |\n| cell_size: 80 | | |\n+------------------+---------+------------------+\n| columns: 16 | False | 1173.794678 ms |\n| rows: 640 | | |\n| cell_size: 320 | | |\n+------------------+---------+------------------+\n| columns: 2 | True | 0.000000 ms |\n| rows: 10 | | |\n| cell_size: 5 | | |\n+------------------+---------+------------------+\n| columns: 4 | True | 0.996338 ms |\n| rows: 40 | | |\n| cell_size: 20 | | |\n+------------------+---------+------------------+\n| columns: 8 | True | 16.038330 ms |\n| rows: 160 | | |\n| cell_size: 80 | | |\n+------------------+---------+------------------+\n| columns: 16 | True | 1448.473633 ms |\n| rows: 640 | | |\n| cell_size: 320 | | |\n+-----------------------------------------------+\n```\n</details>\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Package that generates markdown tables from a list of dicts",
"version": "1.2.0",
"project_urls": {
"Homepage": "https://github.com/hvalev/py-markdown-table"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "d8e799010346d9dec761d830b9faefa05ae45059a89f766d127ae849cb53d19c",
"md5": "b1f790c260b991b02e0f9904daf98815",
"sha256": "6965a0dd616af3cd1e4284af22027d251186308a3eaf5a16e25054acb30b4d56"
},
"downloads": -1,
"filename": "py_markdown_table-1.2.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "b1f790c260b991b02e0f9904daf98815",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4.0,>=3.8",
"size": 13289,
"upload_time": "2024-11-13T12:24:30",
"upload_time_iso_8601": "2024-11-13T12:24:30.197754Z",
"url": "https://files.pythonhosted.org/packages/d8/e7/99010346d9dec761d830b9faefa05ae45059a89f766d127ae849cb53d19c/py_markdown_table-1.2.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "68f4c93684cc0db074ee5f9eb6a00e905f64a956d9035d9cc8cb96e837d663b5",
"md5": "dca1f8701780c6d43baedfbf62dab421",
"sha256": "bae30ca97dbbe144ffa6189796c8bed64595ea4caa4d42379e1158dd8d26c873"
},
"downloads": -1,
"filename": "py_markdown_table-1.2.0.tar.gz",
"has_sig": false,
"md5_digest": "dca1f8701780c6d43baedfbf62dab421",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4.0,>=3.8",
"size": 15854,
"upload_time": "2024-11-13T12:24:31",
"upload_time_iso_8601": "2024-11-13T12:24:31.737723Z",
"url": "https://files.pythonhosted.org/packages/68/f4/c93684cc0db074ee5f9eb6a00e905f64a956d9035d9cc8cb96e837d663b5/py_markdown_table-1.2.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-11-13 12:24:31",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "hvalev",
"github_project": "py-markdown-table",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "py-markdown-table"
}