Use case / Layout analysis

Structured Data from Unstructured content

Discover how PyMuPDF can transform unstructured PDF content into structured, machine-readable data, enabling efficient processing with layout analysis.

GNN
Structured data
Positional data
Chunking
Verifiable Evidence Objects
Grounding
  • Source exactly where the answers come from in the document.
  • Ensure transparency and verifiability in your AI workflows.
01

Extract

Read the document's native structure instead of flattening it into images. PyMuPDF is trained on a Graph Neural Network to understand and preserve the document's layout.

02

Format

Convert the content into structured data that keeps context and hierarchy intact. Deliver it as structured Markdown, JSON or Text. Chunk it for retrieval or further processing.

03

Ingest

Send the output to your vector store, prompt, or document workflow.

Structured JSON

Turn every answer into verifiable evidence

Use to_json() when your AI workflow needs more than text. The output keeps each extracted item tied to its page and bounding box, giving you deterministic positional data for locating the exact source region in the original PDF.

01

Page address

Record the page number with every text element so a response can point back to the exact PDF page that supplied its context.

02

Bounding box

Preserve the element's coordinates as a four-value rectangle in PDF space, ready to highlight or inspect the precise source location.

03

Evidence object

Return the answer with its supporting text, page, and box metadata so users can verify the claim instead of trusting an untraceable generated sentence.

Build grounded answers from source locations

Store these evidence objects alongside embeddings or attach them to the LLM response. Your application can then link to a page, draw the bounding box, or show the exact passage that supports an answer.

The following code sample demonstrates the retrieval of evidence objects from source locations.

import json
import pymupdf

doc = pymupdf.open("input.pdf") # open the document
json_text = doc.to_json()
document = json.loads(json_text)

def get_box_content(box):
    """Return content according to the box's object type."""

    object_type = box.get("boxclass")

    if object_type == "table":
        table = box.get("table") or {}

        return {
            "rows": table.get("extract", []),
            "markdown": table.get("markdown", ""),
        }

    if object_type == "picture":
        return box.get("image")

    lines = []

    for line in box.get("textlines") or []:
        line_text = ""

        for span in line.get("spans", []):
            line_text += span.get("text", "")

        lines.append(line_text)

    return "\n".join(lines)

# traverse the document's pages and get the box content
for page in document.get("pages", []):
    print(f"\nPage: {page.get('page_number')}")

    for box in page.get("boxes", []):
        object_type = box.get("boxclass")

        bounding_box = (
            box.get("x0"),
            box.get("y0"),
            box.get("x1"),
            box.get("y1"),
        )

        content = get_box_content(box)

        print(f"Object type: {object_type}")
        print(f"Bounding box: {bounding_box}")

        if object_type == "table":
            print("Table content:")
            print(content["markdown"])
            print("Table rows:", content["rows"])

        elif object_type == "picture":
            print(f"Picture content: {content}")

        else:
            print(f"Text content: {content}")

        print("-" * 50)
PyMuPDF Logo

© 2026 Artifex Software Inc. All rights reserved.