适用人群
把 API 文档保存为 Markdown,代码原样保留
Clean Web Clipper 从页面本身读出代码语言:代码块的 class、父元素,或者高亮库留下的标记,再把它写进 Markdown 代码块。在九个页面的技术语料上,156 个代码块中有 73 个保留了语言标签,两款对比引擎分别只有 20 个和 0 个。
剪藏的文档为什么总要返工
技术文档的主体是代码,而代码恰恰是大多数剪藏工具最先弄丢的部分。你把框架文档的某一页,或者一个以后还会用到的回答存下来,粘贴进笔记,结果每个代码块都是光秃秃的:没有 js,没有 bash,也没有 sql。高亮没了,一眼分清哪段是 shell 命令、哪段是 JSON 请求体的能力也跟着没了。
剩下的损坏在结构上。某个单元格里放着代码示例的表格,被压成了一行。版本切换器和“本页目录”侧栏混进了正文中间。包在代码组件外面的 div 以原始标签的形式留了下来。手工修好这些,比凭记忆重写一遍笔记还费时间,所以很多人干脆不剪藏文档,只把标签页一直开着,直到它过时。
开着的标签页是第三个问题。文档有版本,网址通常没有:你按 v4 读过的那一页,悄悄变成了 v6,某个参数改了名,某个选项被删了,书签照样能打开,只是内容已经不同。你的笔记里没有任何记录说明当初到底是照着哪个版本写的代码。一个在文件头里记着网址和页面自身日期的文件,一年后还能回答这个问题;书签从来回答不了。
笔记里实际得到的是什么
- 代码块带着标签出来。 是 ```js,不是空的代码块:粘贴进 Obsidian、VS Code 或 GitHub,高亮马上就有。
- 语言是读出来的,不是猜出来的。 它来自网站自己的高亮库留下的 class,所以标签的准确程度和原页面一致。
- 单元格里带代码的表格保持完整:技术语料上 15 个表格保留了 12 个,对比的引擎各保留 7 个。
- 参考链接变成
[^1]脚注,定义集中在文末,规范文档里的引用在笔记中依然能对上号。 - 侧栏和版本切换器被直接删掉,而不是转换成文字:在实测的 512 个页面中,残留的 HTML 标签为零。
- 提取基于渲染后的 DOM,所以用 JavaScript 搭建的文档站,你看到什么就剪藏到什么。
- Reddit 讨论帖保留层级结构和每条评论的得分,关于一个库真正有用的回答,往往有一半在那里。
extraction字段说明用了哪条路径:dom,或者jsonld-articlebody,后者表示页面把正文放在结构化数据里,却从未渲染出来。
---
title: "Array.prototype.filter()"
source: "https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/filter"
extraction: "dom"
---
**`filter()`** 方法创建给定数组一部分的浅拷贝,其包含通过所提供函数实现的测试的所有元素。
## 示例
### 筛选排除所有较小的值
```js
function isBigEnough(value) {
return value >= 10;
}
const filtered = [12, 5, 8, 130, 44].filter(isBigEnough);
// filtered is [12, 130, 44]
```为技术文档做好设置
一次花六分钟设置,之后交给快捷键。默认设置是按阅读文章调的;文档需要不同的文件名,不需要作者字段,也不需要图片。
- 安装扩展程序,把图标固定到工具栏。右键点击图标,选择选项,设置会在新标签页中打开。
- 把点击图标时设为“存到文件夹”。这样剪藏就只是按一下键,中间不弹任何窗口。预览窗口在刚上手时有用,熟悉之后就只是碍事。
- 选择文件夹。指向一个已经纳入版本控制的目录,比如你正在开发的仓库里的
docs/clips。浏览器只会请求确认一次,并在这个浏览器配置文件中记住授权。 - 把文件名模板设为
{domain}-{title}。四个框架都有一页叫“快速入门”,文件名里没有域名的话,第四个会悄无声息地变成getting-started-4。 - 在属性部分保留
source和extraction,关闭author。文档页面很少署名,每个文件里都有一个空字段,只是迟早要清理的噪音。 - 把图片设为跳过。别人 IDE 的截图没法搜索,而且图片链接指向的 CDN 迟早会变。
- 打开
chrome://extensions/shortcuts,确认Alt+Shift+M已绑定。如果被别的扩展程序占用了,就在这里改回来。
适合开发者的设置
下面是值得从默认值改掉的几项,以及每一项为什么对技术文档特别重要,而不是对一般阅读重要。
| 设置项 | 取值 | 为什么这样设 |
|---|---|---|
| 点击图标时 | 存到文件夹 | 一天剪藏二十次,不该弹二十次窗口 |
| 文件夹 | 仓库里的 `docs/clips` | 剪藏和代码一样被版本管理、审查和搜索 |
| 文件名模板 | `{domain}-{title}` | 各框架文档的标题会重名,域名不会 |
| 图片 | 跳过 | 截图无法用 grep 搜索,图片地址失效得比文字快 |
| 属性 | 开启 `source` 和 `extraction`,关闭 `author` | 你需要网址和提取路径;文档页没有值得保留的署名 |
| 按网站规则 | `reddit.com` → 子文件夹 `threads` | 论坛回答和官方文档过时的方式不同,值得分开存放 |
| 快捷键 | `Alt+Shift+M` | 手不离键盘,决定了你是真的剪藏还是想想就算了 |
启动服务之前,先执行数据库迁移: ``` ./bin/migrate --env production ``` ```sql SELECT id, created_at FROM sessions WHERE expires_at < now(); ``` 第二个代码块在页面上带有 `class="language-sql"`。第一个什么都没带, 于是保持无标签,而不是被标上一个猜测的语言。
三个工作场景
锁定你当初实际依据的版本
你正在看某个框架 v4 分支的文档,读的是一个在 v5 中被改名的配置参数。你按下 Alt+Shift+M。文件以 example-dev-configuration-reference.md 的名字落进 docs/clips,source 指向带 /v4/ 的网址,文件头里是页面自己声明的日期。
八个月后,这个参数在生产环境里的表现变了,没人记得当初为什么这样设。剪藏文件就在仓库里,和那次改动处在同一段提交范围内,它写明了当时的决定是照着哪个版本的文档做的。而线上网址现在展示的是 v6,已经完全不提这个参数了。
真正解决问题的那个论坛帖子
官方文档只写了顺利的情况;你遇到的问题,解法在一个 Reddit 帖子里,往下翻四层评论,被采纳的回答有 140 分,排在一个 30 分的错误回答下面。你剪藏了这个帖子。按网站规则把它送进 threads,评论结构以嵌套引用块的形式保留下来,每条都带着得分。
回头再读时,得分才是关键。把帖子直接复制粘贴成平铺文本,排序信号就全丢了,你只能把五种意见重读一遍,却分不清社区认同的是哪一个。
一张变量表,直接贴进 Pull Request
部署指南里有一张包含十八个环境变量的表格,其中三个单元格里有代码示例。你在页面上选中这张表,剪藏选中内容,把 Markdown 粘贴进 Pull Request 的描述。GitHub 会把它渲染成表格,因为它是 GFM 表格,而不是截图。
在包含 15 个表格的技术语料上,这个转换器保留了 12 个,对比的每个引擎各保留 7 个。让通用转换器出错的,正是这类单元格:里面有代码或列表的那种。
和常见做法比一比
下面每种做法都行得通,你团队里现在大概就有人在这么做。第三列是真实的代价,包括这个扩展程序自己的。
| 现在的做法 | 得到什么 | 代价是什么 |
|---|---|---|
| 标签页一直开着 | 页面本身,原封不动 | 下次重启浏览器就没了,文档版本还会在你不知情时更新 |
| 复制粘贴到编辑器 | 文字,有时连侧栏一起 | 代码块没有语言标签,表格变成一行 |
| 打印为 PDF | 版式固定的页面副本 | 不能用 `grep` 搜索,不能 diff,Cookie 提示也一并印进去 |
| 加书签 | 一个指针,点一下就有 | 指针打开的是页面今天的内容 |
| 其他剪藏扩展程序 | Markdown,但裁剪得少 | 在 109 个页面上正面对比:重复的菜单行 282–491 条,这里是 102 条 |
| Clean Web Clipper | 带语言标签的代码块和来源文件头的 Markdown | 一次一个页面,没有爬虫,不下载图片 |
结果不对时怎么办
为什么我的代码块没有语言标签?
因为页面没有说明它是什么语言。Clean Web Clipper 读取的是网站高亮库留下的 class,不会看着代码去猜。手工排版、没有 class 的示例,得到的就是无标签代码块,这是诚实的结果。给一段 shell 命令标上猜来的 python,比不标更糟,因为高亮会理直气壮地把错误的部分上色。
为什么指南少了一半?
几乎总是因为选项卡或折叠面板。扩展程序转换的是浏览器实际渲染出来的内容,只有点击后才插入的选项卡内容,在你点击之前根本不在 DOM 里。先打开选项卡、展开折叠的部分再剪藏,或者每个版本各剪藏一次。如果网站把所有选项卡都渲染出来、只用 CSS 隐藏,那么它们会依次全部保留下来。
为什么提示“没有文章”?
API 调试台、搜索结果页或软件包索引,内容大多是链接文字,扩展程序会有意拒绝这类页面:如果提取出的字符中有大约四分之一以上在链接里,它就提示“没有文章”,而不是塞给你三百条链接。也正因为这种拒绝,它在“有效文本比例”上的得分,低于那些总会返回点什么的引擎。
文件里的 extraction 字段是 jsonld-articlebody,这是什么意思?
意思是页面把文章正文放进了结构化数据,却没有完整渲染到 DOM 里,所以正文是从结构化数据里读取的。这一点被记录下来而不是隐藏,因为两条路径的结果可能不同:结构化数据里的副本有时是较早的草稿,有时又是唯一完整的版本。看到这个值,在依赖这段文字之前,值得对照原页面看一眼。
它不做什么
它不会抓取整个文档站,一次只处理一个页面,也就是你正在看的那一页。它不下载图片、示意图或其他二进制文件,图片链接仍然指向原网站。对于没有标注语言的代码块,它不会去猜,所以高亮库没留下 class 的页面,得到的是没有标签的代码块,而不是标错的代码块。在没有正文的页面上,比如 API 调试台或搜索结果页,它会提示“没有文章”,而不是塞给你三百个链接。