Pro edition
Extraction — Deep Reference
At a glance
Section titled “At a glance”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.
Availability & licensing
Section titled “Availability & licensing”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.
Public API surface
Section titled “Public API surface”| Symbol | Parameters | Default behavior | Returns | Throws or fails with | Notes |
|---|---|---|---|---|---|
CitedTextExtractor::__construct() | ?int $maxTokensPerChunk = null, int $minChunkLength = 10 | No token budget; trimmed text under 10 bytes is dropped | CitedTextExtractor | Does not throw | A null budget means one block per node. |
CitedTextExtractor::extract() | AstDocument $document | Depth-first walk; one block per qualifying text node, split by the token budget | list<CitedTextBlock> | Does not throw | Deterministic; chunkIndex resets to 0 on each call. |
CitedTextBlock::__construct() | five readonly fields | Immutable value object; no serializer method | — | Does not throw | metadata keys: nodeType, pageIndex, plus optional structType, lang, alt, untagged. |
CitedTextBlock::estimatedTokens() | none | ceil(byte length / 4) | int | Does not throw | Budget heuristic; not a tokenizer. |
CitedTableExtractor::extract() | AstDocument $document | Collects outermost Table nodes in document order | list<CitedTableBlock> | Does not throw | Never descends into a table subtree. |
CitedTableBlock::__construct() | five readonly fields | Immutable rectangular row-major cell matrix | — | Does not throw | Short rows are right-padded at extraction time. |
CitedTableBlock::toArray() | none | Serializes to a snake_case plain array | array<string, mixed> | Does not throw | Nested cells serialize via CitedTableCell::toArray(). |
CitedTableCell::__construct() | seven readonly fields | Immutable cell record with citation coordinates | — | Does not throw | Padding cells carry an empty nodeId and confidence 0.0. |
CitedTableCell::toArray() | none | Serializes to a snake_case plain array; bbox nests or is null | array<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): arrayfinal class CitedTableExtractor
public function extract(AstDocument $document): arrayfinal readonly class CitedTextBlock
public function __construct( public string $text, public CitationAnchor $anchor, public float $confidence, public int $chunkIndex, public array $metadata,)
public function estimatedTokens(): intfinal 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(): arrayfinal 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(): arrayBehavior contract
Section titled “Behavior contract”- Node selection.
CitedTextExtractoremits blocks for nodes whose type isParagraph,Heading,ListItem,TableCell,Code, orAnnotation. A node withnulltext is skipped. A node is emitted only when its trimmed text length is at leastminChunkLength(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.
chunkIndexincrements across the whole document walk and resets to 0 on eachextract()call. - Chunking. With
maxTokensPerChunkunset, each node yields one block. When set, text longer thanmaxTokensPerChunk * 4bytes 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
CitationAnchorcarries the node id, page index, a bounding box, a confidence, and anullcontent 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
confidenceattribute when it is an int or float; the default is 1.0. Non-numeric attribute values fall back to the default. - Block metadata.
metadataalways carriesnodeTypeandpageIndex.structType,lang, andaltare copied when present on the node.untaggedis set totruewhen the node carries anuntaggedattribute. - Table selection.
CitedTableExtractorcollects only the outermostTablenodes, in document order. Once aTablenode is processed its subtree is not re-examined; nested tables are unsupported. - Matrix shape. Rows come from
TableRowchildren; cells come from theirTableCellchildren. Other child types are ignored.colCountis the maximum cell count across all rows. Short rows are right-padded tocolCountwith synthetic cells: emptynodeId,nulltext,nullbbox, 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
confidenceattribute 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
TRstructure element (§14.8) when the source is tagged.
Edge cases & failure modes
Section titled “Edge cases & failure modes”- 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
confidenceattribute 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.
TableCelltext is extracted twice by design: as text blocks byCitedTextExtractor, and inside matrices byCitedTableExtractor. Deduplicate downstream when running both extractors over one document.- Padding cells are identifiable by an empty
nodeIdand confidence 0.0. A real but empty cell keeps its non-emptynodeId. - No cryptographic operation occurs in this module, so there is no FIPS-mode-specific behavior.
Conformance
Section titled “Conformance”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.
Development notes
Section titled “Development notes”- Reusing one
CitedTextExtractorinstance across documents is safe sequentially;extract()resetschunkIndexbefore each walk. - Tune
minChunkLengthto 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
maxTokensPerChunkaccordingly. CitedTableBlock::toArray()andCitedTableCell::toArray()emit snake_case keys for JSON pipelines.CitedTextBlockhas no serializer; encode its fields yourself.- The
contentHashfield ofCitationAnchoris alwaysnullon this surface. Compute content hashes downstream when the pipeline needs them.
Publication boundary
Section titled “Publication boundary”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.