Pro edition
Projection
At a glance
Section titled “At a glance”Projection parses a PDF content stream into a flat token list and emits a new content stream from those tokens. Emission requires an explicit declared intent. This module is not a general-purpose PDF editor.
Note. “Projection” here means content-stream token projection. It is not coordinate or geospatial projection. For geospatial features, see the Geo module.
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.
There is no separate per-feature license flag. A required ProjectionIntent argument gates emission at the API level, not a license switch.
Install
Section titled “Install”composer require nextpdf/pro:^3The code lives under the NextPDF\Pro\Projection namespace.
Conceptual overview
Section titled “Conceptual overview”ContentProjectionWriter provides three static operations:
tokenize()parses a content stream into a flat, ordered token list. This is read-only and needs no intent.emit()writes a new content stream from a (possibly modified) token list. It requires aProjectionIntent.roundTrip()tokenizes then re-emits without changes, for validation.
The output is conceptually a new content stream, not an edited copy of the original. The emitter normalizes whitespace and comments but keeps the operator sequence and operand values exact. The intent enum has exactly two cases — sanitization (redaction) and steganographic embedding — and deliberately has no generic case, so static analysis can detect unintended use.
Why it works this way
Section titled “Why it works this way”Projection refuses to be a general-purpose PDF editor. Emission rebuilds a fresh content stream from a flat token list, so the original is never mutated in place. That one-way model is what makes redaction trustworthy: removed tokens are absent from the output, not painted over. emit() therefore demands an explicit ProjectionIntent, and the enum offers only sanitization and steganographic embedding — no generic case. Static analysis can then flag any emission that lacks a declared, known purpose. The design trades editing convenience for a guarantee that destructive intent is always visible at the call site.
Design background: Redaction is not a black rectangle.
Behavior contract
Section titled “Behavior contract”tokenize($contentStream)returns a list of tokens covering strings, names, numbers, arrays, dictionaries, booleans, null, and operators.emit($tokens, $intent)requires an explicit intent; the type system enforces this at the call site.roundTrip()output is not byte-identical to the input, but the operator sequence and operand values match.- The emitter formats numbers to keep the integer and float distinction and re-escapes literal strings.
- The two declared intents are sanitization (a destructive, irreversible redaction operation) and steganographic embedding.
Code sample — Quick start
Section titled “Code sample — Quick start”The following reflects the documented public API. The repository does not ship a runnable example for this module.
use NextPDF\Pro\Projection\ContentProjectionWriter;
$tokens = ContentProjectionWriter::tokenize($contentStream);Code sample — Production
Section titled “Code sample — Production”use NextPDF\Pro\Projection\ContentProjectionWriter;use NextPDF\Pro\Projection\ProjectionIntent;
$tokens = ContentProjectionWriter::tokenize($contentStream);
// Validate first: a clean round-trip must hold before any modification.$check = ContentProjectionWriter::roundTrip($contentStream);
// Apply your modification to $tokens, then emit with a declared intent.$output = ContentProjectionWriter::emit($tokens, ProjectionIntent::Sanitization);Edge cases & gotchas
Section titled “Edge cases & gotchas”- Run
roundTrip()and confirm it holds before you trust a modify-and-emit sequence. Treat a failing round-trip as a stop condition. - The sanitization intent is irreversible. Removed content cannot be recovered from the output.
- The emitter normalizes whitespace and drops comments, so byte-level comparison with the original will differ even for an unmodified round-trip.
Performance
Section titled “Performance”Tokenize and emit are linear in content-stream length. The tokenizer bounds octal escape reads and hex string handling. There is no published throughput figure. Measure with representative content streams.
Security notes
Section titled “Security notes”The required intent argument prevents misuse as a general editor. The sanitization intent is destructive and irreversible; verify the round-trip first and confirm the redacted output before distribution. This module logs no content.
Conformance
Section titled “Conformance”Tokenization follows the lexical and content-stream conventions in ISO 32000-2; the source annotates the relevant clauses.
Enterprise boundary note
Section titled “Enterprise boundary note”Enterprise does not change Projection behavior. Enterprise adds higher-tier privacy and compliance features documented separately; they are not required to use the projection API.
Core fallback / alternative
Section titled “Core fallback / alternative”There is no Core equivalent. Without Pro, callers must build their own content-stream tokenizer; the intent-gated projection model is a Pro-only addition.
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.