Skip to content
getnextpdf.com

Pro edition

Projection

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.

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.

Terminal window
composer require nextpdf/pro:^3

The code lives under the NextPDF\Pro\Projection namespace.

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 a ProjectionIntent.
  • 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.

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.

  • 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.

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);
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);
  • 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.

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.

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.

Tokenization follows the lexical and content-stream conventions in ISO 32000-2; the source annotates the relevant clauses.

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.

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.

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.