一个 Chrome 浏览器插件(Manifest V3),为 note.com 上的日语文章自动标注读音,支持三种注音方式(三选一):
| 模式 | 效果 | 说明 |
|---|---|---|
| 平假名 | 漢字かんじ | 只给含汉字的词注音,送り仮名自动对齐(如 食たべる) |
| 片假名 | 漢字カンジ | 同上,读音以片假名显示 |
| 罗马音 | 漢字kanji | 汉字和假名词都注音,基于发音(は→wa、を→o、長音→重复元音) |
分词与读音来自 kuromoji.js(IPADIC 词典,约 18MB,已打包在插件内),完全离线运行,不发送任何数据到外部服务器。
- 打开 Chrome,访问
chrome://extensions - 打开右上角「开发者模式」开关
- 点击「加载已解压的扩展程序」,选择本项目根目录(包含
manifest.json的目录) - 访问任意 note.com 文章页,等待 2–4 秒(首次加载词典),正文即出现注音
- 点击工具栏图标打开设置弹窗:
- 右上角开关:开启 / 关闭注音(即时生效,无需刷新)
- 三张卡片:切换 平假名 / 片假名 / 罗马音
- 设置通过
chrome.storage.sync保存并跨设备同步 - 鼠标悬停在注音词上会有淡绿色高亮,方便对照
- 复制正文时不会带上注音文本(
rt设置了user-select: none)
├── manifest.json # MV3 清单
├── content/
│ ├── content.js # 主逻辑:分词、DOM 遍历、<ruby> 注入、SPA 动态内容监听
│ ├── kana.js # 假名/罗马音转换、送り仮名读音对齐(纯函数,可单测)
│ └── content.css # 注音样式
├── popup/ # 设置弹窗(HTML/CSS/JS)
├── lib/kuromoji.js # kuromoji 浏览器构建(打了一行补丁,见下)
├── dict/ # IPADIC 词典(12 个 .dat.gz)
├── assets/ # logo(纯矢量 SVG,字形已转路径,不依赖字体)
├── icons/ # 扩展图标(由 logo 渲染生成)
└── test/pipeline.test.js # Node 端核心管线测试
- kuromoji 补丁:官方浏览器构建用 browserify 的
path.join拼接词典 URL,会把chrome-extension://折叠成chrome-extension:/导致加载失败。lib/kuromoji.js的BrowserDictionaryLoader.loadArrayBuffer中加了一行还原双斜杠的补丁(搜PATCH)。 - 动态内容:note.com 是 SPA,用
MutationObserver+requestIdleCallback分块处理新增节点,避免长文章卡顿;自身 DOM 修改期间暂停 observer 防止死循环。 - 安全跳过:不处理
contenteditable(note.com 编辑器)、code/pre、表单控件、 已有的ruby等区域。 - 还原机制:关闭开关或切换模式时,把所有注入的
ruby.jfr-ruby还原为纯文本并normalize(),不留痕迹。
npm install kuromoji --no-save --prefix /tmp/kuromoji-test
node test/pipeline.test.js /tmp/kuromoji-test/node_modules/kuromojilogo 的设计概念即产品机制本身:明朝体的墨色「読」字之上,浮着若竹绿圆体注音「よみ」, 底下一笔薄荷色荧光划呼应插件的悬停高亮。字形取自 OFL 开源字体 Shippori Mincho(主字)与 Zen Maru Gothic(注音), 已全部转为矢量路径,SVG 在任何环境渲染一致。
- 分词基于 IPADIC,复合词偶有误读(如「振り仮名」被切为「振り/仮名(かめい)」)
- 跨 token 的促音在罗马音模式下会丢失双写(「撮った」→ to ta 而非 totta)
- 仅匹配 note.com;要支持其他网站,在
manifest.json的content_scripts.matches和web_accessible_resources.matches中添加对应域名即可
插件完全离线运行,不收集、不传输任何用户数据,详见 隐私政策 / Privacy Policy。
Chrome Web Store 上架所需的表单文案(单一用途说明、权限用途、数据声明、打包命令等) 见 docs/STORE_LISTING.md。