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

> Learn how Chandra's header and footer filtering works. Discover how to omit page headers and footers using the include_headers_footers parameter in this technical guide.

- Repository: [Datalab/chandra](https://github.com/datalab-to/chandra)
- Tags: deep-dive
- Published: 2026-03-27

---

**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`](https://github.com/datalab-to/chandra/blob/main/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`](https://github.com/datalab-to/chandra/blob/main/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`](https://github.com/datalab-to/chandra/blob/main/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`](https://github.com/datalab-to/chandra/blob/main/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):

```bash
chandra input.pdf output_dir

```

Include headers and footers in the output:

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

```

### Python API Usage

```python
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`](https://github.com/datalab-to/chandra/blob/main/chandra/output.py) within the `parse_html` function, while configuration handling occurs in [`chandra/scripts/cli.py`](https://github.com/datalab-to/chandra/blob/main/chandra/scripts/cli.py) and [`chandra/model/__init__.py`](https://github.com/datalab-to/chandra/blob/main/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`](https://github.com/datalab-to/chandra/blob/main/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`](https://github.com/datalab-to/chandra/blob/main/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.