Skip to content

Commit

Permalink
new post / 2023-12-17-rendering-csv-as-markdown-table-in-mkdocs-mater…
Browse files Browse the repository at this point in the history
…ial.md
  • Loading branch information
copdips committed Dec 17, 2023
1 parent 0d172dd commit 3c8e3da
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 31 deletions.
4 changes: 0 additions & 4 deletions docs/assets/blog_data/test.md

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
---
authors:
- copdips
categories:
- web
- mkdocs
comments: true
date:
created: 2023-12-17
description: ''
---

# Rendering CSV as Markdown table in Mkdocs Material

Markdown table is not easy to write in IDE. So I want to write CSV and render it as Markdown table. Previously I used a pre-build script during CICD time to convert CSV to Markdown table. But it's not convenient to preview the result locally. So I want to find a way to render CSV as Markdown table in Mkdocs Material.

<!-- more -->
@
After I asked the [pymdown-extensions](https://github.com/facelessuser/pymdown-extensions) maintainer, he gave me some [tips](https://github.com/facelessuser/pymdown-extensions/discussions/2273#discussioncomment-7871897). A big thanks to [@facelessuser](https://github.com/facelessuser).

1. In markdown file, use code block with language `csv` to render CSV as Markdown table.

````markdown
```csv-path
my_csv_file_path.csv
```
````

2. In `mkdocs.yml`, add [custom fence](https://squidfunk.github.io/mkdocs-material/setup/extensions/python-markdown-extensions/#superfences) for `csv-path` language:

```yaml
- pymdownx.superfences:
custom_fences:
- name: csv-path
class: csv-path
format: !!python/name:tools.pymdownx_md_render.md_csv_path_render
```

3. Install additional pip dependencies:

```bash
pip install pandas, tabulate
```

4. In `tools/pymdownx_md_render.py`, add a new function `md_csv_path_render()` to handle csv code block. Check [here](https://github.com/facelessuser/pymdown-extensions/issues/2240) to see the `pymdownx_md_render.py` example.
`tablefmt="github"` is to set the alignment.

```python title="tools/pymdownx_md_render.py"
... other imports
import pandas as pd

... other functions

def md_csv_path_render(
src="",
language="",
class_name=None,
options=None, md="",
**kwargs):
"""Formatter wrapper."""
try:
df = pd.read_csv(src)
return markdown.markdown(
df.to_markdown(tablefmt="github", index=False),
extensions=["tables"])
except Exception:
import traceback

print(traceback.format_exc())
raise
```

!!! note "We can use other modules (for e.g. [csv2md](https://github.com/lzakharov/csv2md)) than [pandas](https://pandas.pydata.org/docs/index.html) as pandas is a little heavy"

```python
# no need to pip install pandas, tabulate
# instead pip install csv2md
...
from csv2md.table import Table
...
with open(src, encoding="utf-8") as f:
table = Table.parse_csv(f)
md_table = table.markdown() # (1)
return markdown.markdown(md_table, extensions=["tables"])
```

1. You can set the alignment parameters [here](https://github.com/lzakharov/csv2md/blob/938fbbbe8dce0be393ff3c0915e3fe90c129e552/csv2md/table.py#L11).

5. To build the mkdocs, must use `python -m mkdocs build` instead of `mkdocs build`. Otherwise, the local `tools` module will not be loaded.

6. Demo:

My save the csv file at: csv file at : https://github.com/copdips/copdips.github.io/blob/main/docs/assets/blog_data/test.csv

My markdown file:

````markdown
```csv-path
./docs/assets/blog_data/test.csv
```
````

Rendered result:

```csv-path
./docs/assets/blog_data/test.csv
```
8 changes: 5 additions & 3 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ site_author: Xiang ZHU
site_name: A code to remember
site_url: https://copdips.com
use_directory_urls: false
watch:
- tools

# Use main branch for code actions, default to master branch
# https://squidfunk.github.io/mkdocs-material/setup/adding-a-git-repository/?h=content+action#code-actions
Expand Down Expand Up @@ -49,9 +51,9 @@ markdown_extensions:
- name: md-render
class: md-render
format: !!python/name:tools.pymdownx_md_render.md_sub_render
- name: csv
class: csv
format: !!python/name:tools.pymdownx_md_render.md_csv_render
- name: csv-path
class: csv-path
format: !!python/name:tools.pymdownx_md_render.md_csv_path_render
- pymdownx.tilde
- pymdownx.tabbed:
alternate_style: true
Expand Down
1 change: 0 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,3 @@ mkdocstrings
mkdocstrings-python
mkdocs-video
mkdocs-glightbox
pandas
31 changes: 8 additions & 23 deletions tools/pymdownx_md_render.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import yaml
import re
from collections import OrderedDict
import pandas as pd
from csv2md.table import Table


def yaml_load(stream, loader=yaml.Loader):
Expand Down Expand Up @@ -72,31 +72,16 @@ def md_sub_render(src="", language="", class_name=None, options=None, md="", **k
raise


def md_csv_render(src="", language="", class_name=None, options=None, md="", **kwargs):
def md_csv_path_render(
src="", language="", class_name=None, options=None, md="", **kwargs
):
"""Formatter wrapper."""
try:
df = pd.read_csv(src)
return df.to_html()
with open(src, encoding="utf-8") as f:
table = Table.parse_csv(f)
md_table = table.markdown()
return markdown.markdown(md_table, extensions=["tables"])

# with open(src) as f:
# table = Table.parse_csv(f)

# text = table.markdown()

# # Specify the file path for the markdown file
# md_file_path = src.replace('.csv', '.md')

# # Open the markdown file in write mode and write the content of 'new' to it
# with open(md_file_path, 'w') as md_file:
# md_file.write(text)

# fm = {}
# md = markdown.markdown(
# text,
# extensions=fm.get("extensions", []),
# extension_configs=fm.get("extension_configs", {}),
# )
# return md
except Exception:
import traceback

Expand Down

0 comments on commit 3c8e3da

Please sign in to comment.