- 开发工具
- CLI
- 后端
【免费下载链接】sapling
A Scalable, User-Friendly Source Control System.
导读
sapling-output-plugin是 Sapling 网站(基于 Docusaurus + MDX)内置的一个 remark/MDX 插件,它让文档作者可以写出只含命令、不含输出的示例代码块(with-output代码块),并由真实运行的 Sapling CLI 在构建期自动补全输出结果。本文将以 website/src/plugins/sapling-output/README.md 为骨架,结合插件源码、debugruntest命令实现和站点配置,讲清它的使用语法、内部执行链路、运行依赖以及本地调试方法,读完即可在自己的文档项目中复刻这套“命令输出自动生成”的写作模式。
一、插件定位:在文档构建期“跑出”示例输出
在传统技术文档写作中,命令示例的输出往往是作者手工复制粘贴的,容易随版本迭代而失真。sapling-output-plugin解决了这个问题:它在文档静态构建阶段,把 Markdown(MDX)里标记为with-output的代码块转换成 Sapling 自身的.t测试文件,交给真实 CLI 执行,再把执行后补全的输出回填到代码块中渲染出来。
从站点配置可以看出它的接入位置——website/docusaurus.config.js 中,它作为 Docusaurus docs 的remarkPlugins之一注册:
remarkPlugins: [ [require('remark-github').default, {repository: 'facebook/sapling'}], require('sapling-output-plugin'), ],插件本质是一个把 MDX AST 中所有lang === 'with-output'的code节点收集起来、异步改写其value的 remark 转换器(见 website/src/plugins/sapling-output/src/index.ts)。它借助unist-util-visit遍历语法树,并用Promise.all并行处理所有待补全的代码块。
二、使用语法:with-output代码块与隐藏区
1. 最简单的用法
在任意 MDX 文档中,把语言标记写成with-output:
```with-output $ echo a ```构建渲染后,插件会运行这条命令并把真实输出补在下方,页面最终显示为:
$ echo a a2. 语法来源:.t测试的简化版
with-output的语法与 Sapling 集成测试使用的.t测试文件高度一致(语法解析器见 eden/scm/sapling/testing/init.py),区别在于:在.t文件中每条命令前需要两个空格前缀,而with-output代码块不需要。插件会在内部把每一行自动加上" "前缀,转成标准的.t输入(对应源码processInput中的逻辑:website/src/plugins/sapling-output/src/index.ts)。
3. 用# hide begin/# hide end隐藏准备命令
文档作者经常需要在示例前做初始化,又不希望这些准备命令出现在读者面前。插件支持用# hide begin和# hide end圈定隐藏区域,例如:
```with-output # hide begin $ sl init repo $ cd repo $ touch a b # hide end $ sl add a $ sl st ```渲染结果为(准备命令被隐去,只剩读者关心的命令和输出):
$ sl add a $ sl st A a ? b注意:
# hide begin/# hide end之间的命令仍会真实执行,只是其命令行不回显、其输出也不参与渲染。
三、内部原理:从 MDX 到.t再到回填输出
插件的核心实现在 website/src/plugins/sapling-output/src/index.ts,整个流程可分为四步。
1. 注入示例运行环境头(EXAMPLE_HEADER)
插件会在每个示例最前面插入一段被# hide begin/# hide end包裹的环境准备脚本(源码第 18-35 行),包括:
- 向
$HGRCPATH追加[ui]、[init]、[templatealias]配置:例如设置prefer-git=false,以及sl_difflink、github_pull_request_number、github_pr_state、github_pull_request_status_check_rollup等模板别名,使示例中的 PR 相关模板输出与真实环境一致; - 导出
TEST_PROD_CONFIGS=1,以加载生产环境模板; - 导出
HGCOLORS=16、SL_COLORS=16,强制 16 色输出,保证渲染出的彩色终端文本稳定可预期。
2. 生成临时.t文件并调用debugruntest --fix
renderExample(源码第 116-146 行)会在系统临时目录下创建前缀为mdx-sapling-output的临时目录,把处理后的示例写入example.t,然后调用:
sl debugruntest -q --fix example.t其中--fix(等价于-i)表示“按实际输出更新测试文件”。执行结束后插件重新读回被补全的example.t,这就是渲染输出。调用失败时,退出码1表示“至少有一处输出不匹配”,这是预期结果,会被吞掉;其他错误码才会抛出。
3. 清理输出(processOutput)
读回的.t输出需要还原为文档友好的形式(源码第 72-93 行):
- 删除每行开头的两个空格前缀(
.t的输出行标记); - 移除
# hide相关行以及# hide begin到# hide end之间的整段内容; - 去掉文件开头的空行。
4. 颜色支持
终端颜色 ANSI 序列会被映射为 HTML 颜色。源码中内置了 Windows Console 的 Campbell 调色板(COLORS常量,第 95-113 行),把\x1b[38;5;Nm之类的颜色码转换为对应的十六进制色值,从而在页面上还原命令输出的彩色效果(如A、?等状态标记的颜色区分)。
5. CLI 选择:SL环境变量
默认情况下插件调用sl命令;若希望指向特定路径的 Sapling 可执行文件,可设置环境变量SL(源码第 183-185 行):
SL=/path/to/sl yarn build四、运行依赖:debugruntest命令详解
插件正常运行的前提是系统中存在可用的 Sapling CLI(sl)。它依赖的debugruntest(别名debugrt、.t)是 Sapling 内置的.t测试执行命令,定义于 eden/scm/sapling/commands/debug.py:
sl debugruntest [OPTION]... [TEST]... -i, --fix 更新测试以匹配实际输出 -j, --jobs 并行运行的 job 数 -x, --ext 要导入的扩展模块 -d, --direct 不使用隔离直接运行 --record 记录测试状态其中norepo=True意味着该命令可在任意目录执行,无需处于仓库内——这正是插件能在文档构建期自由生成临时.t文件并运行的前提。
关于.t格式与debugruntest的更多细节(与run-tests.py的差异、扩展语法、Python>>>doctest 块等),可参考 eden/scm/sapling/testing/init.py。例如debugruntest支持 Python doctest 风格的>>>块——站点中 zstdelta 文档 就大量使用了这一特性,直接在with-output代码块里写交互式 Python 代码并让插件补全运行结果。
五、开发与调试指南
1. 插件工程结构
插件是一个独立的 TypeScript 工程,目录结构如下(详见 website/src/plugins/sapling-output/package.json):
src/index.ts:插件全部实现(CommonJS 导出 remark 插件);package.json:依赖tmp-promise、unist-util-visit、typescript,产物输出到dist/;yarn.lock:锁定依赖版本。
2. 在 Docusaurus 项目中应用修改
插件的构建产物为dist/index.js(main字段指定),Docusaurus 通过require('sapling-output-plugin')加载的正是这个产物。因此,修改插件源码后需要重新编译,再在 Docusaurus 项目内执行yarn install以生效。
3. TypeScript 编译
开发插件本体时,在 website/src/plugins/sapling-output 目录下:
yarn install yarn build构建站点静态版本前务必执行上述两步。若正在活跃开发插件,则改用监听模式:
yarn install yarn watchTypeScript 监听器会在后台增量更新dist/目录。注意:Docusaurus 不会热加载插件产物,修改后需要重启 Docusaurus 才能看到变化。
4. 调试临时文件
插件运行时会在系统临时目录创建前缀为mdx-sapling-output的临时目录,默认执行结束后自动删除。如需保留现场用于排查,设置环境变量:
MDX_SAPLING_OUTPUT_DEBUG=1 yarn build设置后临时目录将不会被自动清理,可以检查生成的example.t(包含注入的环境头与补全后的输出)来定位问题。
六、仓库内的真实使用示例
with-output语法已在站点文档中实际投入使用。例如 website/docs/dev/internals/zstdelta.md 中讲解 ZstDelta 的diff/apply用法时,就直接书写了只含输入、不含输出的 Python 交互块,由插件在构建期补全len(a)、len(diff)、布尔判断等运行结果:
```with-output >>> import bindings, hashlib >>> a = b"".join(hashlib.sha256(str(i).encode()).digest() for i in range(1000)) >>> len(a) >>> b = a[:10000] + b'x' * 10000 + a[11000:] >>> diff = bindings.zstd.diff(a, b) >>> len(diff) >>> bindings.zstd.apply(a, diff) == b ```这种“示例即测试、输出即真相”的写作方式,保证了文档中的命令输出永远与当前版本的 Sapling 实际行为保持一致,也是本插件的核心价值所在。
小结
sapling-output-plugin通过把 MDX 中的with-output代码块转为.t测试并借助sl debugruntest --fix真实执行,实现了文档示例输出的自动化与准确性。它覆盖了从语法设计(# hide begin/# hide end)、环境注入、输出回填到颜色渲染的完整链路,并提供了MDX_SAPLING_OUTPUT_DEBUG、SL等实用的调试与定制手段。若你的文档项目同样基于 Docusaurus,并希望命令示例永不过期,可直接复用这一插件的实现思路:接入方式、源码与命令定义分别见 website/src/plugins/sapling-output/README.md、website/src/plugins/sapling-output/src/index.ts 与 eden/scm/sapling/commands/debug.py。
- 开发工具
- CLI
- 后端
【免费下载链接】sapling
A Scalable, User-Friendly Source Control System.
相关推荐
zsh-completions 补全文档:示例代码规范
zsh completions 补全文档:示例代码规范 zsh completions 是为 Zsh(Z Shell)提供额外补全定义的开源项目,旨在通过丰富的
开发工具CLISupermemory文档即代码:MDX与静态站点生成实践
Supermemory文档即代码:MDX与静态站点生成实践 痛点与解决方案 你是否正面临这些文档管理难题?团队协作时文档版本混乱,代码与文档更新不同步,静态站点
人工智能RAGAgent 记忆AI Agent后端MCP 服务知识图谱前端Kornia Models 文档的「最短可运行示例 + 真实输出图」页面模式:基于 generate_model_examples.py 的自动化文档实践
Kornia Models 文档的「最短可运行示例 + 真实输出图」页面模式:基于 generate_model_examples.py 的自动化文档实践 导读
计算机视觉人工智能深度学习图像处理
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考