doc-pdf-highlight
v0.1.1
Published
精准跨标签文本高亮库,支持 DOCX 转换 HTML 与 PDF.js 双场景。基于纯文本索引的 DOM 最小侵入包裹方案,精确匹配与 Levenshtein 模糊匹配双模式。
Maintainers
Readme
doc-pdf-highlight
精准跨标签文本高亮库,同时支持 DOCX 转换 HTML 与 PDF.js 两种场景。
需要长期维护一个文档阅读器,既能在 Word 导出的 DOM 里划关键词,又能在 PDF.js 里定位和高亮?直接用这个就行。
核心特性
- 跨标签精准定位 — 基于纯文本索引,不会被
<span>、<b>、<br>等标签打断匹配 - 最小侵入包裹 — 用
Text.splitText+replaceChild包裹,不破坏 DOM 结构和事件绑定 - 精确 + 模糊匹配 — 精确不行自动降级到 Levenshtein 模糊匹配(带剪枝 + 拆分插入片段)
- PDF.js 专用管道 — 自动处理几何阅读顺序、textLayer 渲染等待、重渲补偿
- Zero dependency — 纯浏览器 DOM API,无任何第三方依赖
- TypeScript 友好 — 自带
.d.ts类型声明
安装
npm install doc-pdf-highlightyarn add doc-pdf-highlightCDN 引用(UMD):
<script src="https://unpkg.com/doc-pdf-highlight/dist/highlight.umd.js"></script>
<script>
// 全局变量 DocPdfHighlight
DocPdfHighlight.highlightPhrasesInDocxWithMapping('#content', ['关键词']);
</script>快速上手
场景一:DOCX 转换的 HTML 文档
import { highlightPhrasesInDocxWithMapping, clearDocxHighlight } from 'doc-pdf-highlight';
// 高亮关键词(自动忽略空格和标点)
const count = highlightPhrasesInDocxWithMapping('#document-container', [
'项目背景',
'技术架构',
'测试报告'
]);
console.log(`共高亮 ${count} 处命中`);
// 清除所有高亮
clearDocxHighlight('#document-container');CSS 样式:
.keyword-highlight {
background-color: rgba(31, 107, 255, 0.05);
color: #1f6bff;
padding: 0.1em 0.2em;
border-bottom: 1.5px solid #1f6bff;
border-radius: 0.15em 0.15em 0 0;
}
.paragraph-highlight {
/* 包含高亮关键词的段落的附加样式 */
}场景二:PDF.js 嵌入文档
import { ensurePdfHighlight, injectPdfHighlightStyles } from 'doc-pdf-highlight';
const iframe = document.querySelector('#pdf-viewer');
const doc = iframe.contentDocument;
// 注入 PDF 专用样式(只执行一次)
injectPdfHighlightStyles(doc);
// 一键高亮:自动找命中页 → 跳页 → 等渲染 → 高亮
const count = await ensurePdfHighlight(iframe, ['关键词1', '关键词2'], {
waitTimeout: 3000,
debug: false,
});
console.log(`高亮数量:${count}`);场景三:自定义文本节点收集策略
import { createCustomHighlighter } from 'doc-pdf-highlight';
// 创建只做精确匹配的高亮器
const myHighlighter = createCustomHighlighter({
enableFuzzy: false,
keywordClass: 'my-custom-highlight',
});
myHighlighter('#content', ['精确匹配']);场景四:预构建索引(性能优化)
import { buildDocxHighlightIndex, highlightInDom } from 'doc-pdf-highlight';
// 先构建索引
const index = buildDocxHighlightIndex('#content');
// 多轮高亮复用同一索引
highlightInDom('#content', ['关键词A'], { index });
highlightInDom('#content', ['关键词B'], { index });API 总览
| 函数 | 用途 |
|------|------|
| highlightPhrasesInDocxWithMapping(container, phrases, options?) | DOCX 场景一键高亮 |
| highlightInDom(container, phrases, options?) | 通用高亮入口,支持自定义收集器 |
| createCustomHighlighter(defaults?) | 工厂:创建配置固化的高亮器(返回 (container, phrases, options?) => number) |
| buildDocxHighlightIndex(container) | 构建 DOCX 容器的高亮索引 |
| buildPdfPageHighlightIndex(pageEl, opts?) | 构建 PDF 页面的几何阅读顺序索引 |
| clearDocxHighlight(container) | 清除所有高亮包裹,还原 DOM 结构 |
| scrollToHighlight(container, index?) | 滚动到第 index 个高亮 |
| normalizeText(str) | 标准化文本(去空白 + 去标点 + NFKC) |
| defaultDomCollector(root) | 默认 DOM 顺序文本节点收集器 |
| pdfReadingOrderCollector(pageEl, opts?) | PDF 阅读顺序文本节点收集器 |
| ensurePdfHighlight(iframe, keywords, options?) | PDF 一键高亮全套流程 |
| injectPdfHighlightStyles(doc) | 向 pdf.js iframe 注入样式 |
| pdfFindFirstMatchPage(app, keywords, debug?) | 查第一个命中页码 |
| waitPdfPageReady(iframeDoc, app, pageNum, timeout?) | 等待 textLayer 就绪 |
选项说明
interface HighlightOptions {
enableFuzzy?: boolean; // 是否启用模糊匹配兜底(默认 true)
fuzzyThreshold?: number; // 允许的最大编辑距离比例(默认 0.3)
collector?: (root: Element) => Text[]; // 自定义文本节点收集器
useParagraphHighlight?: boolean; // 是否给所在段落加 .paragraph-highlight(默认 true)
index?: HighlightIndex; // 预构建索引,避免重复遍历 DOM
keywordClass?: string; // 关键词 span CSS 类名(默认 'keyword-highlight')
paragraphClass?: string; // 段落 CSS 类名(默认 'paragraph-highlight')
}License
MIT
