Python中的一个Markdown读写库:mduti

小知识,大挑战!本文正在参与「程序员必备小知识」创作活动。本文已参与「掘力星计划」,赢取创作大礼包,挑战创作激励金。

在处理数据时,我们可能需要动态地修改 Markdown 文件以展示分析结果。这时,一个好用又简便的第三方库就派上用场了。大家好,我是披着狼皮的羊,今天和大家介绍一个处理 Markdown 的 Python 库:mdutils

PyPI 项目主页:pypi.org/project/mdu…

Github 仓库:github.com/didix21/mdu…

官方文档:mdutils.readthedocs.io/en/latest/

写在前面

mdutils 支持 ATX(大家最为熟知的 # 写法)和 Setext(.rst 文件的写法,有用过 Sphinx 的小伙伴们应该知道把)两种风格。除了常用的基础语法,这个库也支持文字着色、居中等骚操作。由于这些东西我并不是很常用,Github Markdown 也不支持,就不展开讨论了,有兴趣的伙伴们请移步到官方文档。

用之前直接 pip 安装即可:

pip install mdutils
复制代码

创建 Markdown 文件

from mdutils import mdutils

f = MdUtils(file_name="hello.md")
复制代码

file_name.md 后缀可写可不写,不影响输出结果。

MdUtils 还有一个可选参数 title,将标题以 Setext 风格写在文件开头。

This is a title
===============
复制代码

创建 MdUtils 实例后不会马上创建 Markdown 文件,需在代码最后一行手动执行:

f.create_md_file()
复制代码

标题

mdFile.new_header(level=1, title='Header 1')
mdFile.new_header(level=2, title='Header 2')
mdFile.new_header(level=3, title='Header 3')
mdFile.new_header(level=4, title='Header 4')
mdFile.new_header(level=5, title='Header 5')
mdFile.new_header(level=6, title='Header 6')
复制代码
# Header 1
## Header 2
### Header 3
#### Header 4
##### Header 5
###### Header 6
复制代码

段落和文本格式

f.new_line("This is a **line** with line break.", wrap_width=0)
复制代码
This is a **line** with line break.
复制代码

用这个方法的时候记得带上 wrap_width=0,因为其默认值是 120,会使你的句子在奇怪的地方换行(我表示非常的不理解)。

表格

list_of_strings = ['Items', 'Descriptions', 'Data', 'Item 0', 'Description Item 0', '0', 'Item 1', 'Description Item 1', '1', 'Item 2', 'Description Item 2', '2', 'Item 3', 'Description Item 3', '3', 'Item 4', 'Description Item 4', '4']
f.new_table(columns=3, rows=6, text=list_of_strings)
复制代码
|Items|Descriptions|Data|
| :---: | :---: | :---: |
|Item 0|Description Item 0|0|
|Item 1|Description Item 1|1|
|Item 2|Description Item 2|2|
|Item 3|Description Item 3|3|
|Item 4|Description Item 4|4|
复制代码

new_tabletext_align 参数可让内容向左/右对齐,参数选项包含 leftrightcenter,默认 center

链接

f.new_line('This is an inline link: ' + f.new_inline_link(link='https://github.com/didix21/mdutils', text='mdutils'))
复制代码
This is an inline link: [mdutils](https://github.com/didix21/mdutils)
复制代码

与其他方法不同的是,new_inline_link 方法只返回 markdown 格式的链接,不会直接写入文件

列表

无序列表

items = ['Item 1', 'Item 2', 'Item 3', 'Item 4', ['Item 4.1', 'Item 4.2', ['Item 4.2.1', 'Item 4.2.2'], 'Item 4.3', ['Item 4.3.1']], 'Item 5']
f.new_list(items)
复制代码
- Item 1
- Item 2
- Item 3
- Item 4
    - Item 4.1
    - Item 4.2
        - Item 4.2.1
        - Item 4.2.2
    - Item 4.3
        - Item 4.3.1
- Item 5
复制代码

有序列表

items = ['Item 1', 'Item 2', 'Item 3', 'Item 4', ['Item 4.1', 'Item 4.2', ['Item 4.2.1', 'Item 4.2.2'], 'Item 4.3', ['Item 4.3.1']], 'Item 5']
f.new_list(items, marked_with='1')
复制代码
1. Item 1
2. Item 2
3. Item 3
4. Item 4
    1. Item 4.1
    2. Item 4.2
        1. Item 4.2.1
        2. Item 4.2.2
    3. Item 4.3
        1. Item 4.3.1
5. Item 5
复制代码

Todo 列表

items = ['Item 1', 'Item 2', ['1. Item 2.1', '2. Item 2.2'], 'Item 3']
f.new_checkbox_list(items)
复制代码
- [ ] Item 1
- [ ] Item 2
    - [ ] 1. Item 2.1
    - [ ] 2. Item 2.2
- [ ] Item 3
复制代码

如果想打勾其中的一些,在要该字符串前添加一个 x

items = ['Item 1', 'Item 2', ['Item 2.1', 'x Item 2.2'], 'x Item 3']
f.new_checkbox_list(items)
复制代码
- [ ] Item 1
- [ ] Item 2
    - [ ] Item 2.1
    - [x] Item 2.2
- [x] Item 3
复制代码

这个做法我非常的不理解,如果我就想显示 x Item 2.2 又该怎么办呢???

图片

mdFile.new_line(mdFile.new_inline_image(text='snow trees', path='https://github.com/didix21/mdutils/blob/master/doc/source/images/photo-of-snow-covered-trees.jpg'))
复制代码
![snow trees](https://github.com/didix21/mdutils/blob/master/doc/source/images/photo-of-snow-covered-trees.jpg)
复制代码

new_inline_link 一样,new_inline_image 只返回 markdown 格式的链接,不会直接写入文件

自动生成目录

MdUtils.create_md_file 之前一行执行:

f.new_table_of_contents(table_title='Table of Contents', depth=6复制代码

生成的目录会放在文件开头。默认只生成一级目录,可通过 depth 参数修改。

总结

总的来说,这个第三方库可圈可点,使用的话有几点需要注意:

  1. 记得转义 ]) 等字符(视情况而定);
  2. 如果上线使用的话可能会有代码注入的问题有访问本地文件的风险
  3. 其他需要注意的点我已经标粗了,大家留意,避免踩坑。

其他的没什么问题,用不用这个库,大家自行斟酌。

说句题外话,我也贡献了为这个库贡献了 一行 代码:

screencapture-github-didix21-mdutils-pull-63-2021-10-30-00_16_57.png

如果有后续的话会再跟大家更新,拜拜~