Pdf Processor
When word-wrapped prose looks exactly like a table
TLDR
PDF generators that encode paragraphs as individual word-level text items create false-positive borderless table classifications because scattered word $X$-coordinates trigger spatial column anchor clustering. Ratio-based fill-rate gates (tagged / (bands * anchors)) fail because the line-start anchor inflates density. Adding an explicit anchor quality gate requiring $\ge 50\%$ of column anchors to appear across $\ge 25\%$ of participating bands eliminates prose table misclassifications.
| Document Layout | $X$-Anchor Clustering Behavior | Fill-Rate Gate Result | Anchor Quality Gate Result |
|---|---|---|---|
| Word-Span Paragraph Prose | 1 Line-start anchor + 8 noise word anchors | $0.304$ (Passes ratio threshold) | Rejected ($1/9$ anchors qualified) |
| Structured Stream Table | 4 Consistent data column anchors | $0.750$ (Passes ratio threshold) | Passed ($4/4$ anchors qualified) |
Technical defect analysis & anchor quality gate
// Anchor Quality Gate: Ensures column anchors appear consistently across bands
export function validateAnchorQualityDistribution(colAnchors, bands) {
// For small groups (<= 5 bands), anchors must appear in ALL bands
const minPresenceBands = bands.length <= 5
? bands.length
: Math.max(3, Math.floor(bands.length * 0.25));
const qualifiedAnchorsCount = colAnchors.filter(anchor => { const distinctBandIndices = new Set(anchor.items.map(item => item._band)).size; return distinctBandIndices >= minPresenceBands; }).length;
// Require at least half of the detected anchors to meet the band presence threshold return qualifiedAnchorsCount >= Math.ceil(colAnchors.length / 2); }
Rule of thumb: Combine overall fill-rate ratio gates with anchor quality distribution checks to prevent word-span prose from misclassifying as borderless stream tables.
Read this post in the full Engineering Journal →