# Anchor Text Mechanism in OLMoCR: Encoding PDF Layouts for Language Models

> Discover the anchor text mechanism in OLMoCR, which injects position-annotated PDF text into LLM prompts, providing spatial grounding without image data.

- Repository: [Ai2/olmocr](https://github.com/allenai/olmocr)
- Tags: deep-dive
- Published: 2026-07-06

---

**The anchor text mechanism extracts a compact, position‑annotated textual representation of PDF pages and injects it into LLM prompts between `RAW_TEXT_START` and `RAW_TEXT_END` markers, providing spatial grounding without image data.**

The anchor text mechanism is a lightweight grounding strategy implemented in the allenai/olmocr repository that transforms PDF pages into deterministic, coordinate‑aware string representations. By preserving the spatial relationships between text and image elements, this approach enables vision‑language models to reason about document structure without processing raw pixel data. According to the olmocr source code, the system linearizes page geometry into a concise format that can be embedded directly into training and inference prompts.

## How the Anchor Text Mechanism Works

At its core, the mechanism relies on **position‑aware extraction** and **deterministic linearization** to create a textual snapshot of each page.

### Extraction and Parsing

The primary entry point is `get_anchor_text()` defined in **[`olmocr/prompts/anchor.py`](https://github.com/allenai/olmocr/blob/main/olmocr/prompts/anchor.py)**. This function supports four distinct PDF engines:

- **`pdfreport`** – Custom engine that parses pages into a `PageReport` object containing media‑box dimensions, `TextElement` instances with (x,y) coordinates, and `ImageElement` instances with bounding boxes.
- **`pdftotext`** – External Poppler utility for text extraction.
- **`pdfium`** – Chromium‑based PDFium library.
- **`pypdf`** – Pure Python PDF parser.

When using the `pdfreport` engine (around line 80 of [`anchor.py`](https://github.com/allenai/olmocr/blob/main/anchor.py)), the parser creates structured objects that maintain the geometric relationships between page elements.

### Linearization Process

The `_linearize_pdf_report()` function transforms the structured `PageReport` into a compact string format. This process:

1. Merges overlapping image regions to reduce noise.
2. Truncates output to a specified `target_length` (use `-1` to return only page dimensions).
3. Emits a position‑annotated string where each element is prefixed with its coordinates.

The resulting format follows this structure:

```

Page dimensions: 612.0x792.0
[Image 35x45 to 400x300]
[120x600]Some cleaned text...

```

The bracketed prefixes indicate where text appears on the page, while `[Image ...]` blocks denote image regions with bounding boxes.

## Generating Anchor Text from PDFs

To extract anchor text from a specific page, invoke `get_anchor_text()` with your preferred engine:

```python
from olmocr.prompts.anchor import get_anchor_text

pdf_path = "/path/to/document.pdf"
page_num = 2

anchor = get_anchor_text(
    local_pdf_path=pdf_path,
    page=page_num,
    pdf_engine="pdfreport",
    target_length=4000,
)
print(anchor)

```

*The `get_anchor_text` implementation resides in* **[`olmocr/prompts/anchor.py`](https://github.com/allenai/olmocr/blob/main/olmocr/prompts/anchor.py)** *around line 17, with the `pdfreport` engine logic and `_linearize_pdf_report` helper located immediately after.*

## Embedding Anchor Text in Prompts

Once generated, the anchor text must be embedded into prompts using specific markers that the model can recognize. The **[`olmocr/prompts/prompts.py`](https://github.com/allenai/olmocr/blob/main/olmocr/prompts/prompts.py)** file provides helper functions for this purpose.

### Prompt Construction Functions

- **`build_finetuning_prompt(anchor_text)`** – Wraps anchor text with instruction headers and `RAW_TEXT_START`/`RAW_TEXT_END` delimiters.
- **`build_openai_silver_data_prompt(anchor_text)`** – Formats anchor text for OpenAI API compatibility.

The delimiters allow downstream utilities like `extract_raw_text()` to recover the original anchor string from completed prompts.

### Example: Building a Training Prompt

```python
from olmocr.prompts.prompts import build_finetuning_prompt

prompt = build_finetuning_prompt(anchor)

# Result: "Below is the image of one page ... RAW_TEXT_START\n{anchor}\nRAW_TEXT_END"

```

*These prompt builders are defined in* **[`olmocr/prompts/prompts.py`](https://github.com/allenai/olmocr/blob/main/olmocr/prompts/prompts.py)** *between lines 45 and 53.*

## Pipeline Integration

The anchor text mechanism is integrated directly into the data loading pipeline at **[`olmocr/train/dataloader.py`](https://github.com/allenai/olmocr/blob/main/olmocr/train/dataloader.py)**. The `BaseMarkdownPDFDataset` class invokes `get_anchor_text()` during sample preparation (lines 211‑212):

```python
anchor = get_anchor_text(
    sample["pdf_path"],
    page=1,
    pdf_engine="pdfreport",
    target_length=self.target_anchor_text_len,
)
sample["anchor_text"] = anchor
sample["instruction_prompt"] = build_finetuning_prompt(anchor)

```

This integration ensures every training sample contains spatially grounded text context. The mechanism is also validated by unit tests in **[`tests/test_anchor.py`](https://github.com/allenai/olmocr/blob/main/tests/test_anchor.py)**, which verify length constraints and formatting consistency across different PDF engines.

## Summary

- The **anchor text mechanism** converts PDF pages into coordinate‑annotated text strings using `get_anchor_text()` in [`olmocr/prompts/anchor.py`](https://github.com/allenai/olmocr/blob/main/olmocr/prompts/anchor.py).
- It supports four extraction engines, with `pdfreport` providing the most detailed layout preservation through `PageReport` and `TextElement` objects.
- The **linearization process** produces a compact format like `[120x600]Text content` that encodes spatial position directly in the string.
- **Prompt builders** in [`olmocr/prompts/prompts.py`](https://github.com/allenai/olmocr/blob/main/olmocr/prompts/prompts.py) wrap this text between `RAW_TEXT_START` and `RAW_TEXT_END` markers for reliable extraction.
- The pipeline automatically attaches anchor text to training samples in [`olmocr/train/dataloader.py`](https://github.com/allenai/olmocr/blob/main/olmocr/train/dataloader.py), enabling layout‑aware document understanding without image processing.

## Frequently Asked Questions

### What is the anchor text mechanism in OLMoCR?

The anchor text mechanism is a deterministic text extraction pipeline that creates position‑aware string representations of PDF pages. It captures the spatial coordinates of text and image elements, then formats them into a concise linear text that can be inserted into LLM prompts as grounding context.

### How does the anchor text mechanism handle images?

When using the `pdfreport` engine, the mechanism identifies image regions and converts them into `[Image x1,y1 to x2,y2]` blocks within the linearized output. The `_linearize_pdf_report()` function merges overlapping image areas to prevent duplication while preserving the bounding box coordinates that indicate where images appear on the page.

### Which PDF engines does the anchor text mechanism support?

The `get_anchor_text()` function supports four engines: `pdfreport` (custom layout‑preserving parser), `pdftotext` (Poppler utility), `pdfium` (Chromium library), and `pypdf` (Python‑native parser). The `pdfreport` engine provides the richest spatial metadata through `PageReport` objects, while the other engines offer faster text‑only extraction.

### How is anchor text integrated into training prompts?

Training prompts integrate anchor text through helper functions like `build_finetuning_prompt()` in [`olmocr/prompts/prompts.py`](https://github.com/allenai/olmocr/blob/main/olmocr/prompts/prompts.py). These functions wrap the raw anchor text between `RAW_TEXT_START` and `RAW_TEXT_END` markers, creating a structured prompt that the dataloader (in [`olmocr/train/dataloader.py`](https://github.com/allenai/olmocr/blob/main/olmocr/train/dataloader.py)) attaches to each training sample as the `instruction_prompt` field.