Converts between Markdown and structured data, enabling formatted text generation and parsing.
ⓘ This plugin is a sub-package of the omdsh-dev/dsh-toolkit monorepo — stars and activity count the whole repository.
- Language
- TypeScript
- License
- MIT
- Branch
- main
Install
$ dsh plugin --profile web add github:omdsh-dev/dsh-toolkit#path:packages/dsh-tool-markdownRun the command above in your terminal to install this plugin via the dsh CLI. You can switch Profile in the top-right corner. New to dsh? Read the beginner tutorial
Install via your agent
Install the DeepSeek Harness plugin omdsh-dev/dsh-toolkit/packages/dsh-tool-markdown for me: review the repository at https://github.com/omdsh-dev/dsh-toolkit first, then run the install command and verify the plugin loads successfully.
Paste this instruction to the DSH Web GUI assistant — it will install and verify for you.
一句话定位
DSH 工具插件 tool-markdown,给模型提供 HTML↔Markdown 互转、HTML/管道表格转 GFM 表格、从 Markdown 标题生成目录这四类确定性文本转换能力。零依赖、手写解析器、纯函数运行不联网,适合让模型在拿到网页源码、邮件导出或用户粘贴的 HTML 时给出可预测、可校验的 Markdown 结果。
核心能力
- 把 HTML 片段或完整文档转成 GFM 风格的 Markdown(块级/行内全映射、表格转 GFM、实体解码、script/style 等标签剥离)
- 把 Markdown 转回白名单安全的 HTML(只输出允许的标签,文本一律 HTML 转义,不可能逃逸出
<script>之类危险标签) - 规范化表格:HTML
<table>或管道分隔文本统一转成 GFM 表格(自动列补齐、|转义、识别分隔行) - 从 Markdown 标题生成嵌套目录列表(GitHub 风格锚点、重复标题自动加
-1/-2后缀、跳过代码围栏内的伪标题) - 解析时自动剥离
script/style/iframe/object/noscript/template等危险或噪音标签,提升安全性和可读性 - 输入大小保护:超过
maxBytes默认 256KB、硬顶 1MB 直接报错不截断;HTML 嵌套深度 > 64 层报错
技术实现
- 语言: TypeScript(ESM)
- 关键依赖:
@deepseek-ai/cordis@^4.0.1、@deepseek-ai/dsh-tools(peer)、@deepseek-ai/dsh-invariants(peer);无运行时 npm 依赖,HTML 解析器与 Markdown 解析器均为手写 - 架构模式: Cordis 插件——
apply(ctx)中通过ctx.tools.register(defineTool({...}))注册名为markdown的工具;inject = ['tools'];通过包内cordis.patch.yml将 row idtool-markdown插入 profile layer stack - 入口文件:
packages/dsh-tool-markdown/src/index.ts(同时导出invariant.ts注册一个空的 invariant companion)
适用场景
当模型在 DSH 中处理用户贴过来的网页源码、邮件 HTML 导出、或者想把已写好的 Markdown 渲成安全 HTML 时调用本插件。它解决模型硬编码 HTML 处理时常见的实体错误、表格错乱和网页噪音(导航/脚本/广告)混入输出的痛点。如果你需要的是网页正文抽取(去掉导航广告只留文章),这个工具做不到,应该另寻带 Readability 能力的方案。
前置依赖与兼容性
| 依赖 | 最低版本 | 说明 |
|---|---|---|
| DSH | 0.1.0-rc.8+ | README 标注已迁移并验证 @deepseek-ai/[email protected] |
| Node.js | ^22.19.0 或 >=24.0.0 | package.json#engines.node |
| @deepseek-ai/cordis | ^4.0.1 | peerDependency,类型/运行时契约 |
| @deepseek-ai/dsh-tools | >=0.0.1-rc.1 <0.2.0 | peerDependency,提供 defineTool / ctx.tools.register |
| @deepseek-ai/dsh-invariants | >=0.0.1-rc.1 <0.2.0 | peerDependency,invariant companion 注册 |
| 平台 | 跨平台 | 无 os/cpu 限制、无原生模块 |
安装方式
dsh plugin --profile web add github:omdsh-dev/dsh-toolkit/packages/dsh-tool-markdown
配置项
本插件无需额外配置(没有 ctx.config Schema)。所有参数都是 markdown 工具的入参,按 action 分发:
| 配置 | 类型 | 说明 | 默认值 |
|---|---|---|---|
action | enum | 要执行的操作:html2md / md2html / table / toc | 必填 |
html | string | html2md 的输入,可以是 HTML 片段或完整文档 | — |
markdown | string | md2html / toc 的输入 | — |
text | string | table 的输入,可以是 HTML <table> 或管道分隔文本(必须含未转义的 |) | — |
baseUrl | string | 解析相对 href/src 的基准地址(naive join,不处理 query/hash 合并细节) | 空 |
maxBytes | integer | 输入大小上限(字节),超过抛错不截断 | 256000(硬顶 1000000) |
工具超时:timeoutMs = 2000(src/index.ts:130)。
常见问题
Q: 这个工具能自动抽取网页正文(去掉导航/广告/页脚)吗?
A: 不能。html2md 只做字面映射,nav/header/footer 默认全部透传。需要正文抽取请另寻带 Readability/Mozilla Readability 能力的工具。
Q: 输入超大时会被悄悄截断吗?
A: 不会。maxBytes 默认 256KB、硬顶 1MB,超过直接抛错(markdown: <label> exceeds N bytes)。如果你的 HTML 经常超过 1MB,请先用其他工具分块再传入。
Q: md2html 输出可以直接 dangerouslySetInnerHTML 渲染吗?
A: 可以。所有文本内容都经过 HTML 转义(< > & " ' 五字符),输出标签严格限定在 p h1-h6 ul ol li blockquote pre code a img strong em br hr table thead tbody tr th td 这 18 个白名单标签,javascript:/data: 链接降级为纯文本,markdown 里内嵌的 <script> 只会显示为可见文本不会执行。
Q: HTML 实体字符会被双重解码吗?
A: 不会。命名实体(& < © 等子集)和数字实体(&#x...; / &#...;)会解码一次;未知实体按字面保留——所以 &lt; 解码后是 <,文本里看到的还是 <,不会被错解成 <。
Q: 工具参数会不会泄露到日志?
A: 会。工具参数会写进 DSH 会话日志,和模型调用记录在一起。所以不要把含密钥、session cookie、个人隐私数据的 HTML 当入参传入——任何能读会话日志的人都会看到。
Q: 装到 web profile 之后 dsh run 能直接用吗?
A: 不一定。dsh run 默认使用 headless profile。web 与 headless 是两个独立 profile,互不覆盖。要让 dsh run 也用上,需要再执行一次 dsh plugin --profile headless add ...。
Q: HTML 表格里 colspan="3" 怎么办?
A: 转换时会被展平成 N-1 个空单元格占位,整体行宽按最大行补齐,确保 GFM 表格列对齐。GFM 本身不支持合并单元格,这种展平是约定。
上手难度
入门 — 只有一个工具、四个动作,参数不超过 6 个;没有需要理解的配置 schema;安装后通过 DSH 的工具调用机制直接使用,普通用户不需要读源码。
已知问题与限制
- 不做 Readability 类正文抽取,网页导航/页头/页脚会原样透传到 Markdown 输出中
- HTML 嵌套深度上限 64 层,超出会抛
markdown: HTML nesting exceeds 64 levels错误(防栈溢出,非静默) - 输入超过
maxBytes(默认 256KB、硬顶 1MB)直接报错,不会截断也不重试 baseUrl是 naive join:不解析协议相对 URL//host/path、不合并 query/hash、不处理相对路径..解析- 工具参数会写进会话日志,传入含密钥/会话数据的 HTML 等于泄露——这是设计上的取舍,不是 bug
- HTML 解析器覆盖约 95% 模型场景的语法子集(h1-h6/p/ul/ol/li/table/blockquote/pre/code/a/img/strong/em/br/hr 等),CSS/SVG/MathML 等不解析,遇到未知容器元素直接递归透传
md2html只实现 CommonMark 子集(标题/围栏代码/引用/列表/表格 + 行内code/**bold**/*italic*/[text](url)/),不支持嵌套列表、任务列表、删除线、脚注等扩展语法
DSH 零依赖工具包 collection —— time / encoding / json / calculator / csv / regex / markdown / diff / stat / schema 十个确定性工具,统一入口一键安装。
为什么
DSH 生态仓库持续增长,单插件在 hub 中容易被淹没;collection 分类是辨识度最高的形态。本仓库把 10 个工具插件 vendored 冻结为 pack artifact 快照(各子仓库独立演进,当前源位于 omdsh-dev 组织下),统一工程、统一测试、统一维护。
定位(官方 Profile Bundle 生态方向):本仓库是 collection 与安装辅助仓库——每个子包都是可独立安装/启用/禁用/卸载的 bundle(dsh plugin --profile <p> add <子包>);collection 提供目录、清单与批量安装脚本。meta 包 @deepseek-ai/dsh-toolkit 保留为可选的原子挂载模型(见下文两种运行模型)。
分发边界:根 meta 包保持 private: true,用于 Git/collection 分发,不代表会发布到 npm registry。根目录已提交由当前 src 构建出的 lib/index.js 与 lib/types/index.d.ts,因此从 Git 安装时不依赖消费端 lifecycle;prepack 仍会在生成 pack artifact 前执行完整构建。
工具一览
| 工具 | 能力 | 用例数 |
|---|---|---|
time | ISO 8601 / 时区 / 日历运算 / 时长差 | 65 |
encoding | base64 / url / hex / hash / UUID | 46 |
json | JMESPath 子集查询 | 66 |
calculator | 安全数学表达式求值(无 eval) | 31 |
csv | RFC 4180 解析 / 查询 / 统计(严格引号) | 50 |
regex | 测试 / 提取 / 替换 / 静态解释(worker 硬超时) | 63 |
markdown | HTML↔Markdown / GFM 表格 / 目录生成(白名单安全) | 71 |
diff | 文本/JSON/CSV/Markdown 结构化比较与 unified diff(只读) | 124 |
stat | 描述统计 / 百分位数 / 频数分布 / 相关性(零依赖确定性) | 82 |
schema | JSON Schema 验证 / 路径 / 解释 / 安全 default(零网络零动态) | 125 |
| 合计 | 723 |
架构
dsh-toolkit/
├── src/index.ts # meta 包:相对路径动态导入 10 个子包 apply(),聚合注册
├── packages/dsh-tool-* # vendored 子包(pack artifact 快照,name 保持 @deepseek-ai/dsh-tool-*)
├── scripts/
│ ├── link-deps.sh # 构建期 junction(cordis → vendor/cordis,dsh-tools → packages/core/tools)
│ ├── build-all.sh # 一键构建 10 子包 + meta 包(tsc)
│ ├── test-all.sh # 一键跑 10 子包 vitest(合计用例数)
│ ├── install.sh # meta / 逐包两种挂载模式(含 dry-run)
│ ├── install-web.sh # 独立 bundle 批量安装 → web profile
│ ├── install-headless.sh # 独立 bundle 批量安装 → headless profile
│ └── install-all.sh # web + headless 都装
├── catalog.json # collection 清单(hub collection 分类识别依据)
└── tsconfig.base.json # 共享编译配置(固化踩坑经验)
与实施文档方案 A 的工程化适配:子包为私有 Git/collection 包,peer 名解析在 profile 内不可行, 故 meta 包采用相对路径动态导入(零解析魔法、打包自足);子包 runtime 依赖 (
@deepseek-ai/dsh-tools)在 npm 独立模式(默认)下不依赖 DSH monorepo,monorepo 模式经子包构建期 junction 解析。
安装
仓库位于 omdsh-dev/dsh-toolkit(public)。
独立 bundle 模型(推荐)
每个子包独立安装、启用、禁用、卸载:
# 安装单个工具到 web profile
dsh plugin --profile web add github:omdsh-dev/dsh-tool-csv
# 一次性任务(headless)profile
dsh plugin --profile headless add github:omdsh-dev/dsh-tool-diff
批量安装(collection 辅助脚本,幂等——重复执行不会重复添加):
./scripts/install-web.sh # 全部 10 工具 → web profile
./scripts/install-headless.sh # 全部 10 工具 → headless profile(dsh run 使用面)
./scripts/install-all.sh # 两个 profile 都装
验证与运行:
dsh --profile web --dump-config | grep tool-csv # 行存在即安装成功
dsh run "使用 csv 工具解析 'a,b\n1,2'" # headless 端到端
⚠️ web 与 headless 是不同 profile:web 安装不会自动覆盖 headless;
dsh run默认使用 headless。 Windows 路径使用正斜杠(C:/...)。
npm pack tarball 安装
本地构建后用 tarball 路径安装(不依赖 GitHub):
# tarball 方式(web 为例;headless 同)
npm pack
dsh plugin --profile web add <npm pack 产物 tarball 路径>
meta bundle 模型(可选)
需要一次原子挂载全部工具时,挂载根 meta 包:
dsh plugin --profile web add github:omdsh-dev/dsh-toolkit
dsh --profile web --dump-config | grep tool-kit
⚠️ 若 profile 已单独挂载过同名插件(tool-time/.../tool-diff/tool-stat/tool-schema),挂 meta 包会注册重名报错—— 此时先移除旧插件,或用独立 bundle 模型。meta apply 具备原子性(任一子插件失败时 逆序回滚已注册工具,不残留部分状态)。
手动安装与旧版本兼容
旧场景(monorepo 集成、不支持 Profile Bundle 的旧快照或插件开发调试环境——本地 junction/symlink、手动编辑 profile 层)。
构建与测试
npm 独立模式(默认,推荐):无需 DSH monorepo;npm install(devDependencies 自包含)后即可:
npm run build:all # 10 子包 + meta 包 tsc + 产物完整性验证(无 .ts 残留导入、10+1 个 lib/index.js)
bash scripts/test-all.sh # 10 子包 vitest 全量(723 用例);任一失败整体非零退出
npm pack # prepack 自包含(build:all),tarball 含 lib + 10 个子包
monorepo 模式(可选:源码贡献/旧 snapshot):显式提供 DSH monorepo 根:
export DSH_MONOREPO=<DSH 0.1.0-rc.8(npm)安装路径> # 或作为第一个参数
bash scripts/build-all.sh # link-deps + 10 子包 + meta 包 tsc + 产物完整性验证
bash scripts/test-all.sh
prepack已指向build:all(完整构建 10 子包 + meta),保证 pack artifact 含全部运行入口;根 Git 入口由当前src预构建并提交。 本仓库只在本地验证构建、测试与 pack artifact;不要将这些结果解读为 npm registry 发布或未实际执行的 consumer/profile 验证。
同步 vendored(子仓库有更新时)
把 packages/<name> 与源仓库重新同步(src/tests/package.json/tsconfig/cordis.patch.yml/LICENSE/README.md),并在 README 标注子包版本。
新增工具
见 docs/CONTRIBUTING.md:复制模板子包 → 实现 → 测试 → build-all 验证 → 更新 catalog.json。
许可
MIT
Read the usage guide →
Install steps, key points, FAQ and compatibility for this plugin — auto-derived from indexed fields.
Listing badge
[](https://deepseek-plugin.org/plugins/omdsh-dev/dsh-toolkit/packages/dsh-tool-markdown)Paste this markdown into your GitHub README to link back to this listing. The badge only states the listing — not a security endorsement.