Skip to main content

layout_modes/
layout_modes.rs

1//! PDF 两种版式模式对照:`auto`(行归并 + 表格 + 分栏)与 `raw`(按内容流顺序)。
2//!
3//! ```bash
4//! cargo run -p docparser-pdf --example layout_modes -- doc.pdf
5//! ```
6//!
7//! 无 PDFium 时自动回退 `pdf-extract` 兜底后端(无 bbox,版式模式退化为 raw 语义)。
8
9use docparser_core::engine::DocumentEngine;
10use docparser_core::plugins;
11use docparser_core::registry::Registry;
12use docparser_pdf::{LayoutMode, PdfOptions};
13
14fn engine_with(mode: LayoutMode, max_pages: Option<usize>) -> DocumentEngine {
15    let mut registry = Registry::new();
16    plugins::text::register_defaults(&mut registry);
17    let mut options = PdfOptions::new().with_layout_mode(mode);
18    options.max_pages = max_pages;
19    // 与 CLI 同一条装配路径:register_with 把选项注入 worker / 兜底后端 / 插件
20    docparser_pdf::register_with(&mut registry, &options);
21    DocumentEngine::new(registry)
22}
23
24fn main() -> Result<(), Box<dyn std::error::Error>> {
25    let path = std::env::args()
26        .nth(1)
27        .unwrap_or_else(|| "doc.pdf".to_string());
28
29    for mode in [LayoutMode::Auto, LayoutMode::Raw] {
30        match engine_with(mode, Some(3)).parse(&path) {
31            Ok(doc) => {
32                let blocks: usize = doc.pages.iter().map(|p| p.blocks.len()).sum();
33                println!(
34                    "{:>7}: {} 页 / {} 块 / {} 字符",
35                    mode.as_str(),
36                    doc.pages.len(),
37                    blocks,
38                    doc.meta.text_length
39                );
40                if let Some(page) = doc.pages.first() {
41                    for block in page.blocks.iter().take(3) {
42                        println!("         {:?}: {}", block.kind, block.content);
43                    }
44                }
45            }
46            Err(e) => println!("{:>7}: 失败 [{}] {}", mode.as_str(), e.code, e.message),
47        }
48    }
49    Ok(())
50}