From 82b75073af8b30046fb40a27d26e179ded05c10d Mon Sep 17 00:00:00 2001 From: Xiang ZHU Date: Sun, 17 Dec 2023 14:51:20 +0100 Subject: [PATCH] new post / 2023-12-17-rendering-csv-as-markdown-table-in-mkdocs-material.md --- docs/assets/blog_data/test.md | 4 - ...sv-as-markdown-table-in-mkdocs-material.md | 107 ++++++++++++++++++ mkdocs.yml | 8 +- requirements.txt | 1 - tools/pymdownx_md_render.py | 31 ++--- 5 files changed, 120 insertions(+), 31 deletions(-) delete mode 100644 docs/assets/blog_data/test.md create mode 100644 docs/posts/2023/2023-12-17-rendering-csv-as-markdown-table-in-mkdocs-material.md diff --git a/docs/assets/blog_data/test.md b/docs/assets/blog_data/test.md deleted file mode 100644 index 19dd13a5..00000000 --- a/docs/assets/blog_data/test.md +++ /dev/null @@ -1,4 +0,0 @@ -| name | age | -| ---- | --- | -| aa | 11 | -| bb | 22 | diff --git a/docs/posts/2023/2023-12-17-rendering-csv-as-markdown-table-in-mkdocs-material.md b/docs/posts/2023/2023-12-17-rendering-csv-as-markdown-table-in-mkdocs-material.md new file mode 100644 index 00000000..05ee6faa --- /dev/null +++ b/docs/posts/2023/2023-12-17-rendering-csv-as-markdown-table-in-mkdocs-material.md @@ -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. + + + +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). + +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 + ``` diff --git a/mkdocs.yml b/mkdocs.yml index fa384b4d..94abed8d 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -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 @@ -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 diff --git a/requirements.txt b/requirements.txt index 55a331de..2c2fc500 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,4 +7,3 @@ mkdocstrings mkdocstrings-python mkdocs-video mkdocs-glightbox -pandas diff --git a/tools/pymdownx_md_render.py b/tools/pymdownx_md_render.py index 0f548ef1..49691cef 100644 --- a/tools/pymdownx_md_render.py +++ b/tools/pymdownx_md_render.py @@ -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): @@ -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