docs: modern English README with badges and star history

Switch to English as default README with badge bar (release, CI,
license, stars) and star-history chart. Add separate README.zh-CN.md
for Chinese version. Remove project structure section.

Change-Id: I3bc378bb024e1e75db95e08fd932b29e4d4b1c63
This commit is contained in:
wujunchen 2026-04-26 11:00:29 +08:00
parent 89265a93bb
commit 2bc7288a44
2 changed files with 190 additions and 108 deletions

182
README.md
View file

@ -1,150 +1,116 @@
<p align="center">
<img src="https://img.shields.io/github/v/release/fancive/obsidian-parallel-reader?style=flat-square&color=blue" alt="Release">
<img src="https://img.shields.io/github/actions/workflow/status/fancive/obsidian-parallel-reader/ci.yml?style=flat-square&label=CI" alt="CI">
<img src="https://img.shields.io/github/license/fancive/obsidian-parallel-reader?style=flat-square" alt="License">
<img src="https://img.shields.io/github/stars/fancive/obsidian-parallel-reader?style=flat-square" alt="Stars">
</p>
# Obsidian Parallel Reader
一个 Obsidian 插件:左边原文、右边 AI 摘要卡片,滚动联动、点击跳转。
> **[中文文档](./README.zh-CN.md)**
灵感来自 [这个 B 站视频](https://www.bilibili.com/video/BV1FxoGBVETm/) 的阅读工作流演示。
Split-view reading for Obsidian — your original note on the left, AI-generated summary cards on the right, with scroll-sync highlighting.
## 功能
Inspired by [this reading workflow demo](https://www.bilibili.com/video/BV1FxoGBVETm/).
- **自适应切段** — LLM 自行判断主题边界,不依赖 markdown 标题。短段合并、长段拆分。
- **Anchor 定位** — 每张摘要卡片携带原文逐字引用,插件通过 `indexOf` 定位行号(含多级容错回退)。
- **滚动联动** — 滚动编辑器时,右侧对应卡片自动高亮。
- **右键菜单** — 复制 Markdown / 纯文本 / anchor 引用 / 跳转原文 / 编辑 / 删除卡片。
- **Markdown 渲染** — 摘要通过 Obsidian 的 `MarkdownRenderer` 渲染表格、加粗、代码、wikilink 均正常显示。
- **流式输出** — 支持 OpenAI Chat 和 Anthropic API 的 SSE 流式响应,生成时实时显示进度。
- **持久化缓存** — 生成结果按源文件 SHA-1 + 生成配置缓存在 `cache.json`,重新打开秒出;内容或配置变更后显示"已过期"提示。
- **面板操作** — 重新生成、复制全部 Markdown、导出到 Vault。
- **文件感知** — 缓存跟随文件重命名,源文件删除时自动清理。
- **Prompt 控制** — 可选输出语言、卡片数量范围、自定义 system prompt。
- **中英双语 UI** — 命令、设置、面板文案全部支持中文和英文。
- **多 Provider 支持** — Anthropic、OpenAI、Gemini、OpenRouter、Groq、DeepSeek、Moonshot、千帆、MiniMax、xAI、Mistral、Cerebras、智谱、Ollama、LM Studio 及自定义兼容端点。
## Features
## 安装
- **Adaptive segmentation** — the LLM decides natural topic boundaries. Short sections merge, long ones split. No dependency on markdown headings.
- **Scroll-sync** — scrolling the editor auto-highlights the matching card on the right.
- **Streaming** — real-time SSE streaming for OpenAI Chat and Anthropic APIs, so you see progress as it generates.
- **20+ providers** — Anthropic, OpenAI, Gemini, OpenRouter, Groq, DeepSeek, Moonshot, Ollama, LM Studio, and more. Plus Claude Code CLI and Codex CLI backends.
- **Persistent cache** — summaries are cached by content SHA-1 + settings fingerprint. Reopen a note and cards appear instantly. Edits or config changes show a stale banner.
- **Rich rendering** — cards render through Obsidian's `MarkdownRenderer`, so tables, bold, code, and wikilinks all work natively.
- **Card editing** — right-click any card to copy, edit, delete, or jump to source.
- **Export** — save cards as a Markdown note in your vault, or copy to clipboard.
- **Bilingual UI** — full Chinese and English support for commands, settings, and notices.
### 手动安装
## Quick Start
1. 下载 [最新 Release](https://github.com/fancive/obsidian-parallel-reader/releases) 中的 `main.js`、`manifest.json`、`styles.css`
2. 在 Vault 的 `.obsidian/plugins/` 目录下创建 `parallel-reader` 文件夹
3. 将三个文件放入该文件夹
4. Obsidian → **设置 → 第三方插件 → 已安装插件** → 启用 **Parallel Reader**
### Install
### 选择后端
**Manual** — Download `main.js`, `manifest.json`, and `styles.css` from the [latest release](https://github.com/fancive/obsidian-parallel-reader/releases), place them in `.obsidian/plugins/parallel-reader/`, and enable the plugin in Obsidian settings.
插件支持两种后端:
### Configure a Provider
| 后端 | 说明 |
|------|------|
| **API / Provider**(默认) | 直连 LLM API支持 20+ provider |
| **Claude Code CLI** | 通过本地 `claude -p` 调用,复用 Claude Code 登录态 |
| **Codex CLI** | 通过本地 `codex exec` 调用,复用 Codex 登录态 |
Open plugin settings, pick a provider preset, enter your API key and model ID. Done.
### API / Provider 模式
在插件设置中选择一个 Provider preset填入 API Key 和模型 ID 即可。
| Provider | API 格式 | 说明 |
|----------|----------|------|
| Anthropic | `anthropic-messages` | 默认 preset推荐 |
| Provider | Format | Notes |
|----------|--------|-------|
| Anthropic | `anthropic-messages` | Default, recommended |
| OpenAI | `openai-chat` | Chat Completions |
| Google Gemini | `google-generative-ai` | generateContent |
| OpenRouter / Groq / DeepSeek / Moonshot 等 | `openai-chat` | OpenAI 兼容格式 |
| Ollama / LM Studio | `openai-chat` | 本地模型,无需 API Key |
| 自定义端点 | 任意 | 填写 Base URL 即可 |
| OpenRouter / Groq / DeepSeek / Moonshot / ... | `openai-chat` | OpenAI-compatible |
| Ollama / LM Studio | `openai-chat` | Local, no API key needed |
| Custom endpoint | Any | Just fill in Base URL |
Model ID 支持 `provider/model` 写法(如 `anthropic/claude-sonnet-4-6`),匹配当前 preset 时自动剥离前缀。
Model IDs support `provider/model` notation (e.g. `anthropic/claude-sonnet-4-6`) — the matching prefix is stripped automatically.
### CLI 模式Claude Code / Codex
### CLI Backends (Optional)
切换后端为 **Claude Code CLI****Codex CLI**,插件通过本地 CLI 调用 LLM。
Switch backend to **Claude Code CLI** or **Codex CLI** to use your local CLI installation.
Obsidian 从 GUI 启动时不继承 shell `PATH`,需要在设置中填写 CLI 的绝对路径:
Since Obsidian's GUI doesn't inherit your shell `PATH`, enter the absolute CLI path in settings:
```bash
# 查看路径
which claude # Claude Code
which codex # Codex
```
在插件设置的 **CLI 路径** 中填入该路径,点击 **Test** 验证。
## Usage
## 命令
| Action | Effect |
|--------|--------|
| Click a card | Jump editor to that section |
| Right-click a card | Context menu: copy, edit, delete, jump to source |
| Scroll the editor | Right-side card auto-highlights |
| `Alt+↑` / `Alt+↓` | Navigate between cards |
| `Enter` in summary pane | Jump to active card's source line |
| Ribbon icon | Open the parallel reader pane |
| File context menu | Generate / regenerate / clear cache |
| 命令 | 说明 |
|------|------|
| 为当前笔记生成对照笔记(缓存优先) | 有缓存直接显示,否则调用 LLM |
| 强制重新生成(绕过缓存) | 忽略缓存重新调用 LLM |
| 打开对照笔记面板 | 打开右侧面板 |
| 导出当前对照笔记到 Vault | 保存为 Markdown 文件 |
| 复制当前对照笔记 Markdown | 复制到剪贴板 |
| 取消当前对照笔记生成 | 取消正在进行的生成 |
| `Alt+↑` / `Alt+↓` | 在摘要卡片间切换 |
| `Enter`(在摘要面板内) | 跳转到当前卡片对应的原文位置 |
## How It Works
## 交互
| 操作 | 效果 |
|------|------|
| 点击卡片 | 跳转到原文对应位置 |
| 右键卡片 | 上下文菜单 |
| 滚动编辑器 | 右侧卡片自动高亮 |
| 拖选文字 | 正常选择文本(不触发跳转) |
| 文件右键菜单 | 生成 / 重新生成 / 清除缓存 |
| Ribbon 图标 | 打开对照面板 |
## 开发
```bash
npm install
npm run dev # 监听 main.ts + src/**/*.ts自动重新构建
npm run build # 生产构建
npm run typecheck # TypeScript 类型检查strict 模式)
npm run lint # Biome lint
npm test # 构建 + 类型检查 + 测试
```
### 项目结构
| 文件 | 职责 |
|------|------|
| `main.ts` | 插件生命周期、命令注册、缓存管理、滚动联动 |
| `src/view.ts` | 右侧面板视图、卡片渲染、键盘导航、导出 |
| `src/modal.ts` | 卡片编辑弹窗 |
| `src/settings-tab.ts` | 设置面板 |
| `src/providers.ts` | API 请求/响应适配器Anthropic、OpenAI、Gemini |
| `src/streaming.ts` | SSE 流式解析 |
| `src/prompt.ts` | Prompt 构建、语言控制、自定义 prompt 模板 |
| `src/schema.ts` | JSON 提取、卡片数据归一化、结构化输出 schema |
| `src/anchor.ts` | Anchor 到行号的匹配(含容错) |
| `src/settings.ts` | 默认值、Provider preset、缓存指纹 |
| `src/i18n.ts` | 中英文 UI 翻译 |
| `src/cache.ts` / `src/cards.ts` / `src/navigation.ts` / `src/scroll.ts` / `src/vault.ts` / `src/markdown.ts` | 各种纯函数工具模块 |
## 设计
LLM 返回如下 JSON
The LLM returns structured JSON:
```json
{
"cards": [
{
"title": "3-10 字短标题",
"anchor": "40-80 字,从原文逐字复制,用于定位",
"gist": "20-40 字一句话领读",
"bullets": ["3-6 条支撑要点,每条 20-50 字"]
"title": "Short heading",
"anchor": "Verbatim quote from source for positioning",
"gist": "One-sentence lead-in",
"bullets": ["Supporting detail 1", "Supporting detail 2"]
}
]
}
```
- **anchor** 是滚动联动的核心机制,通过 `content.indexOf(anchor)` 定位行号,不依赖 markdown 标题。
- **gist + bullets** 双层结构在多次迭代后确定 — 纯散文太密、纯列表太碎,一句话导读 + bullet 兼顾概览和细节。
**Anchor** is the key mechanism — a verbatim quote that the plugin locates via `indexOf` with multi-level fallbacks, keeping scroll-sync working without relying on headings.
## 已知限制
**Gist + bullets** gives both overview and scannable detail — pure prose felt like a wall of text, pure bullets felt fragmented.
- **文档长度**:默认 20,000 字符,超长笔记会截断(可在设置中调大)。
- **Provider 差异**:部分 OpenAI 兼容 provider 可能不支持某些可选字段,请根据报错切换 API 格式。
- **Preview 模式**:滚动联动在阅读模式下也能工作,但精度取决于 CodeMirror 的行位置计算。
## Development
```bash
npm install
npm run dev # watch mode
npm run build # production build
npm run typecheck # TypeScript strict mode
npm run lint # Biome
npm test # build + typecheck + tests
```
## Star History
<a href="https://www.star-history.com/#fancive/obsidian-parallel-reader&Date">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=fancive/obsidian-parallel-reader&type=Date&theme=dark" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=fancive/obsidian-parallel-reader&type=Date" />
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=fancive/obsidian-parallel-reader&type=Date" />
</picture>
</a>
## License
MIT
[MIT](./LICENSE)

116
README.zh-CN.md Normal file
View file

@ -0,0 +1,116 @@
<p align="center">
<img src="https://img.shields.io/github/v/release/fancive/obsidian-parallel-reader?style=flat-square&color=blue" alt="Release">
<img src="https://img.shields.io/github/actions/workflow/status/fancive/obsidian-parallel-reader/ci.yml?style=flat-square&label=CI" alt="CI">
<img src="https://img.shields.io/github/license/fancive/obsidian-parallel-reader?style=flat-square" alt="License">
<img src="https://img.shields.io/github/stars/fancive/obsidian-parallel-reader?style=flat-square" alt="Stars">
</p>
# Obsidian Parallel Reader
> **[English](./README.md)**
Obsidian 对照阅读插件 — 左边原文、右边 AI 摘要卡片,滚动联动、点击跳转。
灵感来自 [这个 B 站视频](https://www.bilibili.com/video/BV1FxoGBVETm/) 的阅读工作流演示。
## 功能
- **自适应切段** — LLM 自行判断主题边界,不依赖 markdown 标题。短段合并、长段拆分。
- **滚动联动** — 滚动编辑器时,右侧对应卡片自动高亮。
- **流式输出** — 支持 OpenAI Chat 和 Anthropic API 的 SSE 流式响应,生成时实时显示进度。
- **20+ Provider** — Anthropic、OpenAI、Gemini、OpenRouter、Groq、DeepSeek、Moonshot、Ollama、LM Studio 等,还支持 Claude Code CLI 和 Codex CLI。
- **持久化缓存** — 按源文件 SHA-1 + 配置指纹缓存,重新打开秒出。内容或配置变更后显示"已过期"提示。
- **Markdown 渲染** — 通过 Obsidian 的 `MarkdownRenderer` 渲染表格、加粗、代码、wikilink 均正常显示。
- **卡片编辑** — 右键任意卡片:复制、编辑、删除、跳转原文。
- **导出** — 保存为 Vault 中的 Markdown 文件,或复制到剪贴板。
- **中英双语 UI** — 命令、设置、面板文案全部支持中文和英文。
## 快速开始
### 安装
**手动安装** — 从 [最新 Release](https://github.com/fancive/obsidian-parallel-reader/releases) 下载 `main.js`、`manifest.json`、`styles.css`,放入 `.obsidian/plugins/parallel-reader/`,然后在 Obsidian 设置中启用。
### 配置 Provider
打开插件设置,选择 Provider preset填入 API Key 和模型 ID 即可。
| Provider | 格式 | 说明 |
|----------|------|------|
| Anthropic | `anthropic-messages` | 默认,推荐 |
| OpenAI | `openai-chat` | Chat Completions |
| Google Gemini | `google-generative-ai` | generateContent |
| OpenRouter / Groq / DeepSeek / Moonshot 等 | `openai-chat` | OpenAI 兼容格式 |
| Ollama / LM Studio | `openai-chat` | 本地模型,无需 API Key |
| 自定义端点 | 任意 | 填写 Base URL 即可 |
Model ID 支持 `provider/model` 写法(如 `anthropic/claude-sonnet-4-6`),匹配当前 preset 时自动剥离前缀。
### CLI 模式(可选)
切换后端为 **Claude Code CLI****Codex CLI**,通过本地 CLI 调用 LLM。
Obsidian GUI 不继承 shell `PATH`,需要在设置中填写绝对路径:
```bash
which claude # Claude Code
which codex # Codex
```
## 使用
| 操作 | 效果 |
|------|------|
| 点击卡片 | 跳转到原文对应位置 |
| 右键卡片 | 上下文菜单:复制、编辑、删除、跳转 |
| 滚动编辑器 | 右侧卡片自动高亮 |
| `Alt+↑` / `Alt+↓` | 在卡片间导航 |
| `Enter`(摘要面板内) | 跳转到当前卡片原文 |
| Ribbon 图标 | 打开对照面板 |
| 文件右键菜单 | 生成 / 重新生成 / 清除缓存 |
## 原理
LLM 返回结构化 JSON
```json
{
"cards": [
{
"title": "短标题",
"anchor": "从原文逐字复制的引用,用于定位",
"gist": "一句话领读",
"bullets": ["支撑要点 1", "支撑要点 2"]
}
]
}
```
**anchor** 是滚动联动的核心 — 通过 `indexOf` 加多级容错定位行号,不依赖标题。
**gist + bullets** 兼顾概览和细节 — 纯散文太密,纯列表太碎。
## 开发
```bash
npm install
npm run dev # watch 模式
npm run build # 生产构建
npm run typecheck # TypeScript strict 模式
npm run lint # Biome
npm test # 构建 + 类型检查 + 测试
```
## Star History
<a href="https://www.star-history.com/#fancive/obsidian-parallel-reader&Date">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=fancive/obsidian-parallel-reader&type=Date&theme=dark" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=fancive/obsidian-parallel-reader&type=Date" />
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=fancive/obsidian-parallel-reader&type=Date" />
</picture>
</a>
## License
[MIT](./LICENSE)