Home

Table representations

DocSlicer always extracts tables as structured cells — rows, columns, spans, and header roles — available on result.tables. But when a table lands inside a chunk or block, its text has to be serialised to a string so it can be embedded or fed to a model. The table_representation parameter controls that serialisation.

result = docslicer.parse_document(
    "report.pdf",
    table_representation="markdown",  # "markdown" (default) | "melted" | "jsonl"
)

The setting applies to every table rendered into chunk and block text (and to chart blocks, which the same setting governs — see Chart representations). The structured cells on result.tables are unaffected — they're always there regardless of which representation you pick.


The example table

Each format below serialises the same source table — a financial breakdown whose header is two rows deep, with a single Three Months Ended label spanning (colspan) the two dated columns beneath it:

|          |           Three Months Ended            |
|          | December 27, 2025  | December 28, 2024  |
|----------|--------------------|--------------------|
| iPhone®  |            $85,269 |            $69,138 |
| Mac®     |              8,386 |              8,987 |
| iPad®    |              8,595 |              8,088 |

How that two-level header is flattened — or whether it's flattened at all — is the main thing that separates the three formats.


markdown (default)

Preserves the original 2D layout, multi-row headers and all. It's the most human-readable and the safest general-purpose choice for RAG, since the embedded text mirrors how the table looks on the page:

|          | Three Months Ended | Three Months Ended |
|          | December 27, 2025  | December 28, 2024  |
|----------|-------------------:|-------------------:|
| iPhone®  |            $85,269 |            $69,138 |
| Mac®     |              8,386 |              8,987 |
| iPad®    |              8,595 |              8,088 |

Column and row spans are filled by duplicating the spanned value into each covered cell, and the header separator is drawn under the last header row.

The aligned columns above are for readability only. The actual chunk text is not padded into neat columns — cells are joined with single-space pipes to conserve tokens. A frontier LLM reads the unaligned form just as well, and the saved whitespace adds up across a long document.


melted

One row per cell, with the full header path joined by > and the row label kept in front. Because every value sits next to its complete header context on its own line, this format is good for sparse or pivot-style tables where retrieving an individual cell matters:

iPhone® | Three Months Ended > December 27, 2025 | $85,269
iPhone® | Three Months Ended > December 28, 2024 | $69,138
Mac® | Three Months Ended > December 27, 2025 | 8,386
Mac® | Three Months Ended > December 28, 2024 | 8,987
iPad® | Three Months Ended > December 27, 2025 | 8,595
iPad® | Three Months Ended > December 28, 2024 | 8,088

Each line reads row label | header path | value. A label-only row (a section header with no data) collapses to just its label.


jsonl

One JSON object per data row, with multi-row headers joined by _ into a single key. Useful when chunks are fed into structured extraction or tool-use pipelines that parse JSON rather than free text:

{"Metric": "iPhone®", "Three Months Ended_December 27, 2025": "$85,269", "Three Months Ended_December 28, 2024": "$69,138"}
{"Metric": "Mac®", "Three Months Ended_December 27, 2025": "8,386", "Three Months Ended_December 28, 2024": "8,987"}
{"Metric": "iPad®", "Three Months Ended_December 27, 2025": "8,595", "Three Months Ended_December 28, 2024": "8,088"}

The leading row-label column becomes the Metric key when it has no header of its own.


Choosing a format

FormatShapeTends to suit
markdown2D grid, layout preservedHuman-readable output and general-purpose RAG — a safe default.
meltedOne fact per row (label | header | value)Sparse or pivot tables, where keeping each value next to its full header path may help single-cell retrieval.
jsonlOne JSON object per rowFeeding chunks into structured-extraction or tool-use pipelines that parse JSON.

These are starting points, not hard rules — the best format depends on your documents, embedding model, and downstream task. Run an eval on your own corpus to see what actually works best for you; the right choice is whichever measurably improves retrieval or extraction on your data.

The choice only affects the text representation of tables inside chunks and blocks. For the structured Table object — cells, spans, and per-cell roles — see Table. For where table blocks sit in the chunking pipeline, see Chunking and Blocks.