Skip to content
getnextpdf.com

Pro edition

Extraction — Deep Reference

This page is the contract-level reference for NextPDF\Pro\Extraction. The module contains five public symbols: two extractors (CitedTextExtractor, CitedTableExtractor) and three immutable value objects (CitedTextBlock, CitedTableBlock, CitedTableCell). Both extractors consume a parsed NextPDF\Ast\AstDocument; neither reads raw PDF bytes. Extraction is deterministic and structural. No semantic, embedding, or ranking step exists anywhere in this module. The task-oriented view lives on the capability page.

This capability ships in NextPDF Pro (nextpdf/pro) and activates with a Pro-tier license envelope. A deployment without that entitlement does not load the capability’s classes. Compare editions and get a license.

No runtime capability flag gates this module. The classes are available whenever nextpdf/pro is installed and licensed.

SymbolParametersDefault behaviorReturnsThrows or fails withNotes
CitedTextExtractor::__construct()?int $maxTokensPerChunk = null, int $minChunkLength = 10No token budget; trimmed text under 10 bytes is droppedCitedTextExtractorDoes not throwA null budget means one block per node.
CitedTextExtractor::extract()AstDocument $documentDepth-first walk; one block per qualifying text node, split by the token budgetlist<CitedTextBlock>Does not throwDeterministic; chunkIndex resets to 0 on each call.
CitedTextBlock::__construct()five readonly fieldsImmutable value object; no serializer methodDoes not throwmetadata keys: nodeType, pageIndex, plus optional structType, lang, alt, untagged.
CitedTextBlock::estimatedTokens()noneceil(byte length / 4)intDoes not throwBudget heuristic; not a tokenizer.
CitedTableExtractor::extract()AstDocument $documentCollects outermost Table nodes in document orderlist<CitedTableBlock>Does not throwNever descends into a table subtree.
CitedTableBlock::__construct()five readonly fieldsImmutable rectangular row-major cell matrixDoes not throwShort rows are right-padded at extraction time.
CitedTableBlock::toArray()noneSerializes to a snake_case plain arrayarray<string, mixed>Does not throwNested cells serialize via CitedTableCell::toArray().
CitedTableCell::__construct()seven readonly fieldsImmutable cell record with citation coordinatesDoes not throwPadding cells carry an empty nodeId and confidence 0.0.
CitedTableCell::toArray()noneSerializes to a snake_case plain array; bbox nests or is nullarray<string, mixed>Does not throw
final class CitedTextExtractor
public function __construct(
private readonly ?int $maxTokensPerChunk = null,
private readonly int $minChunkLength = 10,
)
public function extract(AstDocument $document): array
final class CitedTableExtractor
public function extract(AstDocument $document): array
final readonly class CitedTextBlock
public function __construct(
public string $text,
public CitationAnchor $anchor,
public float $confidence,
public int $chunkIndex,
public array $metadata,
)
public function estimatedTokens(): int
final readonly class CitedTableBlock
public function __construct(
public readonly string $nodeId,
public readonly int $pageIndex,
public readonly int $rowCount,
public readonly int $colCount,
public readonly array $matrix,
)
public function toArray(): array
final readonly class CitedTableCell
public function __construct(
public readonly string $nodeId,
public readonly int $row,
public readonly int $col,
public readonly ?string $textContent,
public readonly ?BoundingBox $bbox,
public readonly int $pageIndex,
public readonly float $confidence,
)
public function toArray(): array
  • Node selection. CitedTextExtractor emits blocks for nodes whose type is Paragraph, Heading, ListItem, TableCell, Code, or Annotation. A node with null text is skipped. A node is emitted only when its trimmed text length is at least minChunkLength (default 10). All lengths are byte lengths.
  • Traversal order. The walk is depth-first from the document root. A qualifying node is emitted before its children are visited. chunkIndex increments across the whole document walk and resets to 0 on each extract() call.
  • Chunking. With maxTokensPerChunk unset, each node yields one block. When set, text longer than maxTokensPerChunk * 4 bytes is split. The splitter prefers a sentence boundary — a newline, or a period followed by a space — found by scanning backward at most 200 bytes from the preferred cut. Otherwise it hard-breaks at the budget. Spaces after a cut are skipped; empty chunks are dropped.
  • Citation anchor. Each block’s CitationAnchor carries the node id, page index, a bounding box, a confidence, and a null content hash. Nodes without a bounding box receive a shared zero-area sentinel, BoundingBox(0, 0, 0, 0), so the anchor is always structurally valid.
  • Text confidence. Confidence reads the node’s confidence attribute when it is an int or float; the default is 1.0. Non-numeric attribute values fall back to the default.
  • Block metadata. metadata always carries nodeType and pageIndex. structType, lang, and alt are copied when present on the node. untagged is set to true when the node carries an untagged attribute.
  • Table selection. CitedTableExtractor collects only the outermost Table nodes, in document order. Once a Table node is processed its subtree is not re-examined; nested tables are unsupported.
  • Matrix shape. Rows come from TableRow children; cells come from their TableCell children. Other child types are ignored. colCount is the maximum cell count across all rows. Short rows are right-padded to colCount with synthetic cells: empty nodeId, null text, null bbox, the table’s page index, confidence 0.0. A table with no rows or no columns yields no block.
  • Cell confidence. A real cell’s confidence reads its confidence attribute when it is an int or float; the default is 0.8. Text blocks default to 1.0; table cells default to 0.8.
  • Structure mapping. The traversed hierarchy maps to the PDF logical-structure model (ISO 32000-2:2020 §14.7). Table rows map to the TR structure element (§14.8) when the source is tagged.
  • Nothing on this surface throws. Both extract() methods return an empty list for a document with no qualifying nodes.
  • The zero-area bounding box is a shared singleton sentinel. Callers needing a real region must detect it explicitly: width === 0.0 && height === 0.0.
  • All length checks and splits are byte-based. When no sentence boundary exists within the 200-byte window, a hard break can fall inside a multibyte UTF-8 sequence.
  • The 4-bytes-per-token figure is a budgeting heuristic only. It is not a tokenizer and does not match any specific model’s tokenization. estimatedTokens() uses the same heuristic.
  • A numeric string in a confidence attribute is not coerced; the default applies. Only int and float values are honored.
  • Whitespace skipping after a cut removes plain spaces only. Tabs and newlines at a chunk start are preserved.
  • TableCell text is extracted twice by design: as text blocks by CitedTextExtractor, and inside matrices by CitedTableExtractor. Deduplicate downstream when running both extractors over one document.
  • Padding cells are identifiable by an empty nodeId and confidence 0.0. A real but empty cell keeps its non-empty nodeId.
  • No cryptographic operation occurs in this module, so there is no FIPS-mode-specific behavior.

When the source document is tagged, the AST mirrors the logical-structure hierarchy of ISO 32000-2:2020 §14.7, and Table/TableRow nodes correspond to the §14.8 Table/TR structure elements. Extraction quality is bounded by tagging quality; untagged content produces fewer or coarser nodes.

These are structural-alignment statements. This module consumes whatever structure the Core AST subsystem produced.

  • Reusing one CitedTextExtractor instance across documents is safe sequentially; extract() resets chunkIndex before each walk.
  • Tune minChunkLength to filter noise nodes (page numbers, stray glyph runs) before chunking, not after.
  • For CJK and other multibyte scripts the byte-based heuristic over-counts tokens; size maxTokensPerChunk accordingly.
  • CitedTableBlock::toArray() and CitedTableCell::toArray() emit snake_case keys for JSON pipelines. CitedTextBlock has no serializer; encode its fields yourself.
  • The contentHash field of CitationAnchor is always null on this surface. Compute content hashes downstream when the pipeline needs them.

This page documents externally observable behavior and the supported public API surface only. Internal namespace paths, helper classes, mechanism tables, runbook filenames, and ticket prefixes are out of scope.