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

@zstadmin/doc-pdf-highlight

v0.1.0

Published

精准跨标签文本高亮库,支持 DOCX 转换 HTML 与 PDF.js 双场景。基于纯文本索引的 DOM 最小侵入包裹方案,精确匹配与 Levenshtein 模糊匹配双模式。

Readme

doc-pdf-highlight

精准跨标签文本高亮库,同时支持 DOCX 转换 HTMLPDF.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-highlight
yarn add doc-pdf-highlight

CDN 引用(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