dsh-patent-number-stamp
Verifieddsh-patent-number-stamp · v1.3.0 · MIT
DSH 插件:从 PDF 文件名里提取设定范围内的字符(「涉案专利」/「D数字」/「D数字-数字」/「证据数字」/「证据数字-数字」),以正红大字标到首页页眉空白处(顶部居右,右侧被占自动左让),原地改写并默认留备份;提不到字符报错跳过;文件名出现多个不同数字时不直接加注、报错列候选,待询问用户后用 label 消歧;可选用 label 参数手写指定(与文件名不一致时回显 filenameMismatch 告警);页眉已有同一字符视为已标注不重复盖;落盘前逐像素自检。
Install
dsh plugin add dsh-patent-number-stamp Confirm the layer applied with dsh --profile default --dump-config — see the install guide.
Source
Tags
Readme
dsh-patent-number-stamp · 专利文件序号标注
DSH 插件:从 PDF 文件名里提取设定范围内的字符,以正红大字盖到 PDF 首页页眉空白处(顶部居右),原地改写原文件。
- 中文名:专利文件序号标注
- 插件名(Loader id / npm 包名):
dsh-patent-number-stamp - 注册的工具:
patent_number_stamp(只有一个) - 注册的技能:
patent-number-stamp(skills/patent-number-stamp/SKILL.md,model/user 均可调起,与同族专利插件同一套注册方式)
它做什么
D1-CN1291282A.pdf → 首页页眉右上角盖红色「D1」
D1-2-对比文件.pdf → 盖「D1-2」
涉案专利-固态照明装置.pdf → 盖「涉案专利」
证据1-中文译文.pdf → 盖「证据1」
证据6-1的中文译文.pdf → 盖「证据6-1」
- 顶部居右:标注右缘对齐
页宽 - rightMargin。 - 有字自动左让:右侧被既有文字/墨迹占住时,横向往左让,直到刚好放下且不压到原字;整行放不下就往下挪一行(仍在页眉搜索深度内),全都放不下才报错。
- 原地改写:直接写回原路径;写回前默认留一份
原名.bak-YYYYMMDD-Hhmmss.pdf备份(backup: false可关)。 - 落盘前逐像素自检:页数不变、文字层能在计划位置读到该字、计划框内有足量正红像素、标注框外零差异——任一项不过就不写盘,原文件分毫不动。
- 幂等:页眉文字层里已有同一字符时判为「已标注」,不重复盖。
文件名提取规则(lib/extract.js)
只认这五种形式,且只看文件名(不含目录名):
| 形式 | 例 | 提取结果 |
|---|---|---|
涉案专利 |
涉案专利-固态照明装置.pdf |
涉案专利 |
D数字 |
D1-CN1291282A.pdf、d5-us2006….pdf |
D1、D5 |
D数字-数字 |
D1-2-对比文件.pdf |
D1-2 |
证据数字 |
证据1-中文译文.pdf |
证据1 |
证据数字-数字 |
证据6-1的中文译文.pdf |
证据6-1 |
细则:
- 在文件名任意位置搜索,
D不区分大小写(d12-3→D12-3),并归一到大写D。 - 长格式优先:
D1-2、证据6-1是一个整体,不会拆成D1、证据6。-后面不是纯数字时退回短格式(D1-对比文件.pdf→D1)。 - 前向后顾:
D前面紧贴字母/数字时不算(USD100、MD5、2024D1都不提取);中文、连字符、下划线之后的D算(图D1、-D4、D1_备份)。「证据」不受此限:前面紧贴字母/数字也算(D1证据2会命中两者,不会吞掉证据2)。 - 提不到 → 报错跳过,不写任何文件。
- 命中多个不同标注 → 不写任何文件,报错里列出全部候选(同一标注重复出现不算多命中)——调用方不要自行选择、不要直接加注,先询问用户要标哪一个(「不懂就问」),确认后用
label参数消歧。每份文件、每次都要重新询问,不得沿用以往的选择(不同案件详情不同,选择未必相同)。
可选手动指定(label 后门)
文件名不方便改的场合(网络盘、只读目录、批量脚本)、或多数字歧义询问用户后的消歧,可以用 label 参数直接指定要标的字符:
- 必须过同一套五形式校验(
涉案专利/D数字/D数字-数字/证据数字/证据数字-数字,整串匹配,D不分大小写)——后门只放宽「来路」,不放宽「合法性」; - 给出时优先于文件名提取;
- 用文件名印证:一致 → 正常标;不一致(或文件名提不到)→ 照标,但结果里
filenameMismatch: true,detail与工具输出里都会带⚠告警,点名手写值与文件名值; - 多命中消歧不算不一致(2026-10-23 口径):文件名同时含多个候选(如「证据6-证据1的中文译文」含
证据6、证据1)、经询问用户后选定其中之一时,文件名可印证 →filenameMismatch: false,回显带「消歧:文件名同时含:证据6、证据1,已确认标「证据6」(消歧)」(filenameNote);选定值不在候选里才算filenameMismatch: true。
| 情形 | 结果 |
|---|---|
不给 label,文件名合规 |
labelSource: filename,照标 |
不给 label,文件名提不到 |
报错,不写文件 |
不给 label,文件名多命中 |
报错列候选,不写文件 → 先询问用户,再用 label 消歧 |
label 与文件名一致 |
labelSource: argument,filenameMismatch: false |
label 是多命中候选之一(询问后消歧) |
labelSource: argument,filenameMismatch: false + filenameNote 注明消歧 |
label 与文件名不同 / 提不到 / 不在候选里 |
labelSource: argument,filenameMismatch: true + ⚠ 告警 |
label 形式不合法 |
报错,不写文件 |
工具
| 工具 | 作用 |
|---|---|
patent_number_stamp |
从文件名提取字符(或用 label 手写指定)→ 首页页眉落笔(顶部居右 / 自动左让)→ 内存中自检 → 原地写回(默认留备份)。dryRun: true 只计划+自检、不落盘;previewPath 可把标注后首页渲成 PNG 供肉眼核验。 |
参数
| 参数 | 类型 | 说明 |
|---|---|---|
path |
string(必填) | PDF 路径;相对路径按会话工作目录解析。文件名需含五种形式之一(除非用 label 指定);出现多个不同数字时不直接加注,先询问用户再用 label 指定。 |
label |
string | 可选:手写指定字符(涉案专利/D数字/D数字-数字/证据数字/证据数字-数字 之一)。给出时优先于文件名;是文件名候选之一(询问后消歧)→ filenameMismatch: false + filenameNote 注明;与文件名对不上则 filenameMismatch: true + 告警。省略则完全从文件名提取。 |
dryRun |
boolean | 只计划+自检,不写任何文件。默认 false。 |
previewPath |
string | 可选:标注后首页渲染成 PNG 存到这里。 |
返回要点
label(最终所标字符)、labelSource(filename/argument)、filenameMismatch(与文件名是否对不上)、filenameLabel(文件名提取出的字符,提不到/多命中时为 null)、filenameNote(消歧备注:多命中候选清单与确认结果)、applied、alreadyStamped、movedLeft(因被占而左让的距离,0=顶部居右)、stamp.x/y(落点,渲染坐标 pt)、verified(自检明细:redPixels/outsideDiffering 等)、backupPath、font。
技能
skills/patent-number-stamp/SKILL.md 随插件一起注册(source: 'bundled',inject 为 ['tools', 'skills'],与 dsh-patent-draft-revision 等同族插件同一模式)。在 DSH 技能列表里可直接调起,内容涵盖:
- 铁律:字符只来自文件名或用户明确给的
label(不自行发明/改写)、文件名出现多个不同数字时不直接加注、先询问用户(不懂就问)、这是原地改写需先确认、不要用 Acrobat/脚本替代(本插件带逐像素自检)、label后门不一致必须告知用户。 - 工作流程:先确认范围与授权 → 核对文件名能否提出字符(五种形式)→ 多数字歧义先询问用户、再用
label消歧 → 逐个调用(建议先dryRun一个确认落点)→ 交付时说明落点/自检/备份/消歧。 - 常见情形表:提不到、多数字歧义(询问消歧)、同数字重复、想指定别的字符、右侧被占、需改字号颜色分别怎么办。
- 边界:只处理首页、
/Rotate ≠ 0与加密 PDF 报错、自检不过则整体放弃。
配置(cordis.patch.yml)
color: '#FF0000' # 标注色(正红)
fontSize: 16 # 字号 pt;相对页眉正文明显大
topInset: 10 # 页面顶部内缩,标注行起点
rightMargin: 24 # 不避让时右缘对齐 页宽-rightMargin
leftMargin: 24 # 左让不越过它
headerZoneHeight: 64 # 页眉搜索深度(pt)
rowGap: 4 # 换行间隔
padH: 6 # 与相邻墨迹的横向安全间隙
padV: 2 # 纵向安全间隙
mergeGap: 4 # 墨迹游程合并阈值
fontPath: '' # 留空自动挑单体 TTF(黑体优先);不要填 .ttc
backup: true # 写回前留 .bak-时间戳 备份
fontPath不能填.ttc(TrueType 集合):pdf-lib 的embedFont内部只调fontkit.create(buffer),吃不了集合。留空即可,会自动选simhei.ttf(黑体)→ 华文宋体 → 仿宋 → 等线 → 楷体,并在缺字形时自动退让。
安装(本机 = 本地 link)
已在桌面 profile 装好:
C:\Users\hanch\.dsh\profiles\desktop\package.jsondependencies加"dsh-patent-number-stamp": "link:D:/Dgit/Dplugins/dsh-patent-number-stamp"dsh.profile.bundles数组里加"dsh-patent-number-stamp"
node_modules\dsh-patent-number-stamp→ junction 指向插件目录- 插件目录内
node_modules下是逐包 junction(pdf-lib/pdfjs-dist/@pdf-lib/fontkit/@napi-rs/canvas/@deepseek-ai/schemastery),指向 profile 的 node_modules。不要换成「整个 node_modules 一条 junction」:profile 里node_modules\dsh-patent-number-stamp又指回本目录,会形成无限递归,任何-Recurse扫描都会被绕进去。 @deepseek-ai/dsh-tools/@deepseek-ai/dsh-skill不建 junction:宿主由 loader 的解析钩子把它重定向到 app.asar 内部;独立node跑测试时用scripts/_register-dsh-tools-stub.mjs补桩(它会一并接管这两个模块名)。
装完重启 DSH。改代码后同样必须重启:host 进程按模块 URL 缓存已加载的插件,切换开关/重装都不会重新导入。
测试
node scripts/test-extract.mjs # 提取规则 38 例 + label 后门决策 27 例(纯逻辑,无外部依赖)
node scripts/test-stamp.mjs # 落笔端到端 7 组断言(合成 PDF:贴右/左让/幂等/旋转报错/dryRun/备份/错误提示)
node --import ./scripts/_register-dsh-tools-stub.mjs scripts/test-module.mjs # 模块契约(导出/工具注册/技能注册/render content 形状/来源与不一致告警)
或一次性 npm test(等价跑齐上面三条)。
卸载
# 在 profile 目录执行
pnpm remove dsh-patent-number-stamp
# 再删掉 profile 的 cordis.patch.yml 里 id 为 patent-number-stamp 的那条,然后重启 DSH
已知边界
- 页面
/Rotate ≠ 0会直接报错(不做而非做错):旋转会让「顶部居右」的几何失效。先用阅读器把页面旋转拍平再标注。 - 加密 PDF 报错,需先解密。
- 只处理首页;页眉搜索深度默认 64pt,超出该范围的既有内容不参与避让判定(但逐像素自检仍会兜底发现误改)。
- 原地写回前会留备份;若目标正被 PDF 阅读器占用导致写回失败,会报错并保留原文件。