Skip to content

Commit 293f781

Browse files
RoyLinRoyLin
authored andcommitted
feat(doc): improve PDF extraction fallback logic for better text recovery
Reduce dependence on weak text fallbacks for PDF by using intelligent fallback between lopdf and pdf-extract: - Try lopdf first for position-aware extraction - Try pdf-extract as backup comparison - Use pdf-extract if it has 5x more content (handles embedded fonts) - Otherwise prefer lopdf for better position info This reduces dependence on any single extraction method.
1 parent 46c174d commit 293f781

1 file changed

Lines changed: 28 additions & 7 deletions

File tree

  • core/src/composite_document_parser/ocr

core/src/composite_document_parser/ocr/mod.rs

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -364,14 +364,35 @@ pub fn extract_document_runtime_metadata(doc: &ParsedDocument) -> Option<Documen
364364

365365
fn parse_pdf(path: &Path) -> Result<String> {
366366
// Try lopdf first for better text extraction with position info
367-
if let Ok(text) = parse_pdf_with_lopdf(path) {
368-
if !text.trim().is_empty() {
369-
return Ok(text);
370-
}
367+
let lopdf_result = parse_pdf_with_lopdf(path);
368+
let lopdf_text = lopdf_result.unwrap_or_default();
369+
370+
// Try pdf-extract for comparison
371+
let pdf_extract_text = pdf_extract::extract_text(path)
372+
.with_context(|| format!("failed to extract text from PDF {}", path.display()))?;
373+
374+
// Use the better extraction result based on content quality
375+
// Prefer lopdf if it has meaningful content (position-aware extraction)
376+
// But use pdf-extract if it has significantly more content (5x threshold)
377+
let lopdf_trimmed = lopdf_text.trim();
378+
let pdf_extract_trimmed = pdf_extract_text.trim();
379+
380+
if lopdf_trimmed.is_empty() {
381+
return Ok(pdf_extract_trimmed.to_string());
371382
}
372-
// Fallback to pdf-extract
373-
pdf_extract::extract_text(path)
374-
.with_context(|| format!("failed to extract text from PDF {}", path.display()))
383+
384+
if pdf_extract_trimmed.is_empty() {
385+
return Ok(lopdf_trimmed.to_string());
386+
}
387+
388+
// If pdf-extract has significantly more content, prefer it
389+
// This handles cases where lopdf misses embedded fonts or complex content
390+
if pdf_extract_trimmed.len() > lopdf_trimmed.len() * 5 {
391+
return Ok(pdf_extract_trimmed.to_string());
392+
}
393+
394+
// Otherwise prefer lopdf for better position info
395+
Ok(lopdf_trimmed.to_string())
375396
}
376397

377398
/// Text item with position for table detection.

0 commit comments

Comments
 (0)