What Fallback Extractors Are Used for PDFs When Primary Extraction Fails

When primary PDF extraction fails in the book-to-skill repository, the system automatically falls back through three sequential extractors—pdftotext (Poppler utility), pypdf (pure-Python reader), and pdfminer.six (advanced Python parser)—raising an ExtractionError only if all three alternatives fail.

The book-to-skill repository implements a resilient PDF processing pipeline that gracefully handles extraction failures through a predefined hierarchy of fallback extractors for PDFs. When the primary extraction method—whether Docling for technical documents or pdftotext for standard text—returns empty or None results, the system immediately attempts alternative parsing libraries to maximize text recovery across diverse PDF formats and encoding schemes.

Understanding the Primary Extraction Modes

Before examining the fallback chain, it is essential to understand how the system selects the primary extractor. In book_to_skill/utils.py, the extraction mode determines the initial strategy:

  • Technical mode: Uses Docling (extract_with_docling) for layout-aware extraction optimized for technical books and complex document structures.
  • Text mode (default): Uses pdftotext (extract_with_pdftotext) from the Poppler utilities for standard text extraction.

The Three Fallback Extractors for PDFs

When the primary extractor fails to produce usable text, the code in book_to_skill/utils.py (lines 89-108) initiates a sequential fallback chain through three alternative parsers.

pdftotext (Poppler Utility)

The first fallback attempts extraction using the external pdftotext binary. Implemented in book_to_skill/parsers/pdf.py at lines 76-88, the extract_with_pdftotext function executes pdftotext -layout <file> - via subprocess and sanitizes the output using the clean_pdftotext helper. This method excels with scanned documents processed with OCR and standard PDFs with embedded text.

pypdf (Pure-Python Reader)

If pdftotext returns no content, the system attempts extraction using pypdf. The extract_with_pypdf function in book_to_skill/parsers/pdf.py (lines 112-129) instantiates pypdf.PdfReader, iterates through each page to extract text content, and applies cleaning operations. This pure-Python implementation requires no external system dependencies.

pdfminer.six (Advanced Python Parser)

The final fallback utilizes pdfminer.six for deep PDF structure parsing. Located in book_to_skill/parsers/pdf.py at lines 133-141, the extract_with_pdfminer function calls pdfminer.high_level.extract_text to retrieve content from complex PDFs that other parsers might miss, then applies standard text cleaning.

How the Fallback Chain Works in Code

The orchestration logic resides in book_to_skill/utils.py, where the system evaluates each extractor's output sequentially:


# Sequential fallback logic (utils.py lines 89-108)

text = extract_with_pdftotext(input_str)
if not text:
    text = extract_with_pypdf(input_str)
if not text:
    text = extract_with_pdfminer(input_str)

If extract_single_file detects empty results from the primary extractor, it proceeds through this chain automatically. The function returns a dictionary containing the successful extraction_method and extracted text, allowing you to identify which parser succeeded.

Implementing Manual Fallback Extraction

For custom workflows requiring explicit control over the fallback sequence, you can import the individual extractors from book_to_skill/parsers/pdf:

from book_to_skill.parsers.pdf import (
    extract_with_pdftotext,
    extract_with_pypdf,
    extract_with_pdfminer,
)

pdf_path = "technical_manual.pdf"

# Attempt Poppler-based extraction

text = extract_with_pdftotext(pdf_path)
if not text:
    # Fallback to pure-Python pypdf

    text = extract_with_pypdf(pdf_path)
if not text:
    # Final attempt with pdfminer.six

    text = extract_with_pdfminer(pdf_path)

print(f"Extracted {len(text) if text else 0} characters")

Alternatively, use the high-level utility function to leverage the automatic fallback chain:

from book_to_skill.utils import extract_single_file

result = extract_single_file("example.pdf")
print(f"Method used: {result['extraction_method']}")
print(f"Text length: {len(result['text'])}")

Handling Total Extraction Failure

If all three fallback extractors for PDFs fail to return usable text, the system raises an ExtractionError defined in book_to_skill/exceptions.py. This exception advises users to install one of the required dependencies: poppler-utils for pdftotext, pypdf, or pdfminer.six. The error ensures that extraction failures are explicit rather than returning silent empty results.

Summary

  • The book-to-skill repository implements a cascading fallback system for PDF extraction that attempts three alternative parsers when primary extraction fails.
  • The fallback sequence follows this order: pdftotext (Poppler) → pypdf (pure-Python) → pdfminer.six (advanced parser).
  • Primary extraction depends on mode selection: Docling for technical documents and pdftotext for standard text extraction.
  • All fallback logic is orchestrated in book_to_skill/utils.py (lines 89-108), with individual implementations residing in book_to_skill/parsers/pdf.py.
  • Complete extraction failure triggers an ExtractionError with guidance on installing required dependencies.

Frequently Asked Questions

What triggers the fallback extractors in book-to-skill?

The fallback chain activates when the primary extractor—either Docling in technical mode or pdftotext in text mode—returns None or an empty string. The extract_single_file function in book_to_skill/utils.py checks the primary output and automatically proceeds through pdftotext, pypdf, and pdfminer.six until successful extraction occurs.

Can I use the fallback extractors individually without the automatic chain?

Yes, each fallback extractor is exposed as an independent function in book_to_skill/parsers/pdf.py. You can import extract_with_pdftotext, extract_with_pypdf, or extract_with_pdfminer directly to implement custom retry logic or select specific parsers based on your document characteristics.

Why does the fallback sequence prioritize pdftotext over pypdf?

The pdftotext utility from Poppler typically provides superior formatting preservation and OCR compatibility compared to pure-Python libraries. The system prioritizes this external tool before falling back to pypdf and pdfminer.six, which offer better availability (no system dependencies) but may struggle with complex layouts.

What happens if none of the fallback extractors work?

If pdftotext, pypdf, and pdfminer.six all fail to extract text, the code raises an ExtractionError from book_to_skill/exceptions.py. This exception message directs users to install the necessary dependencies: poppler-utils (for pdftotext), pypdf, or pdfminer.six, ensuring transparent failure handling rather than silent data loss.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →