Skip to main content

dict2str

用 Python 字典/列表描述富文本内容,一键转换成 txt / Markdown / HTML 三种格式。

  • 纯 Python 实现,零第三方依赖
  • 支持 Python 3.9+
  • 无状态渲染,线程安全,可重复调用
  • HTML 输出默认转义,防止内容注入
  • 支持有序/无序列表任意层级嵌套、任务列表、表格、样式等

目录


安装

要求 Python >= 3.9:

# 克隆后本地安装
git clone https://github.com/arcturus-script/dict2str.git
cd dict2str
pdm install

快速开始

from dict2str import dict2str

d = dict2str(
    [
        {"h1": {"content": "今日任务", "style": "color: red"}},
        {"taskList": {"contents": [
            {"content": "跑 10 公里"},
            {"content": "写完作业", "complete": True},
        ]}},
    ],
    type="markdown",   # 可选:"markdown" / "html" / "txt"
)

print(d)
# # 今日任务
# - [ ] 跑 10 公里
# - [x] 写完作业

d.set("html")
print(d)
# <h1 style='color: red'>今日任务</h1>
# <label>
#   <input type='checkbox' disabled/>跑 10 公里
# </label>
# <label>
#   <input type='checkbox' disabled checked/>写完作业
# </label>

数据结构

输入是 一个元素节点,或 元素节点组成的列表/元组:

# 单个节点:{元素名: {参数}}
dict2str({"h1": {"content": "标题"}}, type="markdown")

# 多个节点(推荐,同一节点 dict 内可并排放多个不同元素,按字典顺序输出)
dict2str([
    {"h1": {"content": "标题"}},
    {"bold": {"content": "正文"}},
], type="markdown")
  • 元素名:见下表,如 h1、bold、orderedList
  • 参数:每个元素一个 dict,最常用的是 content
  • 渲染过程不会修改输入数据,同一个对象可以反复 str() / 切换格式

支持的元素

元素名(别名) 说明 关键参数
txt 普通文本(HTML 下输出 <div>) content
bold 粗体 **text** / <strong> content
italic 斜体 *text* / <i> content
strikethrough 删除线 ~~text~~ / <del> content
code 行内代码 `text` / <pre> content
blockQuote (blockquote) 引用 > text / <blockquote> content
h1 ~ h6 一到六级标题 content
h 通用标题 level(1~6)、content
link 链接 url、content(默认 "a link")
img 图片 url、alt(默认 "a image")
orderedList (ol) 有序列表 contents、items(嵌套)
unOrderedList (ul) 无序列表 contents、items(嵌套)
taskList (tasklist) 任务勾选列表 contents(每项含 complete)
table 表格 contents、position、样式参数

基础元素示例

nodes = [
    {"txt":           {"content": "普通文本"}},
    {"bold":          {"content": "加粗"}},
    {"italic":        {"content": "斜体"}},
    {"strikethrough": {"content": "删除线"}},
    {"code":          {"content": "print('hi')"}},
    {"blockQuote":    {"content": "引用内容"}},
    {"h":             {"level": 2, "content": "二级标题"}},
]
元素 txt markdown html
bold 加粗 **加粗** <strong>加粗</strong>
italic 斜体 *斜体* <i>斜体</i>
strikethrough 删除线 ~~删除线~~ <del>删除线</del>
code print('hi') `print('hi')` <pre>print('hi')</pre>
blockQuote 引用内容 > 引用内容 <blockquote>引用内容</blockquote>
h2 二级标题 ## 二级标题 <h2>二级标题</h2>

链接与图片

[
    {"link": {"url": "https://example.com", "content": "示例网站"}},
    # txt:  示例网站: https://example.com
    # md :  [示例网站](https://example.com)
    # html: <a href='https://example.com'>示例网站</a>

    {"img": {"url": "https://example.com/a.png", "alt": "示意图"}},
    # txt:  示意图: https://example.com/a.png
    # md :  ![示意图](https://example.com/a.png)
    # html: <img src='https://example.com/a.png' alt='示意图'/>
]

任务列表

{"taskList": {"contents": [
    {"content": "未完成任务"},
    {"content": "已完成任务", "complete": True},
]}}

txt:

🔴 未完成任务
🟢 已完成任务

markdown:

- [ ] 未完成任务
- [x] 已完成任务

html:

<label> <input type="checkbox" disabled />未完成任务 </label>
<label> <input type="checkbox" disabled checked />已完成任务 </label>

通用参数

所有元素都支持以下参数(未使用到时自动忽略):

参数 适用格式 默认值 说明
content 全部 — 元素正文
end 全部 多数元素为 "\n";italic/strikethrough/code 的 md/html 为 "" 追加在输出末尾的字符串
style html None CSS 样式,渲染成 style='...';txt/md 下忽略
escape html True 是否转义正文里的 HTML 特殊字符,详见 HTML 转义
{"bold": {"content": "注意", "end": " | ", "style": "color: red;"}}
# markdown: **注意** |
# html    : <strong style='color: red;'>注意</strong> |

列表嵌套

列表的每一项是 {"content": ..., "items": {...}, "style": ...}, 其中 items 又是一个或多个元素定义,从而支持任意层级、不同类型列表互相嵌套:

{"orderedList": {"contents": [
    {"content": "A", "items": {"unOrderedList": {"contents": [
        {"content": "B"},
        {"content": "C", "items": {"orderedList": {"contents": [
            {"content": "D"},
            {"content": "E"},
        ]}}},
    ]}}},
    {"content": "F"},
]}}

markdown 输出(自动按层级缩进):

1. A

- B
- C
  1. D
  2. E

2. F

HTML 下列表容器和每个列表项都可以单独设置 style:

{"orderedList": {
    "style": "color: red;",          # <ol style='...'>
    "contents": [
        {"content": "重点项", "style": "font-weight: bold;"},  # <li style='...'>
        {"content": "普通项"},
    ],
}}

表格

contents 是二维数据,第一行是表头;可以传 list 或 tuple,行列长度可以不一致(短行自动补空单元格)。

{"table": {
    "contents": [
        ("姓名", "分数"),
        ("张三", "95"),
        ("李四", "88"),
    ],
    "position": "center",   # markdown 对齐:center(默认) / left / right / 其他值(无冒号)
}}
| 姓名 | 分数 |
| :--: | :--: |
| 张三 |  95  |
| 李四 |  88  |
  • position="left" → :--,"right" → --:,非法值 → --
  • markdown 单元格中的 | 会自动转义成 \|,换行替换为空格
  • HTML 表格每行数据渲染为独立的 <tr>,并支持自定义样式:
参数 默认值 作用
style width: 100%; border-collapse: collapse; margin-bottom: 10px; <table> 样式
th_style(兼容旧名 th-style) text-align: center; border: 1px solid #e6e6e6; background-color: #F5F5F5; 表头单元格样式
td_style(兼容旧名 tdStyle) text-align: center; border: 1px solid #e6e6e6; 数据单元格样式

txt 格式下表格用制表符分隔:姓名\t分数\n张三\t95\n。

HTML 转义

为避免正文内容被浏览器当成 HTML 解析,html 输出默认开启转义:

d = dict2str([{"bold": {"content": "<script>alert('x')</script>"}}], type="html")
print(d)
# <strong>&lt;script&gt;alert('x')&lt;/script&gt;</strong>
  • 文本节点转义 <、>、&;属性值(url/style 等)额外转义单/双引号,无法逃逸属性
  • 内容是自己拼接的可信 HTML 时,有两种方式放行:
# 1) 全局关闭转义
dict2str(data, type="html", escape=False)

# 2) 只对某个元素关闭
[
    {"bold": {"content": "<b>保留标签</b>", "escape": False}},
    {"bold": {"content": "<b>仍然转义</b>"}},
]

切换输出格式

d = dict2str(data, type="markdown")
str(d)                       # 当前格式渲染
d.set("html")                # 切换格式,返回 self,可链式调用
dict2str(data).set("txt")    # 链式写法
str(dict2str({"a": 1}))      # type=None(默认)时直接返回 str(content)

支持的格式:"markdown"、"html"、"txt"。

异常说明

遇到非法输入会抛出明确异常(旧版本部分错误只 print 提示):

场景 异常
不支持的输出格式,如 type="pdf" ValueError
未知元素名 ValueError(信息中附带全部支持的元素名)
content 不是 dict / list / tuple TypeError
节点列表中某项不是 dict TypeError
元素参数不是 dict(如 {"h1": "x"}) TypeError
标题 level 不在 1~6 ValueError
表格 contents 为空或不是列表 ValueError
列表项缺少 content ValueError
列表项 items 不是 dict TypeError
参数中使用保留字 _level ValueError

API 参考

dict2str(content, type=None, *, escape=True)

参数 说明
content 单个元素 dict,或元素 dict 组成的 list/tuple;不会被修改
type "markdown" / "html" / "txt" / None(原样 str() 透传)
escape 仅对 html 生效,是否转义内容,默认 True
方法 / 属性 说明
set(type) 切换输出格式,校验失败抛 ValueError,返回 self
parse() 执行渲染并返回字符串
__str__() 等价于 parse(),因此可直接 print(d) / str(d)

运行示例与测试

仓库根目录的 example.py 既是功能演示也是零参数测试脚本(119 个断言,覆盖全部元素、三种格式、嵌套、表格、转义与异常分支):

pdm run python example.py        # 全部通过退出码为 0,任一失败退出码为 1

License

MIT

Metadata

Release files for dict2str 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for dict2str 0.1.0
File Size Uploaded
dict2str-0.1.0.tar.gz 23.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for dict2str 0.1.0
File Interpreter ABI Platform
dict2str-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 42.8 kB

Release files / dict2str-0.1.0.tar.gz

Download URL dict2str-0.1.0.tar.gz
Size 23.2 kB
Tags Source
SHA-256 checksum
How to use checksums
d828f4215e03b75690e9f92086b141890e0ba07bbdccd4be7144b7a483f4237f
BLAKE2b-256 checksum
How to use checksums
78e42055f4091b5bddee24425da8fbf4a4f99ad5a4c3d62da9c3ae6071871f81
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via pdm/2.29.2 CPython/3.14.4 Linux/6.18.33.1-microsoft-standard-WSL2

Release files / dict2str-0.1.0-py3-none-any.whl

Download URL dict2str-0.1.0-py3-none-any.whl
Size 19.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d4eb4cd772daa8cca7e31a7d29a2c1972d7f3854857d429c387a9dc01a2a2012
BLAKE2b-256 checksum
How to use checksums
2d9ebe8ca394f0a2e08e248c288e3081fc7bf29d75d3a3d67c2c2f286a76ae99
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via pdm/2.29.2 CPython/3.14.4 Linux/6.18.33.1-microsoft-standard-WSL2

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

0.0.3

1 release file

0.0.2

1 release file

0.0.1

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page