在读者阅读的地方解释每一个难词 — popup 使用方法
popup 是一个技能,可以给任何项目的网页、文档和 README 里的专业术语配上解释卡片。安装后用平常的话吩咐 智能体:它会建立术语表、接到你的页面上,并在里检查结果。
它能做什么
读者卡在一个不认识的词上,整段话就读不懂了。popup 在这个词上放一张小卡片:鼠标悬停(手机上点一下,键盘用 Tab)卡片就会打开。所有解释都放在一个术语表 文件里,改一次,所有页面都跟着改。
在这里试试:把鼠标移到本页带虚线的词上,比如 JSON、 或 。这就是 SONUB 的术语弹窗,popup 做出的卡片也是这个样子。
一张卡片里有什么
- 词语、读法和所属领域
- 加粗的一行含义
- 两三句话的解释
- 通俗地说 — 一个日常比喻
- 例子 — 每行一个,代码及其作用
- 带“复制”按钮的源代码片段
- 点一下就在原处切换卡片的相关术语,以及通往项目中更深入页面的“了解更多”链接
安装
在项目文件夹的终端里运行这行命令。想在所有项目中使用就加上 -g。装好后开启智能体的新会话,让它读取这个技能。
npx skills add https://sonub.com -s popup
npx skills add https://sonub.com -s popup -g
工具 popup.py 只需要 Python 3.8 或更高版本(只用标准库)。弹窗本身不需要框架,也没有构建步骤,在任何现代浏览器中都能运行。
使用方法 — 吩咐你的智能体
在 Claude Code 中,输入 /popup,后面写上要处理的内容。在其他智能体中,说“用 popup 技能来……”。要求越具体,它就越精确地只做那一部分。
试着说
- “/popup 入门页面”
- “/popup token、采样、温度”
- “/popup 顶部菜单”
- “/popup 让 README 对初学者更易读”
智能体做的事 — 七个步骤
- 找到目标 它先确定是哪些页面、文件或部分,并先查找项目里是否已有术语表或提示框机制。如果有,就在原有机制上扩展,而不是再加一套弹窗机制。
- 一次性准备 popup.py init 会复制 popup.js 和 popup.css,为你选择的语言写一个空的术语表,并写入设置文件 .popup.json。然后在你的布局里加两行。
- 检查 popup.py audit 会为每个文档列出它已经用到的术语表词条,以及还没有词条的候选词:缩写、camelCase 词和词。你自己语言里的词检测不出来,所以由阅读正文后挑选。
- 挑选 它挑出新手会卡住的词、不懂就读不懂整段的词,以及在项目中反复出现的词。日常用语和正文当场就解释了的词不选。
- 撰写 它用项目提供的每一种语言撰写每个词条,只写经过核实的事实。词条放进一个输入文件,先用 popup.py add --dry-run 预览,再合并进去。没有 --overwrite 就绝不覆盖已有词条。
- 接上 main 和 article 里的普通文字会自动包裹。变形词和句子用 data-term 标记,链接、卡片和标题旁边放一个 ? 按钮。在 上阅读的 Markdown 则改用 GLOSSARY.md 和链接。
- 验证 popup.py check 校验术语表,智能体再在里打开页面检查:悬停、移开、点击、相关术语、Esc、Tab、窄屏和其他语言。没能检查到的部分会写进报告。
popup.py 工具 — 你也可以自己运行
popup.py 在已安装技能的 scripts 文件夹里(例如 .claude/skills/popup/scripts/popup.py),下面的框里简写为 popup.py。路径从 git 仓库根目录下的 .popup.json 读取。
加到网页上
没有构建步骤。把这两行放进页面或布局,popup.js 就会读取术语表并在正文中找出术语。
<link rel="stylesheet" href="/popup/popup.css">
<script defer src="/popup/popup.js" data-glossary="/popup/glossary.json"></script>
术语表 JSON — 所有解释都在这里
页面只指向术语 id,解释都写在这一个文件里。每种语言必须有 term、short 和 long;easy、example、code 和 reading 可选。id 一旦用了就不再改。
{
"defaultLocale": "en", "locales": ["en", "ko"],
"categories": { "web": { "en": "Web", "ko": "웹" } },
"terms": {
"api": {
"category": "web", "aliases": ["API", "APIs"], "related": ["endpoint"], "href": "../docs/api.md",
"text": {
"en": { "term": "API", "short": "…", "long": "…", "easy": "…", "example": "`GET /users/42` asks for user 42" },
"ko": { "term": "API", "reading": "에이피아이", "short": "…", "long": "…" }
}
}
}
}
标记词语的方法
main · article · [data-popup-root]- 自动 — 包裹这些区域内普通文字中每个术语的第一次出现
<span data-term="api">APIs</span>- 变形词,以及不应被自动匹配到的短语和句子
<button class="popup-info" data-term="api"></button>- 链接、卡片和标题旁的 ? 按钮 — 方便手机和键盘使用
<a href="/docs/api" data-term="api">- 加在链接上:鼠标停留 400 ms 后显示预览,点击照常打开链接
data-popup-scope="shell"- 用于在某一部分里意思不同的词
PopupGlossary.apply(element)- 单页应用重新渲染后包裹新内容(不会重复包裹)
它也适用于 React、Vue 和 Svelte,MkDocs、Docusaurus 和 VitePress,以及服务器模板和应用 — 技能里的 references/integrate.md 介绍了每种技术栈的接法。
在 GitHub 上 — README 和 Markdown
GitHub 不运行 JavaScript,所以 Markdown 用链接代替弹窗。popup.py md 写出 GLOSSARY.md,popup.py link 把每个文件中每个术语的第一次出现连到它。链接标题就是简短含义,所以鼠标悬停就能看到。代码块、标题和 front matter 不会被改动,表格里的 | 会变成 \|,表格就不会被破坏。
Call the [API](../GLOSSARY.md#api "The agreed way one program asks another for something") with an API key.
读者怎样使用
- 悬停打开卡片,移开就关闭 — 从词语移到卡片上时卡片保持打开。
- 点击会固定卡片,方便复制代码或打开链接;再点一次就关闭。
- 点相关术语的标签,卡片会在原处切换。
- 用 Tab 移到词语上会打开卡片,Enter 进入卡片,Esc 关闭卡片并把焦点放回词语上。
- 在手机上(640 px 或更窄),卡片是一张从底部滑上来的面板;在大屏幕上靠近底部的词,卡片会翻到词语上方。
- 它支持从右到左书写的语言和深色模式,并按每种文字的需要匹配词语:韩语助词、阿拉伯语前缀、中文和日文。
常见问题
页面不会满是下划线吗?
每个术语在每个页面或部分里只在第一次出现时包裹,而且技能要求智能体每段最多三四条下划线。
我的项目已经有提示框了,会怎样?
智能体会先找现有的术语表或提示框机制,并在其上扩展。比如 SONUB 不加 popup.js,而是在自己 17 种语言的 Laravel 术语表里添加词条。
多种语言怎么处理?
所有语言都放在同一个术语表 JSON 里。check 会发现缺少的语言,弹窗显示页面语言(html lang)的解释。
解释写错了怎么办?
错误的弹窗会把错误的内容教给每一位读者,所以技能只允许智能体写它在文档中或实际运行代码核实过的数字、版本和行为。要修正时,只改一次术语表,所有页面都会跟着变。