当前位置: 首页 > news >正文

如何为 doc2dash 编写自定义解析器:从 Parser 协议到 Patcher 的完整插件开发指南

如何为 doc2dash 编写自定义解析器:从 Parser 协议到 Patcher 的完整插件开发指南

【免费下载链接】doc2dashCreate docsets for Dash.app-compatible API browsers.项目地址: https://gitcode.com/gh_mirrors/do/doc2dash

doc2dash 是一款把离线 HTML 文档转换成 Dash、Zeal 等 API 浏览器可直接检索的 docset 的开源工具,而**编写自定义解析器(Parser 插件)**正是它最核心的扩展能力:只要你的文档格式内置解析器不认,就可以用一个几十行的 Python 类教 doc2dash 读懂它。本文带你从 Parser Protocol 到 Patcher,完整走一遍插件开发的每一步 🧩

一、解析器插件的三大职责

在动手之前,先理解 doc2dash 对解析器插件的期望。官方扩展文档 docs/extending.md 明确列出三个任务:

  1. 检测(detect):判断一个目录是不是自己能解析的文档,并猜出 docset 的合适名称;
  2. 解析(parse):遍历文档目录,把每一个需要被索引的条目(函数、类、章节……)报告给 doc2dash;
  3. 修补(patch):往 HTML 文件里插入锚点标记,让 Dash 打开文档时能自动生成目录(TOC)。

这三件事分别对应接口里的detect()parse()make_patcher_for_file(),协议定义位于src/doc2dash/parsers/types.py

二、Parser Protocol:四个接口逐一拆解

Parser 是一个 Python Protocol(结构化协议),你不需要继承任何基类,只要类满足以下形状即可:

接口形式作用
name类变量解析器名称,出现在命令行输出里
__init__(source)实例方法接收文档目录路径,doc2dash 会自动实例化
detect(path)静态方法返回文档名称;不是自己的文档则返回None
parse()生成器方法逐个yield一个ParserEntry条目
make_patcher_for_file(path)上下文管理器产出一个可执行的Patcher函数

第一步:用 detect() 快速识别文档类型

detect()是最轻量的入口——它只读文件头或标志性文件来判断"这份文档是不是我的"。最经典的技巧是找一个机器可读的标志文件。内置的 intersphinx 解析器(src/doc2dash/parsers/intersphinx.py)只检查文档根目录是否存在objects.inv并校验其前两行格式,命中就从文件里直接读出项目名作为 docset 名称:

@staticmethod def detect(path: Path) -> str | None: try: with (path / "objects.inv").open("rb") as f: if f.readline() != b"# Sphinx inventory version 2\n": return None return f.readline().split(b": ", 1)[1].strip().decode() except FileNotFoundError: return None

💡 小贴士:detect()遇到不属于自己的目录必须安静地返回None,绝不能抛异常——自动检测流程get_doctype()(位于src/doc2dash/parsers/__init__.py)会依次询问每个解析器,第一个命中者胜出。

第二步:用 parse() 生成索引条目

parse()是一个生成器,每发现一个值得索引的符号就yield一个ParserEntryParserEntrysrc/doc2dash/parsers/types.py里的一个不可变数据类,只有三个字段:

  • name:条目的完整显示名(如parse);
  • type:条目类型,取自EntryType枚举,涵盖ClassFunctionMethodModuleGuideSection等二十余种(对应 Dash 支持的条目类型);
  • path:文档内相对路径加#锚点,例如api.html#module-parse

这些条目会被逐条写入 docset 内部的 SQLite 索引(流程见src/doc2dash/convert.py中的convert_docs()),最终决定你在 Dash 里能搜到什么。

第三步:make_patcher_for_file() 准备打补丁

这个方法必须是一个上下文管理器:进入时打开目标文件、产出一个Patcher可调用对象,退出时把修改写回磁盘。内置实现用 BeautifulSoup 读取 HTML、修改、再编码回写,正是这个"进—改—出"的三段式结构。

三、Patcher:让 TOC 自动生成的关键函数

Patcher本质上是一个签名固定为patch(name, type, anchor, ref) -> bool的函数:doc2dash 会在anchor指定的位置之前插入一段ref引用,返回值表示是否成功找到锚点。

具体流程在src/doc2dash/parsers/patcher.pypatch_anchors()中:它先按文件分组收集所有带锚点的条目,然后对每个文件调用你的make_patcher_for_file(),批量执行修补。插入的引用格式是固定约定,例如:

//apple_ref/cpp/Method/foo

所以你的 Patcher 要做的,就是在 HTML 里定位到id="anchor"的元素,在其前面插入一个<a class="dashAnchor" name="...">标签。定位不到就返回False,doc2dash 只会记一条调试日志并继续,不会中断整个转换。

四、用 --parser 参数加载你的自定义解析器

写好解析器后,无需修改 doc2dash 源码。只要你的模块可以被导入,直接通过--parser传入"模块路径.类名"即可:

$ doc2dash --parser my_pkg.my_parser.MyParser path/to/docs

该选项的导入机制在src/doc2dash/__main__.pyImportableType中实现:它按最后一个.拆分模块名与类名,动态导入后取出类对象。如果--parser省略,doc2dash 才会走get_doctype()自动检测流程。

五、最佳起点:研读内置 intersphinx 解析器

官方给出的最实用建议是——直接照着现成解析器抄。项目内置的完整参考实现是src/doc2dash/parsers/intersphinx.py,它展示了全部技巧:

  • detect()校验标志文件格式并顺带提取项目名;
  • parse()委托给intersphinx_inventory.py读取机器可读清单,再用一张INV_TO_TYPE映射表把源格式类型翻译成EntryType
  • make_patcher_for_file()内用 BeautifulSoup 做多路回退定位(dt[id=...]headerlinkspan[id=...]依次尝试),兼容 Sphinx、MkDocs、pydoctor 等不同生成的页面结构。

六、验证你的解析器:参考现有测试写法

项目自带了可直接模仿的测试范例:

  • tests/parsers/test_detectors.py:验证每个解析器的detect()对不存在的目录都能优雅返回None,且能识别对应样例文档;
  • tests/parsers/test_patcher.py:用了一个极简的FakeParser驱动patch_anchors(),验证"只有带#锚点的条目会被修补""失败只记日志不崩溃"等关键行为。

你的插件开发完成后,建议用同样的思路写两个小测试:一个测detect()的正反用例,一个测parse()产出的ParserEntry三元组是否正确。

七、总结:开发清单速查

✅ 1. 在detect()中找到你文档格式的"指纹"(标志文件或文件头) ✅ 2.parse()里把每个符号映射为ParserEntry(name, EntryType, "path#anchor")✅ 3.make_patcher_for_file()按"打开 → yield patch 函数 → 写回"三段式实现 ✅ 4. 用--parser 模块.类名运行,观察索引条目数量与 TOC 修补日志 ✅ 5. 参照tests/parsers/补齐正反用例

从 Parser Protocol 的四个接口到 Patcher 的上下文管理器,整套协议设计得非常克制:协议在src/doc2dash/parsers/types.py中总共只有百余行,却足以支撑任意文档格式接入 Dash 生态。现在,去把那些 Dash 官方文档集里没有的 API 文档,变成你指尖一按即达的检索体验吧 🚀

【免费下载链接】doc2dashCreate docsets for Dash.app-compatible API browsers.项目地址: https://gitcode.com/gh_mirrors/do/doc2dash

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

http://www.cnnetsun.cn/news/4249308.html

相关文章:

  • WinScript 快速上手指南:把 Windows 精简、隐私与性能优化变成勾选操作
  • PDF补丁丁完全使用指南:免费开源PDF工具箱,书签编辑与批量处理快速上手
  • 灰色预测GM(1,1)模型:小样本时间序列预测的数学建模利器
  • 基于springboot的英语课程教学管理系统毕业设计项目源码
  • 【AI大模型】一文搞懂多模态大模型,从“文字专家“到“全能感知者“,零基础小白收藏这一篇就够了!!
  • 3步搭好企业微信审批超时提醒系统:EasyWeChat审批监控完整指南
  • GNOME 系统监视器 Applet:3 步快速在状态栏显示 CPU、内存与网速
  • 神奇弹幕 MagicalDanmaku 使用指南:一款免费的 B 站直播场控机器人如何接管你的直播间
  • 6 个下游聚合有 1 个 hang 住,Tomcat 200 个线程全卡死:CompletableFuture 编排的 4 个隐形约定
  • SillyTavern 性能优化:5 步快速提速清单,让角色卡和聊天变快变轻(附 config.yaml 参数速查)
  • 一条链接搞定B站视频下载与AI总结
  • 低剖面180W AC-DC电源设计:从效率到散热的全流程解析
  • MSLab 入门指南:用 3 条 PowerShell 命令搭出 Azure Local 测试集群
  • 为什么Venice值得关注:LinkedIn开源的行星级派生数据平台完整指南
  • KISS-Matcher是什么:MIT开源的3D点云配准利器,一文读懂FastRobust全局配准的完整原理
  • MT-GNN:连续时间网格演化与度量张量嵌入的脑形态预测
  • OBS 直播按键显示怎么做?Input Overlay 免费插件 5 分钟配置教程
  • 免费开源 Crimson 字体完整使用指南
  • AI奖励作弊第一课:ai-safety-gridworlds的tomato_watering浇番茄环境实战教程
  • 审查员常用链接
  • K8s集群Containerd运行时配置定时备份实操
  • 大模型VS大语言模型:核心区别详解,一篇文章带你搞清楚
  • llama-cpp-agent 生产部署与调优完全指南:采样参数、性能瓶颈与常见问题解决方案
  • Axure 汉化完整指南:4 步流程修复 Axure 11/10/9 英文界面
  • 基于STM32F4单片机的FreeRTOS移植思路及过程
  • copymanga-downloader 常见问题10问10答:杀毒软件误报、登录失败一次解决
  • WorkshopDL 创意工坊模组下载:5 分钟免费拿好你的第一个模组
  • 揭秘500+份模板从何而来:expo-react-native-cicd工作流生成器的代码实现原理
  • 基于SpringBoot+vue房产销售系统设计与实现毕业设计项目源码
  • PolarFire FPGA评估套件实战:低功耗高安全中端FPGA选型与调试指南