EvilFlowersViewer是一个基于pdf.js库的PDF查看器,它让用户查看并与PDF文档交互 直接在浏览器中。 它由一个大学团队开发,是可靠、高效和易于定制的.
特征
- PDF 文档在浏览器中直接渲染
- 缩小文档的大小
- 通过页面缩略图视图进行页面导航
- 文档中的文本搜索
- 可选语义 / AI 搜索与关键词结果一起显示
- 共享整个文档或与所选页面共享
- BibTeX、BibLaTeX、RIS和文献目录中的引用导出
- 打印整个文档或带有所选页面
- 下载文档
- 浅/ 暗主题( 荣耀主机提供的主题, 否则是读者保存的选择, 否则是系统偏好)
- 全屏模式
- 从已停靠的绘图铁路上编辑文档( 自由手、 形状、 突出显示器、 清除器、 撤销/ 重写) 页面旁边,所以它从来没有覆盖文档
- 在页面角和缩略图上显示的页面书签
- 方便键盘和屏幕阅读器(参见 无障碍(中文(简体) )
智能浏览器
每个都仅在主机通过它所需要的回调时出现(参见: 智能浏览器:
- 解释 在可拖动弹出中选定段落、数字、表格或方程式,并手 解释到聊天
- 阅读聊天 关于公开出版物,停靠在页面旁:流出答案 链接回到书中,推荐出版物作为卡片,以及附件(选定 可移动芯片
- 聊天历史: 重新打开先前的对话; 对其他出版物的聊天只读
- 图、表和方程徘徊概述目录从页面中提取的内容, 带有显示裁剪、标题、表格或 LaTeX 的卡片以及聊天和解释动作
- 大赦国际的要点: 标出一个提示的助手的句子,从文字上划出,带有 每个亮点的注释徽章, 一个边栏列表 步过它们,并显示/隐藏每个 注释
- 建议: 开放页或a的类似、先决条件和高级出版物 选择
样式隔离( S)
所有取景器样式都标注在单个下 .efv-viewer 根类和尾风
全球飞行前禁用,所以 导入此库后, 将不再重写主机
应用程序 (单位:千美元)*, (中文(简体) ), body,按钮、输入和滚动条不受影响。 有用吗
其它方式: 每个工具都作为 .efv-viewer .x (台风) important: '.efv-viewer'以自己的宿主盟誓 .text-primary 或者说 .bg-secondary 无法
复为观相. Inter字体是自行托管的(没有外部Google字体请求).
消费者只需导入样式表——不需要人工范围界定/包装:
import '@evilflowers/evilflowersviewer/dist/style.css';
无障碍
使用键盘和辅助技术来使用:
- 键盘: 所有控件都可以通过 标签; 页面缩略图、工具 颜色表对 输入编号 :空间快捷键 : ←编号 :→ 页 次, + 键编号 :- 说吧 缩放, 法语 搜索, T级 目录, 一、导 言 资料, 页:1 份额, C级 引用, 英格兰 步骤后退(解释出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出 (中文(简体) ). 在任何文本字段中打入,包含主机,从不触发这些快捷键.
- 屏幕阅读器: 每个仅图标按钮都有一个可访问的名称(本地化),切换
曝光
aria-pressed编号 :aria-expanded左边的铁路是role="toolbar",对话框是role="dialog"+ 键aria-modal装入者通过role="status"。光彩化的页布是aria-hidden; 可选择的 pdf.js 文本 层中包含可读内容,当前搜索匹配在其上被标记 (单位:千美元)role="mark", (中文(简体) ),aria-current="true") (中文(简体) ). - 焦点运动( M): 一个可见
:focus-visible为键盘用户显示环并全部 动画尊重prefers-reduced-motion。 。 。 . - 观众的根带有一个
lang属性匹配options.lang所以发音是 没错 所有A11y CSS都标注在下面.efv-viewer永远不要碰主页.
开始
所需经费: 节点 ≥ 22.13 (由pdfjs-dist 6要求).
要从"邪恶花朵"开始 跟着这些步骤:
- 安装 EvilFlowersViewer 包 :
npm install @evilflowers/evilflowersviewer
- 导入默认值
renderPDFViewer函数和样式表:
import renderPDFViewer from '@evilflowers/evilflowersviewer';
import '@evilflowers/evilflowersviewer/dist/style.css';
- 用单个选项对象称呼它 。 它还原了Vue
App举个例子 可以在拆卸时卸载 :
const app = renderPDFViewer({
rootId: '#my-viewer', // CSS selector of the mount element
data: uint8ArrayOfPdf, // TypedArray of the PDF bytes
options: { theme: 'light', lang: 'en' /* … */ },
config: { download: true, share: true, print: true, edit: false },
});
// later, e.g. on route change:
app.unmount();
查看器选项和属性文档
| 投入 | 说明 |
|---|---|
| 根编号 | 您使用的组件标识 renderViewer 函数. |
| 数据 | 键入箭头( 如 . Uint8Array)与 PDF 字节. 也通过 data 或者说 url。 。 。 . |
| url 密码 | PDF 的 URL (中文(简体) ). pdf.js 获取它并显示进度栏;当服务器回答 HTTP 范围请求时(Accept-Ranges: bytes, (中文(简体) ), 206),第1页在文件全部下载之前制作. 没有 Range 支持, 文件将全部流出 . |
| http页眉 | 可选 Record<string, string> 随同发送 url 请求,例如:. Authorization。 。 。 . |
| 证书 | 可选布尔。 以交叉原产地发送 cookie url 请求. |
| 范围 | 可选号码。 每个Range请求的字节(pdf.js默认为65536). |
| 选项 | 可选对象由主题,语言,引用Bib,homeFunction等组成. |
| 选项。 主题 | "黑暗"或"光"。 强迫观众主题. 没有它,观看者使用读者最后选择的日/月切换(保存在 localStorage 作为 efv-theme),否则系统偏好,随之而来的是活体. |
| 选项。lang | "请"或"恩". 指定查看器的语言. |
| 选项 | 字符串或无效。 载有文件的引用(例如, @article{name, ...}) (中文(简体) ). |
| 选项。家庭功能 | 函数( 类型 : () => void)或无. 回向出家观相. |
| 选项。关闭功能 | 函数( 类型 : () => void)或无. 闭取相者. |
| 选项 | 函数( 类型 : “ (页数: 字符串) |
| 共享功能。页面 | 与所选页面字符串( 如“ 1, 3-6, 10 ”) 或无效( 表示没有页面) . |
| 共享功能. expaireDate | ISO 字符串指定共享文档的寿命 . |
| 函数 QQ 返回 | 返回含有共享文档链接的字符串. |
| 选项。打印功能 | 函数( 类型 : “ (页数: 字符串) |
| 选项.语义搜索功能 | 函数( 类型 : (query: string) => Promise<ISemanticSearchResult[]>)或无. 可选语义/AI搜索. 提供时,搜索面板显示第二列AI结果({ page, text, score? })关键词相匹配;省略面板时仅保留关键词. |
| 选项.edit 包 | 管理编辑功能的可选对象,包含以下功能: |
| 编辑 Package.saveGroupFunc | 函数( 类型 : (name: string) => Promise<{ response: { id: string } }>) (中文(简体) ). 保存新组并返回其ID. |
| 编辑软件包。 getGroupsFunc | 函数( 类型 : () => Promise<{ id: string; name: string }[]>) (中文(简体) ). 收回所有可用的组. |
| 编辑 Package.saveLayerFunc | 函数( 类型 : `( svg: string, groupId: string, page: number) @ 许诺 < ILayer |
| 编辑 Package.update LayerFunc | 函数( 类型 : (id: string, svg: string, groupId: string, page: number) => Promise<void>) (中文(简体) ). 更新特定页面上组合中的现有层. |
| 编辑软件包。 getLayerFunc | 函数( 类型 : “ (页: 数字, 组ID: 字符串) ) @% 承诺<ILayer> |
| 编辑软件包。 getLayersFunc | 可选函数( 类型 : (groupId: string) => Promise<IPageLayer[]>, (中文(简体) ), IPageLayer =: { id, svg, page }) (中文(简体) ). 在一个请求中返回组的每层;查看器在进入编辑模式时会加载一次,结果中缺失的页面没有分层,页面翻转不再取取. 失败后,观众会回到 getLayerFunc。与目录: GET /api/v1/annotation-items?annotation_id=<groupId>&paginate=false。 。 。 . |
| 选项.page 书签包 | 可选 { getBookmarksFunc, addBookmarkFunc, removeBookmarkFunc } 持续页印。 没有它,书签仍然有效 但只能持续到观众. |
| 选项 | 函数( 类型 : (entry: ISuggestedEntry) => void) (中文(简体) ). 为被点击的出版物卡打开主机的详细视图(建议,聊天). |
| 选项。bookmark 切换功能 | 函数( 类型 : (entry: ISuggestedEntry) => Promise<{ isOnShelf, shelfRecordId? }>) (中文(简体) ). 从读者的书架上添加或去掉一张卡片的出版物. |
| 选项 | 函数( 类型 : (kind: SUGGESTION_KIND, context?: { selectedText?, page? }) => Promise<ISuggestedEntry[]>),启用建议和选择菜单的"类似". |
| 选项。解释功能 | 函数( 类型 : (text: string, context?: IExplainContext) => Promise<IExplainResult>)启用“解释”; context 携带 page 关于数字/表/方程式, regionId。 。 。 . |
| 选项。聊天包 | 可选 IChatPackage。启用读取聊天-见 智能浏览器。 。 。 . |
| 选项 | 可选 IRegionPackage。允许图/表/方程式徘徊. |
| 选项. 代理说明包 | 可选 IAgentAnnotationPackage。启用 AI 突出显示层及其侧边栏. |
| 配置 | 可选配置对象控制查看器特性 . |
| 配置. 下載 | 布尔. 启用或禁用下载特性. |
| 相会. 份额 | 布尔. 启用或禁用共享特性 . |
| 配置. print | 布尔. 启用或禁用打印特性. |
| 配置编辑 | 布尔. 启用或禁用编辑功能. |
智能浏览器
观众从不跟后端说话 每个智能特性都是主机回调 一个特性在召回未通过时完全隐藏 - 没有按钮,没有菜单项,没有 层。 所有类型都从包中导出.
坐标和页
- 页面编号总是 读者 页面号码 (基于 1, 如查看器所示) 。 A 类 服务剪切或重排的复制件的主机在回答前转换它们.
- 职位(
IPageBox)是分数0..1页面宽度和高度 左上边 来源数字 :{ x0, y0, x1, y1 }在任何缩放时都保持正确.
聊天 - options.chatPackage
chatPackage: {
// Required. Stream the answer through the handlers; resolve when done.
// chatId is the conversation to continue, or null to start one — return the id used.
sendMessageFunc: async (message, contexts, { onChunk, onMessage, onEntries, onError }, { page, chatId }) => {
// ...
return { chatId };
},
resetFunc: () => {}, // optional: forget the current conversation
suggestions: ['Summarize this chapter'], // optional: prompt shortcuts in an empty chat
getChatsFunc: async () => [...], // optional, with getChatFunc: enables chat history
getChatFunc: async (chatId) => [...],
deleteChatFunc: async (chatId) => {}, // optional: delete buttons in history
}
- 公开出版物始终是聊天的主题,并非作为上下文发送.
contexts带读者随附的:selection, (中文(简体) ),explain, (中文(简体) ),region或者说highlight(单位:千美元)IChatContext) (中文(简体) ). - 答文为平.
[[page:12]]财务报告和审定财务报表[[region:<id>]]转换为跳入 书.onEntries将出版物显示为卡片(助理推荐工具). - 历史列表
IChatSummary物项;aboutThisBook: false聊天只开放读取.
区域 - options.regionPackage
regionPackage: {
// Called once per page and cached.
getRegionsFunc: async (page) => [
{ id, kind: 'figure' | 'table' | 'equation', page, bbox, caption, category, markdown, latex, imageUrl },
],
}
无 imageUrl 将卡片从页面中切入到区域中.
大赦国际强调: options.agentAnnotationPackage
agentAnnotationPackage: {
getAnnotationsFunc: async () => [
{ id, title, prompt, summary, status: 'pending' | 'done' | 'failed', unresolvedCount,
highlights: [{ id, seq, page, quads: [IPageBox, ...], text, note }] },
],
requestAnnotationFunc: async (prompt) => annotation, // optional: "ask to highlight" box
deleteHighlightFunc: async (annotationId, highlightId) => {}, // optional
deleteAnnotationFunc: async (annotationId) => {}, // optional
}
每个亮点都是按读取顺序排列的一句话(seq),每个文本行为一四.
试试看
npm run dev 挂载样本应用程序( m)src/App.vue每一个功能被接通 嘲笑英寸
src/assets/examples/params/examples.ts。AI 突出显示模拟读取 PDF 样本的真实文本
线条,因此在实际文本上突出显示地块;区域框每页固定.
捐款
我们欢迎社区捐款,帮助让邪恶斗士Viewer变得更好。 捐款,请跟随 这些步骤:
- 叉子恶花Viewer 仓库
- 为您的更改创建新分支
- 做你的改变,并用一个明确的承诺信息
- 将您的更改推进到您的防御库
- 创建拉动请求, 将您的更改合并到主 EvilFlowersViewer 主库
承认
这一开放源码项目由学生和博士生负责 信息学和信息技术学院 斯洛伐克大学 技术。 该软件供大学使用,配合其教育和研究活动。 我们 感谢教职员工对我们工作的支持和他们对开放源码社区的贡献.
