How Chandra Header and Footer Filtering Works: A Complete Technical Guide

Chandra's header and footer filtering works by inspecting the data-label attributes of OCR layout blocks and omitting any blocks labeled "Page-Header" or "Page-Footer" when the include_headers_footers parameter is set to False.

The datalab-to/chandra repository provides an optional header and footer filtering mechanism that lets you control whether page headers and footers appear in the final OCR output. This feature is governed by a single boolean flag that defaults to excluding these peripheral regions, ensuring cleaner extraction of main document content.

Configuration Options

You can control header and footer filtering through either the command-line interface or the Python API.

Command-Line Interface

In chandra/scripts/cli.py, the filtering behavior is controlled by the --include-headers-footers flag. This boolean switch defaults to False, meaning headers and footers are excluded unless explicitly requested.

Python API

When using the Python API, pass the include_headers_footers argument directly to the generate() method of the InferenceManager class. The parameter accepts a boolean value where False (default) filters out headers and footers, and True preserves them.

Implementation Details

The filtering mechanism operates through a three-stage pipeline involving argument parsing, propagation, and block-level inspection.

CLI Argument Definition

The CLI flag is defined in chandra/scripts/cli.py (lines 63-66) as a boolean option that defaults to False. When provided, this value is passed through **kwargs to the underlying model's generate() method.

Argument Propagation

Inside chandra/model/__init__.py (lines 24-30), the include_headers_footers value is extracted from the caller's kwargs and stored in an output_kwargs dictionary. This dictionary is then forwarded to the output parsing functions.

Block-Level Filtering Logic

The actual filtering occurs in chandra/output.py within the parse_html function (which also powers parse_markdown). The parser iterates over top-level <div> blocks generated by the OCR layout analysis. Each block carries a data-label attribute indicating its structural role. If the attribute equals "Page-Header" or "Page-Footer" and include_headers_footers is False, the block is skipped entirely (lines 59-63). This logic executes after layout parsing but before final HTML or Markdown serialization.

Practical Usage Examples

Command-Line Usage

Exclude headers and footers (default behavior):

chandra input.pdf output_dir

Include headers and footers in the output:

chandra input.pdf output_dir --include-headers-footers

Python API Usage

from chandra.model import InferenceManager
from chandra.model.schema import BatchInputItem
from PIL import Image

# Load a single page image

page_image = Image.open("page1.png")

# Prepare batch input

batch = [BatchInputItem(image=page_image, prompt_type="ocr_layout")]

# Create manager (default vllm)

manager = InferenceManager(method="vllm")

# Generate output without headers/footers (default)

result = manager.generate(batch)

# Generate output including headers and footers

result_with_hdr = manager.generate(
    batch,
    include_headers_footers=True
)

Summary

  • Default behavior: Headers and footers are filtered out unless explicitly enabled via --include-headers-footers or include_headers_footers=True.
  • Detection method: The system relies on data-label attributes assigned during OCR layout analysis, specifically looking for "Page-Header" and "Page-Footer" labels.
  • Implementation location: Filtering logic resides in chandra/output.py within the parse_html function, while configuration handling occurs in chandra/scripts/cli.py and chandra/model/__init__.py.
  • Scope: This is a post-processing filter applied after OCR inference but before output generation, affecting both HTML and Markdown outputs.

Frequently Asked Questions

What is the default behavior for headers and footers in Chandra?

By default, Chandra excludes headers and footers from the OCR output. The --include-headers-footers CLI flag and the include_headers_footers Python parameter both default to False, which triggers the filtering mechanism to skip any blocks labeled as "Page-Header" or "Page-Footer" during the parsing stage.

How does Chandra identify headers and footers in document layouts?

Chandra identifies headers and footers through the data-label attributes assigned to layout blocks during the OCR inference process. When the layout model processes a document, it categorizes text blocks into structural elements. The parse_html function in chandra/output.py checks these labels and filters out blocks marked "Page-Header" or "Page-Footer" when the inclusion flag is disabled.

Can I filter headers but keep footers (or vice versa)?

No, the current implementation uses a single boolean flag that controls both headers and footers simultaneously. As implemented in chandra/output.py (lines 59-63), the code checks for both "Page-Header" and "Page-Footer" labels under the same condition. To keep only one type, you would need to post-process the output or modify the filtering logic in the source code.

Does enabling headers and footers affect OCR accuracy?

Enabling headers and footers does not affect the accuracy of the underlying OCR engine itself, as the text is still recognized during the initial inference stage. However, including these regions may introduce repetitive text (such as page numbers or document titles) into your output, which could affect downstream text analysis or indexing operations. The filtering option simply controls whether these recognized regions appear in the final serialized output.

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 →