Pro edition
AST
At a glance
Section titled “At a glance”The AST module turns a PDF into an immutable, navigable document tree. It uses the tagged-structure tree when present and falls back to a heuristic builder for untagged documents, attaching bounding boxes and text to each node.
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 per-feature license flag exists. The code ships with the Pro edition; build behavior is governed entirely by AstBuildOptions (resource limits and page ranges), not a license switch.
Install
Section titled “Install”composer require nextpdf/pro:^3The code lives under the NextPDF\Pro\Ast namespace.
Conceptual overview
Section titled “Conceptual overview”AstBuilder orchestrates the PDF-to-tree pipeline: check the cache, reject encrypted input early, read the structure tree for tagged PDFs, fall back to an untagged path otherwise, attach bounding boxes from content-stream analysis, then cache the result. The output is an AstDocument whose nodes are immutable; updates reconstruct the affected subtree bottom-up rather than mutating in place.
Two fallback strategies exist for untagged PDFs: a bare fallback and an optional heuristic builder (AstBuildOptions::$useHeuristic). The module also provides an emitter path that can write an AST back to a PDF and verify the result, plus a mutation log for tracking changes applied to the tree.
Why it works this way
Section titled “Why it works this way”The tree is immutable by construction. Each edit rebuilds only the affected root-to-node path and shares the untouched subtrees by identity, so a built AstDocument is safe to hold, cache, and hand to concurrent readers without defensive copies. This mirrors how a PDF itself changes on disk: the write-back path appends an incremental update through AstWriter rather than rewriting the file, leaving the original bytes — and any existing signatures — intact. An append-only revision is also cheap to verify structurally, which is why AstWriter can check its own output before returning it. Reconstructing subtrees instead of mutating in place is the one decision that makes the module both navigable and safely editable.
Design background: Incremental updates and why they matter.
Behavior contract
Section titled “Behavior contract”AstBuilder::build($sourceHash)accepts the full SHA-256 hex of the source PDF and returns anAstDocument.- Encrypted PDFs are rejected with a dedicated unsupported-encryption error; decrypt before building.
- When no structure tree is present, the builder uses the untagged path automatically — heuristic if enabled, bare fallback otherwise.
- Resource limits in
AstBuildOptions(max nodes, max depth, max memory, wall-clock timeout) cause a build-limit or build-timeout error rather than unbounded work. - The cache key incorporates the source hash and the options hash, so two builds with identical inputs and options return the same tree.
AstNodeis immutable; consumers receive new node instances when the tree changes.
Code sample — Quick start
Section titled “Code sample — Quick start”The following reflects the documented public API.
use NextPDF\Pro\Ast\AstBuilder;use NextPDF\Pro\Ast\AstBuildOptions;
$builder = new AstBuilder($pdfReader, new AstBuildOptions());$document = $builder->build($sha256OfPdf);Code sample — Production
Section titled “Code sample — Production”use NextPDF\Pro\Ast\AstBuilder;use NextPDF\Pro\Ast\AstBuildOptions;
$options = new AstBuildOptions( maxNodes: 100_000, maxDepth: 200, maxMemoryBytes: 256 * 1024 * 1024, timeoutSeconds: 30.0, useHeuristic: true,);
$builder = new AstBuilder($pdfReader, $options, $astCache);
try { $document = $builder->build($sha256OfPdf);} catch (\NextPDF\Pro\Ast\Exception\AstUnsupportedEncryptionException $e) { // Decrypt the source first, then retry.}Edge cases & gotchas
Section titled “Edge cases & gotchas”- Pages whose content stream cannot be parsed are skipped during bounding-box attachment; the tree is still returned, just without boxes for those pages.
- The heuristic builder is opt-in. With it disabled, untagged PDFs yield a coarser tree from the bare fallback.
- The page range in
AstBuildOptionsuses 0-based, inclusive indices; leaving both bounds null processes all pages.
Performance
Section titled “Performance”Build cost scales with node count and page count; AstBuildOptions bounds both. The cache short-circuits repeated builds of the same input with the same options. The wall-clock timeout (default 30 s) and node ceiling (default 100,000) bound worst-case work; measure with representative documents.
Security notes
Section titled “Security notes”Treat input as untrusted. The builder rejects encrypted PDFs rather than partially processing them. Resource ceilings (nodes, depth, memory, time) protect against pathological or hostile documents. This module logs no document content.
Conformance
Section titled “Conformance”The structure-tree path reads tagged-PDF structures defined by ISO 32000-2; the module’s source annotates the relevant content-stream and structure clauses.
Enterprise boundary note
Section titled “Enterprise boundary note”Enterprise does not change AST behavior. Enterprise adds higher-tier compliance and archival capabilities documented separately; they are not required to build or consume an AST.
Core fallback / alternative
Section titled “Core fallback / alternative”Without Pro, there is no equivalent document tree; callers parse content streams directly using NextPDF Core primitives. See /modules/ast/.
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.