Pro edition
Converter
At a glance
Section titled “At a glance”NextPDF\Pro\Converter reads an existing PDF and exports its content to one
of three text-based targets: positioned HTML, simplified SVG, or plain text.
It is a content-extraction exporter, not a pixel-perfect PDF renderer.
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 Converter classes resolve whenever the Pro package is installed and autoloaded.
Install
Section titled “Install”composer require nextpdf/pro:^3Conceptual overview
Section titled “Conceptual overview”The Converter parses the text-showing operators inside a PDF content stream —
Tj, TJ, and ' per ISO 32000-2:2020 §9.4 — and rebuilds an approximate
representation of each page. It reads positioning from the Td and Tm text
operators and font size from Tf, then maps points to output coordinates.
Three converters are exposed, one per ConversionTarget:
PdfToHtmlConverterwraps each page in a positioned container and emits absolutely-positioned<div>elements for each text run. Output is a self-contained HTML5 document.PdfToSvgConverterparses a limited set of drawing operators (rectangles viare, lines viam/l) plus text, and emits matching<rect>,<line>, and<text>elements for one page.PdfToTextConverterextracts only the decoded text, page by page, separated by a page-break marker.
This is a deliberately bounded exporter. It approximates text position; it does not reflow, it does not rasterize, and it does not reproduce vector paths, shading, clipping, transparency, or embedded images. For full-fidelity HTML-to-PDF rendering in the opposite direction, use the Core HTML pipeline.
Why it works this way
Section titled “Why it works this way”A PDF stores text as positioned glyph-showing operators, not semantic
characters, so there is no reliable document text to read back. The Converter
therefore scans the content-stream operators directly — Tj, TJ, ', plus
Td, Tm, and Tf for placement — and rebuilds an approximate layout instead
of reflowing or rasterizing the page. That bounded scan is what keeps export
linear in byte length, deterministic for identical input, and safe on untrusted
bytes without executing embedded logic. It also sets the honest ceiling: glyphs
are not reverse-mapped to Unicode, so custom-encoded fonts export as raw bytes
and exact visual fidelity stays out of scope.
Design background: Why the text in a PDF is not really text.
Behavior contract
Section titled “Behavior contract”- Input. Raw PDF bytes (
string). An empty string raisesInvalidArgumentException. - Output. A
ConversionResultvalue object holding the produced string, theConversionTarget, the processed page count, and a processing-time measurement. - Coverage. Text export (
Tj/TJ/') is the verified path, exercised by the unit suite. SVG export covers rectangles, straight lines, and text only. RGB stroke color is not yet propagated to SVG output. - Determinism. For identical input and configuration, the produced HTML,
SVG, or text byte stream is stable. The
processingTimeMsfield is a wall measurement and is not part of the deterministic surface. - Encoding. HTML output is
htmlspecialchars-escaped; SVG output is XML-escaped. Common PDF string escape sequences (\n,\r,\t,\(,\),\\) are decoded for the text target.
Public API surface
Section titled “Public API surface”| Type | Kind | Key members |
|---|---|---|
NextPDF\Pro\Converter\PdfToHtmlConverter | final class | convert(string $pdfData, ?ConversionConfig $config = null): ConversionResult |
NextPDF\Pro\Converter\PdfToSvgConverter | final class | convert(string $pdfData, int $pageIndex = 0, ?ConversionConfig $config = null): ConversionResult |
NextPDF\Pro\Converter\PdfToTextConverter | final class | convert(string $pdfData): ConversionResult, extractPage(string $pdfData, int $pageIndex): string |
NextPDF\Pro\Converter\ConversionConfig | final readonly class | __construct(ConversionTarget $target, bool $embedFonts = false, bool $embedImages = true, float $scaleFactor = 1.0, string $cssClass = 'pdf-page') |
NextPDF\Pro\Converter\ConversionResult | final readonly class | string $output, ConversionTarget $target, int $pageCount, float $processingTimeMs, size(): int, isValid(): bool |
NextPDF\Pro\Converter\ConversionTarget | enum | Html5, Svg, PlainText; mimeType(): string, fileExtension(): string |
Code sample — Quick start
Section titled “Code sample — Quick start”<?php
declare(strict_types=1);
use NextPDF\Pro\Converter\PdfToTextConverter;
$pdf = file_get_contents('report.pdf');$result = (new PdfToTextConverter())->convert($pdf);
echo $result->pageCount, " pages, ", $result->size(), " bytes of text\n";echo $result->output;Code sample — Production
Section titled “Code sample — Production”<?php
declare(strict_types=1);
use NextPDF\Pro\Converter\ConversionConfig;use NextPDF\Pro\Converter\ConversionTarget;use NextPDF\Pro\Converter\PdfToHtmlConverter;
function exportPreview(string $pdfBytes): string{ if ($pdfBytes === '') { throw new InvalidArgumentException('empty PDF payload'); }
$config = new ConversionConfig( target: ConversionTarget::Html5, scaleFactor: 1.0, cssClass: 'doc-preview', );
$result = (new PdfToHtmlConverter())->convert($pdfBytes, $config);
if (! $result->isValid()) { throw new RuntimeException('converter produced no output'); }
return $result->output;}Edge cases & gotchas
Section titled “Edge cases & gotchas”- A PDF with no
BT/ETtext blocks yields empty or page-shell-only output; scanned (image-only) PDFs produce no text because there is no OCR step. PdfToSvgConverterconverts a single page at a time, selected by$pageIndex; an out-of-range index yields an empty page stream.- Positioning is approximate. Text placed with non-text transforms, rotated text, or column flow may not reproduce its original visual layout.
- Glyph-to-Unicode mapping is not applied; text from fonts using custom encodings may export as the raw byte sequence.
Performance
Section titled “Performance”Parsing is linear in PDF byte length. Memory tracks the input plus the
produced output string. The performance_budget front-matter is the
per-invocation reference for a typical office document.
Security notes
Section titled “Security notes”The converter parses untrusted PDF bytes with bounded strpos/substr
scanning over text operators; it does not execute embedded JavaScript or
follow external references. Treat exported HTML as untrusted content and
escape it appropriately for its destination. See the Core security model.
Conformance
Section titled “Conformance”| Claim | Spec clause | Status |
|---|---|---|
Tj text-showing operator parsed | ISO 32000-2:2020 §9.4 | Verified (unit suite) |
TJ array text-showing operator parsed | ISO 32000-2:2020 §9.4 | Verified (unit suite) |
| Full vector/raster page fidelity | — | Not supported (out of scope) |
Core fallback / alternative
Section titled “Core fallback / alternative”There is no Core equivalent for PDF export. For the forward direction (authoring a PDF from HTML), the open-source Core HTML pipeline is the supported path. See /modules/core/html/.
Enterprise boundary note
Section titled “Enterprise boundary note”The Converter is a Pro-tier text/shape exporter. It does not perform OCR, semantic reconstruction, or document understanding. Those are separate concerns and are not provided by this module.
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.