npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

dsh-patent-claim-annotation

v1.3.0

Published

DSH 插件:输入专利 PDF,定位权利要求书与说明书【具体实施方式】,在实施方式段落左侧以红色大括号 + 红字标签标出各权利要求对应之处(标签规范:首现裸号「权1」、复现括注「权1(特征)」、多权逗号列表「权1(机架),2,3」,groups 结构化自动合成);连续同类段落合并为一个括号,跨页在页内断开并标注「(续)」(续标单独占行、与主体同字号);无文字层时用插件内 Tesseract / Windows.Media.Ocr 识别,或用外部权威文本直接合成透明文字层;附计划留痕(<输出>.plan.j

Readme

dsh-patent-claim-annotation

DSH 插件:把专利说明书的【具体实施方式】里对应各权利要求的内容标出来——在段落左侧画红色大括号 + 红字标签,输出标注版 PDF。

  • 连续且同属一条权利要求的段落 → 合并成一个括号
  • 一段多权 → groups:[{claim…}] 结构化,标签自动合成;标签规范只有一种(技能/README/verify 三处同步):首现裸号「权1」、复现括注「权1(机架)」、多权逗号列表「权1(机架),2,3,4,7」;兼容旧写法「权1中机架」。括注里的特征必须逐字取自权利要求原文(4~12 字,禁止概括/改写);特征号体例(无效程序对照意见陈述书)写「权1-特征1-1,1-2,1-3」——「特征N-M」是外部特征号、不计入权集(1.3.0 起,见下)
  • 一条权利要求跨页 → 按页断开,后续页标签自动加「(续)」(单独占行、与主体块同字号)
  • 没有文字层 → OCR(Tesseract 优先、失败降级 Windows.Media.Ocr 免装后端);手上有权威文本时用 patent_claim_text + outputPath 直接合成透明文字层(无需 OCR,画面逐像素不变)
  • 交付前自检:框外不许有任何改动(未改动页按逐对象字节判定、免渲染;有标注页逐像素)+ 三表互校(label ↔ groups ↔ 表1/表2,1.3.0 起表1 支持一权多行按并集比对)+ 引文逐字命中校验(干净文本 ∪ PDF 文字层双通道,不在成品里搜自己)
  • 计划留痕:annotate 落盘 <输出>.plan.json(items+report+options+逐条落点+sha256),verify 传 planPath/planSha256 直读——"自检的计划 = 生成的计划"机械可证,不必重抄 6K 字符;回显的 sha256 是完整 64 位指纹(= plan.json 的 sha256 字段值,不是 Get-FileHash)
  • 段落定位两套口径:有 [00xx] 段号的写段号("0037"),老公告文本没有段号时用 id = p<页>-<段序>(p10-2 = 第 10 页第 2 段,与无效请求书「D1 第10页第二段」同口径)
  • 已适配:繁体(中国台湾公告本)、扫描件 OCR 逐字空格、老公告顿号条目(1、 一 种…,页眉失效按"数字条目 ≥3"启发式回退)、无页眉的中文译文、日本公开公报体例(段首方括号小标题/【0001】 独占一行/【权利要求1】)
  • 自检请用未标注的原件:拿成品当输入时,页边距检查会把旧括号当墨迹、说明书页范围会把插件自己追加的说明页算进去——自检会在结尾明确提示这一点

安装

方式一:npm(不需要本机安装 git)

DSH 桌面端 → 侧栏「插件」→「添加插件」,输入:

dsh-patent-claim-annotation

方式二:从 Gitee 仓库安装(需要本机已安装 git;地址必须带结尾的 .git)

https://gitee.com/hc905/dsh-patent-claim-annotation.git

不带 .git 的裸地址(https://gitee.com/hc905/dsh-patent-claim-annotation)会被 pnpm 当成 tarball 去解包,报 ERR_PNPM_TARBALL_EXTRACT;实测 pnpm 11.7.0 必须带 .git。

方式三:本地路径(开发用)

link:<插件目录的绝对路径>

装完重启 DSH。改代码后同样必须重启:host 进程按模块 URL 缓存已加载的插件,切换开关/重装都不会重新导入(plugin_manager 自己会报 restart-required)。

同一台机器不要同时装「npm 版」「git 版」「本地 link 版」——三者的挂载 id 都是 patent-claim-annotation,会冲突。

本地开发安装(本机现状)

# 已在本机桌面 profile 装好(link 安装):
#   C:\Users\hanch\.dsh\profiles\desktop\package.json
#   "dsh-patent-claim-annotation": "link:D:/Dgit/Dplugins/dsh-patent-claim-annotation"
# 依赖解析靠目录内 node_modules 下的**逐包 junction**(pdf-lib / pdfjs-dist /
# @napi-rs/canvas / @pdf-lib/fontkit / @deepseek-ai/schemastery),指向 profile 的
# node_modules。不要把它换成"整个 node_modules 一条 junction":profile 里
# node_modules\dsh-patent-claim-annotation 又指回本目录,会形成无限递归,
# 任何 -Recurse 扫描(备份、索引、杀毒)都会被绕进去。

卸载

# 在 profile 目录执行(npm / git / 本地 link 都用这个包名)
pnpm remove dsh-patent-claim-annotation
# 再把 profile 的 dsh.profile.bundles 里的 dsh-patent-claim-annotation 删掉,然后重启 DSH

交付物约定

一次 patent_claim_annotate 调用产出一个 PDF + 一份计划留痕:

  1. 标注版 PDF —— <原文件名>权利要求对照标注版.pdf。默认两节都标:scope:"summary+embodiment"(=【发明内容】+【具体实施方式】);也可只标一节(summary/embodiment)或整篇说明书(description)。无【发明内容】小标题(美国申请译文体例)时自动识别「概述/概要/SUMMARY」小节,并在说明页写范围声明行。
  2. 「对应关系说明」直接渲染成新页附在这个 PDF 的最后(lib/pdfreport.js)——不单独出 docx(lib/docx.js 的写出器仅留给 scripts/spec-report-format.mjs 生成格式规范)。抬头只有标题(固定为「权利要求与说明书对应关系说明」,不随文件名变化)+ 可选的"文字来源"一行 + 可选的范围声明一行,没有"案件:…|标注对象:…"那一行。
  3. <输出>.plan.json(C4 计划留痕):items + report + options + 逐条落点(字号/行数/包围盒)+ sha256。verify 传 planPath/planSha256 直读,不再要求重抄计划;输出已存在时先备份 <名>.bak-<时间戳>(C10)。

说明页的四张表:逐条对应关系与依据 / 段落块-标签-页码 / 无对应与部分对应 / 未标注但可作旁证的段落。排版规则(写死,patent_claim_verify 会检查):

  • 每行统一最小行高(29pt ≈ 两行 9pt)+ 行内不跨页:行高由最高的格子决定,所以「依据」要短(一句最有力的原文片段,≤60 字,超了落笔前拒收并指出「第 N 行·第 M 列·X 字」);放不下就整行挪到下一页并重复表头。行高超标时插件只给候选建议(紧凑区间/放宽该列/人工确认合并)——N7:不自动合并段落块凑行高。
  • "依据"的引文口径(表头声明 + verify 机器校验):逐字引自说明书原文或权利要求书;「……」可拼接、各段各自逐字;括注照抄原文。改一个字自检会指出;N8:verify 只提示不改文件,引文差异由人改。
  • 固定列宽、权利要求 与 对应段落 两列收窄(约 3.0cm / 4.6cm),余宽给「依据」;列宽随页面可用宽度等比缩放(A4 纵向、左右各 1.27cm)。对应段落 列写"[0006]-[0012]、[0014]"这类紧凑引用。
  • 表头浅灰底纹、单元格垂直居中、细灰边框;全篇字体优先宋体(本机可嵌入的宋体是华文宋体 STSONG.TTF;simsun.ttc 是字体集合,fontkit 嵌不进去),宋体缺字形时按 仿宋→黑体→等线→楷体 退让。

标签规范只有一种(此处与 SKILL、verify 三处同步):首现裸号「权1」、复现括注「权1(机架)」、多权逗号列表「权1(机架),2,3,4,7」;括注特征逐字取自权利要求原文(4~12 字,N6:禁止自动概括/改写——排不下时给候选标签+预计字号由人选,别删特征词);兼容旧写法「权1中机架」。一段多权用 groups:[{claim,features?}],label 交给插件合成(手写 label 必须与 groups 权集一致,否则报错)。

特征号体例(1.3.0 起,无效程序刚需):按意见陈述书的特征拆分表写标签时用「权1-特征1-1」「权1(特征1-1,1-2,1-3)」这类特征号(「特征N-M」,含全角/半角连字符)——它是外部特征号、不是权利要求号:权集解析、label↔groups 校验、三表互校都把它排除(「权1-特征1-1,1-2,1-3」权集={1},行首列「权1-特征1-1 设备」认作权1 的子行,表1 可按特征一权多行拆写、同权各行按并集与表2 比对)。括注写特征号时逐字校验只提示「括注系外部特征号(非权利要求原文片段)」并放行(C7);claim 区间「权8-11」与旧标签规范不受影响。

成品要与别的 PDF 合成一本时:说明页必须排在整份文件的最后(在附图标记-中文释义对照表之后)。流程是「先合并、再用 annotate:false 追加说明页」——annotate:false 只追加说明、不重复画括号,自检改为证明原有各页未变(同样走逐对象字节判定,基本免渲染、秒级出结果)。落笔前会检测末尾结构并回显"说明页将落在谁之后";输入末尾已有说明页时默认拒绝重复追加(C13)。

六个工具

| 工具 | 作用 | |---|---| | patent_claim_outline | 认页、权利要求 1..N 原文(claims 解析后文本原样回传)、段落清单(默认【发明内容】+【具体实施方式】,scope 可选四档)与页码/几何。段落正文总量 > 3 万字符时只给"段号+摘要"(textMode:compact)。老公告顿号条目/断字页眉有启发式回退(warnings 写明)。只读 | | patent_claim_candidates | 按字符 n-gram 排候选段落(dice2/dice3/coverage),恒定 top-K、不按分数截断(低分标 low 供复核),挖出权利要求里逐字出现在该段的片段(括注特征候选),并聚合一段多权汇聚点(hubs,≥3 条命中同段 + 候选合成标签) | | patent_claim_text | 把外部干净文本(.docx/.txt/.md)与 PDF 的段落、权利要求对齐,登记文字来源与版次(含 SHA-256),提示 A/B 版次风险。PDF 无文字层时传 outputPath 直接合成透明文字层(无需 OCR,几何取渲染行框、画面逐像素不变)。对齐结果自动落干净文本登记 <PDF>.textsource.json(verify 引文双通道的「干净文本」一侧)。只读 PDF(除合成输出与登记文件) | | patent_claim_annotate | 落笔:红色大括号 + 红字标签(groups 自动合成/校验)→ 标注版 PDF;同一次调用把「对应关系说明」(四张表)附在这个 PDF 的最后;落盘 <输出>.plan.json(sha256 全量回显);dryRun:true 只预检不落笔——校验类问题(label 权集/引文/说明表字数/段落定位/字形)全部收集后一次返回(C5,不再首错即止),排版预算照常回显;重跑覆盖先备份;末尾结构检测;预览默认给省 token 的标注联系表 | | patent_claim_verify | 自检:原件各页框外零差异(未改动页按逐对象字节判定并免渲染,有标注页逐像素)、墨色、无白底、页边距;三表互校(硬,表1 一权多行按并集);依据引文逐字命中(干净文本 ∪ PDF 文字层双通道、剥段号前缀)、标签特征逐字出自 claim 原文、实渲字号=计划字号(软)。传 planPath/planSha256 直读生成计划(同源,不必重抄)。阈值可从入参传(verifyMarginInkMax 等,入参优先于 config);「(续)」等标签检索做归一化匹配 | | patent_claim_ocr | 没有文字层时 OCR:Tesseract(chi_sim)优先,失败降级 Windows.Media.Ocr(系统自带免装);跳过判据按字符分布(正文页 0 字不误跳过)。已移除 Acrobat 链路;全链路失败时报错附可执行出路 |

插件不替你判断哪段对应哪条权利要求:那要读原文、看上下文、认上下位概念,由模型判定;工具只给语料与线索,并把「落笔」「自证」做成可复核的两步。

配置(cordis.patch.yml)

color: '#FF0000'            # 标注色(样张实测标签为纯红)
outputSuffix: '权利要求对照标注版'
fontPath: ''                # 留空=自动挑单体 TTF 中文字体(**宋体优先**:华文宋体→仿宋→黑体→等线→楷体)
labelScale: 1.35            # 标签字号 = 正文字号 × 该倍数
labelMinSize: 8             # 标签最小字号(C2:5.5 → 8pt 下限,可配;正文 21.6pt 前 1:4 过小)
labelSingleLineMinSize: 8   # 优先排一行,为此最多缩到这个字号
maxLabelLines: 4            # 标签最多折 4 行(C2:宁可折行也别删特征词;「(续)」单独占行、可多占 1 行)
braceWidth: 0               # 0=自动(约 1.5 倍正文字号)
braceStroke: 0              # 0=自动(约 0.22 倍正文字号)
continuationSuffix: '(续)'
maxTextChars: 500           # outline 默认单条原文截断长度
fullTextCharLimit: 30000    # 段落正文总量超过它,outline 只给"段号+摘要"(压缩模式)
previewDpi: 150
ocrLang: chi_sim            # OCR 引擎链:Tesseract 优先,失败降级 Windows.Media.Ocr(已移除 Acrobat 链路)
ocrEngine: auto             # auto / tesseract / windows(C7 免装后端)
ocrDpi: 300
ocrConcurrency: 3           # OCR 渲染与识别各同时跑几路(调大更快、更占内存)
tesseractPath: ''           # 留空则按常见路径找
tessdataDir: ''             # 留空则复用系统/小奕自带语言包并缓存到 LOCALAPPDATA
reportBasisMaxChars: 60     # 说明表"依据"字数上限(C8:超限落笔前拒收并给建议)
reportExplanationMaxChars: 70  # 说明表"说明/未标注原因"字数上限
verifyDpi: 150              # 自检逐像素比对分辨率(只作用于有标注/可疑的页)
verifyConcurrency: 4        # 自检逐像素页的并发渲染数
verifyDiffTolerance: 16     # 单通道像素差超过它才算"不同"(原 8)
verifyInkTolerance: 72      # 成品像素与目标色的最大通道差,超过不算本插件的墨(原 60)
verifyColorDelta: 24        # 各处主色与配置色的最大通道差(原 8)
verifyMarginInkMax: 0.08    # 括号框内允许的原件墨迹占比(原 0.05)
verifyRuleColumnRatio: 0.4  # 整页墨迹覆盖高度比例超过它判为框线/装订线列(原 0.5)

patent_claim_annotate 的预览参数:previewDir(导出目录)、previewFullPages(是否额外整页导出,默认 false)、previewPages(限几页)、previewColumns(联系表列数,默认 2)。 外部文本优先:有权威文字版本时先跑 patent_claim_text,把返回的 textSourceLine 填进 report.textSource。

1.3.0(C4):上面五个 verify* 阈值也可以直接作为 patent_claim_verify 的工具入参 传(同名同义,入参优先于 config)——「括号压正文」被原件自带高亮/印刷框线误触发时, 不用改插件配置就能临时放宽(如 verifyMarginInkMax: 0.3)并当场交付;失败文案里也会写明 这条出路。放宽阈值请向用户披露。引文校验的「干净文本」通道用 verify 的 textPath 入参或 patent_claim_text 的登记文件(<PDF>.textsource.json)。

性能与自检阈值(1.1.0 起)

慢在哪:一次完整标注里,最贵的两处是 ①每次工具调用都重新认页/切段(扫描件 1.7 秒/次, 一次任务要调 outline→candidates→annotate→verify 各一遍);②patent_claim_verify 把 原件 + 标注版的每一页都渲染成 150DPI 位图再逐像素比(32 页 = 64 次渲染 ≈ 19 秒)。

怎么快起来(实测,样本 = TW569491B 扫描件 32 页、6 处标注):

| 阶段 | 1.0.1 | 1.1.0 | 靠什么 | |---|---|---|---| | 认页/切段(每次调用) | 1.7s | 0(首次 1.7s) | 按 路径+mtime+大小+范围 缓存切段结果(lib/structure.js) | | 落笔 patent_claim_annotate | 2.0s | 0.3s | 切段缓存 + 预览联系表按页并行渲染 | | 自检 patent_claim_verify | 19.4s | 0.7s | 未改动页按逐对象字节判定、免渲染(见下)+ 有标注页两文档并行渲染 + Uint32 整字快判 | | OCR(6 页 300DPI) | 22.6s | 11.8s | 渲染与 Tesseract 各 3 路并行 |

自检的两条证明路径(先字节、后像素,逐级退让):

  1. 逐对象字节比对(lib/integrity.js):落笔只追加对象,原件既有对象一个字节不改。 于是逐个对象比哈希——页面叶子对象没变 ⇒ 同一个渲染器必然渲染出同样的像素。这比逐像素 更强(逐像素会漏掉小于一个像元的位移,字节相等不会),而且免渲染,0.1 秒量级。 只有页树节点(Kids 追加了说明页)与文档信息字典允许变化;页树另按"前缀未变"核对页序。
  2. 逐页渲染逐像素(慢路径):有标注的页(顺带证明墨真的落了)、以及字节比对发现 可疑的页(有对象变了、页树对不上、pdf-lib 打不开)一律照旧渲染比对。

正确性优先:换了写出器、对象编号被重排时,逐对象比对会自认不可用并退回全量逐像素, 只慢不假。负样本回归实测:未标注页被加内容、已标注页框外被加内容、计划与成品对不上、 页被删掉、落笔颜色配错——五种情况全部被抓。

阈值为什么放宽(默认值与理由,均可在 cordis.patch.yml 里覆盖):

| 阈值 | 旧 → 新 | 理由 | |---|---|---| | verifyMarginInkMax | 5% → 8% | 扫描件页边有框线/噪点/装订痕迹;而括号真压住正文时墨迹占比通常 >25%,仍抓得住 | | verifyDiffTolerance | 8 → 16 | 150DPI 抗锯齿抖动在 ±10 内,真改动(文字位移、换图)是 ±100 起步 | | verifyInkTolerance | 60 → 72 | 红字压在灰底/扫描噪点上会整体偏移;蓝色标注差 255 照样挡在外面 | | verifyColorDelta | 8 → 24 | 抗锯齿边缘把主色往白色拉;配错颜色(#FF00FF)差 255 必被抓 | | verifyRuleColumnRatio | 0.5 → 0.4 | 多认一些细框线与虚线;正文列(<20%)不会被误认 |

想更严就把这些键调回去,或把 verifyDpi 提到 200——有标注的页才付这个代价。

踩过的坑(改代码前先看)

  1. 字体不能乱挑:simsun.ttc/msyh.ttc 是 TrueType 集合,pdf-lib 的 embedFont 吃不了;simsunb.ttf 名字像"宋体粗体",实际是 SimSun-ExtB(只有扩展 B 区生僻字),常用字会渲染成方框。现在候选从黑体开始,并且每次落笔前用 missingGlyphs() 逐个字符验字形,缺字直接报错。
  2. CNIPA 页眉会被读成一行(6CN102804493 B说明书4/6 页),不能整行匹配正则,只能把页眉成分全部抠掉再看剩下什么。
  3. OCR 条目号会断:11. 被读成 1 1.,所以要允许数字串里有空格,并且只认"连号 1,2,3…"的候选。
  4. 标签排版:权1(续) 曾被折成 权1(续 / )——现在有中日韩避头尾、开括号行尾禁则、括号成组不拆。
  5. 标签选型目标函数:候选行数 1..maxLabelLines 各排一次,剔掉超出括号高度 2.2 倍的,再在剩下的里取字号最大、行数最少且不与同页其它标注重叠的。避免"一行小字 5.5pt"与"三行大字撞邻居"两种极端。
  6. Windows PowerShell 5.1 把无 BOM 的 UTF-8 .ps1 当 GBK 读,中文字符串里的 $ 会被吞掉——本插件的 .ps1 一律纯 ASCII。
  7. junction 递归:profile 的 node_modules\<插件名> 指回插件目录;如果插件目录下的 node_modules 又整体指向 profile 的 node_modules,-Recurse 扫描会无限递归(实测把一次语法检查跑成了死循环)。现在改成逐包 junction。
  8. 目标文件被占用:交付物常被 PDF 阅读器/预览窗格锁着,writeFileSync 只会甩 EBUSY。现在统一走 writeFileChecked(),报"正被其它程序占用,请关闭后重试",并给出可换输出路径的提示。
  9. 表格行高:行高永远由该行最高的格子决定(Word 的 trHeight、PDF 里的 MIN_ROW_HEIGHT 都只是下限)。想行高齐只有一条路——把每格文字写短(尤其"依据"),插件能做的是固定列宽 + 统一最小行高 + 行内不跨页。
  10. 联系表要裁、不要缩:把整页缩成一张拼图会让标签糊掉;正确做法是按标注包围盒裁窄条再拼(lib/sheet.js),只留左页边距 + 一点正文。本案 11 处标注 → 1 张 0.84MP,相比 4 张整页 8.7MP 省约 10 倍像素,且文字全可读。
  11. 阈值压缩的暗礁:段落一压成摘要,模型就可能"没读过"某段却以为判过了,而 verify 只证明"画了的画对了"、证明不了"该画的都画了"。所以压缩模式下 patent_claim_candidates 恒定返回 top-K(低分标 low),并要求把未落笔的实质段落写进说明的表 4——把漏读变成纸面声明。
  12. 外部文本连排会串门:把"权利要求书 + 说明书"放在一个文件里时,最后一条权利要求会把后面整篇说明书吞进自己的文本(实测过)。splitExternalClaims 现在先在说明书起点([00xx] 或"说明书/技术领域/…"标题行)截断。
  13. 字形缺口不止在标签上:说明页的标题里写了 ↔,黑体没有这个字形,直接渲染成方框(−(U+2212) 也没有)。现在说明页的每个字都先验字形,缺了就报错并指出是哪条文字——比事后看方框强得多。
  14. 对"已标注的 PDF"再跑会读到自己画的标签:标签就在文字层里,会被当成正文——既混进段落文字(实测把 [0050] 这类段号吃掉、段落数从 38 掉到 36),又把"正文栏左边界"从 65pt 拉到 0pt(括号被压成 3pt)。现在三处都做了防护:解析阶段剔掉"贴着左边距 + 长得像本项目标签"的文字(正则必须覆盖 权1(材料)、权1(续) 这类带中文标签与括号后缀的写法,并把页数报出来提醒你"这份可能已经标注过"),栏边界改用全体正文行的中位数,段落区间允许区间内缺段号(OCR 常把 [0010] 并进上一段)。
  15. 字体缺字要自动兜底,不是直接报错:用户就想要标题里的 ↔,黑体偏偏没有。现在按"要画的所有字"挑字体——配置字体缺字就在候选里找一款能全覆盖的(本机 STSONG.TTF/STKAITI.TTF 有 ↔ 与 −),自动换并如实提示;候选都没有才报错。
  16. 自检快路径靠的是"落笔只追加对象"(1.1.0):lib/integrity.js 逐对象比哈希,页面叶子对象没变就免渲染。两个前提要看住——①写出器必须保留对象编号(pdf-lib 是;哪天换库、编号被重排,比对会自认不可用并退回全量逐像素,只会慢不会假);②有标注的页永远走像素路径,因为那是唯一能同时证明"墨真的落了"的路径。别图快把这条也跳过。
  17. 切段结果是缓存共享的(1.1.0):buildStructure 按 路径+mtime+大小+范围 缓存,同一份文件一次会话只切一次段。代价是返回的结构只读——在上面原地 sort/push 会污染别的调用方。

开发脚本(scripts/)

| 脚本 | 用途 | |---|---| | inspect.mjs | 打印结构轮廓:node scripts/inspect.mjs <专利.pdf> [--all] [--json out.json] [--chars N] | | annotate.mjs | 吃标注计划 JSON 落笔 → 标注版 PDF(末尾含「对应关系说明」页),可加 --verify、--preview dir、--full-pages | | verify.mjs | 对已产出的标注版 PDF 跑自检:node scripts/verify.mjs <plan.json> --input <原件.pdf> --output <标注版.pdf> [--dpi 150] | | merge.mjs | 按页搬页组新 PDF(合并/取页都行):node scripts/merge.mjs <输出.pdf> <源A.pdf[:1-9]> [<源B.pdf[:1-9,18-19]>] | | text.mjs | 外部文本对齐:node scripts/text.mjs <专利.pdf> <外部文本> [--source 出处] [--version B] [--claims-only] [--from 37] [--to 50] | | ocr.mjs | node scripts/ocr.mjs <无文字层.pdf> [--dpi 300](只走 Tesseract) | | selfcheck-tools.mjs | 工具层离线自检:真实跑 6 个工具的 execute,把返回值对 output.schema 逐字段验一遍,并跑 render | | spec-report-format.mjs | 生成格式规范文档(docs/对应关系说明-格式规范.docx):字体/页面/标题/表格/换行规则 + 示例表。示例表用插件自己那套排版代码渲染,供别的插件(如「附图标记-中文释义对照表」)照抄 | | test-claims.mjs | 回归测试(npm test 第二步):合成样本(现代体例/老公告/无文字层扫描件)走工具入口覆盖 1.2.0 改进点——groups 合成标签、三表互校、引文逐字校验、老公告条目识别、无文字层+外部文本合成、planPath 复跑、C8 拒收/C10 备份/C13 重复说明页拦截/C11 题注 | | win-ocr.ps1 | Windows.Media.Ocr 免装后端(C7):OCR 引擎链第二级;纯 ASCII(PS 5.1 把无 BOM UTF-8 当 GBK 读的坑) | | sandbox-tools.ps1 | 给 selfcheck-tools 搭沙箱(复制插件 + 逐包 junction + harness 模块桩) |

DSH 对工具输出做严格校验(未声明字段会让整次调用作废),而 host 又会缓存插件模块, 所以改完工具代码务必跑一遍 scripts/sandbox-tools.ps1——它能在不重启 host 的情况下 抓住 schema 不匹配。若 .ps1 被执行策略拦住,用 powershell -ExecutionPolicy Bypass -File scripts/sandbox-tools.ps1 -Pdf <专利.pdf>。

已知限制

  • 页面 /Rotate 不为 0 时拒绝落笔(要强行试就传 allowRotated: true)。
  • 左边距很窄时标签会缩字号(下限 8pt 可配);真放不下会出警告并给 ≥2 个候选标签+预计字号,不会静默画错——特征词不删(N6),由人选候选。
  • 标注是追加的内容流:原页面内容原样搬运,框外零差异已由 patent_claim_verify 证明(未改动页按逐对象字节判定、有标注页逐像素)。
  • OCR 只走免装链路:Tesseract(chi_sim)→ Windows.Media.Ocr。Acrobat 链路已彻底移除(多数机器装不了,装了 Pro 的也没有无人值守入口)。识别错误是已接受的代价;有权威文本时优先 patent_claim_text 合成文字层(字面比 OCR 准)。
  • 合成文字层(patent_claim_text 的 outputPath)按文档顺序把外部文本填进渲染行框:段落号会落在段首、字面逐字来自权威文本,但每段落在哪一页取决于行带数量——与原件行数差异大时页归属可能漂移,落笔前照常看 outline 的页码回显。
  • verify 不写文件(N8):引文差异/表间不一致只提示,由人改后重跑。

变更记录

见 CHANGELOG.md。

许可证

MIT(见 LICENSE)。