Перейти к основному содержимому
X

dsh-pdf-math-reader

xiayifan1024/dsh-pdf-math-reader

Bilingual PDF reader for DeepSeek Harness that translates paragraph by paragraph: single-page, selected-text and full-document translation with a prompt that asks the model to keep formulas, citations and DOIs, a glossary that forces chosen terms, bilingual / translation-only / source-only views, per-paragraph notes with page highlights, document Q&A, and Markdown / printable HTML export.

Установка

dsh plugin --profile web add github:xiayifan1024/dsh-pdf-math-reader

README

dsh-pdf-math-reader icon

dsh-pdf-math-reader

PDF Math Reader — 在 DeepSeek Harness 中阅读、翻译、记笔记与 AI 问答一体化的学术 PDF 工作台。

License: MIT PDF.js DeepSeek Harness GitHub

dsh-pdf-math-reader(界面名称:PDF Math Reader)是一个运行在 DeepSeek Harness Web UI 中的 PDF 阅读与学术翻译插件。设计参考 PDFMathTranslate “保持公式、引用与版式语义”的学术文档阅读思路,但以 本地阅读 + 段落级双语对照 的方式落地,不修改原 PDF。

它适合读论文、技术报告、教材和带文本层的 PDF:PDF 在浏览器内渲染,翻译、术语表、 阅读笔记、AI 文献问答都在同一个面板中完成。

PDF Math Reader 界面:左侧目录、中间 PDF 页面、右侧译文与笔记

目录

功能

阅读

  • 侧边栏「PDF 阅读」入口,目录与真实页面缩略图导航。
  • 本地渲染 PDF,支持翻页、缩放、适合宽度、双栏文本重建。
  • 左右侧栏可拖动分隔条调整宽度,宽度自动保存。
  • 文本层使用 PDF.js 原生 TextLayer,选中范围与页面文字对齐。
  • ← / → 翻页,↑ / ↓ 滚动当前页;A / D 也可以翻页。
  • 鼠标滚轮在页面内滚动,到达顶部/底部后自动翻到上一页/下一页(1 秒冷却)。

翻译

  • 段落级 双语 / 仅译文 / 仅原文 三种视图。
  • 单页翻译、选中文本翻译、全文批量翻译,带进度与停止。
  • 翻译提示词要求原样保留公式、LaTeX、引用、DOI、编号、代码与 URL。
  • 术语表:每行 source=target 或 source:target,命中术语强制使用指定译名。
  • 译文按段缓存,切换页面不重复请求;可在设置中清除缓存。
  • 目标语言与术语表保存在浏览器 localStorage。

公式

  • 独立公式按区域识别:结合公式编号、右侧对齐、数学字体、运算符、上下标与垂直留白, 不把标题、页码、列表编号或表格单元当成公式。
  • 每条公式以一个完整块显示:独立渲染的 PDF 高清裁剪图 + 编号,不再把上下限、分子分母 拆成多张碎片卡片。
  • 公式区域内的文本项从正文段落中剔除;双语模式下公式只显示一次,公式前后段落各自保留 原文与译文。
  • 点击公式块可定位并高亮 PDF 原区域;长公式支持横向滚动,支持放大查看。
  • 自动识别有误时可点工具栏「框选公式」手动框出完整区域,或在公式卡片上选「不是公式」 撤销误判。修正按文档指纹 + 页码持久化,重新打开文档后仍生效,也可以一键恢复自动识别。
  • 正文中的行内公式在翻译请求里替换为 ⟦MATH_001⟧ 形式的唯一占位符;译后必须验证占位符 完整、未重复、无未知标记。校验失败会把该段标记为失败并提供重试,不会保存错误译文。
  • 公式块预留 latex 字段。第二阶段接入公式识别服务后使用 KaTeX 渲染,并保留原图对照; 识别或渲染失败时自动回退到原图。

Attention 论文公式 (1)、(2) 与 MultiHead 公式的独立高清裁剪,分式、上下标和编号均完整

上图为 tests/fixtures/attention.pdf 的真实裁剪结果:公式 (1) 的求和式分式、上标 T 与下标 d_k 均未被裁切,公式 (2) 的上下标完整;编号在卡片标题中单独显示。

笔记

  • 点击 PDF 段落,切到右侧「笔记」标签即可写笔记。
  • 笔记以标签卡片展示:页码、原文摘录、笔记内容。
  • 点击笔记卡片跳转到对应页并定位段落;再次点击段落可取消高亮。
  • 有笔记的段落在页面上以黄色高亮显示,当前选中段落以橙色高亮显示。
  • 笔记保存在本地 localStorage,按文档指纹区分,支持编辑与删除。

AI 文献阅读

  • 右侧「AI 阅读」标签,支持多轮问答。
  • 上下文范围可选:本页及相邻页 或 全文。
  • 回答只基于传入的文档文本,不要求模型“记住”整篇 PDF。
  • 可导入 DSH Skill,或从本地 .md / .txt 文件导入自定义阅读方法。
  • 适合问:核心贡献、公式含义、实验结论、方法与 baseline 的差异等。

导出

  • 导出双语 Markdown;独立公式以编号 + 公式文本块保留。
  • 导出 Markdown + 公式图片 ZIP:压缩包内包含 .md 与 equations/*.png,离线打开时 公式仍然可见。
  • 导出可打印的对照 HTML;公式图片以 data URI 内嵌,不依赖外部文件。可直接用浏览器 “打印为 PDF”。

快速开始

环境要求

  • DeepSeek Harness Desktop / Web UI,且 profile 中已配置可用的模型路由。
  • 构建客户端需要 Node.js 22+ 与 npm。
  • 运行时不需要 Python、BabelDOC 或额外 PDF 工具。

安装到 DSH

推荐直接从 GitHub 安装:

dsh plugin --profile <你的 profile> add github:xiayifan1024/dsh-pdf-math-reader

也可以克隆仓库后使用本地 bundle:

plugin_manager install_bundle target=<本仓库绝对路径>

例如:

plugin_manager install_bundle target=D:\plugins\dsh-pdf-math-reader

安装成功后,侧边栏会出现「PDF 阅读」图标。若安装前 Web UI 已经打开,请刷新页面 (Ctrl+Shift+R)以加载新的客户端 bundle。

首次打开面板时,插件会请求:

GET /pdf-reader/api/health

确认模型服务、provider、model 与请求限制。

使用流程

  1. 点击侧边栏「PDF 阅读」。
  2. 点击「打开 PDF」或把 PDF 拖进面板。
  3. 检查译文面板中的公式块;自动识别不准时点「框选公式」手动修正,或点公式卡片上的 「不是公式」撤销误判。
  4. 在右侧「译文」中翻译当前页、选中文本或全文。
  5. 点击段落 → 切到「笔记」记录要点。
  6. 切到「AI 阅读」,选择上下文范围后提问;需要时导入 Skill。
  7. 从右上角导出双语 Markdown、Markdown + 公式图片 ZIP 或对照 HTML。

快捷键

操作快捷键
上一页 / 下一页← / →,或 A / D
当前页向上 / 向下滚动↑ / ↓
滚轮翻页页面滚到顶部/底部后继续滚动,1 秒冷却
取消段落高亮、选区与公式框选Esc
输入框中输入不会触发上述快捷键

配置

配置位于 cordis.patch.yml,也可以在 profile 的 patch 层覆盖:

config:
  provider: deepseek-account   # 留空则使用 profile 默认模型
  model: deepseek-flash
  maxSegmentsPerRequest: 5
  maxCharsPerRequest: 3800
  maxTextChars: 8000
  timeoutMs: 180000
  cacheEntries: 600
  chatMaxChars: 24000
  chatTimeoutMs: 150000
  chatMaxTokens: 2048
字段默认值说明
providerprofile 默认覆盖模型 provider
modelprofile 默认覆盖模型 id
maxSegmentsPerRequest5单次翻译请求的最大段数
maxCharsPerRequest3800单次翻译请求的最大字符数
maxTextChars8000单个段落的最大字符数
timeoutMs180000翻译请求超时
cacheEntries600翻译结果内存缓存条数
chatMaxChars24000AI 阅读上下文最大字符数
chatTimeoutMs150000AI 阅读请求超时
chatMaxTokens2048AI 阅读最大输出 token

隐私与安全

  • PDF 不上传:PDF 文件在浏览器内读取和渲染,只有你主动翻译或提问的文本会发送到模型。
  • 使用现有模型:插件不保存 API Key;翻译与问答走当前 DSH profile 的模型路由。
  • 资源隔离:PDF.js、CMaps、字体全部由本插件 Host 提供,资源路径经过包含性校验,拒绝盘符路径、绝对路径和目录穿越。
  • 提示词约束:文档段落作为数据传入,并要求模型保留公式与引用;AI 回答被限定在提供的文档片段内。
  • 本地数据:术语表、笔记、面板宽度与公式框选修正保存在浏览器 localStorage;翻译缓存只存在当前页面会话内。

架构

┌──────────────────────────────┐
│ Web UI(React,client.js)    │
│  PDF.js · TextLayer · 笔记    │
└──────────────┬───────────────┘
               │ 同源 HTTP
┌──────────────▼───────────────┐
│ DSH Host(index.js)          │
│  静态资源 · 翻译 · 问答 · Skill │
└──────────────┬───────────────┘
               │ ctx.llm
┌──────────────▼───────────────┐
│ 当前 profile 的模型路由        │
└──────────────────────────────┘

Host 路由:

方法路径用途
GET/pdf-reader/api/health模型与限制信息
POST/pdf-reader/api/translate批量段落翻译
POST/pdf-reader/api/chatAI 文献问答
GET/pdf-reader/api/skills列出可用 DSH Skill
POST/pdf-reader/api/skill读取 Skill 内容
GET/pdf-reader/assets/*PDF.js 运行时资源

实现要点:

  • PDF 页面先渲染 canvas,再单独提取文本,文本层失败不阻塞阅读。
  • 文本重建保留 PDF 内容流顺序,并处理双栏换栏、纵向回跳、段落缩进与行间距。
  • 先识别公式区域并合并上下标、上下限、分式与编号,再把剩余文本重建为段落;页面模型按 阅读顺序输出 blocks(paragraph / equation),正文段落从 blocks 派生,旧调用方 (翻译、笔记、AI 上下文)继续可用。
  • 公式 bbox 统一存放 scale-1 的 PDF 页面坐标;高亮和裁剪时通过 viewport 换算,缩放、 侧栏改宽与重新打开文档后仍然一致。
  • 公式图由独立 canvas 按显示尺寸 × DPR 渲染,并受最大像素预算约束;缓存键包含文档、 页码、裁剪范围与渲染分辨率,手动修正后对应缓存失效。
  • 行内公式使用 ⟦MATH_xxx⟧ 占位符隔离,Host 侧对返回译文做完整、重复与未知标记校验。
  • PDF.js 可能把一个整句正文和尾部运算符放在同一个文本项里;提取时会按项内数学 token 范围拆成子项,只把公式片段替换为占位符,不隐藏整句正文。扩展公式范围时会排除 of / is / a / the 等停用词,只有变量形状的短 token(单字母、Greek、含数字/下划线、 大写缩写或已知函数名)才会并入公式。
  • 修改公式区域会递增翻译 epoch、取消正在执行的翻译并清理 loading 状态,避免旧请求按 重建前的段落编号回填译文。
  • 每个文档拥有独立的页面模型缓存;切换文档后的旧异步任务不会写入新文档缓存。
  • 打开文件带任务编号;连续打开时过期任务会被销毁,避免旧文件覆盖新文件。
  • 翻译与问答请求绑定客户端断开信号,停止后会取消 Host 侧模型生成。
  • 切换目标语言会中止旧请求并递增 epoch,旧结果不会回填到新语言状态。

页面模型的公式块:

{
  id: 'page6-equation1',
  type: 'equation',
  pageIndex: 5,
  bbox: [x0, y0, x1, y1],        // scale-1 PDF 页面坐标,含编号与留白
  imageBbox: [x0, y0, x1, y1],   // 裁剪图范围,去掉右侧编号留白
  equationNumber: '(1)',
  sourceItemIds: [],             // PDF.js 文本项索引,便于追溯
  latex: null,                   // 第二阶段填入
  detectionSource: 'automatic'   // 或 'manual'
}

blocks 按阅读顺序混合 paragraph 与 equation;paragraphs 由 blocks 派生, 翻译、笔记和导出仍然可以只处理正文段落。

开发

npm install
npm run build
npm test

client.js 由 src/ 打包生成,不要直接编辑。构建使用 esbuild,React 与 JSX runtime 由 DSH 浏览器模块表提供。

index.js                 Host 插件入口:路由、模型调用、Skill、安全校验
lib/                     可独立测试的 Host 纯函数(翻译/问答/占位符校验)
src/plugin.jsx           主面板、阅读器、公式块、笔记、AI 阅读交互
src/pdf.js               PDF.js 加载、文本重建、公式裁剪、缩略图、目录
src/equations.js         公式区域识别、bbox/裁剪尺寸、手动修正合并
src/zip.js               无依赖 ZIP(store)写入器
src/api.js               同源 HTTP API 客户端
src/locales.js           中英文界面文案
src/styles.js            使用 --dsw-alias-* 主题 token 的样式
assets/                  PDF.js 4.10.38、CMaps、标准字体(Apache-2.0)
tests/                   node:test 单测与固定 PDF 回归样本
tests/fixtures/          attention.pdf(Attention Is All You Need)
scripts/                 构建与 Node 侧冒烟测试
client.js                构建产物

测试覆盖:

  • node:test 纯函数单测:翻译 JSON 严格解析、术语表、批次切分、问答历史与提示词。
  • 占位符校验:完整、重复、未知标记、空输出回退与失败标记。
  • 公式识别:真实 Attention PDF 的公式 (1)/(2)、分式/上下标合并、表格误判、缩放坐标一致性。
  • 手动修正:删除自动公式、重新框选并恢复原文条目。
  • 公式裁剪尺寸:DPR、最大像素预算与超长边裁限。
  • Markdown + 图片 ZIP 的中央目录与本地区块。
  • Host 路由、翻译 JSON 严格解析、Skill 读取、资源路径越界、客户端断开取消。
  • 客户端模块加载器包装与 Slot 注册。
  • 相邻文本片段拼接、双栏段落边界。

公式回归样本

固定样本为 tests/fixtures/attention.pdf(Attention Is All You Need,15 页)。当前启发式 在整篇样本上的自动识别结果:

页页面内容识别结果
4公式 (1) Attention(Q,K,V)1 个完整公式块,含编号
5MultiHead、where head_i、公式 (2) FFN3 个公式块(前两条无编号)
6Positional Encoding 两条公式2 个公式块;表 1 未被误判
7学习率公式 (3)1 个完整公式块
8表 2/3 的数值与 · 乘号0 个公式块(表格未被误判)
其余页标题、正文、参考文献0 个公式块

回归测试覆盖公式 (1)/(2) 的完整 bbox、碎片不出现在正文段落、编号正确、缩放后 bbox 不变、 表格不误判,以及手动框选/撤销/恢复。该结果只代表这一篇样本;扩展论文时仍需重新评估覆盖率。 样本来自 Vaswani et al., Attention Is All You Need(arXiv:1706.03762), 仅用于文本提取与公式区域回归测试。

限制与路线图

  • 当前是阅读器内的段落对照,不生成重排后的单语/双语 PDF;对照 HTML 可通过浏览器打印为 PDF。
  • 公式第一阶段采用“区域识别 + 高清裁剪 + 占位符保护”,latex 字段为第二阶段预留; 尚未接入公式识别服务,也尚未用 KaTeX 渲染。
  • 行内公式与正文的边界、基线及换行仍是下一项任务;当前优先保证独立公式与占位符校验。
  • 自动识别是启发式规则,需用更多论文评估覆盖率;已提供“框选公式/不是公式/恢复自动识别” 的人工修正入口。
  • 扫描版 PDF 没有文本层时不会自动 OCR;页面会提示无文本。
  • 双栏/多栏布局使用启发式重建,极端排版可能需要人工调整段落边界。
  • AI 对话保存在当前文档会话内,切换文档会重置;笔记、术语表与公式修正持久化在浏览器本地。
  • 路线图:接入公式识别服务 + KaTeX、BabelDOC 双语 PDF、OCR、跨会话笔记同步、多文档书架。

常见问题

安装后看不到「PDF 阅读」图标?
刷新 Web UI,或重新打开面板。确认 plugin_manager install_bundle 返回 application: applied。

翻页时显示「正在渲染页面…」?
这是正常的页面渲染提示,不是模型请求。模型只在翻译、AI 问答和打开面板时的 health check 中调用。

模型不可用 / 翻译失败?
检查 /pdf-reader/api/health 返回的 llm、provider、model;确认当前 profile 已登录可用模型,或在配置中覆盖 provider / model。

扫描版 PDF 没有文本?
当前版本不做 OCR;页面会提示无文本。可在路线图中跟踪 OCR 支持。

选中范围和文字对不齐?
插件使用 PDF.js 原生 TextLayer;极少数 PDF 的字体度量不完整时仍可能有偏差。请附上页面截图与 PDF 版本反馈。

致谢

本项目与上述项目无隶属关系;PDFMathTranslate 的 BabelDOC 排版管线未包含在本仓库中。

贡献

欢迎提交 issue 和 pull request。提交前请:

  1. 运行 npm test。
  2. 如果修改了 src/,重新运行 npm run build 并提交生成的 client.js。
  3. 在 PR 中说明测试环境、复现步骤和截图(涉及 UI 时)。
  4. 不要提交个人 PDF、API Key、profile 配置或包含个人路径的日志。

License

本插件代码采用 MIT License。PDF.js 以 Apache-2.0 分发, 许可证见 assets/PDFJS-LICENSE。

Похожие плагины