如何使用docutils的Transform为rst2html待办列表添加自定义CSS类?
docutils自定义Transform实现待办标记高亮方案
1. 自定义Transform编写
Transform是docutils提供的文档树修改接口,继承基类后重写apply方法即可实现自定义节点处理逻辑:
import re import docutils.nodes from docutils.transforms import Transform # 匹配对勾+日期的待办前缀规则 TODO_PREFIX_PATTERN = re.compile(r'^(✓)\s*\((\d{4}-\d{2}-\d{2})\)\s*') class TodoItemTransform(Transform): # 转换优先级,200属于解析后、渲染前的执行区间,无冲突即可 default_priority = 200 def apply(self): # 遍历文档所有无序列表项 for list_item in self.document.traverse(docutils.nodes.list_item): # 取列表项第一个段落文本匹配前缀 first_para = list_item.first_child_matching_class(docutils.nodes.paragraph) if not first_para: continue para = list_item[first_para] raw_text = para.astext() match_res = TODO_PREFIX_PATTERN.match(raw_text) if not match_res: continue # 给整个列表项添加已完成待办的CSS类 list_item['classes'].append('todo-completed') # 可选:将对勾和日期单独封装为带类的行内节点,方便单独样式控制 check_mark = match_res.group(1) date_str = match_res.group(2) # 移除原段落开头的匹配文本 para.children = para.children[len(match_res.group(0)):] # 插入带样式类的对勾节点 check_node = docutils.nodes.inline(classes=['todo-check']) check_node.append(docutils.nodes.Text(f"{check_mark} ")) # 插入带样式类的日期节点 date_node = docutils.nodes.inline(classes=['todo-date']) date_node.append(docutils.nodes.Text(f"({date_str}) ")) # 把两个节点插回段落开头 para.insert(0, date_node) para.insert(0, check_node)
2. 应用自定义Transform
有两种常用的应用方式,可根据使用场景选择:
方案A:自定义转换脚本
适合需要集成到其他自动化流程的场景,编写自定义转换脚本如下:
from docutils.core import publish_string from docutils.writers.html4css1 import Writer # 替换为你自己的Transform定义文件路径 from your_transform_file import TodoItemTransform # 读取待转换的rst文件 with open("your_todo_list.rst", "r", encoding="utf-8") as f: rst_content = f.read() # 执行转换并注册自定义Transform html_result = publish_string( rst_content, writer=Writer(), settings_overrides={ "extra_transforms": [TodoItemTransform], "stylesheet_path": "custom_todo_style.css", # 可选:关联自定义样式表 } ) # 输出HTML文件 with open("output.html", "w", encoding="utf-8") as f: f.write(html_result.decode("utf-8"))
方案B:封装自定义命令行工具
如果你希望用类似原生rst2html.py的命令行方式使用,可以封装专属转换命令:
#!/usr/bin/env python from docutils.core import publish_cmdline, default_description from docutils.writers.html4css1 import Writer # 替换为你自己的Transform定义文件路径 from your_transform_file import TodoItemTransform cmd_desc = f"支持待办标记高亮的RST转HTML工具\n{default_description}" if __name__ == "__main__": publish_cmdline( writer=Writer(), description=cmd_desc, settings_overrides={ "extra_transforms": [TodoItemTransform] } )
将上述代码保存为rst2html_todo.py,添加可执行权限后即可直接调用:./rst2html_todo.py 输入.rst 输出.html
3. 配套样式示例
在你的CSS文件中添加对应规则即可实现彩色高亮:
/* 已完成待办项整体样式 */ .todo-completed { opacity: 0.9; text-decoration: none; } /* 对勾样式 */ .todo-check { color: #27ae60; font-weight: bold; } /* 日期样式 */ .todo-date { color: #2980b9; }
内容的提问来源于stack exchange,提问作者Maxim Kim
相关产品推荐
相关产品推荐

