主题
LiteParse —— 开源 PDF 解析器,支持空间文字抽取、OCR 与边界框。
本 crate 是核心 Rust 库。Node.js、Python 与 WebAssembly 的语言绑定以符合各语言习惯的封装,重新导出了同一批类型。
[LiteParse::parse] 运行的是一条固定流水线;[stages] 模块把其中每一步都作为公开函数暴露出来,供需要自己编排流水线的调用方使用。
结构体 LiteParseConfig
LiteParse 文档解析的配置。
pub struct LiteParseConfig {
pub ocr_language: String,
pub ocr_enabled: bool,
pub ocr_server_url: Option<String>,
pub ocr_server_headers: Vec<(String, String)>,
pub tessdata_path: Option<String>,
pub max_pages: usize,
pub target_pages: Option<String>,
pub extract_screenshots: bool,
pub continue_on_page_error: bool,
pub dpi: f32,
pub output_format: OutputFormat,
pub preserve_very_small_text: bool,
pub password: Option<String>,
pub quiet: bool,
pub num_workers: usize,
pub image_mode: ImageMode,
pub extract_images: bool,
pub image_output_dir: Option<String>,
pub extract_links: bool,
pub keep_headers_footers: bool,
pub extract_annotations: bool,
pub extract_form_fields: bool,
pub extract_structure_tree: bool,
pub extract_blocks: bool,
pub extract_content_bounds: bool,
pub extract_xfa_packets: bool,
pub extract_document_metadata: bool,
pub detect_screenshot_rects: bool,
pub render_form_fields: bool,
pub ocr_failure_fatal: bool,
pub ocr_hedge_delays_ms: Vec<u64>,
pub emit_word_boxes: bool,
pub extract_text_metadata: bool,
pub crop_box: Option<CropBox>,
pub skip_diagonal_text: bool,
pub page_orientation_corrections: Vec<PageOrientationCorrection>,
pub include_complexity: bool,
pub extract_vector_graphics: bool,
}字段
| 名称 | 类型 | 文档 |
|---|---|---|
ocr_language | String | OCR 语言代码(Tesseract 格式:“eng”、“fra”、“deu” 等)。 |
ocr_enabled | bool | 是否启用 OCR。为 true 时,对文字稀疏页与内嵌图片执行 OCR。 |
ocr_server_url | Option<String> | HTTP OCR 服务 URL(未提供时使用 Tesseract) |
ocr_server_headers | Vec<(String, String)> | 每次请求 ocr_server_url 时附带的额外 HTTP 头,形如 (name, value) 键值对。用于鉴权,例如 ("Authorization", "Bearer …")。ocr_server_url 为 None 时忽略。 |
tessdata_path | Option<String> | tessdata 目录路径。未设置时回退到 TESSDATA_PREFIX 环境变量。 |
max_pages | usize | 最多解析多少页。 |
target_pages | Option<String> | 指定要解析的页(例如 “1-5,10,15-20”)。为 None 表示全部页。 |
extract_screenshots | bool | 把解析出的页面渲染为 PNG 并通过 ParseResult.screenshots 返回。默认 false;PNG 载荷可能很大。 |
continue_on_page_error | bool | 在某页发生 PDFium 抽取失败后继续解析,并在 ParseResult.page_errors 中报告。默认 false 以保留快速失败行为。无论该项如何设置,打开文档与文档级失败仍然是致命的。 |
dpi | f32 | 渲染页面的 DPI(供 OCR 与截图使用)。 |
output_format | OutputFormat | 输出格式。 |
preserve_very_small_text | bool | 保留通常会被过滤掉的极小文字。 |
password | Option<String> | 加密/受保护文档的密码。 |
quiet | bool | 抑制进度输出。 |
num_workers | usize | 并发 OCR 工作线程数。默认为(CPU 核数 - 1),最小 1。 |
image_mode | ImageMode | 控制位图引用在 markdown 输出里如何呈现。该项不会开启内嵌图片抽取。 |
extract_images | bool | 把内嵌图片的字节与元数据抽取到 ParseResult.images。默认 false。为向后兼容,ImageMode::Embed 也会开启抽取(见 [LiteParseConfig::effective_extract_images])。 |
image_output_dir | Option<String> | 抽取出的内嵌图片写到的目录。要求 extract_images 为 true。 |
extract_links | bool | 抽取超链接批注,并在 markdown 输出里渲染成 [text](url)。默认开启。做基准对比(纯文本 ground truth 从不使用链接语法)时可关闭。 |
keep_headers_footers | bool | 在 markdown 输出里保留滚动的页眉/页脚,而不是剥离。默认情况下,markdown 渲染器会移除在多篇页面的上/下页面带里重复出现的行(以及 Page N of M 这类单页版式)。设为 true 即全部保留 —— 对宁可在下游去重、也不愿丢内容的抽取流程很有用。只影响 Markdown 输出。 |
extract_annotations | bool | 把所有 PDF 批注抽取进每个解析出的页面。默认 false。这与 extract_links 相互独立,后者只控制 Markdown 的链接重建。 |
extract_form_fields | bool | 抽取 AcroForm 控件字段与值。默认 false。 |
extract_structure_tree | bool | 抽取标签 PDF 的逻辑结构树。默认 false。 |
extract_blocks | bool | 输出每页分类好的版面块(标题、段落、列表项、带逐格边界框的表格、代码、分隔线、图形)及其边界框。默认 false。这就是 Markdown 渲染器所消费的同一套拆解结果,只是以数据形式暴露。它与 output_format 无关:blocks 在 JSON 与 text 模式下同样可得,开启它也绝不会改变渲染出的 Markdown。 |
extract_content_bounds | bool | 输出每页的 content_bounds:其顶层内容对象在视口坐标下的边界框并集(可见内容的范围)。默认 false,以保持默认输出形态不变。只要开启 extract_vector_graphics,内容边界仍会内部计算以供白填充启发式使用。 |
extract_xfa_packets | bool | 从 XFA 表单文档中抽取原始 XFA 数据包(名称 + XML 内容)到 ParseResult.xfa_packets。默认 false。非 XFA 文档返回空列表。 |
extract_document_metadata | bool | 把文档级来源元数据收集到 ParseResult.doc_meta。默认 false:对由非 PDF 格式转换而来的输入为 None,因为这些事实描述的是中间 PDF 而非调用方的文件。 |
detect_screenshot_rects | bool | 在渲染出的页面截图里检测实心矩形与粗线,并挂到每个 ScreenshotResult.rects 上。它工作在位图上,因此也能在没有矢量路径的扫描/压平页里找到结构。默认 false(每页多一次全位图扫描)。 |
render_form_fields | bool | 把 AcroForm 字段外观(已填值、复选框状态)画进渲染出的位图(截图与 OCR 输入)。这会初始化一个 PDFium 表单填充环境并执行文档的 open/JS 动作,因此默认关闭:普通解析既不该执行文档脚本,也不该改变带表单 PDF 的位图字节。 |
ocr_failure_fatal | bool | 系统性的 OCR 失败(所有 OCR 任务都失败,且至少一个是主要文字来源为 OCR 的文字稀疏页)是否让整个解析中止。默认 true:暴露根因,而不是静默输出空白页。设为 false 时,OCR 不可用会保留已恢复的原生文字并返回部分结果 —— 适合宁可要降级文档也不要硬失败的调用方(例如宿主本身有 OCR 兜底,或把 OCR 当作尽力而为的增强)。 |
ocr_hedge_delays_ms | Vec<u64> | 针对 HTTP OCR 引擎的请求对冲时间表(毫秒)。为空(默认)表示不对冲。给出多个延时(例如 [0, 5000, 10000, 15000, 20000])时,每次 OCR 尝试都会在每个延时各发一个重复请求,并取最先成功的那个 —— 用额外的 OCR 服务负载换取慢速/卡死 pod 上更低的尾部延迟。对 Tesseract 引擎无影响。 |
emit_word_boxes | bool | 在每个 TextItem 上输出逐词子框(TextItem.words)。默认 false:文字项本身已带自己的框,而逐词框会让文字项载荷大约翻倍(体积 + napi 序列化),所以只对做词级边界框归属的调用方才值得计算。为 false 时 TextItem.words 恒为空,逐词追踪完全跳过(零分配)。 |
extract_text_metadata | bool | 在公开的文字项上附带丰富的 PDF 文字元数据:MCID、字形宽度、字体度量/字重/异常状态、填充/描边颜色、原始字符码以及生成的尾随空格状态。默认 false,以保持 LiteParse 轻量的响应形态。版面所需的度量在内部依然可得;源字符码与生成空格状态只有开启该项才会计算。 |
crop_box | Option<CropBox> | 把输出限制在每页的某个子区域。每个字段表示从对应边裁掉的页面比例(例如 left = 0.5 丢弃左半边)。只有当文字项完全落在保留矩形 [left·W, (1-right)·W] × [top·H, (1-bottom)·H](左上原点)之内时才保留。None(默认)保留整页。它在 OCR 合并之后应用,因此区域之外的 OCR 文字也会被丢弃。 |
skip_diagonal_text | bool | 丢弃倾斜文字 —— 旋转角度与最近直角(0/90/180/270)偏离超过 2° 的项。默认 false。 |
page_orientation_corrections | Vec<PageOrientationCorrection> | 由调用方提供的逐页朝向修正,例如来自一个看过渲染页面的上游朝向分类器。每条记录指明一个从 1 开始的页号,以及该页内容在视口中呈现出的顺时针旋转角(0/90/180/270);LiteParse 会在抽取前按该角度反向旋转该页,于是文字坐标、阅读顺序、页面尺寸与 OCR 位图都会正向输出。它在 PDF 自身的 /Rotate 之上叠加。未列出的页以及超出文档末尾的页保持原样。默认为空。 |
include_complexity | bool | 在 parse 期间计算逐页复杂度信号,并挂到每个 ParsedPage 上(在 JSON 里以每页一个 complexity 对象呈现)。这些信号与独立的 is_complex API 返回的完全相同。默认 false。 |
extract_vector_graphics | bool | 在解析结果里暴露页面级的矢量路径数据(shapes 与合并后的水平/垂直 lines)。默认 false;即使关闭,路径对象仍会在内部被版面检测查看。 |
方法
pub fn effective_extract_images(self: &Self) -> bool { /* ... */ }是否应当执行内嵌图片抽取。为 true 的条件是
pub fn effective_emit_word_boxes(self: &Self) -> bool { /* ... */ }本次运行是否需要逐词框,无论由哪个阶段
pub fn output_word_boxes(self: &Self) -> bool { /* ... */ }绑定层是否返回
TextItem.words(napi、python、wasm;
结构体 PageOrientationCorrection
调用方为某一页提供的朝向修正。见 [LiteParseConfig::page_orientation_corrections]。
pub struct PageOrientationCorrection {
pub page: u32,
pub angle: u16,
}字段
| 名称 | 类型 | 文档 |
|---|---|---|
page | u32 | 从 1 开始的文档页号。 |
angle | u16 | 该页内容在视口中呈现出的顺时针角度;必须是 0、90、180、270 之一。 |
方法
pub fn quarter_turns_to_apply(self: &Self) -> Result<i32, String> { /* ... */ }需要加到页面
/Rotate上的四分之一圈数,使内容读起来
结构体 CropBox
以「每边裁掉的比例」表示的页面子区域。所有字段取值都在 [0, 1];区域非空要求 left + right < 1 且 top + bottom < 1。原点在左上角,与 TextItem 坐标一致。
pub struct CropBox {
pub top: f32,
pub right: f32,
pub bottom: f32,
pub left: f32,
}字段
| 名称 | 类型 | 文档 |
|---|---|---|
top | f32 | |
right | f32 | |
bottom | f32 | |
left | f32 |
枚举 ImageMode
属性:
Other("#[serde(rename_all = \"lowercase\")]")
markdown 输出器使用的图片处理方式。
Off—— 完全不输出图片引用。Placeholder(默认)—— 按阅读顺序,在每个图片的 y 位置输出引用,但不抽取也不返回像素字节。既让响应体积保持小,又让 LLM 能看到图表在文档里的位置。Embed—— 输出与Placeholder相同的引用,并把内嵌像素字节抽取到ParseResult.images(等价于设置LiteParseConfig::extract_images)。
pub enum ImageMode {
Off,
Placeholder,
Embed,
}枚举变体
Off
Placeholder
Embed
枚举 OutputFormat
属性:
Other("#[serde(rename_all = \"lowercase\")]")
支持的输出格式。
pub enum OutputFormat {
Json,
Text,
Markdown,
}枚举变体
Json
Text
Markdown
常量与静态项
常量 DEFAULT_PAGE_BATCH_SIZE
当 [crate::parser::LiteParse::open_batch_session] 的调用方没有指定批大小时,每批处理的页数。小到足以让实体化的结果保持可控,大到足以让每批一次的文档重开开销保持很低(在一份 457 页的文档上,这个批大小约占 13%,批大小取 50 时~约 4%)。
pub const DEFAULT_PAGE_BATCH_SIZE: usize = 25;常量 DEFAULT_DPI
OCR 位图与截图的默认渲染分辨率(LiteParseConfig::dpi)。
pub const DEFAULT_DPI: f32 = 150.0;枚举 LiteParseError
pub enum LiteParseError {
Pdf(pdfium::PdfiumError),
Io(std::io::Error),
Json(serde_json::Error),
Image(image::ImageError),
Ocr(String),
Conversion(String),
Config(String),
Other(String),
}枚举变体
Pdf(pdfium::PdfiumError)
Io(std::io::Error)
Json(serde_json::Error)
Image(image::ImageError)
Ocr(String)
Conversion(String)
Config(String)
Other(String)
模块 glyph_resolver
可选的树外(out-of-tree)字形还原钩子。
对于缺失或损坏 /ToUnicode 的字体,liteparse 内置的还原方式是:PostScript 字形名 → Adobe Glyph List,再用内嵌字体程序的反向 cmap(见 [crate::extract])。它是确定性的,但解不开那些字形名与 cmap 同样是垃圾的问题字体。[GlyphResolver] 让调用方接入更强的还原策略 —— 例如「字形轮廓 → Unicode 数据库」—— 而 liteparse 不必背上这份依赖。
解析器拿到的是字形矢量轮廓(路径线段),而不是 pdfium 句柄,因此实现自身不需要 pdfium,也与 liteparse 的字体内部保持解耦。它只在万不得已时被调用:某个字形已被 liteparse 判定不可信、且内置还原已经失败。
pub mod glyph_resolver { /* ... */ }Trait
Trait GlyphResolver
从字形的矢量轮廓还原出 liteparse 内置 cmap/AGL 还原无法解码的字形所对应的 Unicode 文本。
实现都在树外(发布的 @llamaindex/liteparse 不自带任何 resolver)。请用 [crate::LiteParse::with_glyph_resolver] 注入一个。
pub trait GlyphResolver: Send + Sync {
/* Associated items */
}必需项
必需方法
resolve: 依据轮廓还原一个字形。
提供的方法
fn resolve_codepoint(self: &Self, segments: &[(i32, f32, f32)]) -> Option<u32> { /* ... */ }把字形还原成单个码点,不做连字展开
常量与静态项
常量 GLYPH_RESOLVER_FONT_SIZE
在把字形路径线段交给 [GlyphResolver] 之前,采样时使用的字号(单位:点)。
以轮廓哈希为键的 resolver 必须正好在这个字号上采样,键才能对得上。
pub const GLYPH_RESOLVER_FONT_SIZE: f32 = 10.0;模块 layout
markdown 分类器所做块拆解的公开、可序列化视图。
分类器内部的 Block 是一个带逐变体载荷的 Rust enum。这种形态无法跨越 napi 或 PyO3 边界 —— 两者都不支持携带数据的 enum —— 所以公开类型是一个由 kind 区分的扁平结构体,变体专属字段以 Option 形式存在。这与本 crate 已有的 StructureAttributeValue 暴露方式一致,并让 Rust、JSON、Node、Python 与 WASM 共用同一种块形态,而不是分裂成三种。
凡是不适用于该块 kind 的字段都为 None,序列化时会被跳过,因此一个标题序列化成 {kind, text, level, bbox},而不是一堆 null。
pub mod layout { /* ... */ }结构体 LayoutCell
一个表格单元格:它渲染出的文本与它占据的区域。
背后没有墨迹的单元格,其 bbox 为 None —— 例如为补齐参差网格而插入的填充,或在估算位置(而非观察到的边界)处拆开的合并跨度的一半。
pub struct LayoutCell {
pub text: String,
pub bbox: Option<crate::types::Rect>,
pub colspan: Option<u16>,
pub rowspan: Option<u16>,
}字段
| 名称 | 类型 | 文档 |
|---|---|---|
text | String | |
bbox | Option<crate::types::Rect> | |
colspan | Option<u16> | 合并跨度,只出现在 merged_table 单元格上(且只在大于 1 时)。被邻格跨度吸收的单元格会整行缺席,与 HTML 的占位模型一致。 |
rowspan | Option<u16> |
结构体 LayoutBlock
一个分类后的块,以及它在页面上的位置。
由 kind 区分块的种类;每个字段各自适用于哪些种类见字段说明。块按阅读顺序出现,与 markdown 渲染器输出它们的顺序一致,因此这里的第 N 个块就是该页 markdown 里的第 N 个块。
pub struct LayoutBlock {
pub kind: String,
pub text: Option<String>,
pub level: Option<u8>,
pub bold: bool,
pub italic: bool,
pub ordered: Option<bool>,
pub marker: Option<String>,
pub lines: Option<Vec<String>>,
pub lang: Option<String>,
pub header: Option<Vec<LayoutCell>>,
pub rows: Option<Vec<Vec<LayoutCell>>>,
pub header_rows: Option<usize>,
pub id: Option<String>,
pub format: Option<String>,
pub bbox: Option<crate::types::Rect>,
}字段
| 名称 | 类型 | 文档 |
|---|---|---|
kind | String | 取自 heading、paragraph、list_item、code、table、merged_table、grid_fallback、rule、figure。 |
text | Option<String> | 带文字的那些种类(heading、paragraph、list_item)的渲染文本。表格文字在 header/rows 里;代码与网格文字在 lines 里。 |
level | Option<u8> | 标题层级(1–6),或 list_item 的列表嵌套深度。 |
bold | bool | 块内文字是否整体加粗 / 倾斜。仅 paragraph 与 list_item;为 false 时省略。 |
italic | bool | |
ordered | Option<bool> | list_item:列表是否有序,以及标记在页面上原样出现的样子(138.、iii)、•)。 |
marker | Option<String> | |
lines | Option<Vec<String>> | code 与 grid_fallback 的逐行原文。 |
lang | Option<String> | 为 code 尽力而为给出的语言提示。 |
header | Option<Vec<LayoutCell>> | table:检测到表头时的表头行。 |
rows | Option<Vec<Vec<LayoutCell>>> | table:正文行。merged_table:全部行(表头行在前,数量由 header_rows 给出);行是参差的 —— 被邻格跨度覆盖的单元格缺席。 |
header_rows | Option<usize> | merged_table:rows 开头有几行是表头行。 |
id | Option<String> | figure:图片在页内的 id 与其编码格式,与 markdown 渲染器发出的 img_{id}.{format} 目标一致。 |
format | Option<String> | |
bbox | Option<crate::types::Rect> | 该块占据的页面区域,坐标空间与 text_items 相同(左上原点、72 DPI 视口)。它是构成该块的所有来源行的并集,因此换行标题或多行段落会上报整条区域。块没有页面几何可依时为 None。 |
模块 parser
LiteParse 编排器:输入解析、配置,以及固定的解析顺序。
不变式:parse() 的每一步都必须经由 [crate::stages]。本文件只掌握顺序以及「配置→阶段」的接合;它不得直接伸手进 extract、ocr_merge、projection 或 markdown_layout,否则自己编排阶段的调用方就无法再复现 parse()。tests/stages_compose.rs 正是对这一等价性的断言。
pub mod parser { /* ... */ }结构体 ParseResult
解析一篇文档的结果。
pub struct ParseResult {
pub total_pages: u32,
pub pages: Vec<crate::types::ParsedPage>,
pub page_errors: Vec<crate::types::PageError>,
pub text: String,
pub outline: Vec<crate::types::OutlineTarget>,
pub images: Vec<crate::types::ExtractedImage>,
pub screenshots: Vec<ScreenshotResult>,
pub image_error_count: u32,
pub form_type: Option<i32>,
pub creator: Option<String>,
pub producer: Option<String>,
pub doc_meta: Option<crate::types::DocumentMetadata>,
pub xfa_packets: Option<Vec<crate::types::XfaPacket>>,
}字段
| 名称 | 类型 | 文档 |
|---|---|---|
total_pages | u32 | 源文档的总页数,指应用 target_pages 或 max_pages 限制之前的总数。 |
pages | Vec<crate::types::ParsedPage> | 投影过文字版面的解析页。 |
page_errors | Vec<crate::types::PageError> | 开启 continue_on_page_error 时收集到的页级 PDFium 抽取失败。 |
text | String | 整篇文档的文本,由所有页拼接而成。 |
outline | Vec<crate::types::OutlineTarget> | 文档大纲(书签),若存在。markdown 输出器在未标签化的 PDF 上把它作为高优先级标题来源。 |
images | Vec<crate::types::ExtractedImage> | 从文档抽取出的位图。除非解析器配置了 extract_images,否则为空。每条记录带着 markdown 输出器所引用的同一 id 与 format,因此调用方无需解析 markdown 就能把它们对应起来。 |
screenshots | Vec<ScreenshotResult> | 以 PNG 编码的页面截图。除非启用 extract_screenshots,否则为空。 |
image_error_count | u32 | 无法抽取的内嵌图片对象数量。一张坏图片不会让整篇文档的解析失败。 |
form_type | Option<i32> | PDFium 表单类型(0 无、1 AcroForm、2 XFA 完整、3 XFA 前景),只在启用表单字段抽取时出现。 |
creator | Option<String> | 文档 /Info 中的 Creator 项,若存在。 |
producer | Option<String> | 文档 /Info 中的 Producer 项,若存在。 |
doc_meta | Option<crate::types::DocumentMetadata> | 文档来源元数据(日期、版本/安全、签名、增量保存标记、trailer ID、原始 XMP 以及源文件大小)。仅在启用 extract_document_metadata 时出现;对由非 PDF 格式转换而来的输入为 None。 |
xfa_packets | Option<Vec<crate::types::XfaPacket>> | 原始 XFA 数据包,仅在启用 extract_xfa_packets 时出现。Some([]) 表示抽取已在非 XFA 文档上运行过。 |
结构体 ScreenshotResult
渲染单页截图的结果。
pub struct ScreenshotResult {
pub page_num: u32,
pub width: u32,
pub height: u32,
pub image_bytes: Vec<u8>,
pub is_solid_fill: bool,
pub rects: Vec<crate::types::ScreenshotRect>,
}字段
| 名称 | 类型 | 文档 |
|---|---|---|
page_num | u32 | |
width | u32 | |
height | u32 | |
image_bytes | Vec<u8> | |
is_solid_fill | bool | 每个像素同色时为 true(渲染后为空白页)。 |
rects | Vec<crate::types::ScreenshotRect> | 在位图中检测到的实心矩形/直线(视口坐标)。仅在 LiteParseConfig::detect_screenshot_rects 开启时填充。 |
结构体 LiteParse
LiteParse 的主编排器。
线程安全
LiteParse 是 Send + Sync,可以跨线程共享(例如放在 Arc 后面,或在多线程 tokio 运行时里并发使用)。
PDFium 本身不是线程安全的,所以所有 PDFium FFI 工作 —— 文档加载、页面渲染、文字抽取 —— 都要经由 [pdfium::Library] 持有的进程级全局锁串行化。对调用方而言,这意味着并发的 parse_* / screenshot* 调用是安全的,但它们的 PDFium 部分会顺序执行。OCR 阶段与网格投影(在 OCR 密集的文档上占据大部分运行时间)在锁之外运行,保持完全并发。
pub struct LiteParse {
// Some fields omitted
}方法
pub fn new(config: LiteParseConfig) -> Self { /* ... */ }pub fn with_ocr_engine(self: Self, engine: std::sync::Arc<dyn OcrEngine>) -> Self { /* ... */ }覆盖 OCR 引擎。一旦设置,无论
pub fn with_glyph_resolver(self: Self, resolver: std::sync::Arc<dyn crate::GlyphResolver>) -> Self { /* ... */ }注入一个字形还原钩子。一旦设置,liteparse 判定为
pub fn extract_request<''a>(self: &''a Self, target_pages: Option<&''a [u32]>, max_pages: usize) -> stages::ExtractRequest<''a> { /* ... */ }整次解析所用的 extract 阶段请求,由配置推导而来。
pub fn ocr_render_options(self: &Self, grayscale: bool, extracted: &stages::ExtractedPages) -> stages::OcrRenderOptions { /* ... */ }整次解析所用的 OCR 渲染阶段选项,由配置推导
pub fn screenshot_options(self: &Self, continue_on_page_error: bool) -> stages::ScreenshotOptions { /* ... */ }截图阶段的选项,由配置推导。
parse()会传入pub fn block_options<''a>(self: &Self, outline: &''a [OutlineTarget]) -> stages::BlockOptions<''a> { /* ... */ }块分类阶段的选项,由配置推导。
pub fn content_filters(self: &Self) -> stages::ContentFilters<''_> { /* ... */ }内容过滤阶段的选项,由配置推导而来。
pub fn ocr_engine(self: &Self) -> Result<Option<std::sync::Arc<dyn OcrEngine>>, LiteParseError> { /* ... */ }一次解析将要使用的 OCR 引擎:设置了覆盖就用覆盖,否则用
pub async fn is_complex(self: &Self, input: PdfInput) -> Result<Vec<stages::PageComplexityStats>, LiteParseError> { /* ... */ }判定文档中每一页的复杂度,返回一个向量
pub async fn parse(self: &Self, input: &str) -> Result<ParseResult, LiteParseError> { /* ... */ }从文件路径解析文档,返回结构化结果。
pub async fn parse_input(self: &Self, input: PdfInput) -> Result<ParseResult, LiteParseError> { /* ... */ }从文件路径或原始字节解析文档。
pub fn parse_from_pages(self: &Self, pages: Vec<Page>, outline: Vec<OutlineTarget>) -> ParseResult { /* ... */ }从预先抽取好的页面解析,跳过 PDFium 的文字抽取。
pub fn parse_from_blocks(self: &Self, pages: Vec<Page>, page_blocks: Vec<Vec<stages::PositionedBlock>>, all_blocks: Option<Vec<stages::PositionedBlock>>, outline: Vec<OutlineTarget>, images: Vec<crate::types::ExtractedImage>, page_stats: Vec<Option<stages::PageComplexityStats>>) -> Result<ParseResult, LiteParseError> { /* ... */ }直接由块构建输出:调用方自行掌控块级
pub async fn screenshot(self: &Self, input: &str, page_numbers: Option<Vec<u32>>) -> Result<Vec<ScreenshotResult>, LiteParseError> { /* ... */ }生成文档页面的截图,返回 PNG 字节。
pub async fn screenshot_input(self: &Self, input: PdfInput, page_numbers: Option<Vec<u32>>) -> Result<Vec<ScreenshotResult>, LiteParseError> { /* ... */ }从文件路径或原始字节生成截图。
pub fn config(self: &Self) -> &LiteParseConfig { /* ... */ }pub async fn open_batch_session(self: &Self, input: PdfInput, batch_size: usize) -> Result<ParseSession, LiteParseError> { /* ... */ }为「内存有界的批量解析」打开一份文档。
结构体 ParseSession
只打开一次、按内存有界的页批次解析的文档。
pub struct ParseSession {
// Some fields omitted
}方法
pub fn total_pages(self: &Self) -> u32 { /* ... */ }源文档的总页数,指
max_pages或分批之前的总数。pub async fn next_batch(self: &mut Self) -> Result<Option<ParseBatch>, LiteParseError> { /* ... */ }解析并返回下一批,或在范围内的每一页都已处理完毕时返回
None。
结构体 ParseBatch
来自 [ParseSession] 的一批页面。
pub struct ParseBatch {
pub start_page: u32,
pub end_page: u32,
pub result: ParseResult,
}字段
| 名称 | 类型 | 文档 |
|---|---|---|
start_page | u32 | 本批次的第一页源页号,从 1 开始。 |
end_page | u32 | 本批次的最后一页源页号,从 1 开始且含该页。 |
result | ParseResult | start_page..=end_page 范围内的页,按普通结果解析。 |
模块 raw_text
原始文字项:pdfium 的文字流,配合固定的、不含启发式的切分。
[extract_raw_text_items] 是 [crate::extract] 里分段器的底层对应物。它不施加任何版面启发式 —— 没有基于间距的行/词合并、不跳过隐形文字、不做连字展开、不做标点规范化、不去重 —— 因此它的输出是 pdfium 所报内容的稳定函数,消费方可以在其之上自建切分。被已知矩形裁剪隐藏的字形会在分组前被剔除;部分被裁剪的字形只要其宽松框与裁剪区相交就整份保留。未知裁剪则保留文字。
规则:
- 一个项是同一个文本对象的同一角度上的一段字形。若某个字形的文本对象与该项首字形不同,或角度与之相差超过 0.01 rad,就开启一个新项。
- pdfium 生成的
\r或\n会结束当前项并被丢弃。 - 其他所有生成的字形,以及每个 ASCII 空白字形(
\t..\r与空格;U+00A0、U+3000 等不算)都会先追加、再结束该项。因此一个 pdfium 合成的空格永远是项的最后一个字形 —— [RawTextItem::trailing_space_generated] 报的就是它。 - 边界是各字形宽松框的并集。角度、颜色、marked-content id、字体与字体度量取自首字形。
text_width累加逐字形的推进宽度。 - 角度是该字形文本矩阵的基线方向(取其第一列的
atan2(b, a)),而不是 pdfium 的FPDFText_GetCharAngle:错切(斜体)字体的错量落在第二列,它不该改变阅读方向。并与页面/Rotate一起折叠到[0, 2π)。 - [
RawTextItem::grounding_bounds] 是该项真实字形的紧框:所有非生成、非空白的字形(在问题字体还原之后判定)都被投影到沿基线与垂直基线两个方向,极值重新居中为一个矩形,再按角度绕其中心旋转。没有符合条件的字形时为None。错切字体的宽松框会与下一个词重叠,这个框不会。正交、未错切的文字投影其严格字形框的四角。旋转或错切的文字则投影字形轮廓的点(见 [glyph_outline_support]):pdfium 的字符框在页面坐标里已经包住旋转后的字形,其空荡荡的四角无法被旋转回墨迹。轮廓无法替代实际描绘的字形 —— 描边渲染模式、Type3 以及非Identity-H的 CID 字体、读不到的几何 —— 保留其严格框。 - [
RawTextItem::baseline_gap] 只在这样一种项上测量:它是水平字体(Type1、TrueType,或Identity-H的 CID 字体)两个真实字形之间唯一一个 pdfium 生成的空格,且这些字形共享同一基线方向;取上一字形原点到下一字形原点的推进量减去上一个字形的宽度,单位是页面点。在外框无法反映真实间距时,它报出真正的分离程度。相邻字形不合格,或原点倒退(pdfium 在旋转页上反转对象顺序时会这样)时为None。 - [
append_raw_widget_text_items] 追加可见表单控件外观所绘制的文字 —— 在它们被压平之前,pdfium 的文字 API 不会报出这些内容。 - 一个字体被称为“问题字体”,条件是:它被内嵌且其名称/类型符合子集字体启发式,或者任意非生成字形解码到了控制码点或私用区码点。pdfium 无法映射到 Unicode 的字形解码为 0,因而也计入 —— 所以每个 Type3 项都算问题字体。
- 配有 [
GlyphResolver] 时,问题项里每个非生成字形都会被重新解码:先试 Type3 的字形名,再把字形轮廓交给 resolver。无法识别的字形变成空格。没有 resolver 时,文字保持 pdfium 解码出的样子。 - 文本按 C 字符串语义由字形码点构建:码点为 0(无 Unicode 映射的字形)会提前终止文本;不是合法 Unicode 标量值的码点(代理项,或大于 U+10FFFF)会让整个项被丢弃。
坐标是按每个字形经由 [Page::bounds_to_viewport] 换算的 —— 即精确的 FPDF_PageToDevice 量化 —— 而不是仿射近似 [Page::viewport_transform],因此框可以逐位复现。视口会按页面的 /UserUnit 缩放,与 liteparse 各处一致。
pub mod raw_text { /* ... */ }结构体 RawTextItem
一个原始文字项,处于视口坐标空间(左上原点、72 dpi 点)。
pub struct RawTextItem {
pub text: String,
pub char_codes: Vec<u32>,
pub glyph_names: Option<Vec<String>>,
pub angle_radians: f32,
pub text_width: f32,
pub x: f32,
pub y: f32,
pub width: f32,
pub height: f32,
pub grounding_bounds: Option<pdfium::RectF>,
pub baseline_gap: Option<f64>,
pub mcid: Option<i32>,
pub font_name: String,
pub font_size: f32,
pub font_weight: i32,
pub font_height: f32,
pub font_ascent: f32,
pub font_descent: f32,
pub font_is_buggy: bool,
pub trailing_space_generated: bool,
pub fill_color: Option<u32>,
pub stroke_color: Option<u32>,
}字段
| 名称 | 类型 | 文档 |
|---|---|---|
text | String | 字形码点的 UTF-8。保留空白,包括尾随空格;NUL 与非法标量值的语义见模块文档。 |
char_codes | Vec<u32> | 按页顺序每字形一项:内容流里的原始字符码,pdfium 生成的字形为 0。 |
glyph_names | Option<Vec<String>> | 仅 Type3 字体为每字形给一项,与 char_codes 平行:字体把该码点绑定到的 PostScript 字形名,未绑定时为 ""。其他所有字体类型为 None。 |
angle_radians | f32 | 逆时针旋转角(弧度),已折叠页面旋转,取值在 [0, 2π)。保留为弧度,便于消费方按自己需要的精度换算。 |
text_width | f32 | 各字形推进宽度之和(文本空间)。 |
x | f32 | |
y | f32 | |
width | f32 | |
height | f32 | |
grounding_bounds | Option<pdfium::RectF> | 该项真实字形的紧框,形态为一个矩形,需按 angle_radians 绕其中心旋转;见模块文档。视口坐标空间。 |
baseline_gap | Option<f64> | 跨唯一一个生成空格的推进间隙,单位页面点;见模块文档。相邻字形重叠时为零或负。 |
mcid | Option<i32> | 首字形所属文本对象的 marked-content id,若存在。 |
font_name | String | 基础字体名,已按 pdfium 的方式剥去子集标签;首字形没有文本对象、或该对象无字体时为 ""。 |
font_size | f32 | |
font_weight | i32 | |
font_height | f32 | font_size 乘以文本矩阵的纵向缩放;首字形没有文本对象时为 0。 |
font_ascent | f32 | 字体未暴露度量时为 0。 |
font_descent | f32 | 字体未暴露度量时为 0。 |
font_is_buggy | bool | |
trailing_space_generated | bool | 最后一个字形是 pdfium 合成的空格,而非内容流里的空格字形。 |
fill_color | Option<u32> | 首个字形的填充颜色,打包为 ARGB;仅当其色彩空间可用 RGB 表达时。 |
stroke_color | Option<u32> | 首个字形的描边颜色,打包为 ARGB;可表达时。 |
函数 extract_raw_text_items
抽取 text_page 的原始文字项。view_box 是页面的裁剪框([Page::view_box]);glyph_resolver 是针对问题字体的、可选的基于轮廓的还原(见模块文档),传 None 则问题文字保持原解码结果。
pub fn extract_raw_text_items(page: &pdfium::Page<''_, ''_>, text_page: &pdfium::TextPage<''_, ''_>, view_box: &pdfium::RectF, glyph_resolver: Option<&dyn GlyphResolver>) -> Vec<RawTextItem> { /* ... */ }函数 append_raw_widget_text_items
追加 page_index 页上可见表单控件外观所绘制的文字 —— [extract_raw_text_items] 看不到这些内容:pdfium 的文字 API 只有在外观字形被压平进页面内容后才会报出它们。外观在一个页面的私有副本上压平([Document::widget_appearance_copy]),并用同样的规则抽取,然后追加到 items —— 但某个控件项若在相同几何位置重复了已有项的文字则除外(某些生产者会在两处都输出它)。追加的项不带 marked-content id:外观的 MCID 不属于页面的结构树。
当副本无法构建或读取时返回 false;此时 items 保持不变,调用方继续沿用已有的页面文字。没有此类控件的页是一个无副作用的 true。
pub fn append_raw_widget_text_items(doc: &pdfium::Document<''_>, page: &pdfium::Page<''_, ''_>, page_index: i32, glyph_resolver: Option<&dyn GlyphResolver>, items: &mut Vec<RawTextItem>) -> bool { /* ... */ }结构体 SearchOptions
搜索文字项的选项。
pub struct SearchOptions {
pub phrase: String,
pub case_sensitive: bool,
}字段
| 名称 | 类型 | 文档 |
|---|---|---|
phrase | String | |
case_sensitive | bool |
函数 search_items
在文字项中搜索短语匹配,返回合成的合并项。
连续的文字项会被拼接后搜索。当一个短语跨多个项时,结果是一个合并后的单项,带合并的边界框与匹配到的文字。字体元数据取自第一个匹配到的项。
pub fn search_items(items: &[crate::types::TextItem], options: &SearchOptions) -> Vec<crate::types::TextItem> { /* ... */ }模块 stages
以公开阶段函数形式给出的解析流水线。
LiteParse::parse 是一串固定顺序的阶段:open → orientation → extract → complexity → OCR render → recognition → OCR merge → content filters → grid projection → block classification → markdown rendering。本模块把每个阶段暴露成作用于可序列化类型的函数,于是调用方可以自行跑完同一串阶段,并在阶段之间插入自己的输入 —— 自己的 OCR 引擎、自己的页选择、额外的块 —— 也可以在任意两个阶段之间架一道进程边界。
阶段分成两类。绑定 pdfium 的阶段接收一个已打开的 [Document],必须在打开它的那个 [Library] 存活期间运行(PDFium 是单线程的,背后由进程级全局锁保护,所以这些区段要尽量短,且绝不要把一个 Document 跨 .await 持有)。纯函数 阶段接收并返回普通数据,可以在任何地方运行。
| 阶段 | 函数 | 类型 |
|---|---|---|
| open + orientation | [open], [apply_orientation] | pdfium |
| document facts | [outline], [xfa_packets], [document_metadata] | pdfium |
| extract | [extract] | pdfium |
| complexity | [page_complexity], [layout_complexity] | pdfium / pure |
| OCR | [render_for_ocr] → [recognize] → [merge_ocr] | pdfium / any / pure |
| content filters | [apply_content_filters] | pure |
| projection | [project] | pure |
| markdown | [document_signals] → [extract_blocks] → [render_page_markdown] | pure |
| screenshots | [screenshots] | pdfium |
[Document] 与 [Library] 是把 pdfium crate 的类型原样重导出,因此那个 crate 的句柄 API 也是本模块契约的一部分。
pub mod stages { /* ... */ }结构体 ExtractRequest
[extract] 从文档里取出哪些内容。
pub struct ExtractRequest<''a> {
pub target_pages: Option<&''a [u32]>,
pub max_pages: usize,
pub extract_links: bool,
pub glyph_resolver: Option<&''a dyn crate::GlyphResolver>,
pub output: ExtractionOutputOptions,
}字段
| 名称 | 类型 | 文档 |
|---|---|---|
target_pages | Option<&''a [u32]> | 要抽取的页(从 1 开始);None 表示全部页。 |
max_pages | usize | 抽取页数的上限,在 target_pages 之后应用。 |
extract_links | bool | 把链接批注解析到它所覆盖的文字项上。 |
glyph_resolver | Option<&''a dyn crate::GlyphResolver> | 针对问题字体的兜底字形还原(见 [crate::GlyphResolver])。 |
output | ExtractionOutputOptions | 要产出哪些可选输出(图片、逐词框、表单字段……)。 |
结构体 OcrWindow
滑动渲染窗口内正在进行的 OCR 识别。
[recognize] 会等它拿到的整批位图全部完成。而 LiteParse::parse 改为最多只并行 num_workers 个识别,一个完成就立刻渲染下一页,因此某一页变慢不会让其他 worker 空转。当每一轮都用 [OcrWindow::render_next] 渲染时(它渲染的页数不会超过空闲槽位数),位图内存就被 num_workers 约束住。
原生识别跑在 Tokio 的阻塞线程上。在 WASM 上,识别的 future 可以 await JavaScript 的 promise。
pub struct OcrWindow {
// Some fields omitted
}方法
pub fn new(engine: Arc<dyn OcrEngine>, language: &str, num_workers: usize) -> Self { /* ... */ }启动一个窗口,最多同时运行
num_workers个识别。pub fn available_capacity(self: &Self) -> usize { /* ... */ }还能提交多少张位图而不必等待。
pub fn render_next(self: &Self, document: &Document<''_>, pages: &[Page], start: usize, options: &OcrRenderOptions) -> Result<(Vec<OcrRaster>, usize), LiteParseError> { /* ... */ }[
render_for_ocr] 的结果被限制在available_capacity之内pub fn complete_ready(self: &mut Self) { /* ... */ }记录已经完成的识别,不做等待。
pub async fn complete_one(self: &mut Self) -> bool { /* ... */ }等到一个进行中的识别完成并记录它。返回
pub fn take_completed(self: &mut Self) -> Vec<PageOcrOutcome> { /* ... */ }按提交顺序取出已完成的输出。对
finish的后续调用pub async fn submit(self: &mut Self, raster: OcrRaster) { /* ... */ }为一张位图启动识别,若窗口已满则先等待空闲槽位
pub async fn finish(self: Self) -> Vec<PageOcrOutcome> { /* ... */ }等待剩余的识别并返回全部输出,顺序
pub async fn finish_and_merge(self: Self, pages: &mut [Page], ocr_failure_fatal: bool, emit_word_boxes: bool) -> Result<(), LiteParseError> { /* ... */ }先
finish,再用 [merge_ocr] 把输出并入pages。
结构体 ContentFilters
调用方要求的文字项过滤,作用于 OCR 合并与投影之间。
pub struct ContentFilters<''a> {
pub crop_box: Option<&''a crate::config::CropBox>,
pub skip_diagonal_text: bool,
}字段
| 名称 | 类型 | 文档 |
|---|---|---|
crop_box | Option<&''a crate::config::CropBox> | 只保留完全落在保留页面区域内的项。 |
skip_diagonal_text | bool | 丢弃倾斜文字(水印、旋转盖章)。 |
结构体 DocumentSignals
块分类器需要的全文档级信号:对所有页计算一次,再由 [extract_blocks] 逐页应用。标题层级是相对文档的正文字号排出的,而滚动页眉/页脚是跨页重复出现的那些行 —— 两者都无法只看一页就判定。分批分类页面的调用方必须先对整篇文档计算它,否则标题层级会在批次之间漂移。
pub struct DocumentSignals {
pub body_size: f32,
pub heading_map: Vec<(f32, u8)>,
pub header_footer: std::collections::HashSet<String>,
}字段
| 名称 | 类型 | 文档 |
|---|---|---|
body_size | f32 | 主导正文字号(点);没有任何带字号的行时为 0.0。 |
heading_map | Vec<(f32, u8)> | (font_size, heading_level) 键值对,字号从大到小,层级 1..=6。 |
header_footer | std::collections::HashSet<String> | 需要抑制的滚动页眉/页脚文本(归一化后)。当设置了 keep_headers_footers,或文档短到无法判定时为空。 |
结构体 BlockOptions
除信号之外,[extract_blocks] 的文档级输入。
pub struct BlockOptions<''a> {
pub outline: &''a [crate::types::OutlineTarget],
pub image_mode: crate::config::ImageMode,
pub keep_headers_footers: bool,
}字段
| 名称 | 类型 | 文档 |
|---|---|---|
outline | &''a [crate::types::OutlineTarget] | 文档大纲;属于该页的条目在未标签化 PDF 上作为高优先级标题来源。 |
image_mode | crate::config::ImageMode | 图形是否以及如何在块列表中出现。 |
keep_headers_footers | bool | 关闭滚动版式抑制(信号里的跨页集合与单页检测器都关掉)。 |
结构体 ScreenshotOptions
[screenshots] 渲染页面的方式。
pub struct ScreenshotOptions {
pub dpi: f32,
pub detect_rects: bool,
pub render_form_fields: bool,
pub continue_on_page_error: bool,
}字段
| 名称 | 类型 | 文档 |
|---|---|---|
dpi | f32 | |
detect_rects | bool | 在位图里检测实心矩形/直线(ScreenshotResult::rects)。 |
render_form_fields | bool | 绘制表单字段外观(会执行文档动作)。 |
continue_on_page_error | bool | 渲染失败的页跳过而不是让整个调用失败。 |
函数 open
打开 input 并应用逐页的朝向修正。
/Rotate 的改写只存在于已打开的文档里,因此对同一输入的每次重新打开(抽取、OCR 各轮、截图)都必须经由本函数、并传入同样的 corrections,才能看到同样的页面几何。
pub fn open<''lib>(lib: &''lib Library, input: &crate::types::PdfInput, password: Option<&str>, corrections: &[crate::config::PageOrientationCorrection]) -> Result<Document<''lib>, crate::error::LiteParseError> { /* ... */ }函数 apply_orientation
把 corrections 里列出的页反向旋转,使其内容正向可读。[open] 已经做了这件事;只有在以其他方式打开的文档上才需要直接调用它。
pub fn apply_orientation(document: &Document<''_>, corrections: &[crate::config::PageOrientationCorrection]) -> Result<(), crate::error::LiteParseError> { /* ... */ }函数 repair_acroform
属性:
Other("#[attr = CfgTrace([Not(NameValue { name: \"target_arch\", value: Some(\"wasm32\"), span: crates/liteparse/src/stages.rs:95:11: 95:33 (#0) }, crates/liteparse/src/stages.rs:95:10: 95:34 (#0))])]")
重写那些控件与其页面脱链(orphaned)的 AcroForm,让表单字段抽取能够看到它们。需要重写时返回修复后的输入;文档本身没问题时返回 None。返回值就是用于抽取的 [open] 输入;而来源事实仍应取自原始输入。
pub fn repair_acroform(lib: &Library, input: &crate::types::PdfInput, password: Option<&str>) -> Option<crate::types::PdfInput> { /* ... */ }函数 outline
遍历文档大纲(书签)。它是文档级的,且比打开文档贵数倍,因此按页批量解析的调用方应当只做一次。
pub fn outline(document: &Document<''_>) -> Vec<crate::types::OutlineTarget> { /* ... */ }函数 xfa_packets
来自文档 /XFA 数组的原始 XFA 数据包。非 XFA 文档返回空。
pub fn xfa_packets(document: &Document<''_>) -> Vec<crate::types::XfaPacket> { /* ... */ }函数 document_metadata
来源元数据(日期、安全、签名、增量保存标记、XMP)。input 必须是这些事实所描述的那个文件:传原始输入,而不是 AcroForm 修复后或格式转换后的副本。
pub fn document_metadata(input: &crate::types::PdfInput, document: &Document<''_>) -> crate::types::DocumentMetadata { /* ... */ }函数 extract
从一个已打开的文档里抽取文字项、图形、结构节点以及(可选的)图片。这是唯一一个通过 PDFium 读取文字内容的阶段;下游一切都作用在返回的 [Page] 上。
开启 extract_form_fields 时,抽取可能会把某些页的控件批注压平进页面内容,以恢复其中的文字。这会改变已打开的文档:随后在同一文档上带 render_form_fields 调用 [screenshots] 就会把这些控件绘制两次,而从重新打开的文档得到的 OCR 位图必须再把同样的页压平一次才能对齐。返回的 flattened_form_widgets / flattened_page_numbers 说明了发生了什么;[screenshots_need_pristine_document] 与 LiteParse::ocr_render_options 会据此给出正确的后续做法。
pub fn extract(document: &Document<''_>, request: &ExtractRequest<''_>) -> Result<ExtractedPages, crate::error::LiteParseError> { /* ... */ }函数 page_complexity
为一张已抽取的页打分:它是否需要 OCR,以及原因。它通过 PDFium 读取页面对象(图片、填充路径),因此必须针对该页抽取时所用的文档运行。layout 保持未设置;投影之后的那一半见 [layout_complexity]。
pub fn page_complexity(document: &Document<''_>, page: &crate::types::Page) -> Result<PageComplexityStats, crate::error::LiteParseError> { /* ... */ }函数 layout_complexity
为投影后的页面给出版面难度信号(分栏、表格、密集图形)。纯函数;填充 PageComplexityStats::layout。
pub fn layout_complexity(page: &crate::types::ParsedPage) -> LayoutComplexityStats { /* ... */ }函数 render_for_ocr
把 pages[start..] 中需要 OCR(或 options.selection 指定)的页面位图化,取到 options.max_rasters 为止。返回位图列表以及下次应当续起的下标,于是长文档可以按有界的若干轮跑完。在 await 识别之前请把 [Document] 丢弃。
pub fn render_for_ocr(document: &Document<''_>, pages: &[crate::types::Page], start: usize, options: &OcrRenderOptions) -> Result<(Vec<OcrRaster>, usize), crate::error::LiteParseError> { /* ... */ }函数 recognize
让一个 [OcrEngine] 跑完这批位图,最多同时 num_workers 个。纯识别;失败以逐条结果的形式给出而非报错。在每个目标上结果都按输入顺序返回。自带 OCR 服务的调用方可以跳过本函数,直接用 [OcrRaster] 的事实与其引擎给出的词框(位图像素空间)构造 [PageOcrOutcome]。
pub async fn recognize(rasters: Vec<OcrRaster>, engine: std::sync::Arc<dyn OcrEngine>, language: &str, num_workers: usize) -> Vec<PageOcrOutcome> { /* ... */ }函数 merge_ocr
把识别结果就地并入 pages:丢弃不可用的原生文字、过滤引擎产物、把存活的结果作为 OCR 文字项(视口点)追加。只有当所有结果都失败、且其中失败的页里没有可用原生文字时(ocr_failure_fatal)才报错。
emit_word_boxes 要传 LiteParseConfig::effective_emit_word_boxes:每个引擎结果就是一个词,因此这是 OCR 路径唯一能挂上词框的地方,且它必须与抽取阶段所用的取值一致 —— 否则一次运行只会让原生文字带上有词框。见 ExtractionOutputOptions::emit_word_boxes。
pub fn merge_ocr(pages: &mut [crate::types::Page], outcomes: Vec<PageOcrOutcome>, ocr_failure_fatal: bool, emit_word_boxes: bool) -> Result<(), crate::error::LiteParseError> { /* ... */ }函数 apply_content_filters
就地给 pages 应用 [ContentFilters]。它跑在 [merge_ocr] 之后,因此 OCR 文字也会被过滤;也跑在 [project] 之前,因此被移除的项绝不会进入输出。没有请求任何过滤时是空操作。
pub fn apply_content_filters(pages: &mut [crate::types::Page], filters: &ContentFilters<''_>) { /* ... */ }函数 project
网格投影:把每页的项变成带空间排版的纯文本,并给出 markdown 各阶段所读取的逐行结构。纯函数且逐页进行,因此可以作用于任意页子集。
pub fn project(pages: Vec<crate::types::Page>) -> Vec<crate::types::ParsedPage> { /* ... */ }函数 document_signals
对文档的每一页计算 [DocumentSignals]。
pub fn document_signals(pages: &[crate::types::ParsedPage], keep_headers_footers: bool) -> DocumentSignals { /* ... */ }函数 extract_blocks
把一张投影后的页面分类成最终的块序列:标题、段落、列表、代码、表格、分隔线、图形 —— 已经完成版式抑制、分隔线去重与软连字符拼接。这正是 [render_page_markdown] 所渲染、ParsedPage::blocks 所报告的那套拆解。
表格检测会依据 TextItem.words 切开合并单元格,因此请用 LiteParseConfig::effective_emit_word_boxes 抽取,才能得到 parse() 报告的那些块。
对没有投影行的页(空白页,或纯 OCR 且没有字体元数据)返回 None:那里没有结构可报告,渲染会退回到围栏里的投影文本。
pub fn extract_blocks(page: &crate::types::ParsedPage, signals: &DocumentSignals, options: &BlockOptions<''_>) -> Option<Vec<PositionedBlock>> { /* ... */ }函数 render_page_markdown
由页的块渲染该页的 markdown。分类结果为 None 的页会把它的投影文本放进一个 ```text 围栏里渲染,以免有任何内容被静默丢弃。
pub fn render_page_markdown(page: &crate::types::ParsedPage, blocks: Option<&[PositionedBlock]>) -> String { /* ... */ }函数 layout_blocks
页内块的公开扁平视图(ParsedPage::blocks),其中块框已从投影坐标系映射回视口坐标空间。
pub fn layout_blocks(page: &crate::types::ParsedPage, blocks: &[PositionedBlock]) -> Vec<LayoutBlock> { /* ... */ }函数 canonicalize_image_refs
把重复图片的图形引用改指向规范图片的文件名,作用于每一页的 markdown 与 full_text。只有规范图片会被写到磁盘,因此重复位置若仍写作  就会引用一个并不存在的文件。
pub fn canonicalize_image_refs(pages: &mut [crate::types::ParsedPage], full_text: &mut String, images: &[crate::types::ExtractedImage]) { /* ... */ }函数 screenshots_need_pristine_document
[screenshots] 是否必须跑在一份新打开的文档上,而不是 [extract] 所用那份。当抽取已把控件批注压平进页面内容,并且截图将通过表单环境绘制表单字段时为 true —— 在被改动的文档上这些控件会被画两遍。普通截图不受影响,因为压平提升的正是渲染器本来就会绘制的那些外观流。
pub fn screenshots_need_pristine_document(extracted: &ExtractedPages, options: &ScreenshotOptions) -> bool { /* ... */ }函数 screenshots
把页面渲染为 PNG。page_numbers 从 1 开始;None 表示渲染全部页。
pub fn screenshots(document: &Document<''_>, page_numbers: Option<&[u32]>, options: &ScreenshotOptions) -> Result<Vec<ScreenshotResult>, crate::error::LiteParseError> { /* ... */ }重导出
重导出 ExtractedPages
pub use crate::extract::ExtractedPages;重导出 ExtractionOutputOptions
pub use crate::extract::ExtractionOutputOptions;重导出 LayoutBlock
pub use crate::layout::LayoutBlock;重导出 LayoutCell
pub use crate::layout::LayoutCell;重导出 Block
pub use crate::markdown_layout::Block;重导出 Cell
pub use crate::markdown_layout::Cell;重导出 PositionedBlock
pub use crate::markdown_layout::PositionedBlock;重导出 SpanCell
pub use crate::markdown_layout::SpanCell;重导出 render_blocks
pub use crate::markdown_layout::render_blocks;重导出 OcrResult
pub use crate::ocr::OcrResult;重导出 ComplexityReason
pub use crate::ocr_merge::ComplexityReason;重导出 LayoutComplexityReason
pub use crate::ocr_merge::LayoutComplexityReason;重导出 LayoutComplexityStats
pub use crate::ocr_merge::LayoutComplexityStats;重导出 OcrRaster
pub use crate::ocr_merge::OcrRaster;重导出 OcrRenderOptions
pub use crate::ocr_merge::OcrRenderOptions;重导出 PageComplexityStats
pub use crate::ocr_merge::PageComplexityStats;重导出 PageOcrOutcome
pub use crate::ocr_merge::PageOcrOutcome;重导出 ScreenshotResult
pub use crate::parser::ScreenshotResult;重导出 Document
绑定 pdfium 的那些阶段所接收的 PDFium 句柄类型。重导出出来,调用方就不必直接依赖 pdfium crate。
pub use pdfium::Document;重导出 Library
绑定 pdfium 的那些阶段所接收的 PDFium 句柄类型。重导出出来,调用方就不必直接依赖 pdfium crate。
pub use pdfium::Library;结构体 DocumentMetadata
文档级来源元数据,来自 PDFium 加上对源 PDF 的有界流式扫描。所有字段都保持 optional,这样畸形的元数据绝不会阻碍文档本身被解析。
pub struct DocumentMetadata {
pub creation_date: Option<String>,
pub mod_date: Option<String>,
pub file_version: Option<i32>,
pub is_encrypted: Option<bool>,
pub security_handler_revision: Option<i32>,
pub permissions: Option<u64>,
pub eof_section_count: Option<u32>,
pub startxref_count: Option<u32>,
pub trailer_id_pair_differs: Option<bool>,
pub raw_file_size: Option<u64>,
pub xmp: Option<String>,
pub xmp_truncated: Option<bool>,
pub signature_count: Option<u32>,
pub signature_byte_range_reaches_eof: Option<bool>,
}字段
| 名称 | 类型 | 文档 |
|---|---|---|
creation_date | Option<String> | |
mod_date | Option<String> | |
file_version | Option<i32> | |
is_encrypted | Option<bool> | |
security_handler_revision | Option<i32> | |
permissions | Option<u64> | |
eof_section_count | Option<u32> | 文件中字面的 %%EOF 标记。可粗略反映增量更新:内嵌的 PDF 附件与内容流里的文字都会把它撑大。 |
startxref_count | Option<u32> | 文件中字面的 startxref 标记,注意事项同上。 |
trailer_id_pair_differs | Option<bool> | 最后一个 trailer /ID 数组的两半是否不同 —— 通常意味着文件在创建后被更新过。在最后 1 MiB 里找不到十六进制字符串 /ID 对时为 None。 |
raw_file_size | Option<u64> | |
xmp | Option<String> | 文档目录的 /Metadata XMP 包,上限 64 KiB。文档没有 XMP、XMP 过大以致无法廉价解析(见 extract_document_metadata),或在 WASM 构建下时为 None。 |
xmp_truncated | Option<bool> | 目录的 XMP 流超过 64 KiB 上限、xmp 里只有前 64 KiB 时为 true。 |
signature_count | Option<u32> | |
signature_byte_range_reaches_eof | Option<bool> |
结构体 TextItem
表示从 PDF 页面抽出的单个文字项,包含其内容、位置、尺寸、旋转与字体元数据。
pub struct TextItem {
pub text: String,
pub x: f32,
pub y: f32,
pub width: f32,
pub height: f32,
pub rotation: f32,
pub font_name: Option<String>,
pub font_size: Option<f32>,
pub font_height: Option<f32>,
pub font_ascent: Option<f32>,
pub font_descent: Option<f32>,
pub font_weight: Option<i32>,
pub font_flags: Option<i32>,
pub text_width: Option<f32>,
pub font_is_buggy: bool,
pub has_unicode_map_error: bool,
pub mcid: Option<i32>,
pub fill_color: Option<String>,
pub stroke_color: Option<String>,
pub char_codes: Vec<u32>,
pub trailing_space_generated: bool,
pub confidence: Option<f32>,
pub link: Option<String>,
pub strike: bool,
pub words: Vec<WordBox>,
}字段
| 名称 | 类型 | 文档 |
|---|---|---|
text | String | |
x | f32 | 视口坐标空间(左上原点、72 DPI)。 |
y | f32 | |
width | f32 | |
height | f32 | |
rotation | f32 | 旋转角度(逆时针,已按页面旋转调整)。 |
font_name | Option<String> | |
font_size | Option<f32> | |
font_height | Option<f32> | 文本矩阵给出的 font_size * scale_y —— 已计入 CTM 缩放。 |
font_ascent | Option<f32> | |
font_descent | Option<f32> | |
font_weight | Option<i32> | |
font_flags | Option<i32> | |
text_width | Option<f32> | 各字形宽度之和(尽可能用 charcode 查表)。 |
font_is_buggy | bool | 字体编码是否有缺陷(私用区码点、TrueType 子集等) |
has_unicode_map_error | bool | 该项中是否大部分字符都无法映射到 Unicode(例如没有 ToUnicode 映射的 Type3 字体)。此时文本内容是 PDFium 的字符码兜底结果,并不反映实际渲染的字形。 |
mcid | Option<i32> | 来自 PDF 结构树的 Marked content ID。 |
fill_color | Option<String> | 填充颜色,ARGB 十六进制字符串(例如 “ff000000”)。 |
stroke_color | Option<String> | 描边颜色,ARGB 十六进制字符串。 |
char_codes | Vec<u32> | 来自 PDF 内容流的原始字符码。它们对应源字形而非 Unicode 标量值,因此连字展开产生的文本字符数可能多于本数组的条目数。 |
trailing_space_generated | bool | 尾随的源空格是否是 PDFium 合成的,而不是内容流里真实存在的空格字形。 |
confidence | Option<f32> | OCR 置信度(0.0–1.0)。原生 PDF 文字为 None。 |
link | Option<String> | 当该项落在某个超链接批注的矩形内时的目标 URI。在 extract.rs 中填充;由 markdown 输出器消费。 |
strike | bool | 是否有一条细水平描边/矩形横穿该项的纵向中段(删除线)。在 extract.rs 中填充;markdown 输出器据此把文字包进 ~~…~~。 |
words | Vec<WordBox> | 该项内部的逐词子框,按构建分段时看到的词间空格切分。一个分段会把若干词归在一起(只在行/列边界断开),因此这里给出词级几何以便做边界框归属。没有发生词切分的项(如来自 OCR 或只含单个记号的项)为空。仅用于内部/归属:公开 JSON 输出(output/json.rs)自建其视图、不含它,但它要跨越 napi 边界并必须活过阶段边界(见 stages),所以参与序列化。 |
方法
pub fn text_metadata(self: &Self, enabled: bool) -> TextMetadata<''_> { /* ... */ }该项的富元数据视图:
enabled时为真实值,否则全
结构体 TextMetadata
受 extract_text_metadata 支配的那批 TextItem 字段,并由 [TextItem::text_metadata] 预先设好开关。这个结构体界定了哪些字段算作富文本元数据:每个输出出口(CLI JSON、napi、python、wasm)都以它来构建公开的文字项,所以在这里新加一个元数据字段,若没在每个出口接线,就会在各处成为编译错误。
所有字段都是 Option/切片,因此即便 TextItem 上那些裸 bool 字段也能表达“未开启抽取”:None/空表示调用方没有选择开启,该字段必须从输出中省略。
pub struct TextMetadata<''a> {
pub font_height: Option<f32>,
pub font_ascent: Option<f32>,
pub font_descent: Option<f32>,
pub font_weight: Option<i32>,
pub text_width: Option<f32>,
pub font_is_buggy: Option<bool>,
pub mcid: Option<i32>,
pub fill_color: Option<&''a str>,
pub stroke_color: Option<&''a str>,
pub char_codes: Option<&''a [u32]>,
pub trailing_space_generated: Option<bool>,
}字段
| 名称 | 类型 | 文档 |
|---|---|---|
font_height | Option<f32> | |
font_ascent | Option<f32> | |
font_descent | Option<f32> | |
font_weight | Option<i32> | |
text_width | Option<f32> | |
font_is_buggy | Option<bool> | |
mcid | Option<i32> | |
fill_color | Option<&''a str> | |
stroke_color | Option<&''a str> | |
char_codes | Option<&''a [u32]> | |
trailing_space_generated | Option<bool> |
结构体 WordBox
TextItem 内某个词的边界框,与父项处于同一视口坐标空间(左上原点、72 DPI)。text 是该词的内容,不含词间空格。
pub struct WordBox {
pub text: String,
pub x: f32,
pub y: f32,
pub width: f32,
pub height: f32,
}字段
| 名称 | 类型 | 文档 |
|---|---|---|
text | String | |
x | f32 | |
y | f32 | |
width | f32 | |
height | f32 |
结构体 PageError
在启用「容错逐页错误」时无法抽取的那一页。
pub struct PageError {
pub page_number: u32,
pub message: String,
}字段
| 名称 | 类型 | 文档 |
|---|---|---|
page_number | u32 | 源页号(从 1 开始)。序列化为 page,以与 JSON 输出里逐页字段的兄弟项(pages[]、images[])保持一致。 |
message | String | 人类可读的抽取失败信息。 |
结构体 DocumentAnnotation
一条 PDF 页面批注。坐标与 [TextItem] 一样采用左上原点、72 DPI 的视口坐标空间。
pub struct DocumentAnnotation {
pub subtype: String,
pub contents: Option<String>,
pub created: Option<String>,
pub modified: Option<String>,
pub title: Option<String>,
pub rect: Option<Rect>,
pub quadpoint_rects: Vec<Rect>,
pub uri: Option<String>,
}字段
| 名称 | 类型 | 文档 |
|---|---|---|
subtype | String | |
contents | Option<String> | |
created | Option<String> | |
modified | Option<String> | |
title | Option<String> | |
rect | Option<Rect> | |
quadpoint_rects | Vec<Rect> | |
uri | Option<String> |
枚举 StructureAttributeValue
属性:
Other("#[serde(untagged)]")
标签 PDF 结构元素 /A 字典里的一个标量值。
pub enum StructureAttributeValue {
Boolean(bool),
Number(f32),
String(String),
}枚举变体
Boolean(bool)
Number(f32)
String(String)
结构体 StructureTree
一棵完整的、页面作用域的标签 PDF 逻辑结构树。
pub struct StructureTree {
pub roots: Vec<StructureTreeElement>,
}字段
| 名称 | 类型 | 文档 |
|---|---|---|
roots | Vec<StructureTreeElement> |
结构体 StructureTreeElement
一个标签 PDF 结构元素。字段名遵循本仓库的 snake_case JSON 约定,而不是 PDFium 的 C 拼写。
pub struct StructureTreeElement {
pub element_type: String,
pub id: Option<String>,
pub actual_text: Option<String>,
pub alt_text: Option<String>,
pub title: Option<String>,
pub attributes: std::collections::BTreeMap<String, StructureAttributeValue>,
pub marked_content_ids: Vec<i32>,
pub children: Vec<StructureTreeElement>,
pub annotations: Vec<DocumentAnnotation>,
}字段
| 名称 | 类型 | 文档 |
|---|---|---|
element_type | String | |
id | Option<String> | |
actual_text | Option<String> | |
alt_text | Option<String> | |
title | Option<String> | |
attributes | std::collections::BTreeMap<String, StructureAttributeValue> | |
marked_content_ids | Vec<i32> | |
children | Vec<StructureTreeElement> | |
annotations | Vec<DocumentAnnotation> |
结构体 FormField
一个 AcroForm 控件及其解析后的字段元数据。
pub struct FormField {
pub id: String,
pub field_type: String,
pub page: u32,
pub annotation_index: i32,
pub widget_index: i32,
pub object_number: Option<i32>,
pub name: Option<String>,
pub alternate_name: Option<String>,
pub value: Option<String>,
pub export_value: Option<String>,
pub field_flags: i32,
pub control_count: Option<i32>,
pub control_index: Option<i32>,
pub checked: Option<bool>,
pub rect: Option<Rect>,
pub options: Vec<String>,
pub selected_options: Vec<String>,
}字段
| 名称 | 类型 | 文档 |
|---|---|---|
id | String | |
field_type | String | |
page | u32 | |
annotation_index | i32 | |
widget_index | i32 | |
object_number | Option<i32> | |
name | Option<String> | |
alternate_name | Option<String> | |
value | Option<String> | |
export_value | Option<String> | |
field_flags | i32 | |
control_count | Option<i32> | |
control_index | Option<i32> | |
checked | Option<bool> | |
rect | Option<Rect> | |
options | Vec<String> | |
selected_options | Vec<String> |
结构体 XfaPacket
XFA 表单文档 /XFA 数组里的一个原始数据包。启用 extract_xfa_packets 后出现在 ParseResult.xfa_packets 上。
pub struct XfaPacket {
pub index: u32,
pub name: Option<String>,
pub content_length: u32,
pub content: Option<String>,
}字段
| 名称 | 类型 | 文档 |
|---|---|---|
index | u32 | 在 XFA 数组中的下标(从 0 开始)。 |
name | Option<String> | 数据包名(例如 template、datasets),若存在。 |
content_length | u32 | 解码后的内容长度(字节)。 |
content | Option<String> | 数据包内容(通常是 XML),按 UTF-8 有损解码。无法读取该包流时为 None。 |
结构体 ScreenshotRect
在渲染出的页面位图里检测到的一块实心矩形(或粗线)。坐标与文字项一样处于左上原点、72 DPI 的视口坐标空间。检测跑在位图上,因此也覆盖那些没有矢量路径的扫描/压平页。
pub struct ScreenshotRect {
pub x: f32,
pub y: f32,
pub width: f32,
pub height: f32,
pub color: String,
pub is_line: bool,
}字段
| 名称 | 类型 | 文档 |
|---|---|---|
x | f32 | |
y | f32 | |
width | f32 | |
height | f32 | |
color | String | 填充颜色,ARGB 十六进制字符串(例如 “ff1a2b3c”)。 |
is_line | bool | 当只有一个维度达到矩形最小尺寸时为 true(是一条实线而非填充区域)。 |
结构体 ParsedPage
表示一页完整解析后的结果,含投影后的文字版面。
与 [Page] 一样,序列化是无损的,因此 markdown 各阶段可以跑在与投影相隔一道进程边界的另一侧。公开 JSON 输出会为该类型自建自己的视图(output/json.rs)。
pub struct ParsedPage {
pub page_number: usize,
pub page_label: Option<String>,
pub page_width: f32,
pub page_height: f32,
pub content_bounds: Option<Rect>,
pub text: String,
pub markdown: String,
pub text_items: Vec<TextItem>,
pub projected_lines: Vec<ProjectedLine>,
pub regions: Region,
pub graphics: Vec<GraphicPrimitive>,
pub vector_graphics: Option<VectorGraphics>,
pub figures: Vec<Rect>,
pub projected_item_frames: Vec<(Rect, Rect)>,
pub struct_nodes: Vec<StructNode>,
pub image_refs: Vec<ImageRef>,
pub complexity: Option<crate::ocr_merge::PageComplexityStats>,
pub annotations: Option<Vec<DocumentAnnotation>>,
pub form_fields: Option<Vec<FormField>>,
pub structure_tree: Option<StructureTree>,
pub blocks: Option<Vec<crate::layout::LayoutBlock>>,
}字段
| 名称 | 类型 | 文档 |
|---|---|---|
page_number | usize | |
page_label | Option<String> | 该页对应的文档 /PageLabels 项(“iv”、“A-1”),若 PDF 定义了。它是阅读器展示给用户的页码,并不总等于页在文档中的位置;为 None 表示 PDF 未给它标签,消费方应回退到 page_number。 |
page_width | f32 | |
page_height | f32 | |
content_bounds | Option<Rect> | 该页顶层内容对象在视口坐标下的边界框并集(可见内容范围)。空白页为 None。 |
text | String | |
markdown | String | |
text_items | Vec<TextItem> | |
projected_lines | Vec<ProjectedLine> | markdown 输出器使用的逐行结构元数据。不属于公开 JSON/text 输出。 |
regions | Region | 该页 XY-cut 区域树的根。叶子对应每条 ProjectedLine 的 region_path。仅供内部使用。 |
graphics | Vec<GraphicPrimitive> | 页上的矢量图形(拆解后的路径),markdown 输出器用它检测有框表格 / 分隔线 / 图形聚簇。不属于公开 JSON/text 输出。 |
vector_graphics | Option<VectorGraphics> | 公开的矢量路径抽取。除非显式开启,否则不出现。 |
figures | Vec<Rect> | 由 graphics 推导出的图形区域矩形。在 to_parsed_pages 里预先算好,供 XY-cut 版面流程把它们当作障碍物,并在下游复用于图形分类。 |
projected_item_frames | Vec<(Rect, Rect)> | 每个文字项的 (projected, original) 几何,只有当该页至少有一个项两者不同时才填充。为处理旋转阅读顺序,90°/270° 文字会被转正,整组也可能被挪到页面下方的虚拟画布上以便按正确顺序阅读;ProjectedLine.bbox(以及由此并集出的块框)都处于这个投影坐标系里。块/单元格框在报告前会经这张表映射回去,因此它们与 text_items 落在同一视口坐标空间。没有旋转文字的页此项为空 —— 绝大多数页面属于此类。 |
struct_nodes | Vec<StructNode> | 该页的结构树节点(仅标签化 PDF)。已按前序预展平。markdown 分类器用它做最高优先级的标题 / 图形 / 表格检测。 |
image_refs | Vec<ImageRef> | 页上的位图对象。边界框为视口坐标。在抽取阶段填充;markdown 输出器用它在正确的 y 位置插入 Block::Figure 引用。页内没有内嵌图片时为空。不属于公开 JSON/text 输出。 |
complexity | Option<crate::ocr_merge::PageComplexityStats> | 逐页复杂度信号(与 is_complex API 返回的相同)。仅在设置 LiteParseConfig::include_complexity 时填充,否则为 None。在 JSON 里以每页一个 complexity 对象呈现。 |
annotations | Option<Vec<DocumentAnnotation>> | 开启 LiteParseConfig::extract_annotations 时的页面批注。None 表示未开启抽取;Some([]) 表示已开启但该页没有批注。 |
form_fields | Option<Vec<FormField>> | 开启 extract_form_fields 时的 AcroForm 控件。 |
structure_tree | Option<StructureTree> | 开启 extract_structure_tree 时的标签 PDF 逻辑结构。 |
blocks | Option<Vec<crate::layout::LayoutBlock>> | 开启 extract_blocks 时按阅读顺序给出的分类版面块。None 表示未开启抽取;Some([]) 表示已开启但该页没有结构拆解(空白页,或纯 OCR 且缺少分类器所需的字体元数据)。 |
结构体 ExtractedImage
从页面抽取出的位图及其像素字节。只有在启用 extract_images 时才会出现在 ParseResult.images 上;否则抽取步骤跳过渲染,只产出 ImageRef。当 PDFium 暴露了可直接解码的合法 DCT 流时,JPEG 流会被原样保留而不重新编码;其他图片则由 PDFium 渲染出的位图编码为 PNG。
pub struct ExtractedImage {
pub id: String,
pub name: String,
pub path: Option<String>,
pub page: u32,
pub bbox: Rect,
pub width: u32,
pub height: u32,
pub rotation: f32,
pub format: String,
pub duplicate_of: Option<String>,
pub bytes: std::sync::Arc<Vec<u8>>,
}字段
| 名称 | 类型 | 文档 |
|---|---|---|
id | String | |
name | String | |
path | Option<String> | |
page | u32 | |
bbox | Rect | |
width | u32 | |
height | u32 | |
rotation | f32 | |
format | String | |
duplicate_of | Option<String> | |
bytes | std::sync::Arc<Vec<u8>> | 编码后的图片字节。以共享(Arc)方式持有,因此重复条目引用的是规范图片的缓冲区,而不是每次出现都复制一份。不参与序列化:图片载荷要跨边界时以文件或独立 blob 形式给出,并以 id 为键。 |
结构体 VectorGraphics
页面作用域的矢量路径输出。坐标与文字项一样采用左上原点、72 DPI 的视口坐标空间。
pub struct VectorGraphics {
pub shapes: Vec<VectorShape>,
pub lines: Vec<VectorLine>,
}字段
| 名称 | 类型 | 文档 |
|---|---|---|
shapes | Vec<VectorShape> | |
lines | Vec<VectorLine> |
结构体 VectorShape
一个 PDF 路径对象的描绘状态与视口边界框。
pub struct VectorShape {
pub bbox: Rect,
pub stroke: bool,
pub stroke_color: Option<String>,
pub fill: bool,
pub fill_color: Option<String>,
pub has_curve: bool,
}字段
| 名称 | 类型 | 文档 |
|---|---|---|
bbox | Rect | |
stroke | bool | |
stroke_color | Option<String> | |
fill | bool | |
fill_color | Option<String> | |
has_curve | bool |
结构体 VectorLine
在相邻兼容段被合并之后得到的严格水平或垂直路径段,与 LlamaParse 的 PDFium 路径语义一致。
pub struct VectorLine {
pub x1: f32,
pub y1: f32,
pub x2: f32,
pub y2: f32,
pub stroke: bool,
pub stroke_width: Option<f32>,
pub stroke_color: Option<String>,
pub fill: bool,
pub fill_color: Option<String>,
}字段
| 名称 | 类型 | 文档 |
|---|---|---|
x1 | f32 | |
y1 | f32 | |
x2 | f32 | |
y2 | f32 | |
stroke | bool | |
stroke_width | Option<f32> | |
stroke_color | Option<String> | |
fill | bool | |
fill_color | Option<String> |